FetchContent_Declare与共享库一起使用的问题



我使用FetchContent_Declare与共享库有问题。我试图应用模块化设计(而不是创建一个大型存储库与20个模块,我分配一个专用的存储库到每个模块)。我试图使用FetchContent_Declare以便将相关模块链接在一起(我不是git子模块的粉丝,因为这些需要用户手动初始化它们)。我遇到的问题是,通过上述函数获取的项目生成的DLL不会复制到父项目的二进制输出。下面是一个依赖关系图,让你更清楚。

Repo A:
- bin
- bin-etc
- lib
- include
- project_a
.. header files ..
- src
- CMakeLists.txt : 1
.. source files ..
- CMakeLists.txt : 2
Repo B: Includes A
- bin
- bin-etc
- lib
- output
.. cmake files are built from here .. 
- _deps
- project_a-src
- bin 
.. here the DLL file is being generated .. 
- include
- project_a
.. header files ..
- src
- CMakeLists.txt : 3
.. source files ..
- CMakeLists.txt : 4

./output/_deps/project_a-src/bin中生成DLL文件,而不是在./bin中生成。

以下是我的CMakeLists.txt文件:
# CMakeLists.txt : 1
cmake_minimum_required(VERSION 3.16)
set(PROJECTNAME project_a)
set(PROJECTDIR "${CMAKE_CURRENT_SOURCE_DIR}")
file(GLOB_RECURSE inc "${CMAKE_CURRENT_SOURCE_DIR}/../include/*.hpp")
file(GLOB_RECURSE src "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/../include" FILES ${inc})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${src})
if (MSVC)
add_compile_options(/W3) # warning level 3
add_compile_options(/MP) # Multi-processor compilation
endif()
add_library(
${PROJECTNAME}
SHARED
${inc}
${src}
)
target_include_directories(${PROJECTNAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include/")
# CMakeLists.txt : 2 and 4
cmake_minimum_required(VERSION 3.16)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_SYSTEM_VERSION 10.0.19041.0)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin-etc")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/lib")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin")
project(project_a LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED)
add_subdirectory(src)
# CMakeLists.txt : 3
cmake_minimum_required(VERSION 3.16)
set(PROJECTNAME project_b)
set(PROJECTDIR "${CMAKE_CURRENT_SOURCE_DIR}")
file(GLOB_RECURSE inc "${CMAKE_CURRENT_SOURCE_DIR}/../include/*.hpp")
file(GLOB_RECURSE inc_src "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp")
file(GLOB_RECURSE src "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/../include" FILES ${inc})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${inc_src})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${src})
if (MSVC)
add_compile_options(/W3) # warning level 3
add_compile_options(/MP) # Multi-processor compilation
endif()
add_library(
${PROJECTNAME}
SHARED
${inc}
${inc_src}
${src}
)
target_include_directories(${PROJECTNAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include/")
include(FetchContent)
FetchContent_Declare(project_a
GIT_REPOSITORY <REPO LINK>
GIT_TAG master)
FetchContent_MakeAvailable(project_a)
target_link_libraries(${PROJECTNAME} project_a)

这个问题的解决方案是什么?对于这样的设计,我是否应该使用另一种方法?添加一个简单的copy命令是正确的解决方案吗?

CMAKE_RUNTIME_OUTPUT_DIRECTORY这样的变量会影响所有进一步创建的库的输出目录…除非变量是changed.

CMakeLists.txt(2)中的project_a

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin")

无条件的,所以它会改变变量,即使它是作为子项目构建的(使用FetchContent)。

通常,任何项目在其根CMakeLists.txt中都可以检查它是否实际上是顶级项目. 并且只在

的情况下执行一些设置:
cmake_minimum_required(VERSION 3.21)
project(project_a LANGUAGES CXX)
if (PROJECT_IS_TOP_LEVEL)
# Do global settings only if we are top-level project.
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_SYSTEM_VERSION 10.0.19041.0)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin-etc")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/lib")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin")
endif()
# Other settings are treated as project-specific,
# so could be done in "subproject mode" too.
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED)
add_subdirectory(src)

注意,变量PROJECT_IS_TOP_LEVEL只出现在CMake 3.21中。对于检测,项目是否在旧的CMake版本中是顶级的,请参阅该问题及其答案:如何检测当前作用域是否在CMake中有父节点?

最新更新