我正在尝试使用内部版本号自动标记我的应用程序登录行。这个应用程序是一个没有图形 UI 的普通 C 应用程序;它适用于命令行,因此它是一个“简单”的。
登录 ID 位于由 CMake 自定义的“模板”源文件中configure_file()
命令自定义的“模板”源文件中。最近,我想在这个登录 ID 中包含一个内部版本号。因此,定制不能再在 CMake 时静态完成,而是每次调用 make。
为了实现这一点,CMake 中有两种可能性:
- add_custom_target(),但即使源树中没有其他任何不反映树状态的更改也会触发它;
- add_custom_command(),只有在应用程序(目标)需要再次链接时才能触发。
我选择了第二种解决方案,但没有成功。
这是我的CMakeLists.txt的摘录,登录 ID 在文件ErrAux.c中(PROJECT_SOURCE_DIR 中的模板,在 PROJECT_BINARY_DIR 中配置):
add_executable(anathem ... ${PROJECT_BINARY_DIR}/ErrAux.c ...)
add_custom_command(TARGET anathem PRE_LINK
COMMAND "${CMAKE_COMMAND}" "-DVERS=${PROJECT_VERSION}"
"-DSRC=${PROJECT_SOURCE_DIR}"
"-DDST=${PROJECT_BINARY_DIR}"
-P "${CMAKE_HOME_DIRECTORY}/BuildNumber.cmake"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Numbering build"
VERBATIM
)
这会在链接步骤之前启动脚本BuildNumber.cmake 。它计算下一个内部版本号并使用 自定义ErrAux.cconfigure_file()
。
它工作正常,除了...
它发生在制作序列的后期,对ErrAux.c的更新被忽视了。可执行文件中的登录 ID 包含以前的内部版本号。
下次我运行make时,make注意到生成的ErrAux.c比它的目标模块更年轻,并导致它再次被编译,这反过来又会导致一个链接触发内部版本号更新。即使没有其他文件发生更改并且此循环无法中断,也会发生这种情况。这在编译日志中清楚地显示:
Scanning dependencies of target anathem
[ 13%] Building C object AnaThem/CMakeFiles/anathem.dir/ErrAux.c.o
[ 14%] Linking C executable anathem
Numbering build
3.0.0-45
[ 36%] Built target anathem
症结似乎是add_custom_command(TARGET ...)
无法指定像这样的输出文件 add_custom_command(OUTPUT ...)
。但是后一种形式不能在 PRE_LINK 模式下触发。
作为一种解决方法,我强制编译以“刷新”对象模块:
add_custom_command(TARGET anathem PRE_LINK
COMMAND "${CMAKE_COMMAND}" "-DVERS=${PROJECT_VERSION}"
"-DSRC=${PROJECT_SOURCE_DIR}"
"-DDST=${PROJECT_BINARY_DIR}"
-P "${CMAKE_HOME_DIRECTORY}/BuildNumber.cmake"
COMMAND echo "Numbering"
COMMAND echo "${CMAKE_C_COMPILER}" "\$(C_DEFINES)" "\$(C_INCLUDES)" "\$(C_FLAGS)" -c "${PROJECT_BINARY_DIR}/ErrAux.c"
COMMAND "${CMAKE_C_COMPILER}" "\$(C_DEFINES)" "\$(C_INCLUDES)" "\$(C_FLAGS)" -c "${PROJECT_BINARY_DIR}/ErrAux.c"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Numbering build"
VERBATIM
)
在登录 ID 自定义后强制进行显式编译。它模仿了各种Makefile中的内容,我对生产不安全。这是CMake和make上的一个作弊技巧的一个作弊技巧。
更新:-c
需要选择将链接步骤推迟到最终的应用程序链接过程。
如日志所示,此添加会在链接中造成严重破坏,您可以在其中看到双重编译(标准制作一个和add_custom_command()
一个):
Scanning dependencies of target anathem
[ 13%] Building C object AnaThem/CMakeFiles/anathem.dir/ErrAux.c.o
[ 14%] Linking C executable anathem
Numbering build
3.0.0-47
Numbering
/usr/bin/cc -DANA_DEBUG=1 -I/home/prog/projects/AnaLLysis/build/AnaThem -I/home/prog/projects/AnaLLysis/AnaThem -g /home/prog/projects/AnaLLysis/build/AnaThem/ErrAux.c
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
AnaThem/CMakeFiles/anathem.dir/build.make:798: recipe for target 'AnaThem/anathem' failed
make[2]: *** [AnaThem/anathem] Error 1
更新:即使有正确的链接,我仍然遇到无限循环综合症。生成的应用程序的登录 ID 仍然落后于实际的构建计数器。
有人可以给我一个正确方向的线索吗?
仅供参考,我对 CMake 很陌生,所以我可能会做错事。不要犹豫,批评我的错误。