如何配置CMake目标或命令来预处理C文件



我最初在CMake邮件列表上问了这个问题:如何配置目标或命令来预处理C文件?

我正在将基于GNU Autotools的构建配置移植到CMake,我必须处理C预处理才能生成文件。

预处理器的输入是SQL文件,其中使用了C预处理器指令,如#include "another.sql"等。

目前,Makefile使用以下规则生成普通SQL文件作为输出:

myfile.sql: myfile.sql.in.c
    cpp -I../common $< | grep -v '^#' > $@

因此,myfile.sql是构建过程中的一个产品,类似于共享库或可执行文件。

我应该使用哪些CMake工具来达到同样的效果?

我不清楚我应该使用add_custom_commandadd_custom_target还是两者结合。

显然,我正在寻找一个可移植的解决方案,它至少可以与GNUGCCVisualStudio工具集一起使用。我想我必须定义特定于平台的自定义命令,一个用于cpp预处理器,一个为cl.exe /P

或者,CMake为C预处理器提供了某种抽象吗?

我扫描了档案,但只发现了fortran文件的预处理或基于make功能的解决方案:make myfile.i所以,这不是我想要的。

更新:在CMake邮件列表中添加了基于从Petr Kmoch收到的解决方案的答案。

我通过在邮件列表中复制从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_libraryadd_executable的文件,在这些命令中指定它就足够了。CMake会发现它是一个依赖项,并根据需要运行自定义命令。

  • 如果命令输出文件是中未用作依赖项的最终输出任何其他目标,然后添加一个自定义目标以使用add_custom_target 驱动命令

例如:

add_custom_target(
  ProcessSQL ALL
  DEPENDS myfile.sql
  COMMENT "Preprocessing SQL files"
  VERBATIM)

学分:Petr Kmoch

要利用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.

最新更新