我的项目结构如下:
├── CMakeLists.txt
├── libA
│ ├── CMakeLists.txt
│ ├── include
│ │ └── libA
│ │ └── my_liba.h
│ ├── src
│ │ └── my_liba.cpp
│ └── test
├── libB
│ ├── CMakeLists.txt
│ ├── include
│ │ └── libB
│ │ └── my_libb.h
│ ├── src
│ │ └── my_libb.cpp
│ └── test
└── runner
├── CMakeLists.txt
└── src
└── main.cpp
我想实现以下目标:
libA
和 libB
和 Runner
对于依赖项:libB
依赖于 libA
而 Runner
需要 libB
。
我必须如何配置 libB 和 Runner?
这些是当前的 CMakeLists.txt
文件:
libA/CMakeLists.txt:
cmake_minimum_required(VERSION 3.14)
project (MyLibA)
add_library(${PROJECT_NAME} src/my_liba.cpp)
add_library(Example::LibA ALIAS ${PROJECT_NAME})
target_include_directories( ${PROJECT_NAME}
PUBLIC ${PROJECT_SOURCE_DIR}/include
)
libB/CMakeLists.txt:
cmake_minimum_required(VERSION 3.14)
project (MyLibB)
add_library(${PROJECT_NAME} src/my_libb.cpp)
add_library(Example::LibB ALIAS ${PROJECT_NAME})
target_link_libraries(${PROJECT_NAME} PRIVATE Example::LibA)
target_include_directories( ${PROJECT_NAME}
PUBLIC ${PROJECT_SOURCE_DIR}/include
)
Runner/CMakeLists.txt
project(runner)
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME}
Example::LibB
)
CMakeLists.txt:
cmake_minimum_required(VERSION 3.14)
project(Example)
add_subdirectory(libA)
add_subdirectory(libB)
add_subdirectory(runner)
使用当前配置,我可以从 lib
目录中构建所有内容。
我还可以从 libA
目录内部构建 libA
。但是我无法从那里构建 libB
或 runner
文件夹,这是意料之中的,因为他们不知道在哪里可以找到依赖项。
我必须如何更改我的 CMakeFiles
才能使其正常工作?
答案 0 :(得分:0)
如果您希望能够仅使用 libB
构建脚本构建 libB
,您需要一种使 libB
能够找到 libA
依赖项的方法。>
根据您的问题,我假设您实际上希望将 libA
构建为 libB
构建过程的一部分(您不想在开始 libA
之前安装 libB
} 构建。
这看起来很奇怪,但您可以在 libB/CMakeLists.txt
中执行此操作:
add_subdirectory(../libA)
问题是这样做会破坏根构建脚本。这可以通过检查 libA
目标是否已经存在来解决:
if (NOT TARGET libA)
add_subdirectory(../libA)
endif (NOT TARGET libA)
这样,您要么拥有 libA
目标,因为根构建脚本添加了 libA
子目录,或者您自己添加了它。
add_subdirectory(../libA)
对我来说看起来很奇怪,可能一些有更多 CMake 经验的人会认为它的风格很糟糕,但鉴于您的设置,我在这里看不到其他选项。如果您这样做,其他事情可能会中断,请参阅 this question。
作为旁注,您可能希望在目标之间添加一些依赖项:
add_dependencies(libB libA)
这样,当您构建 libB
时,如果 libA
未构建,则会在 libA
构建开始之前触发 libB
构建。
答案 1 :(得分:0)
add_subdirectory
允许您传递任何目录。如果您不传递子目录,则需要传递第二个参数,指定用于源“子树”的二进制目录。当然,您需要确保不要创建圈子。
这允许您添加目标所依赖的项目的源目录,从而导致包含以下源目录:
libB/CMakeLists.txt
包括 libA
runner/CMakeLists.txt
包括 libB
CMakeLists.txt
要么包含仅 runner
或完全删除(您可以简单地使用 runner
作为源目录)< /li>
用于二进制目录的方便位置是二进制目录的子目录。
CMakeLists.txt
文件的更改libA/CMakeLists.txt
保持不变
libB/CMakeLists.txt
创建一个用作源目录的目录并添加 add_subdirectory
set(LIB_A_BINARY_DIR "${CMAKE_BINARY_DIR}/subproject_build_dirs/libA")
file(MAKE_DIRECTORY ${LIB_A_BINARY_DIR})
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../libA" ${LIB_A_BINARY_DIR})
runner/CMakeLists.txt
与上述更改类似,但如果您想使用 cmake_minimum_required
作为源目录,还要添加 runner
以避免 cmake 产生警告。
cmake_minimum_required(VERSION 3.14)
set(LIB_B_BINARY_DIR "${CMAKE_BINARY_DIR}/subproject_build_dirs/libB")
file(MAKE_DIRECTORY ${LIB_B_BINARY_DIR})
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../libB" ${LIB_B_BINARY_DIR})
CMakeLists.txt
如果你想保留这个文件而不是直接使用 runner/CMakeLists.txt
应该改为以下内容
cmake_minimum_required(VERSION 3.14)
project(Example)
add_subdirectory(runner)