c++ - 如何将应用程序链接到依赖于另一个库的库?

标签 c++ linux cmake linker shared-libraries

我写了一个使用第 3 方共享库的共享库 mylib1,在我的例子中是 libtinyxml2(对于这个问题,第 3 方库是无关紧要的:它可以是任何图书馆)。我写了一个应用程序app1,它依赖于mylib1

构建 mylib1 成功,但构建 app1 失败,可能是因为链接器在链接 app1 时没有被告知链接 libtinyxml2

我错过了什么?

[I][~/Programs/cmake-jenkins/big_proj/src/build]$ make
[ 25%] Building CXX object mylib1/CMakeFiles/mylib1.dir/src/my_functions.cpp.o
[ 50%] Linking CXX shared library libmylib1.so
[ 50%] Built target mylib1
[ 75%] Building CXX object app1/CMakeFiles/app1.dir/src/main.cpp.o
[100%] Linking CXX executable app1
../mylib1/libmylib1.so: undefined reference to `tinyxml2::StrPair::Reset()'
../mylib1/libmylib1.so: undefined reference to `tinyxml2::StrPair::~StrPair()'
collect2: error: ld returned 1 exit status
make[2]: *** [app1/CMakeFiles/app1.dir/build.make:97: app1/app1] Error 1
make[1]: *** [CMakeFiles/Makefile2:402: app1/CMakeFiles/app1.dir/all] Error 2
make: *** [Makefile:84: all] Error 2

文件夹结构

.
├── app1
│   ├── CMakeLists.txt
│   ├── src
│   │   ├── include
│   │   │   └── functions_p.hpp
│   │   └── main.cpp
├── CMakeLists.txt
└── mylib1
    ├── CMakeLists.txt
    ├── src
    │   ├── include
    │   │   └── my_functions.hpp
    │   └── my_functions.cpp

./CMakeLists.txt

# Top level CMakeLists.txt
cmake_minimum_required(VERSION 3.8.2)

add_subdirectory(app1)
add_subdirectory(mylib1)

app1/CMakeLists.txt

project("app1" CXX)

set(APP1_SOURCE_FILES src/main.cpp )
add_executable(app1 ${APP1_SOURCE_FILES})

target_include_directories(app1
    PRIVATE src/include)
target_link_libraries(app1 mylib1)

mylib1/CMakeLists.txt

project("lib1" CXX)

find_library(TINYXML_LIB tinyxml2 REQUIRED)

set(MYLIB1_SOURCE_FILES src/my_functions.cpp )
set(MYLIB_INCLUDE_FILES src/include/my_functions.hpp)
add_library(mylib1 SHARED ${MYLIB1_SOURCE_FILES} ${MYLIB1_INCLUDE_FILES} )

target_include_directories(mylib1
    PUBLIC src/include)
# I have checked that TINYXML_LIB is set, so the library IS found.
target_link_libraries(mylib1 PUBLIC ${TINYXML_LIB})

readelf 输出显示该库依赖于 libtinyxml2.so.6,并且该文件作为 /usr/lib/libtinyxml2.so 存在。 6 在我的系统上。

[I][~/Programs/cmake-jenkins/big_proj/src/build]$ readelf -d mylib1/libmylib1.so
Dynamic section at offset 0x16cd0 contains 29 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libtinyxml2.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [libmylib1.so]

在详细模式下运行生成的 Makefile 显示确实在链接 app1 时,它不会链接到 libtinyxml2:

[ 75%] Linking CXX executable app1
cd /home/danb/Programs/cmake-jenkins/big_proj/src/build/app1 && /usr/bin/cmake -E cmake_link_script CMakeFiles/app1.dir/link.txt --verbose=1
/usr/bin/c++     CMakeFiles/app1.dir/src/main.cpp.o  -o app1 -Wl,-rpath,/home/danb/Programs/cmake-jenkins/big_proj/src/build/mylib1 ../mylib1/libmylib1.so

最佳答案

外部引用在链接最终应用程序时解析,因此在 app1/CMakeLists.txt 中的 target_link_libraries 中包含 libtinyxml2。

关于c++ - 如何将应用程序链接到依赖于另一个库的库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48176441/

相关文章:

android - 无法弄清楚为什么此代码在发送数据包数据时会导致 SIGSEGV

c++ - 在 C++ 中将 double 转换为固定小数点

linux - 如何使用 cURL 测试并等待 HTTP 服务?

php - pngquant 不适用于 php

linux - 尽管使用了 BOOST_ROOT,但无法找到我的本地 Boost 发行版而不是已安装的发行版

c++ - Ubuntu 上编译 MRPT 教程

c++ - 使用抽象层次实现数据结构

c++ - 在Ubuntu 16.04上编译Armadillo C++库时出错

linux - 仅当尚未添加值时才使用 bash 将值添加到数组

c++ - 如何在 cmake 中使用 SDL2 和 SDL_image