Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何强制CMake';s target_include_directories()使用绝对路径_Cmake - Fatal编程技术网

如何强制CMake';s target_include_directories()使用绝对路径

如何强制CMake';s target_include_directories()使用绝对路径,cmake,Cmake,如何强制CMake的函数target\u include\u directories()将值视为绝对路径 例如,我想要这行代码: target_include_directories(foobar PRIVATE "%FOOBAR_INCLUDE%") 只需将%FOOBAR\u INCLUDE%添加到包含目录列表 然而,我们实际得到的是c:\path\to\foobar\%foobar\u INCLUDE% 我知道我能做到 target_include_directo

如何强制CMake的函数
target\u include\u directories()
将值视为绝对路径

例如,我想要这行代码:

target_include_directories(foobar  PRIVATE   "%FOOBAR_INCLUDE%")
只需将
%FOOBAR\u INCLUDE%
添加到包含目录列表

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

我知道我能做到

target_include_directories(foobar  PRIVATE   "$ENV{FOOBAR_INCLUDE}")
但那不是我想要的。这将扩展环境变量的值并插入
FOOBAR\u INCLUDE
值的当前设置


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

不可能添加看起来像相对目录的内容(即
%FOOBAR\u INCLUDE%”
)以这种方式包含目录。CMake将始终尝试将这些操作转换为绝对路径。文件中或多或少说明了这一点:

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

但也适用于
target\u include\u directories()
命令

即使您试图绕过此问题,并手动设置目标的
INCLUDE\u DIRECTORIES
属性:

set_target_properties(foobar PROPERTIES
    INCLUDE_DIRECTORIES "%FOOBAR_INCLUDE%"
)
target_compile_definitions(foobar PRIVATE -I%FOOBAR_INCLUDE%)
CMake将在生成阶段抛出错误:

CMake Error in CMakeLists.txt:
  Found relative path while evaluating include directories of "foobar":

    "%FOOBAR_INCLUDE%"
您可以妥协,提供一个完整路径,但允许
%FOOBAR\u INCLUDE%
变量保留:

target_include_directories(foobar PRIVATE "C:/%FOOBAR_INCLUDE%")
但这将您和您的开发伙伴与C:drive联系在一起


我建议采用您建议的方法,使用环境变量:

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

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

您可以通过生成器表达式诱使CMake接受文字值

target_include_directories(foobar PRIVATE $<1:%FOOBAR_INCLUDE%>)

所以只需传递到它的绝对路径
无需重新运行CMake
CMake的关键在于,如果更改配置,您需要重新运行它。因此-您更改了FOOBAR\u INCLUDE-您应该重新运行cmake。谢谢。它回答了我的问题,尽管我不喜欢“你不能”的答案。有一些公司发展的内部原因,我无法解释为什么它实际上需要成为一个未扩展的环境变量。我必须让当权者知道这一限制。谢谢,很好的把戏,Micha。遗憾的是,使用-I的想法是不可移植的。这只适用于GCC编译器和类似的编译器。它不适用于基于Windows的编译。这就是为什么
target\u include\u directories()
如此强大,令人沮丧的是它只接受绝对路径。(TL;DR
-I
对MSVC有效)的确,编译器标志不是“可移植的”,它们不是天生的。MSVC确实模拟了最基本的标志1:1,唯一的区别是它们被改为“-”表示“/”可选,b“-”和“/”正在使用。或者,
if(MSVC)target\u compile\u定义(foobar PRIVATE/I%foobar\u INCLUDE%)else()。。endif()
如果你想保持纯洁,就可以这样做。CMake通过涵盖每个主要的编译器/平台/IDE组合,给人一种可移植性的错觉。在CMakeLists中有特定于编译器/平台/IDE的指令是很自然的,尤其是在做非常定制的事情时。