gpt4 book ai didi

c++ - 设置子模块目标的输出目录时 CMAKE_BINARY_DIR 和 PROJECT_BINARY_DIR 之间的权衡

转载 作者:行者123 更新时间:2023-12-05 03:44:21 27 4
gpt4 key购买 nike

我正在开发一个将被另一个项目使用的库。主项目使用几个链接为 git 子模块 的库。在用作子模块的库项目中,我可以用两种不同的方式设置 LIBRARY_OUTPUT_DIRECTORYARCHIVE_OUTPUT_DIRECTORY

选项 A 中,使用 ${PROJECT_BINARY_DIR}/lib 构建目标并保存到它们自己的子目录中,但在选项 B 中所有目标都已构建并保存到 ${CMAKE_BINARY_DIR}/lib 目录。

这也可以扩展到由子模块构建的二进制文件。因此,这两个选项中的哪一个将扩展更好/通常用作最佳实践?

选项A

CMakeLists.txt

# Set target properties
set_target_properties(${PROJECT_NAME}_lib_shared PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
set_target_properties(${PROJECT_NAME}_lib_static PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/static)

文件夹结构

.
+-- build
| +-- bin
| +-- MainProject
| +-- test
| +-- lib
| +-- SubModuleA
| +-- SubModuleA_lib_shared.a
| +-- static
| +-- SubModuleA_lib_static.so
| +-- SubModuleB
| +-- SubModuleB_lib_shared.a
| +-- static
| +-- SubModuleB_lib_static.so
+-- lib
| +-- SubModuleA
| | +-- CMakeLists.txt
| +--- SubModuleB
| | +-- CMakeLists.txt
+-- inc
| +-- foo.h
+-- src
| +-- foo.cpp
| +-- main.cpp
| +-- CMakeLists.txt
+-- test
| +-- test.cpp
| +-- CMakeLists.txt
+-- CMakeLists.txt

选项B

CMakeLists.txt

# Set target properties
set_target_properties(${PROJECT_NAME}_lib_shared PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set_target_properties(${PROJECT_NAME}_lib_static PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/static)

文件夹结构

.
+-- build
| +-- bin
| +-- MainProject
| +-- test
| +-- lib
| +-- SubModuleA_lib_shared.a
| +-- SubModuleB_lib_shared.a
| +-- static
| +-- SubModuleA_lib_static.so
+-- SubModuleB_lib_static.so
+-- lib
| +-- SubModuleA
| | +-- CMakeLists.txt
| +--- SubModuleB
| | +-- CMakeLists.txt
+-- inc
| +-- foo.h
+-- src
| +-- foo.cpp
| +-- main.cpp
| +-- CMakeLists.txt
+-- test
| +-- test.cpp
| +-- CMakeLists.txt
+-- CMakeLists.txt

最佳答案

除非有充分的理由,否则您根本不应该在库项目中为您的目标设置输出目录。如果消费者链接到库项目提供的 CMake 目标,那么他们通常甚至不需要知道这些库的确切位置,即使知道,他们也可以通过 target-dependent generator-expressions 访问该位置。 .

此外,即使你确实有充分的理由(例如,因为你想在 CI 构建中归档构建工件并且还没有使用 CPack 生成适当的包),你仍然不应该强制你的在消费者身上设置。如果您允许消费者轻松覆盖默认设置,例如使用该机制确保共享库将位于其项目构建的二进制文件旁边,这是 Windows 上运行可执行文件所必需的,而无需手动修改 PATH 以包含依赖项所在的所有目录,即消费者可以确保通过更改库目标的默认输出目录,可以从构建树运行可执行文件。

因此您不应该设置目标属性,而是通过设置为这些属性设置默认值

if (NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib/static")
endif()

if (NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
endif()

if (NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
endif()

让消费者更方便地一次更改所有目标的输出位置,而无需再次为每个目标手动设置属性。

无论您使用 ${PROJECT_BINARY_DIR} 还是 ${CMAKE_BINARY_DIR} 基本上都无关紧要,但我个人更喜欢使用 ${PROJECT_BINARY_DIR} 因为它确保不会发生冲突,即使两个子项目为其目标选择了相同的名称(例如,多个目标可能定义了一个名为 tests 的可执行文件)。

关于c++ - 设置子模块目标的输出目录时 CMAKE_BINARY_DIR 和 PROJECT_BINARY_DIR 之间的权衡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66493865/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com