I'm using Ubuntu Linux.
I've been trying to get the following cscope command to run when I run "make" from my project directory, so it recompiles cscope and gets updated name information when I make my project.
cscope -b -q -U -R
Per my research and a bit of reading, I should be able to get CMake to run a command when you do 'make' by using the add_custom_command function in CMakeLists.txt.
However, many attempts and variations of it, have not been successful. Is it possible to run this as I want it with add_custom_command?
Simply doing this doesn't seem to work:
add_custom_command(OUTPUT
${CMAKE_CURRENT_BINARY_DIR}/cscope.in.out
${CMAKE_CURRENT_BINARY_DIR}/cscope.out
${CMAKE_CURRENT_BINARY_DIR}/cscope.po.out
COMMAND cscope -b -q -U -R)
I've tried using the TARGET overload of add_custom_command as well, and making a custom target with a dependency on either ALL or the main output file of the project, but that doesn't do anything either.
Ideally this would run after the project has been built, if could tell me what I'm doing wrong or if this is at all the way to do this, I'd be grateful?
I've tried using the TARGET overload of add_custom_command as well, and making a custom target with a dependency on either ALL or the main output file of the project, but that doesn't do anything either.
This seems to be the problem - when a CMake commands requires to be passed a target, they refer to the name of a target you've created previously by using any of add_executable, add_library or add_custom_target, which doesn't necessarily map to an actual artifact file generated by the command.
Here's my take on the problem, and it seems to generate the three cscope files in the build directory.
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
project(te)
add_executable(main main.cpp asdf.cpp)
add_custom_command(TARGET main POST_BUILD COMMAND cscope -b -q -U -R)
Note here that the name of the target here is whatever I've passed as the first argument to the add_executable command.
Related
I'm trying to use add_custom_command to generate a file during the build. The command never seemed to be run, so I made this test file.
cmake_minimum_required( VERSION 2.6 )
add_custom_command(
OUTPUT hello.txt
COMMAND touch hello.txt
DEPENDS hello.txt
)
I tried running:
cmake .
make
And hello.txt was not generated. What have I done wrong?
The add_custom_target(run ALL ... solution will work for simple cases when you only have one target you're building, but breaks down when you have multiple top level targets, e.g. app and tests.
I ran into this same problem when I was trying to package up some test data files into an object file so my unit tests wouldn't depend on anything external. I solved it using add_custom_command and some additional dependency magic with set_property.
add_custom_command(
OUTPUT testData.cpp
COMMAND reswrap
ARGS testData.src > testData.cpp
DEPENDS testData.src
)
set_property(SOURCE unit-tests.cpp APPEND PROPERTY OBJECT_DEPENDS testData.cpp)
add_executable(app main.cpp)
add_executable(tests unit-tests.cpp)
So now testData.cpp will generated before unit-tests.cpp is compiled, and any time testData.src changes. If the command you're calling is really slow you get the added bonus that when you build just the app target you won't have to wait around for that command (which only the tests executable needs) to finish.
It's not shown above, but careful application of ${PROJECT_BINARY_DIR}, ${PROJECT_SOURCE_DIR} and include_directories() will keep your source tree clean of generated files.
Add the following:
add_custom_target(run ALL
DEPENDS hello.txt)
If you're familiar with makefiles, this means:
all: run
run: hello.txt
The problem with two existing answers is that they either make the dependency global (add_custom_target(name ALL ...)), or they assign it to a specific, single file (set_property(...)) which gets obnoxious if you have many files that need it as a dependency. Instead what we want is a target that we can make a dependency of another target.
The way to do this is to use add_custom_command to define the rule, and then add_custom_target to define a new target based on that rule. Then you can add that target as a dependency of another target via add_dependencies.
# this defines the build rule for some_file
add_custom_command(
OUTPUT some_file
COMMAND ...
)
# create a target that includes some_file, this gives us a name that we can use later
add_custom_target(
some_target
DEPENDS some_file
)
# then let's suppose we're creating a library
add_library(some_library some_other_file.c)
# we can add the target as a dependency, and it will affect only this library
add_dependencies(some_library some_target)
The advantages of this approach:
some_target is not a dependency for ALL, which means you only build it when it's required by a specific target. (Whereas add_custom_target(name ALL ...) would build it unconditionally for all targets.)
Because some_target is a dependency for the library as a whole, it will get built before all of the files in that library. That means that if there are many files in the library, we don't have to do set_property on every single one of them.
If we add DEPENDS to add_custom_command then it will only get rebuilt when its inputs change. (Compare this to the approach that uses add_custom_target(name ALL ...) where the command gets run on every build regardless of whether it needs to or not.)
For more information on why things work this way, see this blog post: https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/
This question is pretty old, but even if I follow the suggested recommendations, it does not work for me (at least not every time).
I am using Android Studio and I need to call cMake to build C++ library. It works fine until I add the code to run my custom script (in fact, at the moment I try to run 'touch', as in the example above).
First of,
add_custom_command
does not work at all.
I tried
execute_process (
COMMAND touch hello.txt
)
it works, but not every time!
I tried to clean the project, remove the created file(s) manually, same thing.
Tried cMake versions:
3.10.2
3.18.1
3.22.1
when they work, they produce different results, depending on cMake version, one file or several. This is not that important as long as they work, but that's the issue.
Can somebody shed light on this mystery?
How can I make a program in Rust which can be executed from anywhere without using cargo run, by just clicking on the file?
Is there any crate? I have written code for snake game and I want to run it by just clicking on a file.
If you compile a Rust application with:
cargo build --release
it will place a binary file in ./target/release. So if your application is called snake_game, you can run it with ./target/release/snake_game, or by double-clicking on that file.
This binary is completely self-contained, so you can move or copy it to somewhere else on your computer.
First build your binary for release
cargo build --release
Next handle permissions
Typically chmod +x target/release/whateverYourProgramIsCalled to make executable, but cargo did this for us already
You can check it's Octal Permissions
ls -l target/release/whateverYourProgramIsCalled
chmod +x target/release/whateverYourProgramIsCalled
ls -l target/release/whateverYourProgramIsCalled
As you can see nothing has changed... the permissions were already correct for executing
Run that executable
./whateverYourProgramIsCalled
Optional: run from anywhere
You can run that binary anywhere from the command line
To do this you need to add it to your path
For mac you can add to your path from /etc/paths
whatever editor you prefer.... vi, code, etc...
sudo code /etc/paths
I added a path like this, saved and authenticated with a password
/Users/`whoami`/code/rust/binaries
whoami command is surrounded by `
next copy your new binary over to where it needs to be, in that binaries folder
cp whateverYourProgramIsCalled /Users/`whoami`/code/rust/binaries
Then open a new terminal window
Check your command is in your path
where whateverYourProgramIsCalled
Run your command from anywhere
whateverYourProgramIsCalled
Rejoice
There is another method you can do by using rustc. It will create an executable binary file in the same directory where your file exists.
Make sure you are in the src directory and the name of your file is main.rs.
rustc main.rs
./main
The advantage of using rustc is that you can run any file not only main.rs. just do:
rustc filename.rs
./filename
You can run it from terminal and also by clicking on that file.
Just wanted to add another answer here, not sure if it's related to a more recent version of rust.
If in the root of your project you just run the command cargo install --path . it will add it to cargo and allow you to run the binary just with project name.
Archlinux.
I downloaded mtools, which includes mcopy, which is what I'm after. The instructions in the INSTALL file say do this:
# ./configure
# make
These worked fine, now I have a bunch of .o files and of course executables.
What do I need to do, so I can just type
# mcopy
and have it run? Since I don't have it "installed" right now, doing that just says
-bash: mcopy: command not found
The usual linux build sequence is
./configure
make
make check
sudo make install
make check attempts to validate if the build took place correctly; not all Makefiles have it but many do. Note you will need sudo make install to do the install in the usual system directories if you are not root.
You can determine which of these options is available for your particular Makefile by
cat Makefile
and reading the labels on the left of the file.
You could create a symbolic link to the application in your /usr/bin folder like
ln -s /fullpath/to/app /usr/bin/aliasnameforapp
Then you can simple call aliasnameforapp from anywhere.
This is the way I install the config files:
file(GLOB ConfigFiles ${CMAKE_CURRENT_SOURCE_DIR}/configs/*.xml
${CMAKE_CURRENT_SOURCE_DIR}/configs/*.xsd
${CMAKE_CURRENT_SOURCE_DIR}/configs/*.conf)
install(FILES ${ConfigFiles} DESTINATION ${INSTDIR})
But I need to convert one of the xml files before installing it. There is an executable that can do this job for me:
./Convertor a.xml a-converted.xml
How can I automatically convert the xml file before installing it? It should be a custom command or target that installing depends on it, I just don't know how to make the install command depend on it though. Any advice would be appreciated!
Take a look at the SCRIPT version of install:
The SCRIPT and CODE signature:
install([[SCRIPT <file>] [CODE <code>]] [...])
The SCRIPT form will invoke the given CMake script files during
installation. If the script file name is a relative path it will be
interpreted with respect to the current source directory. The CODE
form will invoke the given CMake code during installation. Code is
specified as a single argument inside a double-quoted string.
For example:
install(CODE "execute_process(\"./Convertor a.xml a-converted.xml\")")
install(FILES a-converted.xml DESTINATION ${INSTDIR})
Be sure to checkout the entry for execute_process in the manual. Also be aware that macro expansion inside the CODE parameter can be a bit tricky to get right. Check the generated cmake_install.cmake in your build directory where the generated code will be placed.
I think that your specific case would work better if you were to use a custom command and target like so:
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/a-converted.xml
COMMAND ./Convertor a.xml a-converted.xml
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Convertor
)
add_custom_target(run ALL
DEPENDS ${CMAKE_BINARY_DIR}/a-converted.xml
COMMENT "Generating a-converted.xml" VERBATIM
)
install(
FILES ${CMAKE_BINARY_DIR}/a-converted.xml
DESTINATION ${INSTDIR}
)
Note: I don't have all the details, so the directories are probably
not exactly what you'd want in your environment, although it's
a good idea to generate files in the ${CMAKE_BINARY_DIR} area.
That way you can be sure that the file a-converted.xml is built at the time you want to install it. Especially, these two rules make sure that if you make changes to the file, it gets recompiled.
I am installing static file using CMake's INSTALL command.
I want to post process the output file using CMake.
For example, static files have a string like
v={{VERSION}}
I want to replace {{VERSION}} in the output files.
Is this possible with CMake?
Yes, but preprocessing is usually done at cmake invocation step, not during install. This is done using configure_file() command.
Note that configure_file() supports substituting values only in ${} or ##, so if you really need to configure a file with {{}}, you might end up writing your own function using the CMake command file().
Finally, you need to install your configured file. Be sure to
install(FILES ${CMAKE_BINARY_DIR}/your.file)
and not just
install(FILES your.file)
since the latter command would install your source file.