你忽略了一些信息,比如你需要在哪些平台上运行代码以及是否有可用的其他工具。如果你可以使用Ruby、Perl或Python,那么情况会简单得多。我假设你想在Unix和Windows平台上运行代码,并且没有额外的可用工具。
如果你希望从命令中获取输出并将其存储到预处理器符号中,最简单的方法是生成一个头文件,而不是在命令行参数上进行调整。请记住,CMake有一个脚本模式(-P),它仅处理文件中的脚本命令,因此你可以这样做:
CMakeLists.txt:
project(foo)
cmake_minimum_required(VERSION 2.6)
add_executable(foo main.c custom.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_custom_command(OUTPUT custom.h
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/custom.cmake)
"custom.h"文件是通过编译时执行命令"cmake-P custom.cmake"生成的。custom.cmake文件的内容如下:
execute_process(COMMAND uname -a
OUTPUT_VARIABLE _output OUTPUT_STRIP_TRAILING_WHITESPACE)
file(WRITE custom.h "#define COMPILE_TIME_VALUE \"${_output}\"")
它执行指定的命令(在本例中为“uname -a”,您将替换为想要的任何命令),并将输出放到变量_output中,然后将其写入custom.h。请注意,这只适用于输出单行命令。(如果需要多行输出,则必须编写更复杂的custom.cmake文件,具体取决于您如何将多行数据插入程序中。)
主要程序如下:
#include <stdio.h>
#include "custom.h"
int main()
{
printf("COMPILE_TIME_VALUE: %s\n", COMPILE_TIME_VALUE);
return 0;
}
如果你想在编译时计算编译器选项,那么事情就变得更加棘手。对于 Bourne-shell 生成器,你只需要将命令插入反引号中。如果在确定引用方式时感到困惑,请将命令的所有逻辑放置到一个 shell 脚本中,这样你只需在 add_definitions()
中放置 mycommand.sh
即可。
if(UNIX)
add_definitions(`${CMAKE_CURRENT_SOURCE_DIR}/custom-options.sh`)
endif()
对于基于Windows批处理文件的生成器,情况要复杂得多,我没有一个好的解决方案。问题在于
PRE_BUILD
命令不会作为与实际编译器调用相同的批处理文件的一部分执行(请查看BuildLog.htm以获取详细信息),因此我的初始想法无法实现(在
PRE_BUILD
步骤中生成custom.bat,然后对其执行“call custom.bat”,以设置一个可在编译器命令行中引用的变量)。如果批处理文件中有反引号的等效物,那么这个问题将得到解决。
希望这能给予一些思路和起点。
(现在不可避免地会有一个反问:你真正想做什么?)
编辑:我不确定为什么你不想让CMake用于生成头文件。使用${CMAKE_COMMAND}将扩展为用于生成Makefiles/.vcproj文件的CMake,由于CMake实际上不支持便携式Makefiles/.vcproj文件,因此您需要在目标机器上重新运行CMake。
CMake还有一堆实用命令(运行“cmake -E”获取列表)用于此明确原因。例如,您可以执行以下操作:
add_custom_command(OUTPUT custom.h COMMAND ${CMAKE_COMMAND} -E copy file1.h file2.h)
将file1.h复制到file2.h。
如果您不想使用CMake生成头文件,那么您需要调用单独的.bat/.sh脚本来生成头文件,或者使用echo进行生成:
add_custom_command(OUTPUT custom.h COMMAND echo
根据需要进行引用。