如何强制CMake的target_include_directories()使用绝对路径

3

如何强制CMake的函数target_include_directories()将值视为绝对路径?

例如,我想要这行代码:

target_include_directories(foobar  PRIVATE   "%FOOBAR_INCLUDE%")

只需将%FOOBAR_INCLUDE%添加到包含目录列表中即可。

然而,实际上我们得到的是c:\path\to\foobar\%FOOBAR_INCLUDE%

知道我可以做:

target_include_directories(foobar  PRIVATE   "$ENV{FOOBAR_INCLUDE}")

但这不是我想要的。那样会扩展环境变量的值并插入FOOBAR_INCLUDE的当前设置。

我们需要它仅推送环境变量,然后在开发过程中,开发人员将手动更改FOOBAR_INCLUDE的值,而无需每次重新运行CMake。


那么只需将绝对路径传递给它?而无需重新运行CMake CMake的整个目的是在您更改配置时重新运行它。因此,当您更改FOOBAR_INCLUDE时,应该重新运行cmake。 - undefined
2个回答

2
无法直接将类似于相对目录(即"%FOOBAR_INCLUDE%")添加到包含目录中。 CMake 将始终尝试将其转换为绝对路径。这在 include_directories 文档中已经明确说明:

相对路径被解释为相对于当前源目录。

但是也适用于 target_include_directories() 命令。

即使您尝试规避此问题并手动设置目标的 INCLUDE_DIRECTORIES 属性:

set_target_properties(foobar PROPERTIES
    INCLUDE_DIRECTORIES "%FOOBAR_INCLUDE%"
)

CMake在生成阶段会报错:
CMake Error in CMakeLists.txt:
  Found relative path while evaluating include directories of "foobar":

    "%FOOBAR_INCLUDE%"

你可以妥协,提供一个完整的路径,但是允许变量%FOOBAR_INCLUDE%保留。
target_include_directories(foobar PRIVATE "C:/%FOOBAR_INCLUDE%")

但这将使您和其他开发人员被绑定到C盘。
我建议按照您提出的方法使用环境变量:
target_include_directories(foobar  PRIVATE   "$ENV{FOOBAR_INCLUDE}")

或者创建一个FOOBAR_INCLUDE CMake缓存变量,每个开发人员在重新运行CMake之前都可以填充该变量。如果每个开发人员的环境不同,则应重新配置CMake以匹配该环境。


1
谢谢。虽然我不喜欢“你不能”的答案,但这回答了我的问题。由于内部公司开发原因,我无法详细解释为什么它实际上需要是一个未展开的环境变量。我将不得不告知相关方面这个限制。谢谢。 - undefined

1
你可以通过生成器表达式欺骗 CMake 接受字面值。
target_include_directories(foobar PRIVATE $<1:%FOOBAR_INCLUDE%>)

然而,这样做行不通,因为CMake会生成一个关于路径不是绝对路径的错误。
幸运的是,这是一个包含目录,因此您可以尝试手动添加包含标志:
target_compile_definitions(foobar PRIVATE -I%FOOBAR_INCLUDE%)

不错的技巧,Micha。可惜使用-I的想法并不具备可移植性。这只适用于GCC编译器和类似的编译器。对于基于Windows的编译来说是行不通的。这就是使得target_include_directories()如此强大和令人沮丧的地方,因为它只接受绝对路径。 - undefined
真的,编译器标志不是“可移植”的,它们本质上并不是。MSVC确实模仿了大多数基本标志1:1,唯一的区别是他们将“-”改为“/”(可选),同时使用了“-”和“/”。或者,如果你想保持纯粹,可以使用if (MSVC) target_compile_definitions(foobar PRIVATE /I%FOOBAR_INCLUDE%) else() .. endif()。CMake通过涵盖每个主要的编译器/平台/IDE组合来给人以可移植性的错觉。在CMakeLists中使用特定于编译器/平台/IDE的指令是非常自然的,尤其是在进行非常自定义的工作时。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接