Is it somehow possible with CMake (version >= 2.8.7) to execute a macro or command as a last step before the configuration phase finishes?
The functionality should be executed before the following lines get printed on screen:
-- Configuring done
-- Generating done
Up to now I wasn't able to find a CMake target which could be used as a dependency to achieve this with add_custom_command
add_custom_target
or add_dependencies
.
EDIT:
We have a library exporting several CMake macros and some of these macros must be executed at the end of each CMakeLists.txt
file after all other CMake commands were run.
Ideally the desired behavior can be achieved by including a file macros.cmake
in a CMakeLists.txt
file without the necessity to add an additional command at the end of this CMakeLists.txt
file.
It would also be possible to achieve this by gathering all functionality in one macro which needs to be called explicitly at the end of the CMakeLists.txt
.
However, there are already several dependent libraries which would need to be adapted and a solution to this problem would omit this additional work.
Also, adding the macro can be forgotten or the requirement for it being the very last statement can be easily violated.
Example macros.cmake
:
macro(FINAL_MACRO)
message(STATUS "Last step before finishing Configure phase")
endmacro()
# HERE: something like add_custom_target(final_steps)
# followed by something like add_dependencies(final_steps cmake_configure_finished)
Example toplevel CMakeLists.txt
:
cmake_minimum_required(VERSION 2.8.7)
include(macros.cmake)
add_subdirectory(source)
add_subdirectory(interfaces)
# Here FINAL_MACRO should get executed without explicitly writing it down
If there is no other option we will have to require every user to call a special macro at the end of their CMakeLists.txt
file.
CMake executes the child process using operating system APIs directly: On POSIX platforms, the command line is passed to the child process in an argv[] style array. On Windows platforms, the command line is encoded as a string such that child processes using CommandLineToArgvW will decode the original arguments.
CMake can generate a native build environment that will compile source code, create libraries, generate wrappers and build executables in arbitrary combinations. CMake supports in-place and out-of-place builds, and can therefore support multiple builds from a single source tree.
CMake provides a command-line signature to install an already-generated project binary tree: cmake --install <dir> [<options>] This may be used after building a project to run installation without using the generated build system or the native build tool.
CMAKE_CONFIGURATION_TYPES. Specifies the available build types (configurations) on multi-config generators (e.g. Visual Studio, Xcode , or Ninja Multi-Config ). Typical values include Debug , Release , RelWithDebInfo and MinSizeRel , but custom build types can also be defined.
OK - This answer feels a bit fragile since it's making use of undocumented CMake behaviour. However, it does seem to work.
Towards the end of the configuring process, after all commands in the CMakeLists.txt file have been processed, CMake checks the value of CMAKE_BACKWARDS_COMPATIBILITY
. If this variable is being watched via the variable_watch
command, then it will be triggered here.
So you can wrap this functionality into a couple of functions:
function(EOFHook Variable Access)
if(${Variable} STREQUAL CMAKE_BACKWARDS_COMPATIBILITY AND
(${Access} STREQUAL UNKNOWN_READ_ACCESS OR ${Access} STREQUAL READ_ACCESS))
execute_process(COMMAND ${CMAKE_COMMAND} -E echo "In EOF hook command")
... do whatever else is required ...
endif()
endfunction()
function(SetupEOFHook)
variable_watch(CMAKE_BACKWARDS_COMPATIBILITY EOFHook)
endfunction()
To use this in any CMakeLists file, simply call SetupEOFHook()
anywhere in the file.
It's a bit risky; if the variable is also read elsewhere in the CMakeLists.txt e.g. via
message(${CMAKE_BACKWARDS_COMPATIBILITY})
then it would trigger the EOFHook
function here and at the end. You could add more complexity to the function by adding a counter and checking that it's only called once or else issue a message(FATAL_ERROR ...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With