【问题标题】:CMake linked librarys cannot be found找不到 CMake 链接库
【发布时间】:2018-09-18 13:11:15
【问题描述】:

我在我的 linux 机器上使用 ZeroMQ 库创建了一个非常基本的 c++ 示例。

构建项目

为了构建项目,我决定使用 CMake。目前我的 CMakeLists.txt 看起来像这样:

cmake_minimum_required (VERSION 3.9)
project(QSample)

# add ZMQ cmake files and find libzmq
set (ZeroMQ_DIR "/home/vtd/DEV_JOHANN/ZEROMQ/INSTALL_CMAKE/")
find_package(ZeroMQ REQUIRED)

# include also the zmq c++ wrapper
set(SOURCES qSample.cpp /home/vtd/DEV_JOHANN/ZEROMQ/INSTALL/include/zmq.hpp)

add_executable(QSample ${SOURCES})

# add the zmq include path
target_include_directories(QSample PRIVATE "/home/vtd/DEV_JOHANN/ZEROMQ/INSTALL/include")

# add the zmq libs
link_directories("/home/vtd/DEV_JOHANN/ZEROMQ/INSTALL/lib64")

# link the libs
TARGET_LINK_LIBRARIES(QSample libzmq)

# rule to copy the bin to the install folder
install (TARGETS QSample DESTINATION bin)

如您所见,我更改了默认的 zmq 安装路径。那是我第一次尝试使用 CMake,所以如果您发现我的 CMakeLists.txt 有任何改进,那将是很高兴的。

通过 CMake 生成 Makefile 有效,如果我运行 sudo make,它会构建我的项目。之后我跑了sudo make install。现在我的问题来了:

在构建文件夹中运行程序

如果我在指定的 CMake 构建文件夹中运行 ./QSample,我的应用程序会按预期运行。

ldd ./QSample的输出:

linux-vdso.so.1 (0x00007fff78384000)
        libzmq.so.5 => /home/vtd/DEV_JOHANN/ZEROMQ/INSTALL/lib64/libzmq.so.5 (0x00007efeb3f4a000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007efeb3cf9000)
        librt.so.1 => /lib64/librt.so.1 (0x00007efeb3af1000)
        libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007efeb3965000)
        libm.so.6 => /lib64/libm.so.6 (0x00007efeb35d2000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007efeb35b8000)
        libc.so.6 => /lib64/libc.so.6 (0x00007efeb31f6000)
        /lib64/ld-linux-x86-64.so.2 (0x00007efeb4026000)

在安装文件夹中运行程序

如果我现在切换到我的特定安装文件夹,我将无法再运行./QSample

/QSample:加载共享库时出错:libzmq.so.5:无法打开共享对象文件:没有这样的文件或目录

ldd ./QSample的输出:

linux-vdso.so.1 (0x00007ffd975d4000)
        libzmq.so.5 => not found
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fcac89d3000)
        librt.so.1 => /lib64/librt.so.1 (0x00007fcac87cb000)
        libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fcac863f000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fcac82ac000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fcac8292000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fcac7ed0000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fcac8c26000)

现在,我不清楚为什么我不能在安装文件夹中运行它。我必须在我的 CMake 文件中进行哪些更改?

【问题讨论】:

  • 你能包含ldd ./QSample的输出吗?我建议不要使用 sudo 编译代码,除非你也有充分的理由这样做。
  • @GWW 我已经编辑了我的帖子。所以很明显它无法找到 libzmq
  • /home/vtd/DEV_JOHANN/ZEROMQ/INSTALL/lib64 在您的LD_LIBRARY_PATH 中吗?另一种选择是静态链接库。
  • 不,它不在 LD_LIBRARY_PATH 中。问题是,为什么运行 make install 后行为会发生变化
  • 默认情况下,当 build 可执行文件时,CMake 会将 absolute paths 嵌入到可执行文件使用的所有(共享)库中。当安装这个可执行文件时,CMake 只在其中留下库名称。您可以在 [CMake RPATH 处理](gitlab.kitware.com/cmake/community/wikis/doc/cmake/…) 文章中找到有关此过程的更多信息。

标签: c++ cmake static-linking dynamic-linking


【解决方案1】:

你现在正在做

install (TARGETS QSample DESTINATION bin)

改用以下内容(bin 文件夹的完整路径,我的是 /usr/local/bin)

install(TARGETS QSample DESTINATION /usr/local/bin)

接下来,当您的 bin 文件夹中有一些可执行文件时,您需要做的就是编写不带 ./ 的可执行文件名称。/

即在您的提示中只需输入 QSample 就可以了

$QSample

我目前正在开发 ubuntu,以上内容对我来说非常好。希望对您有所帮助。

简而言之,一旦您将可执行文件放在 bin 文件夹中,您就可以从系统中的任何位置运行它们,而无需专门进入安装目录。

【讨论】:

  • 提问者的问题是找不到可执行文件。问题是找到可执行文件需要的 library。你的决定对这项任务没有帮助。至于将bin 替换为/usr/local/bin: 1. 安装前缀(CMAKE_INSTALL_PREFIX)等于/usr/local 时没有任何变化。 2. 在install 命令的DESTINATION 选项中使用绝对路径几乎在所有情况下都是不鼓励
【解决方案2】:

(简要)

将以下行添加到您的 CMakeLists.txt 中,在 add_executable 行之前:

set (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

(不简短)

您的问题是 rpath 处理。默认情况下,在链接阶段,cmake 将使用 -rpath 链接器选项将所有自动发现的带有链接库的文件夹直接放入可执行程序中。

(假设您使用“Unix Makefiles”生成器)如果您开始编译/链接

make VERBOSE=1

在链接阶段,你会看到类似

g++  [lot of everything] -Wl,-rpath,/home/vtd/DEV_JOHANN/ZEROMQ/INSTALL/lib64

这意味着在启动可执行文件时,运行时链接器将首先在文件夹 /home/vtd/DEV_JOHANN/ZEROMQ/INSTALL/lib64 中搜索,然后再搜索 $LD_LIBRARY_PATH。这允许您的程序在安装之前正常启动。

在安装过程中,作为安装过程的一部分,此信息会从可执行文件中剥离,并且无法再找到您的 lib。您可以通过在安装过程中查看输出来识别什么。搜索以下内容:

-- Installing: /usr/local/bin/QSample
-- Set runtime path of "/usr/local/bin/QSample" to ""

末尾的空引号意味着rpath被剥离了。

一种解决方案是将您的 lib 文件夹添加到 LD_LIBRARY_PATH 中,例如:

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/vtd/DEV_JOHANN/ZEROMQ/INSTALL/lib64 ./QSample

或:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/vtd/DEV_JOHANN/ZEROMQ/INSTALL/lib64
./QSample

另一种解决方案是指示 CMAKE 不要剥离 rpath 数据。只需将以下行添加到您的 CMakeLists.txt 中,在 add_executable 行之前:

set (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

这个链接非常彻底地解释了 cmake 中的 rpath 处理:

https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/RPATH-handling

【讨论】:

    猜你喜欢
    • 2015-10-03
    • 1970-01-01
    • 2012-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    • 2013-01-06
    相关资源
    最近更新 更多