将 C++ 库包含到另一个库中?

Including a C++ library into another?

我正在尝试构建一个 C++ 库,它本身将使用另一个库。 我想在最后输出一个 .so 文件,所以它很容易复制并用于任何其他项目。

在这个库中,我使用了另一个库 GLFW。

现在,我可以很好地创建我的库,但是当我使用它时出现链接错误,其中未定义 GLFW 函数。这让我觉得 GLFW 库没有随我的库一起导出。

我见过 this 这似乎是一个解决方案,但我给了我很多重复的符号错误。

我是 cmake 的初学者,所以可能有一些明显的东西我没有看到。这是我的 CMakeLists.txt :

cmake_minimum_required(VERSION 3.22)
project(MyLib)

set(CMAKE_CXX_STANDARD 23)

# define folders path
get_filename_component(ROOT_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
set(HEADER "${ROOT_DIR}/include")
set(SRCS_PATHS  "${ROOT_DIR}/src")
set(TESTS_SRC   "${ROOT_DIR}/tests")
# add dependencies
set(DEP_HEADERS "${ROOT_DIR}/dependencies/GLFW/include")

# set the project sources and headers files
include_directories(${HEADER})
include_directories(${DEP_HEADERS})

set(SRCS [...])


add_library(MyLib SHARED ${SRCS})
# set the project property linker language
set_target_properties(MyLib PROPERTIES LINKER_LANGUAGE CXX)


# target tests
add_executable(window ${TESTS_SRC}/window.cpp)
target_link_libraries(window MyLib)

我发现我不是唯一遇到此问题的人,但我尝试过的大多数答案都不起作用并导致同样的问题。

从你的 CMakeLists.txt 中我可以推断出,你应该做这样的事情(我不喜欢 vendoring,不是这种方法的专家,所以也许有更优雅的东西):

cmake_minimum_required(VERSION 3.20)
project(MyLib)

# glfw static PIC
set(CMAKE_POSITION_INDEPENDENT_CODE_SAVED ${CMAKE_POSITION_INDEPENDENT_CODE})
set(BUILD_SHARED_LIBS_SAVED ${BUILD_SHARED_LIBS})
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(BUILD_SHARED_LIBS OFF)
add_subdirectory(dependencies/GLFW EXCLUDE_FROM_ALL)
set(CMAKE_POSITION_INDEPENDENT_CODE ${CMAKE_POSITION_INDEPENDENT_CODE_SAVED})
set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_SAVED})

# MyLib
add_library(MyLib SHARED [...])
target_include_directories(MyLib PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>)
target_link_libraries(MyLib PRIVATE glfw)
target_compile_features(MyLib PUBLIC cxx_std_23)

# Tests
add_executable(window tests/window.cpp)
target_link_libraries(window PRIVATE MyLib)
target_compile_features(MyLib PRIVATE cxx_std_23)

但老实说,在 CMakeLists 中硬编码所有这些信息是不好的,你应该有一个通用的 CMakeLists 并避免供应商:

cmake_minimum_required(VERSION 3.20)
project(MyLib)

# MyLib
find_package(glfw3 REQUIRED)
add_library(MyLib [...])
target_include_directories(MyLib PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>)
target_link_libraries(MyLib PRIVATE glfw)
target_compile_features(MyLib PUBLIC cxx_std_23)

# Tests
add_executable(window tests/window.cpp)
target_link_libraries(window PRIVATE MyLib)
target_compile_features(MyLib PRIVATE cxx_std_23)

然后您将在构建时决定如何构建每个库:

// build & install glfw once, as static PIC (glfw is not vendored in MyLib source code here)
cd <glfw_source_dir>
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=<glfw_install_dir>
cmake --build build
cmake --build build --target install

// build MyLib as shared
cd <mylib_source_dir>
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCMAKE_PREFIX_PATH=<glfw_install_dir>
cmake --build build