构建后可执行文件缺少完整的库路径
Executable missing full library path after build
我正在使用 CMake 编译一个可执行文件,该可执行文件链接到我已经构建并安装到本地项目目录 (libs/3rdparty) 中的几个库。请注意,这是在安装项目之前进行的,主要用于 运行 单元测试和调试。我遇到的问题是有时有一个链接的库,但可执行文件缺少库的路径。我目前遇到问题的图书馆是 leptonica。但是,我已经 运行 多次使用不同平台上的不同库(osx、fedora、centos、ubuntu)解决这个问题。通过研究,我看到了类似的问题,但我一直无法找到为什么缺少库的完整路径的明确答案。
我试过玩:
CMAKE_BUILD_WITH_INSTALL_RPATH
CMAKE_INSTALL_RPATH
CMAKE_INSTALL_RPATH_USE_LINK_PATH
而且这些好像都没有太大的作用。
我的 CMakeLists 包含:
find_package(Leptonica REQUIRED)
target_link_libraries(${target}
PRIVATE
...
${Leptonica_LIBRARIES}
)
这是 ldd 在其中一个单元测试可执行文件上的输出:
ldd test_utilities
...
libleptonica.so.5.3.0 => not found
libtesseract.so.4 => {MY PROJECT}/libs/3rdparty/tesseract/lib/libtesseract.so.4
leptonica 是唯一在 ~30 个其他图书馆中未被发现的图书馆。
有谁知道这个问题的根本原因是什么?我不打算通过修改 LD_LIBRARY_PATH.
来解决问题
-- 添加了 LeptonicaTargets-release.cmake。根据这个,lib 的完整路径应该在目标中。
#----------------------------------------------------------------
# Generated CMake target import file for configuration "RELEASE".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "leptonica" for configuration "RELEASE"
set_property(TARGET leptonica APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(leptonica PROPERTIES
IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE "/usr/lib/x86_64-linux-gnu/libpng.so;/usr/lib/x86_64-linux-gnu/libz.so;m"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libleptonica.so.1.77.0"
IMPORTED_SONAME_RELEASE "libleptonica.so.5.3.0"
)
list(APPEND _IMPORT_CHECK_TARGETS leptonica )
list(APPEND _IMPORT_CHECK_FILES_FOR_leptonica "${_IMPORT_PREFIX}/lib/libleptonica.so.1.77.0" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
以下是 leptonica/lib 目录中的文件:
ll libs/3rdparty/leptonica/lib/
total 2776
drwxr-xr-x 3 user user 4096 May 30 14:17 ./
drwxr-xr-x 5 user user 4096 May 30 14:17 ../
lrwxrwxrwx 1 user user 21 May 30 14:17 libleptonica.so -> libleptonica.so.5.3.0
-rw-r--r-- 1 user user 2829784 May 30 09:49 libleptonica.so.1.77.0
lrwxrwxrwx 1 user user 22 May 30 14:17 libleptonica.so.5.3.0 -> libleptonica.so.1.77.0
drwxr-xr-x 2 user user 4096 May 30 14:17 pkgconfig/
chrpath --list test_utilities 的输出似乎也包含正确的库路径:
chrpath --list test_utilities
test_utilities: RUNPATH=...:{MY PROJECT}/libs/3rdparty/leptonica/lib:...
对于遇到此问题的任何人,我终于弄明白了。
该问题与该库是 OpenCV 的传递依赖项有关。在 Ubuntu 上,ld 现在默认使用 using --enable-new-dtags,它使用 RUNPATH,而不是 RPATH。存在未在 RUNPATH 中搜索传递依赖项的问题。
见https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/1253638
只需将“-Wl,--disable-new-dtags”添加到目标链接器选项即可解决我的问题。现在找到了所有库,包括我今天添加的 leptonica 以外的其他库。不过,我确信在构建安装包时我可能不得不进行更改。
我正在使用 CMake 编译一个可执行文件,该可执行文件链接到我已经构建并安装到本地项目目录 (libs/3rdparty) 中的几个库。请注意,这是在安装项目之前进行的,主要用于 运行 单元测试和调试。我遇到的问题是有时有一个链接的库,但可执行文件缺少库的路径。我目前遇到问题的图书馆是 leptonica。但是,我已经 运行 多次使用不同平台上的不同库(osx、fedora、centos、ubuntu)解决这个问题。通过研究,我看到了类似的问题,但我一直无法找到为什么缺少库的完整路径的明确答案。
我试过玩:
CMAKE_BUILD_WITH_INSTALL_RPATH
CMAKE_INSTALL_RPATH
CMAKE_INSTALL_RPATH_USE_LINK_PATH
而且这些好像都没有太大的作用。
我的 CMakeLists 包含:
find_package(Leptonica REQUIRED)
target_link_libraries(${target}
PRIVATE
...
${Leptonica_LIBRARIES}
)
这是 ldd 在其中一个单元测试可执行文件上的输出:
ldd test_utilities
...
libleptonica.so.5.3.0 => not found
libtesseract.so.4 => {MY PROJECT}/libs/3rdparty/tesseract/lib/libtesseract.so.4
leptonica 是唯一在 ~30 个其他图书馆中未被发现的图书馆。
有谁知道这个问题的根本原因是什么?我不打算通过修改 LD_LIBRARY_PATH.
来解决问题-- 添加了 LeptonicaTargets-release.cmake。根据这个,lib 的完整路径应该在目标中。
#----------------------------------------------------------------
# Generated CMake target import file for configuration "RELEASE".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "leptonica" for configuration "RELEASE"
set_property(TARGET leptonica APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(leptonica PROPERTIES
IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE "/usr/lib/x86_64-linux-gnu/libpng.so;/usr/lib/x86_64-linux-gnu/libz.so;m"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libleptonica.so.1.77.0"
IMPORTED_SONAME_RELEASE "libleptonica.so.5.3.0"
)
list(APPEND _IMPORT_CHECK_TARGETS leptonica )
list(APPEND _IMPORT_CHECK_FILES_FOR_leptonica "${_IMPORT_PREFIX}/lib/libleptonica.so.1.77.0" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
以下是 leptonica/lib 目录中的文件:
ll libs/3rdparty/leptonica/lib/
total 2776
drwxr-xr-x 3 user user 4096 May 30 14:17 ./
drwxr-xr-x 5 user user 4096 May 30 14:17 ../
lrwxrwxrwx 1 user user 21 May 30 14:17 libleptonica.so -> libleptonica.so.5.3.0
-rw-r--r-- 1 user user 2829784 May 30 09:49 libleptonica.so.1.77.0
lrwxrwxrwx 1 user user 22 May 30 14:17 libleptonica.so.5.3.0 -> libleptonica.so.1.77.0
drwxr-xr-x 2 user user 4096 May 30 14:17 pkgconfig/
chrpath --list test_utilities 的输出似乎也包含正确的库路径:
chrpath --list test_utilities
test_utilities: RUNPATH=...:{MY PROJECT}/libs/3rdparty/leptonica/lib:...
对于遇到此问题的任何人,我终于弄明白了。
该问题与该库是 OpenCV 的传递依赖项有关。在 Ubuntu 上,ld 现在默认使用 using --enable-new-dtags,它使用 RUNPATH,而不是 RPATH。存在未在 RUNPATH 中搜索传递依赖项的问题。
见https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/1253638
只需将“-Wl,--disable-new-dtags”添加到目标链接器选项即可解决我的问题。现在找到了所有库,包括我今天添加的 leptonica 以外的其他库。不过,我确信在构建安装包时我可能不得不进行更改。