首页 > 解决方案 > 一个 CMake 目标可以链接到另一个库目标的 *shared* 版本吗?

问题描述

我有一个项目,其中包含一个核心库(LibA在下面的示例中)、一个可执行文件和一个LibB依赖于第一个库的第二个库()。第二个库 ( LibB) 始终以共享(动态库)形式构建。

有什么方法可以强制我始终链接到LibB共享版本?LibA

这是一个说明问题的小CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.16)

project(my_project LANGUAGES CXX)

# LibA should be buildable in either static or shared form.
add_library(LibA A.cpp)
# In the real case, there are many customizations to `LibA`: 
# compile flags, include dirs, target properties, etc.

add_executable(ExecutableA main.cpp)
target_link_libraries(ExecutableA LibA)

# I want library myB to *always* link against the dynamic library libLibA.so.
add_library(LibB SHARED B.cpp)
target_link_libraries(LibB PUBLIC LibA m pthread)

可以使用以下命令构建它:

echo 'int main() {}' > main.cpp
touch A.cpp B.cpp
mkdir -p build 
cmake -B build/ -S .
cmake --build build/

我知道我可以强制LibA始终与 共享add_library(LibA SHARED A.cpp),但我希望能够构建LibA为静态库。

真正的上下文是我有一个核心库(LibA),并且希望在创建可执行文件时静态链接它,但LibA.so在创建 Python 扩展模块()时动态链接(as LibB.so)。

标签: c++cmake

解决方案


这是不可能的,libA只能是静态的或动态的,不能两者兼而有之。

你需要有两个版本libA,一个是动态的,一个是静态的:

cmake_minimum_required(VERSION 3.16)

project(my_project LANGUAGES CXX)

function( addLibA suffix type )

    set( libname LibA${suffix} )
    add_library(${libname} ${type} A.cpp)

    # specify library properties here

endfunction()

# LibA should be buildable in either static or shared form.
addLibA("s" STATIC)
addLibA("" SHARED)
# In the real case, there are many customizations to `LibA`: 
# compile flags, include dirs, target properties, etc.

add_executable(ExecutableA main.cpp)
target_link_libraries(ExecutableA LibAs)

# I want library myB to *always* link against the dynamic library libLibA.so.
add_library(LibB SHARED B.cpp)
target_link_libraries(LibB PUBLIC LibA m pthread)

推荐阅读