【问题标题】:CMake: How to run a add_custom_command before everything elseCMake:如何在其他一切之前运行 add_custom_command
【发布时间】:2013-04-05 01:43:08
【问题描述】:

我有一个自定义命令

add_custom_command(
    OUTPUT config.h
    PRE_BUILD
    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/mk_config_h.py ${CMAKE_CURRENT_BINARY_DIR}/config.h
)

我正在尝试先运行它,然后生成 unix Makefile。

但是 PRE_BUILD 仅支持 VS2010,这意味着 config.h 是在链接之前构建的。

如何在 cmake 开始编译源代码之前创建自定义命令。

【问题讨论】:

  • 您的自定义命令(即 config.h)的输出文件是否用作另一个 CMake 目标中的源文件(即在通过 add_executableadd_library 传递的源列表中)?如果是这样,您不必担心执行顺序 - CMake 将在需要时调用自定义命令。

标签: cmake


【解决方案1】:

你应该使用add_custom_targetadd_dependencies 来让你的正常目标依赖它:

add_custom_target(
    myCustomTarget
    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/mk_config_h.py ${CMAKE_CURRENT_BINARY_DIR}/config.h
)
add_dependencies(myTarget myCustomTarget)

这应该确保在编译myTarget的源代码之前运行该命令。

【讨论】:

  • 我花了一段时间才发现 add_custom_target 比 add_custom_command 更适合运行可执行文件。感谢您的解决方案!
  • @Anonymous - 不,不是更好。它有一个明显的缺点,它总是按照文档中的描述运行(目标没有输出文件并且总是被认为是过时的,即使命令尝试使用目标名称创建文件),即使依赖没有改变。
  • 使用@Simon 建议的add_custom_targetadd_dependencies 对我有用,强制在我的正常目标构建之前复制来自另一个构建的一些头文件和库文件。我之前曾尝试使用add_custom_command( ... PRE_BUILD ... ),但它不会以正确的顺序执行。
  • 如果自定义目标需要很长时间才能完成,我发现这在并行构建中会失败。稍后的构建阶段将以正确的顺序运行,但将使用未完全编写的输出文件。我还没有弄清楚如何强制运行到完成。
【解决方案2】:

通常基于 makefile 构建系统不需要将标头作为目标的一部分。此外,将标头添加到目标被认为是一种反模式。但生成标头是此规则的一个例外。

http://voices.canonical.com/jussi.pakkanen/2013/03/26/a-list-of-common-cmake-antipatterns/

您应该将${CMAKE_CURRENT_BINARY_DIR}/config.h 设置为其他编译目标的一部分。 例如:

set(PROGRAM1_SOURCES main_program1.cpp)
set(PROGRAM1_HEADERS main_program1.h ${CMAKE_CURRENT_BINARY_DIR}/config.h)
add_executable(program1 ${PROGRAM1_SOURCES} ${PROGRAM1_HEADERS})

这样,CMake 将知道哪个目标实际需要生成的config.h,并且能够将生成命令插入到正确的构建步骤中。

另外,请参阅https://cmake.org/cmake-tutorial/#s5 的示例

【讨论】:

  • 如果您希望从各种 IDE 进行代码分析,则需要标头。
  • @zerophase,我同意。 IDE 的项目文件通常需要引用项目的所有文件。但是 cmake 可以在没有头文件的情况下构建项目。
  • 哦,当然。只是通常最终必须添加标题以支持不同的最终用户。
猜你喜欢
  • 2011-02-25
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
相关资源
最近更新 更多