Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 设置子模块目标时,CMAKE_BINARY_DIR和PROJECT_BINARY_DIR之间的权衡';输出目录_C++_Cmake_Git Submodules - Fatal编程技术网

C++ 设置子模块目标时,CMAKE_BINARY_DIR和PROJECT_BINARY_DIR之间的权衡';输出目录

C++ 设置子模块目标时,CMAKE_BINARY_DIR和PROJECT_BINARY_DIR之间的权衡';输出目录,c++,cmake,git-submodules,C++,Cmake,Git Submodules,我在一个图书馆工作,它将被另一个项目使用。主项目使用两个链接为git子模块的库。在用作子模块的库项目中,我可以用两种不同的方式设置库输出目录和存档输出目录 在选项A中,使用${PROJECT\u BINARY\u DIR}/lib构建目标并将其保存到自己的子目录中,但在选项B中,所有目标都构建并保存到${CMAKE\u BINARY\u DIR}/lib目录中 这也可以扩展到由子模块构建的二进制文件。因此,这两个选项中的哪一个将扩展到更好/通常被用作最佳实践 方案A CMakeLists.txt

我在一个图书馆工作,它将被另一个项目使用。主项目使用两个链接为git子模块的库。在用作子模块的库项目中,我可以用两种不同的方式设置
库输出目录
存档输出目录

在选项A中,使用
${PROJECT\u BINARY\u DIR}/lib
构建目标并将其保存到自己的子目录中,但在选项B中,所有目标都构建并保存到
${CMAKE\u BINARY\u DIR}/lib
目录中

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

方案A CMakeLists.txt 文件夹结构 方案B CMakeLists.txt 文件夹结构
除非有充分的理由,否则根本不应该为库项目中的目标设置输出目录。如果消费者链接到库项目提供的CMake目标,那么他们通常甚至不需要知道这些库的确切位置,即使他们知道,他们也可以通过

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

因此,您不应该设置目标属性,而是通过设置

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\u BINARY\u DIR}
还是
${CMAKE\u BINARY\u DIR}
,这在很大程度上都是不相关的,但我个人更喜欢使用
${PROJECT\u BINARY\u DIR}
,因为它确保不会发生冲突,即使两个子项目为其目标选择了相同的名称(例如,几个目标可能定义了一个可执行文件,该文件名为
tests
)。

谢谢Corristo!回答得很好。我感谢您的努力。
.
+-- 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
# 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
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()