如何在 INTERFACE 库中使用“target_sources”命令?

Que*_*tin 3 c++ cmake

我的项目组织在子目录中(十几个),子目录之间有一些包含。其中一些子目录仅包含头文件(例如 dir1)。

下面看一下项目的组织结构:

project
 |
 |----- src -- dir1  <-- header-only library
 |       |      |--- dir1.h
 |       |      |--- CMakeLists.txt
 |       |
 |       |
 |       | --- dir2
 |       |      |--- dir2.cpp
 |       |      |--- dir2.h
 |       |      |--- CMakeLists.txt
 |       |
 |       | --- file.h
 |       | --- CMakeLists.txt 
 |
 |
 |----- test -- dir1 -- test.cpp
 |       | ---- dir2 -- test.cpp
 |       | ---- includeFile.h
 |
 |
 |----- CMakeLists.txt
Run Code Online (Sandbox Code Playgroud)

我想要一个包含 src 目录中所有代码的库和一个用于运行单元测试的可执行文件。在对 stackOverFlow 和 Cmake 示例进行了一些研究之后,我找到了这些 CMake 文件。每个 src 子目录有一个 makefile,一个用于对所有库进行分组,另一个用于全局。

dir1 CMakeLists

add_library(dir1 INTERFACE)
target_sources(dir1 INTERFACE dir1.h)
target_include_directories(dir1 INTERFACE
  "${PROJECT_SOURCE_DIR}/src/dir1"
)
Run Code Online (Sandbox Code Playgroud)

dir2 CMakeLists

set(dir2_src
  dir2.cpp dir2.h
)

add_library(dir2 ${dir2_src})
Run Code Online (Sandbox Code Playgroud)

src CMakeLists

add_subdirectory(dir1)
add_subdirectory(dir2)


add_library(TheProject INTERFACE)
target_sources(TheProject INTERFACE file.h)
target_include_directories(TheProject INTERFACE
  "${PROJECT_SOURCE_DIR}/src/"
)
target_link_libraries(TheProject INTERFACE dir1
                                dir2
                                ${Boost_LIBRARIES})
Run Code Online (Sandbox Code Playgroud)

主 CMakeLists.txt

project(TheProject)

# gtest
# boost
# compilation flags ...

####### include paths
include_directories("./src/")
include_directories(${Boost_INCLUDE_DIRS})

####### library to compile
add_subdirectory(src)


####### executable
file(GLOB SRCS utest/*/*.cpp)
add_executable(utest ${SRCS} test/includeFile.h)

target_link_libraries(utest gtest_main TheProject)
Run Code Online (Sandbox Code Playgroud)

我几乎在一个没有头文件库和接口的较小项目中使用了相同的组织,并且它起作用了。在这里,我对不同的接口库有一个错误:

CMake Error at CMakeLists.txt:88 (add_executable):
  Cannot find source file:

    file.h

  Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
  .hxx .in .txx
Run Code Online (Sandbox Code Playgroud)

我想我还没有很好地理解INTERFACE的使用。我做了一些研究,但没有解决我的问题。

我还有几个问题:

  • 目录之间存在一些依赖关系(例如,dir1 中的代码包含一些 dir2 文件),我是否应该在它们的 cmake 文件中指定这些依赖关系(使用 target_link_libraries(dir2 dir1))?
  • 代码中include在src和utest中指定了相对路径,使用“dir1/dir1.h”这样的路径不是更好吗?

Tsy*_*rev 8

相对路径,传递给target_sources,被解释相对于进一步调用add_executable(或add_library)。

因为您是add_executable()从顶级目录调用的,所以 CMake 搜索test.h相对于顶级目录,而不是相对于该目录src/

对调用使用绝对路径target_sources

target_sources(TheProject INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/file.h)
Run Code Online (Sandbox Code Playgroud)

由于传递给的 CMake 3.13 相对路径target_sources会立即解析,因此相对于当前源目录。请参阅@markhc 的回答


mar*_*khc 5

作为 Tsyvarev 对任何从 google 遇到此问题的人的回答的插件,target_sourcesCMake 3.13 上的行为已更改。

您现在可以在target_sources调用中使用相对路径。

https://cmake.org/cmake/help/v3.13/command/target_sources.html

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