我有一个大型项目正在从 autotools 转换为 cmake。其余代码库所依赖的库集合。然而,该项目的一部分注定会被分成独立的回购协议。这导致引用库时遇到困难,因为我无法直接使用它们的目标名称,而是使用 find_library 或包搜索等...来定位它们。
考虑到以下项目布局,让 cmake 首先构建库以允许子项目找到它们的最佳方法是什么?
main
|- CMakeLists.txt (top)
|- myLibs/
|----CMakeLists.txt (currently only does add_subdirectory(libX)
|----lib (outputdir from make install)
|----include (public header output dir from make install)
|----mylibA
|-------CMakeLists.txt
|----mylibB
|-------CMakeLists.txt
|-projCollections/ ( collection of programs )
|----CMakeLists.txt (Depends on mylibA and mylibB)
|----projA -> Cannot reference any of myLibs directly
|------CMakeLists.txt (Depends on mylibA )
|----projb
|------CMakeLists.txt (Depends on mylibA and mylibB)
我目前只看到一些解决方案:
使用execute_process立即在myLibs上运行cmake配置和make命令
在 projCollections 上使用ExternalProject_add
在 myLibs 上使用ExternalProject。
ExternalProject 似乎是合理的,但也许我现在只需要允许引用,一旦发生源分离,返回并更新所有(100+)CMakeLists.txt 文件以更改回 find_library...
(当前cmake的基本结构...) 顶级:
cmake_minimum_required(VERSION 3.14)
project(main)
add_subdirectory(myLibs)
add_subdirectory(projCollections)
我的图书馆:
cmake_minimum_required(VERSION 3.14)
project(myLibs DESCRIPTION "myLibs")
add_subdirectory(mylibA)
add_subdirectory(mylibB)
项目集合:
cmake_minimum_required(VERSION 3.14)
project(projCollections DESCRIPTION "projCollections")
add_subdirectory(projA)
add_subdirectory(projB)
项目A:
project(projA )
find_library(MYLIBA NAMES mylibA HINTS ${CMAKE_SOURCE_DIR}/myLibs/libs/mylibA.so NO_DEFAULT_PATH)
add_executable(projA)
target_link_libraries(projA myLibA)
您正在寻找的是FetchContent。按照计划将您的项目分成单独的存储库,然后使用
FetchContent
获取它们。然后它们将被构建并在构建时可供您的项目使用。这是一个小例子:
我已将一个非常小的库项目上传到我的 GitHub,名为 workbench。里面有这些文件:
CMakeLists.txt
cmake_minimum_required(VERSION 3.22.0)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
project(workbench VERSION 1.0.0)
# Using INTERFACE for header only library
add_library(workbench INTERFACE)
# Giving scope to files inside library
target_include_directories(workbench INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
模块.h
#include <string>
static std::string RandomVariable = "Hello from module";
从这里,我创建了一个小项目,其中包含我的工作台库。看起来如下:
CMakeLists.txt
cmake_minimum_required(VERSION 3.22.0)
project(tester VERSION 1.0.0)
# Allows us to use FetchContent
include(FetchContent)
# Fetches the repository from GitHub
FetchContent_Declare(workbench
GIT_REPOSITORY https://github.com/andrelehto/workbench.git
GIT_TAG v1.0.0
)
# Makes the repository available to us
FetchContent_MakeAvailable(workbench)
add_executable(tester main.cpp)
# Link to library from GitHub
target_link_libraries(tester workbench)
主.cpp
#include <iostream>
#include "module.h"
int main() {
std::cout << RandomVariable << std::endl;
}
注意 module.h 现在可以在我们的主项目中使用。