如何设置 CMake 项目以使用本地库?

问题描述 投票:0回答:1

想象以下设置:

您有许多个人库和应用程序:

libA
libB
libC
appA
appB
,它们具有如下依赖树:

appA -> {libA}
libC -> {libA}
appB -> {libB, libC}

其中

appA
取决于
libA
,并且
appB
也从
libA
传递地依赖于
libC

所有库都在积极开发中,因此共享最新版本对于所有人来说都是有用的。

一种方法是将所有项目存储在同一级别,并使用

add_subdirectory()
:

.
├── appA
├── appB
├── libA
├── libB
└── libC

appA
CMakeLists.txt
例如:

add_executable(appA main.cpp)
add_subdirectory(../libA libA)
target_link_library(appA PRIVATE libA)

libC
CMakeLists.txt
例如:

add_library(libC ${libc_SRC})
add_subdirectory(../libA libA)
target_link_library(libC PUBLIC libA)

appB
CMakeLists.txt
例如:

add_executable(appB main.cpp)
add_subdirectory(../libB libB)
add_subdirectory(../libC libC)
target_link_library(appA PRIVATE libB libC)

这种方法效果很好,因为它将源代码直接添加到构建中,因此您可以直接从任何地方对其进行编辑,并且其他人都可以看到编辑内容(与使用包不同,因为这是基于最新安装的)。

但是,如果您想使用此环境之外的库(克隆

libA
并将其放置在
libC
的同一级别以便在其他地方使用
libC
?恶心,这种方法显然不起作用)

是否有某种方法可以设置

find_package()
,使其在设置了特定环境变量后与
add_subdirectory()
完全一样?这样
add_subdirectory()
的所有用途都可以被替换吗?我想提交更改,以便通过安装使用时它可以按预期工作,但随后我可以配置我的环境,以便它以上述开发方式工作

c++ cmake
1个回答
0
投票

根据我所读到的内容,我想我可以回答我自己的问题:

使用以下内容更新每个库:

add_library(libA::libA ALIAS libA)

libA::libA
被添加为别名,即使通过调用
add_subdirectory(../libA libA)

包含库也是如此

现在,通过

libA
包含
add_subdirectory()
的应用程序可以链接到
libA::libA
,因为它仅指向
libA

target_link_libraries(appA PRIVATE libA::libA)

但是,由于

libC
依赖于
libA
,在构建
appA
的背景下,
libC
知道
libA
,这很好,但是,如果将
libC
添加到另一个项目中,则可以构建它现在依赖于该项目添加
libA
target_link_libraries(libC INTERFACE libA::libA)
才能成功,这不好。

因此,我们仍然需要在

find_package(libA REQUIRED)
中调用
libC
来使该依赖项不透明,但如果我们不想将
libA
作为外部包使用,因此还没有安装它,则会失败。

所以解决办法就是检查

libA::libA
是否可用,如果不可用,则尝试使用
find_package(libA REQUIRED)

例如

if (NOT TARGET libA::libA)
    find_package(libA CONFIG REQUIRED)
endif()

现在,如果

libA
之前已通过
libC
可供
add_subdirectory(../libA libA)
使用,那么
libC
就可以找到它,因为它只是构建树中的另一个项目,并且它定义了符号
libA::libA
。但是,如果
libC
以其他方式使用,则
libA::libA
将不会被定义,因此它会尝试在安装位置找到它。如果成功,它会定义
libA::libA
(如果遵循通常的约定)。

所以无论哪种情况,

libC
都能找到它需要的东西。

© www.soinside.com 2019 - 2024. All rights reserved.