我最初在CMake邮件列表上提出了这个问题:How to configure target or command to preprocess C file?
我正在将基于GNU Autotools的构建配置移植到CMake,我必须处理C预处理才能生成文件。
预处理器的输入是使用 C预处理器指令的 SQL 文件,如#include "another.sql"
等。
目前,Makefile
使用以下规则生成普通SQL
文件作为输出:
myfile.sql: myfile.sql.in.c
cpp -I../common $< | grep -v '^#' > $@
因此,myfile.sql
应该是构建过程的产品之一,类似于共享库或可执行文件。
我应该使用哪些CMake工具来达到同样的效果?
我不清楚我是否应该使用add_custom_command
,add_custom_target
或两者合并。
显然,我正在寻找一种可移植的解决方案,至少可以使用 GNU GCC 和 Visual Studio 工具集。我认为我必须定义特定于平台的自定义命令,一个用于cpp
预处理器,一个用于cl.exe /P
。
或者,CMake是否为C预处理器提供了任何类型的抽象?
我扫描了档案,但我只发现了基于 make 功能的fortran文件或解决方案的预处理:make myfile.i
所以,这不是我想要的。
更新:Added answer基于CMake邮件列表上的solution received from Petr Kmoch。
答案 0 :(得分:7)
我正在通过复制解决方案received from Petr Kmoch的基本部分作为对我在邮件列表中的帖子的回复来回答这个问题。
首先,使用add_custom_command
(带有OUTPUT签名的版本)创建自定义命令,以实际进行预处理。
例如:
add_custom_command(
OUTPUT myfile.sql
COMMAND "${CMAKE_C_COMPILER}" -E myfile.sql.in -I ../common
MAIN_DEPENDENCY myfile.sql.in
COMMENT "Preprocessing myfile.sql.in"
VERBATIM)
其次,配置命令触发器:
如果命令输出文件(myfile.sql
)用于另一个目标,则添加为源
文件已添加到add_library
或add_executable
,只需在这些命令中指定即可。 CMake会将其视为依赖项并根据需要运行自定义命令。
如果命令输出文件是未用作依赖项的最终输出
任何其他目标,然后添加自定义目标以使用add_custom_target
例如:
add_custom_target(
ProcessSQL ALL
DEPENDS myfile.sql
COMMENT "Preprocessing SQL files"
VERBATIM)
致谢:Petr Kmoch
答案 1 :(得分:2)
要利用CMake'make myfile.i
功能,您可以执行此操作:
add_library(sql_cpp_target EXCLUDE_FROM_ALL myfile.sql.in.c)
现在运行make myfile.sql.in.c.i
将使用已定义的CMAKE_C_FLAGS
为您生成预处理的来源。可以更改预处理文件的输出名称和目录。
无论如何,您需要将这些make
次调用包装到add_custom_target(ALL ...)
中,以使CMake在构建期间运行它们。
在目标定义中使用CMAKE_MAKE_PROGRAM
变量。
如果您想从构建工具中抽象出来,可以调用cmake本身来为您构建目标。定义自定义目标时使用${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target targetname
。
或者,您可以只运行指定编译器的add_custom_command()
来预处理文件并将它们放在适当的位置。但这似乎不太灵活,IMO。