您遗漏了一些信息,例如您需要在哪些平台上运行它以及是否可以使用任何其他工具。如果你可以使用 Ruby、Perl 或 Python,事情就会变得简单得多。我假设您想在 Unix 和 Windows pqlatform 上运行,并且没有可用的额外工具。
如果您希望命令的输出包含在预处理器符号中,最简单的方法是生成头文件,而不是摆弄命令行参数。请记住,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 脚本中,这样您只需要放入mycommand.sh
您的 add_definitions():
if(UNIX)
add_definitions(`${CMAKE_CURRENT_SOURCE_DIR}/custom-options.sh`)
endif()
对于基于 Windows 批处理文件的生成器,事情要复杂得多,而且我没有一个好的解决方案。问题是这些PRE_BUILD
命令没有作为与实际编译器调用相同的批处理文件的一部分执行(研究 BuildLog.htm 了解详细信息),所以我最初的想法没有奏效(PRE_BUILD
一步生成 custom.bat 然后执行在其上“调用 custom.bat”以获取变量集,稍后可以在编译器命令行中引用该变量集)。如果批处理文件中有等效的反引号,那将解决问题。
希望这能提供一些想法和起点。
(现在到不可避免的反问:你真正
想做什么?)
编辑:我不确定你为什么不想让 CMake 用于生成头文件。使用 ${CMAKE_COMMAND} 将扩展到用于生成 Makefiles/.vcproj-files 的 CMake,并且由于 CMake 并不真正支持便携式 Makefiles/.vcproj-files,因此您需要在目标计算机上重新运行 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 #define SOMETHING 1 > custom.h)
根据需要调整报价。