我试图理解为什么CMake在给定情况下会抱怨。
我有依赖于模块B的模块A,而依赖于模块C的模块。
模块C是模块B的子目录,每个模块的CMakeLists.txt的相关部分如下所示:
模块A可以:
add_library(A STATIC "")
target_include_directories(A PRIVATE
$<TARGET_PROPERTY:B,INCLUDE_DIRECTORIES>
)
模块B可以:
add_library(B static "")
set(some_dirs
C
)
foreach(DIR ${some_dirs})
add_subdirectory(${DIR})
target_link_libraries(B PUBLIC ${DIR})
endforeach(DIR)
模块C可以:
add_library(C STATIC "")
target_include_directories(C
PUBLIC
$<TARGET_PROPERTY:OtherLib,INCLUDE_DIRECTORIES>
PRIVATE
)
有一个可执行文件链接到模块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":
后面是一些垃圾字符,以及其他一些“未能从CMake服务器行解析JSON。
但是,当我将模块C修改为以下内容时:
add_library(C STATIC "")
target_include_directories(C
PUBLIC
PRIVATE
$<TARGET_PROPERTY:OtherLib,INCLUDE_DIRECTORIES>
)
生成错误消失了。
OR 如果我将模块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)
和A:
add_library(A STATIC "")
target_include_directories(A PRIVATE
$<TARGET_PROPERTY:B,INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:C,INCLUDE_DIRECTORIES>
)
然后生成错误也会消失。
我不太理解为什么当模块C使用PUBLIC与PRIVATE包含时CMake认为存在相对路径。我也不理解为什么将C删除为B的依赖关系后问题会消失。我确实知道IMPORTED目标不能有相对路径,但是我的目标都不是IMPORTED,因为它们都在同一个对象中定义项目。