我想要以下结构 A -> B -> C
,其中:
C
是样板代码,第三方库的包装器,非常 基本代码等B
是常用的类、函数和数据 特定于项目领域的结构。A
是项目本身。
我想让以后在我的其他项目中重用 C
或 B(+C)
变得容易。此外,我还有以下要求:
- 由于这三个项目都在进行中,我希望能够构建
C
、C+B
和C+B+A
一枪。 - 我更喜欢静态链接而不是动态链接,因此
C
和C+B
将是静态库,而C+B+A
将是可执行文件 - 我想让 cmake 列表和配置文件保持简单和干净。我在官方 wiki 和互联网上找到的例子非常庞大和可怕。
- 如果我更改
A
、B
或C 的位置,则不需要更改超过几行,那就太好了
在文件系统中。 - 这三个组件都使用了google-test,但我不确定它对项目布局是否重要。
我是 cmake 的新手,我什至不明白编写 XXXConfig.cmake
或 FindXXX.cmake
文件哪个更好。另外,我不确定,我应该如何使用 X_INCLUDE_DIRS
将相对路径从子组件传递到父组件。
最佳答案
首先我必须承认我同意@Tsyvarev。您的 CMake 环境应适合您的流程/工作流程,并应考虑项目规模和团队结构。或者一般来说,将使用 CMake 的环境。这往往是 - 以积极的方式 - 非常活跃。
所以你的这部分问题很难回答,我会专注于技术部分:
- CMake 必须知道依赖项的位置 - 相对或绝对 - 通过
- 有一个单一的源代码树(你不再想要的那个)
- includes/libraries/binaries 的公共(public)目录位置
- 通过配置文件/变量定义获取路径
- 使用主机提供的数据库中的注册或安装
- 为了让您的 CMake 文件尽可能简单,我建议将您的 CMake 代码分组到单独的专用文件中:
- 优先使用工具链文件而不是
if(SomeCompiler)
语句 - 将公共(public)/重复代码部分作为
function()
主体移动到共享的 CMake 包含文件中 - 将复杂的非目标特定代码部分移动到它们自己的 (CMake) 脚本文件中
- 优先使用工具链文件而不是
示例代码
由于您已明确要求使用 find_package()
变体,因此采用 Use CMake-enabled libraries in your CMake project以及上面列出的内容:
MyCommonCode.cmake
cmake_policy(SET CMP0022 NEW)
function(my_export_target _target _include_dir)
file(
WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_target}Config.cmake"
"
include(\"\$\{CMAKE_CURRENT_LIST_DIR\}/${_target}Targets.cmake\")
set_property(
TARGET ${_target}
APPEND PROPERTY
INTERFACE_INCLUDE_DIRECTORIES \"${_include_dir}\"
)
"
)
export(
TARGETS ${_target}
FILE "${CMAKE_CURRENT_BINARY_DIR}/${_target}Targets.cmake"
EXPORT_LINK_INTERFACE_LIBRARIES
)
export(PACKAGE ${_target})
endfunction(my_export_target)
C/CMakeLists.txt
include(MyCommonCode.cmake)
...
my_export_target(C "${CMAKE_CURRENT_SOURCE_DIR}/include")
B/CMakeLists.txt
include(MyCommonCode.cmake)
find_package(C REQUIRED)
...
target_link_libraries(B C)
my_export_target(B "${CMAKE_CURRENT_SOURCE_DIR}/include")
A/CMakeLists.txt
include(MyCommonCode.cmake)
find_package(B REQUIRED)
...
target_link_libraries(A B)
这使所有 3 个构建环境保持独立,仅共享相对静态的 MyCommonCode.cmake
文件。因此,在这种方法中,到目前为止我还没有涵盖您的第一点,但建议使用外部脚本来链接/触发 A/B/C 的构建步骤。
关于c++ - 首选cmake项目结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33534115/