CMake 错误:在评估包含目录时找到相对路径

Ric*_*ehe 5 c++ cmake

我试图理解为什么 CMake 在特定情况下会抱怨。

我的模块 A 取决于模块 B,而模块 B 又取决于模块 C。

模块C是模块B的子目录,每个模块的CMakeLists.txt相关部分如下所示:

模块 A 执行以下操作:

add_library(A STATIC "")

target_include_directories(A PRIVATE 
    $<TARGET_PROPERTY:B,INCLUDE_DIRECTORIES>
)
Run Code Online (Sandbox Code Playgroud)

模块 B 执行以下操作:

add_library(B static "")

set(some_dirs
  C
)

foreach(DIR ${some_dirs})
  add_subdirectory(${DIR})
  target_link_libraries(B PUBLIC ${DIR})
endforeach(DIR)
Run Code Online (Sandbox Code Playgroud)

模块 C 执行以下操作:

add_library(C STATIC "")

target_include_directories(C
  PUBLIC 
    $<TARGET_PROPERTY:OtherLib,INCLUDE_DIRECTORIES>
  PRIVATE
)
Run Code Online (Sandbox Code Playgroud)

有一个可执行文件链接到模块 A。

使用 TARGET_PROPERTY:INCLUDE_DIRECTORIES 的原因是我正在将一个具有大量循环依赖项的大型项目从单一的可执行文件转移到具有不同库的可执行文件。我最初的努力只是创建模块,然后打破循环依赖。因此,在此示例中,target_link_libraries我不使用依赖项,而是target_include_directories将属性 INCLUDE_DIRECTORIES 用于依赖项。我希望这是有道理的。

我收到上述情况的错误,其中包括:

Configuring done
Failed to parse JSON from CMake server.
Failed to parse JSON from CMake server.
CMake Error in A/CMakeLists.txt:
  Found relative path while evaluating include directories of
  "A":
Run Code Online (Sandbox Code Playgroud)

其次是一些垃圾字符和更多“无法从 CMake 服务器行解析 JSON。

但是,当我将模块 C 修改为以下内容时:

add_library(C STATIC "")

target_include_directories(C
  PUBLIC 
  PRIVATE
    $<TARGET_PROPERTY:OtherLib,INCLUDE_DIRECTORIES>
)
Run Code Online (Sandbox Code Playgroud)

生成错误消失了。

或者, 如果我将模块 C 保持原样,但将模块 B 更改为此(即不与 C 链接):

add_library(B static "")

set(some_dirs
  C
)

foreach(DIR ${some_dirs})
  add_subdirectory(${DIR})
#  target_link_libraries(B PUBLIC ${DIR})
endforeach(DIR)
Run Code Online (Sandbox Code Playgroud)

和A:

add_library(A STATIC "")

target_include_directories(A PRIVATE 
    $<TARGET_PROPERTY:B,INCLUDE_DIRECTORIES>
    $<TARGET_PROPERTY:C,INCLUDE_DIRECTORIES>
)
Run Code Online (Sandbox Code Playgroud)

然后生成错误也会消失。

我不太明白为什么 CMake 认为当模块 C 使用 PUBLIC 与 PRIVATE 包含时存在相对路径。我也不明白为什么当我删除 C 作为 B 的依赖项时问题会消失。我确实理解 IMPORTED 目标不能有相对路径,但我的目标都不是 IMPORTED,因为它们都在同一个中定义项目。