In the following CMakeLists.txt file, although I have set an add_custom_command
command with PRE_BUILD
option, the custom command is not always executed before making the main executable:
cmake_minimum_required(VERSION 2.8)
project(VersioningTest)
set(MAJOR 1)
set(MINOR 0)
set(PATCH 0)
set(PRODUCT App-${MAJOR}-${MINOR}-${PATCH})
ADD_EXECUTABLE(${PRODUCT}
main.cpp
Engine.cpp)
add_custom_command(TARGET ${PRODUCT} PRE_BUILD
COMMAND ${CMAKE_COMMAND}
-DMAJOR=${MAJOR}
-DMINOR=${MINOR}
-DPATCH=${PATCH}
-P ${CMAKE_SOURCE_DIR}/SetVersion.cmake
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "setting version...")
So I decided to replace add_custom_command
with add_custom_target
and add_dependencies
:
add_custom_target(SetVersion
COMMAND ${CMAKE_COMMAND}
-DMAJOR=${MAJOR}
-DMINOR=${MINOR}
-DPATCH=${PATCH}
-P ${CMAKE_SOURCE_DIR}/SetVersion.cmake
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "setting version...")
add_dependencies(${PRODUCT} SetVersion)
And it worked. Now the SetVersion.cmake
file is executed everytime before making the main executable. What's wrong with add_custom_command
in my CMake file?
The content of SetVersion.cmake
file:
EXECUTE_PROCESS(
COMMAND svn info ${CMAKE_SOURCE_DIR}
COMMAND grep Revision
OUTPUT_VARIABLE REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
EXECUTE_PROCESS(
COMMAND svn diff ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE SVNDIFF
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(SVNDIFF STREQUAL "")
set(LOCALCHANGES 0)
message("No local changes detected")
else(SVNDIFF STREQUAL "")
set(LOCALCHANGES 1)
message("Local changes detected!")
endif(SVNDIFF STREQUAL "")
configure_file(${CMAKE_SOURCE_DIR}/version.h.in ${CMAKE_SOURCE_DIR}/version.h)
message("Version set") # For testing only
And the content of version.h.in
:
#define MAJOR_VERSION "${MAJOR}"
#define MINOR_VERSION "${MINOR}"
#define PATCH_VERSION "${PATCH}"
#define REVISION "${REVISION}"
#define LOCALCHANGES "${LOCALCHANGES}"
It depends on the CMake generator you use. Here is the relevant section from the add_custom_command documentation:
This option has unique behavior for the Visual Studio Generators.
When using one of the Visual Studio generators,
the command will run before any other rules are executed within the target.
With all other generators, this option behaves the same as PRE_LINK instead.
Under OS X PRE_BUILD
also seems to work for Xcode, which is not documented properly.