I have a multi-file project and I use Cmake build system. I have mapped :make
to a key as I need to compile it very often. The problem is that I need to run the resulting executable just as often. However typing :!./variable_program_name
is very tedious.
Is there any way to detect/get the resulting executable file name?
The recommended way to do this is via a separate target in the Makefile, so that for example :make
just triggers the build, and :make run
triggers (build and) run of the executable. After all, the Makefile knows best what it's building, so the decision how to run the build artifacts (maybe also with passed arguments) is best delegated to it.
To "return" the executable from the Makefile, the :make
output is parsed and populates the quickfix list . You could define a custom mapping (for the qf
filetype, which is set for such windows) that parses the executable name from the current quickfix line, or even use getqflist()
to parse the entire output. That requires that your Makefile prints out the executable name (and path) in a way that can be detected.
If you can't even reliably get the executable name from the output, but know the directory where the executable is generated in, you can create a list of files (with glob()
) before running :make
, then after it again, and compare the two lists to get the executable name. If you don't want to remove the previous executable from within Vim, a filetime check ( getftime()
) could help.
For anyone viewing this.. I had the same need and decided to solve it with a vim script/plugin. vim-target
Expanding on Ingo Karkat's ideas, this script should do the trick (I am not good with vimscript so I wrote it in bash)
#!/bin/sh
# This script tries to build the project using Makefile, and if that fails
# it tries to generate the Makefile with Cmake.
# Then it finds the latest executable file and runs it
# Remember to manually run cmake after changing CMakeLists.txt as a new
# Makefile will not be automatically regenerated
if [[ -e "Makefile" ]] || [[ -e "makefile" ]]; then
make
if [[ $? -ne 0 ]]; then
echo "Error when running make"
exit
fi
else
if [[ -e "CMakeLists.txt" ]]; then
cmake .
if [[ $? -ne 0 ]]; then
echo "Error when running cmake"
exit
fi
make
if [[ $? -ne 0 ]]; then
echo "Error when running make"
exit
fi
else
echo "CMakeLists.txt doesn't exist"
exit
fi
fi
# Find latest executable file
unset latest
for file in "${1:-.}"/*
do
if [[ -f "$file" ]]; then
latest=${latest-$file}
find "$file" -executable -prune -newer "$latest" | read -r dummy && latest=$file
fi
done
if [[ -x "$latest" ]]; then
./$latest
else
echo "Latest file $latest is not executable"
fi
Just put this script in your $PATH
and map a key to execute it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.