I have a command executed in a POST_BUILD step using add_custom_command(). It takes quite some time, but I don't need the results to run the executable, I just want it to start after the build. Is there a way to run such a command in the background so that the executable can be run right after the build without waiting for the command to finish?
If you are willing to use some platform-specific logic, one way is to use a shell script to launch the command you want to run in the background. A very crude example for Unix systems may look like this:
launcher.sh:
#!/bin/sh
"$#"&
CMakeLists.txt:
add_custom_command(TARGET myTarget POST_BUILD
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/launcher.sh whateverYouWantToRun
)
You could add something equivalent for Windows and then test the CMAKE_HOST_SYSTEM_NAME variable to choose which launcher script to use.
Related
I want to create a directory by using the file(MAKE_DIRECTORY but it doesn't work with the generator expressions.
I'm trying to use the generator expression inside another CMake module, as a rough code snippet:
function_from_another_module(target_name)
and in that module:
file(MAKE_DIRECTORY $<TARGET_FILE_DIR:${target_name}>/foo/bar)
And in my real case, I'm trying to do some management on my exe targets, copy assets, generate files and some other platform based configurations.
The file() command is executed at configuration time and at that time and at that time generator expressions aren't evaluated yet. Furthermore the result may depend which is never available during the configuration process, just during the build.
You may be able to get the desired outcome by using adding build event logic via add_custom_command though:
add_custom_command(TARGET ${target_name} # correct target to attach logic to?
PRE_BUILD # or PRE_LINK/POST_BUILD ?
COMMAND ${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:${target_name}>/foo/bar")
Depending on your asset management logic you may want to create a cmake script doing the copying, execute it using ${CMAKE_COMMAND} -P script_file.cmake ... and pass necessary parameters using -D options, see CMake Command Line Tool: Run a Script
I think I do have a CMake order/parallelism problem.
In my build process, I need to build a tool which is then later used by some other target. This tool is a separate project with a CMakeLists.txt file like this:
project (package-tool LANGUAGES CXX)
set (SOURCES package_tool.cpp)
...
Later in the build, this top level target is referenced by some other target:
...
add_custom_command (OUTPUT "${DST_FILE}"
COMMAND ${PACKAGE_COMMAND} "${DST_FILE}"
COMMAND package-tool.exe -e "${DST_FILE}"
DEPENDS ${PACKAGE_DEPENDENCIES} package-tool)
...
I use ninja for building and the dependencies (ninja -t depends) are looking correctly. Also, the build commands (ninja -t commands) are making sense. But: From time to time, the build fails. The message does not make sense, it reads:
This version of package-tool.exe is not compatible with the version
of Windows you're running.
Because the build runs in parallel (32 processes) I suspect that the package-tool target is not completed when the generated exe is being used in the second target, which might lead to this confusing error message. Again, most of the time the build succeeds but every 10th or 20th run, it fails with that message.
So now my question is:
Is there a way to wait for a tool/target having been finished building in a parallel build in CMake/Ninja ?
Or how do I handle the task of building build tools in the same build process correctly ?
Thank you in advance !
Actually depend on the executable file and run the executable file, not the target. Don't concern yourself with any .exe suffix. Also better don't assume add_custom_command will be run in CMAKE_RUNTIME_OUTPUT_DIRECTORY - if you depend on specific directory explicitly set it with WORKING_DIRECTORY.
add_custom_command (
OUTPUT "${DST_FILE}"
COMMAND ${PACKAGE_COMMAND} "${DST_FILE}"
COMMAND $<TARGET_FILE:package-tool> -e "${DST_FILE}"
DEPENDS ${PACKAGE_DEPENDENCIES} $<TARGET_FILE:package-tool>
)
I have the following CMakeLists.txt:
cmake_minimum_required(VERSION 3.0.0)
project(FlaAlgoTests)
...
include_directories("../lib")
...
add_executable(
flamenco_algorithms_anomaly_stiction_tests
...
)
The flamenco_algorithms_anomaly_stiction_tests executable generates a .xml file when it is complete.
I would like to run a process (I guess using ADD_CUSTOM_COMMAND?) after this executable is run, which converts that xml file to an html file.
How can I do this?
The short answer is yes; you can use ADD_CUSTOM_COMMAND to first execute your built executable (flamenco_stiction_tests.exe), and second to run the additional process (my_additional_process.exe). Try something like this:
add_custom_command(TARGET flamenco_algorithms_anomaly_stiction_tests POST_BUILD
COMMAND flamenco_stiction_tests.exe
COMMAND my_additional_process.exe my_generated_file.xml
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Debug
COMMENT "Running built executable and additional process..."
)
Per the CMake documentation, these will be executed in order. You may also configure a script to run after the executable is built instead, using a combination of configure_file() and add_custom_command. Guaranteeing your generated file is available for the second process may be easier and safer that way.
add_custom_command can be used to execute custom command, however CMake is responsible to call these commands when eg before the build or after the build.
What I am looking for is a way to launch a custom command from the command line, such as :
cmake --build
cmake --my_custom_command
Or
cmake --build
make --my_custom_command
The reason I want to do this is because I would like to :
Create a command to launch by executable.
Create a command which gathers all the necessary include paths from my executable dependencies.
Doing so would allow me to configure my editor without having to manually set these things per project.
In CMake I currently have a simple Python script to generate a header, but if I update the script itself CMake won't re-run the script. Is there a way I can get CMake to do this?
It seems you are directly invoking your code generation script when cmake is run. While it is possible solution but it is definitely not a right way to use code generators with cmake.
I recommend you to use add_custom_command for your case:
add_custom_command(
OUTPUT generated.h
COMMAND ${PYTHON_EXECUTABLE} generator.py
DEPENDS generator.py
)
And next you can simple put your header to the list of source files passed to add_library/add_executable commands. cmake will automatically track all the dependencies and invoke your script.
Term DEPENDS generator.py informs cmake that it should regenerate header if script is changed.
With this approach file generated.h will be generated only at build time (when you run make or execute a build command in IDE). In contrast if you are running your script at cmake time (with execute_process command) then you have to rerun cmake to regenerate your file. Which is possible but you need to use some tricks to introduce a non-standard dependency.