【问题标题】:How to include first a CMake generated config.h conflicting with 3rd party files?如何首先包含与第 3 方文件冲突的 CMake 生成的 config.h?
【发布时间】:2020-03-16 09:54:54
【问题描述】:

我使用 CMake 生成一个 config.h 文件。我认为最好在构建文件夹而不是源文件夹中生成它,因为它不会在版本控制系统中提交。
因此,我不得不向我的目标添加一个包含目录,并包含我的文件,例如 <config.h> 而不是 "config.h"

set(GENERATED_HEADER_DIR ${CMAKE_BINARY_DIR}/geninclude)

execute_process(COMMAND git describe
                OUTPUT_VARIABLE version_description
                OUTPUT_STRIP_TRAILING_WHITESPACE)

configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in"
               "${GENERATED_HEADER_DIR}/config.h")

# ... target configuration

target_include_directories(my_target
                           PRIVATE ${GENERATED_HEADER_DIR}
                           PRIVATE ${SOME_LIB_I_NEED})

我的问题是:一些 lib 还暴露了一个 config.h 文件,并且这两个文件在构建过程中相互混淆。

编辑:该项目是针对 webassembly 构建的,因此显然它需要一次编译所有内容,并且无法链接到 bin 库,因为它通常使用 C++ 项目完成。


有没有办法将我自己生成的文件包含在".h" 而不是<.h> 中,而无需将文件放入我的 src 目录中?

或者有没有办法优先考虑包含,以便我的代码将包含我生成的文件,而 lib 包含它自己的文件?我不认为我可以修改 lib CMake 配置...

【问题讨论】:

  • “或者有没有办法确定包含的优先级” - 包含目录按照列出的顺序进行搜索。然而,维持这个顺序将是相当棘手的。为您的配置文件设置 唯一的包含名称 会简单得多。例如。 #include <XXX/config.h>#include <XXX_config.h>.
  • @Tsyvarev 是的,这是我首先想到的解决方法,但我想知道是否有更好的解决方案,config.h 似乎是一个标准并且许多项目不需要前缀(实际上只有十几个库中的一个与我的代码冲突)
  • are messing up each other during the build. 非常模糊。当前设置不起作用吗?该库应该构建并且您的目标应该首先看到config.h。为什么要在 target_include_directories 中包含 SOME_LIB_I_NEED - 你不想使用 target_add_libraries 吗?
  • Name config.h 完全可以用作 non-interface 标头的名称,即只有在构建库本身时才包含其目录。如果您需要一个配置标头作为 interface 之一,那么您最好将其名称设为 unique(通过为其添加前缀)。
  • @KamilCuk 我认为它是这样制作的,因为目标是 webassembly 并且无法管理库(但我不确定,我只是接管了这个项目)。使用此配置,我的构建看不到我的 config.h 并包含来自第 3 方的文件,这会导致编译错误。

标签: c++ cmake


【解决方案1】:

您应该致力于保持您的包含路径唯一,这样就不会发生这种情况。

实现此目的的一种方法是将大部分包含移动到它们自己的子目录中。所以你可以用#include <MyProject/config.h>代替#include <config.h>

configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in"
               "${GENERATED_HEADER_DIR}/MyProject/config.h")

如果您最终遇到无法做到这一点的情况,例如。因为这两个头文件都是第三方库 A 和 B 的一部分,不受您的控制,所以您需要通过允许每个 .cpp 文件仅使用 lib A 或 lib B 来解决问题,但不能同时使用两者。一旦两个库都可以被同一个源文件使用,您就会在包含文件上遇到冲突,这是无法解决的。任何关于构建命令行或#include <>include "" 上包含目录顺序的巧妙技巧都非常脆弱且不可移植。

【讨论】:

  • 这就是我所做的,我使用了更具体的文件名。但我对更清洁的解决方案感到好奇。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多