Кажется, я обнаружил проблему, возникшую у @ janitor048 с ответом @ richq. К сожалению, у меня недостаточно репутации, чтобы комментировать его ответ - может быть, кто-то другой сможет скопировать и вставить.
@ richq использует как пользовательскую команду, так и пользовательскую цель. Пользовательская команда необходима, чтобы убедить CMake, что заголовок будет создан, в противном случае сценарий CMake может быть выполнен как команда для пользовательской цели. Хотя пользовательская цель всегда будет выполняться, пользовательская команда не будет выполняться, если ее выходной файл уже существует.
Обходной путь - добавить поддельную зависимость (воображаемый файл) к пользовательской цели и сообщить CMake, что пользовательская команда создает этот файл. Этого достаточно, чтобы гарантировать, что пользовательская команда всегда выполняется. К счастью, CMake на самом деле не проверяет, создан этот файл или нет.
Ричк имеет:
# a custom target that is always built
add_custom_target(svnheader ALL
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/svnheader.h)
# creates svnheader.h using cmake script
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/svnheader.h
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/getsvn.cmake)
Это работает для меня:
# a custom target that is always built
add_custom_target(svnheader ALL
DEPENDS svn_header ) # svn_header is nothing more than a unique string
# creates svnheader.h using cmake script
add_custom_command(OUTPUT svn_header ${CMAKE_CURRENT_BINARY_DIR}/svnheader.h
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/getsvn.cmake)
Также, если кто-то хочет использовать Git, используйте это для сценария CMake:
#create a pretty commit id using git
#uses 'git describe --tags', so tags are required in the repo
#create a tag with 'git tag <name>' and 'git push --tags'
find_package(Git)
if(GIT_FOUND)
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags RESULT_VARIABLE res_var OUTPUT_VARIABLE GIT_COM_ID )
if( NOT ${res_var} EQUAL 0 )
set( GIT_COMMIT_ID "git commit id unknown")
message( WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info." )
endif()
string( REPLACE "\n" "" GIT_COMMIT_ID ${GIT_COM_ID} )
else()
set( GIT_COMMIT_ID "unknown (git not found!)")
message( WARNING "Git not found. Build will not contain git revision info." )
endif()
set( vstring "//version_string.hpp - written by cmake. changes will be lost!\n"
"const char * VERSION_STRING = \"${GIT_COMMIT_ID}\"\;\n")
file(WRITE version_string.hpp.txt ${vstring} )
# copy the file to the final header only if the version changes
# reduces needless rebuilds
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
version_string.hpp.txt ${CMAKE_CURRENT_BINARY_DIR}/version_string.hpp)