8

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

我正在将基于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_commandadd_custom_target或者两者结合。

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

或者,CMake 是否为 C 预处理器提供任何类型的抽象?

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

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

4

2 回答 2

8

我通过复制从 Petr Kmoch 收到的解决方案的重要部分来回答自己的问题,作为对我在邮件列表中的帖子的回复。

首先,使用(带有 OUTPUT 签名的版本)创建一个自定义命令add_custom_command来实际进行预处理。

例如:

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_libraryoradd_executable中,则在这些命令中指定它就足够了。CMake 会发现它是一个依赖项,并根据需要运行自定义命令。

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

例如:

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

致谢:Petr Kmoch

于 2012-07-11T23:28:56.003 回答
3

要利用 CMake 的make myfile.i功能,您可以这样做:

add_library(sql_cpp_target EXCLUDE_FROM_ALL myfile.sql.in.c)

现在运行make myfile.sql.in.c.i将使用 defined 为您生成预处理源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。

于 2012-07-10T08:14:27.743 回答