CMake:如何声明对生成的头文件的依赖关系?

问题描述 投票:0回答:1

当生成头文件时,我正在努力使并行make正常运行。 C文件的构建通常在头文件被完全写入之前开始,从而导致各种故障。我找不到任何避免比赛的方法。

让我提供血腥细节。我认为根本的问题不在于这些细节。但为了公平/准确,就在这里。这是一个相对简单,跟随您鼻子的类型设置。所以...有一个文件,AtomTypes.cmake包含

FILE(WRITE "tmp.h" "/* stuff stuff and more stuff */")
FILE(APPEND "tmp.h" "/* its done now */")
# Make sure writing is completed, before file is visible!
FILE(RENAME "tmp.h"  "foo.h")

为了简化上述内容的使用(实际上是又大又笨重的,有一个宏:

MACRO(ADD_TYPES SCRIPT_FILE HEADER_FILE)
   ADD_CUSTOM_COMMAND (
       COMMAND "${CMAKE_COMMAND}" -P AtomTypes.cmake
       OUTPUT "${HEADER_FILE}"
       DEPENDS "${SCRIPT_FILE}"
   )
ENDMACRO()

然后我可以在某个rando目录的“普通” CMakefile中使用它:

ADD_TYPES(some_types.script foo.h)
# A custom target for use in other (dependent) directories.
ADD_CUSTOM_TARGET(my_types DEPENDS foo.h)
# The local library, in this directory
ADD_LIBRARY(foo
   bar.cc
   baz.cc)

# All the blogs say I need this, but it doesn't work
# (doesn't do anything)
ADD_DEPENDENCIES(foo my_types)

bar.ccbaz.cc可能与您猜测的一样:

#include <some/path/foo.h>
/* stuff*/

如果我运行非并行make,则一切正常:没有来自cmake或make的错误,foo.h是自动生成的,一切都能编译,没有错误。并且甚至仅在触摸foo.h时才重新生成types.script,因此依赖项起作用。但是,如果我运行并行make,则构建竞赛。 bar.cc的编译在写入foo.h之前开始。像这样:

bar.cc:30: fatal error: some/path/foo.h:  No such file or directory
 #include <some/path/foo.h>
          ^~~~~~~~~~~~~~~~~
compilation terminated.

当然,第二次运行make解决了该错误。 (失败的构建遗留了foo.h的副本。)

如果我尝试手动调试,则通过查看./CMakeFiles/foo.dir/depend.make,显然存在缺少的依赖项!!很多东西,例如

CMakeFiles/foo.dir/bar.cc.o: some/other/header.h

但绝对不依赖foo.h !!!! ???怎么可能?很明显,在源代码中...

此冒险由cmake version 3.13.4在Debian马stable中带给您。

cmake dependencies auto-generate
1个回答
0
投票

我会尝试这个简单的解决方案:

ADD_LIBRARY(foo
   bar.cc
   baz.cc
   foo.h  # or ${HEADER_FILE}
)

头文件被编译器忽略,但是将头文件包含在目标的源列表中有两个目的:一个用于生成的头文件,例如'config.h'或您的。另一个是在某些头文件已更改时触发目标的重建。这就是为什么不建议使用file(GLOB)来建立来源列表的原因。

© www.soinside.com 2019 - 2024. All rights reserved.