我的编译器:xlc版本10.1环境:AIX5.3链接器:ld
当我使用gcc(4.4.1)在Linux上工作时,我使用以下选项
-Wl,-rpath
Run Code Online (Sandbox Code Playgroud)
(-Wl表示链接器选项)它将一个目录添加到运行时库搜索路径中.
什么是xlc编译器的等价物?
或什么是链接器的-rpath等价物.
谢谢.
我正在修改一个与Automake / libtool文档提供的示例非常相似的项目。摘录:
顶级configure.ac:
LT_INIT
Run Code Online (Sandbox Code Playgroud)
顶级 Makefile.am:
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src doc
Run Code Online (Sandbox Code Playgroud)
./src
生成文件.am:
lib_LTLIBRARIES = libname.la
libname_la_SOURCES = <my cc file list>
libname_la_LDFLAGS = -no-undefined -version-info $(GENERIC_LIBRARY_VERSION)
include_HEADERS = <my h file list>
bin_PROGRAMS = progname
progname_SOURCES = <my cc file list>
progname_LDADD = libname.la
progname_LDFLAGS = -static
Run Code Online (Sandbox Code Playgroud)
在我的包创建软件提供的fakeroot环境中,我执行以下命令
$ autogen.sh # contains the usual calls to aclocal, libtoolize, automake, autoconf.
$ ./configure --prefix="/usr" --disable-static
$ make
...
/bin/sh ../libtool --tag=CXX --mode=link g++ -Wall …
Run Code Online (Sandbox Code Playgroud) 以下列方式设置链接库时
target_link_libraries (SOME_TARGET -L/somedir -lfoo)
Run Code Online (Sandbox Code Playgroud)
cmake不处理RPATH.使用'-L'和'-l'不是最佳实践,或者实际上是错误的?在创建我自己的Find*.cmake时,我经常使用,find_library()
但我得到的查找脚本没有这样做,并使用'-L'和'-l'转到上面的表单.
文档并没有真正解释如何收集RPATH,文档也不是很清楚如何处理"-l"和"-L"你得到的唯一指针是
"以 - ,但不是-l或-framework开头的项目名称被视为链接器标志"
我的项目使用 CMake 并且在 Ubuntu 16.04 上编译没有问题。
启动编译的应用程序时,我收到消息无法打开共享对象文件。
所有共享对象库都可以在同一个非标准文件夹中使用(我在那里需要它们)。
ldd输出显示大多数共享对象都可以找到。这里有些例子:
libboost_filesystem.so.1.55.0 => /path/to/libs/boost/lib/libboost_filesystem.so.1.55.0 (0x00007f2ed1fa0000)
libboost_filesystem.so.1.55.0 => /path/to/libs/boost/lib/libboost_filesystem.so.1.55.0 (0x00007f96af1f5000)
libboost_program_options.so.1.55.0 => /path/to/libs/boost/lib/libboost_program_options.so.1.55.0 (0x00007f96aef85000)
libboost_system.so.1.55.0 => /path/to/libs/boost/lib/libboost_system.so.1.55.0 (0x00007f96aed80000)
Run Code Online (Sandbox Code Playgroud)
由于某种原因,其他一些无法找到。例如:
libboost_iostreams.so.1.55.0 => not found
libboost_chrono.so.1.55.0 => not found
Run Code Online (Sandbox Code Playgroud)
还有其他非 boost 库显示相同的行为,但为了简单起见,我只展示 boost 示例。
以下是已经成功运行的解决方法。但我对“我需要什么”部分中的两点非常感兴趣。
我正在构建一个第三方程序,该程序使用未设置的目录中的库/etc/ld.so.conf
- 因此我将程序与-rpath
选项链接。
运行objdump -x bin/GetHistPrices | grep -i path
检查是否-rpath
设置正确我得到确认它是好的:
RUNPATH
/application/FXCM-API/GetHistPrices/bin:
/application/FXCM-API/lib:
/application/FXCM-API/sample_tools/lib
Run Code Online (Sandbox Code Playgroud)
cmake
将所有库复制到生成可执行文件的同一目录中 [eq ../GetHistPrices/bin
]; 因此第一条路径是可以的。
更重要的是,最后 2 个路径也指向共享库所在的目录 - 这些-rpath
选项由cmake
脚本自动添加。
当我尝试运行该程序不是内部../GetHistPrices/bin/
目录[所在] - EQ我不执行它./GetHistPrices
-所以我得到这个错误信息:
bin/GetHistPrices:加载共享库时出错:
Run Code Online (Sandbox Code Playgroud)libgsexpat.so: cannot open shared object file: No such file or directory
该程序仅在我从bin/
或/application/FXCM-API/lib
目录运行它时启动,因为所需的库位于那里。
1)
当我运行程序时,
LD_LIBRARY_PATH="/application/FXCM-API/GetHistPrices/bin" bin/GetHistPrices
它就会启动。但这也是我在可执行文件中看到的。奇怪的!
2)
添加/application/FXCM-API/GetHistPrices/bin
到/etc/ld.so.conf
让启动程序以及成功。
操作系统是 SLES 12.3 - 老实说,不知何故,它在我看来就像系统中的一个错误。
我的问题:
我做错了什么,即使 …
根据this SO question,Linux executable can't find shared library in same folder传递-Wl,-rpath,${ORIGIN}
是让Linux可执行文件.so
在与可执行文件相同的目录中搜索s的方法。
我们正在使用 cmake,所以我添加了一行表单
target_link_options(Executable PRIVATE -Wl,-rpath=${ORIGIN})
Run Code Online (Sandbox Code Playgroud)
到 CMakeLists.txt。问题在于 cmake 试图将九个字符序列解释${ORIGIN}
为一个变量,并用空替换它。
到目前为止,我已经尝试过:
$${ORIGIN}
\${ORIGIN}
$\{ORIGIN\}
$$\{ORIGIN\}
\$\{ORIGIN\}
Run Code Online (Sandbox Code Playgroud)
这些都没有奏效。我怎样才能做到这一点?
- 编辑 -
正如@Tsyvarev 的评论所指出的,在我的特定情况下,这是一个 XY 问题,因为 cmake 具有直接设计用于操纵 rpath 的设施。使用这个,我能够得到一个解决方案。
就我而言,将以下三行添加到 CMakeLists.txt 就可以了。
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
SET(CMAKE_INSTALL_RPATH "$\{ORIGIN\}")
Run Code Online (Sandbox Code Playgroud)
请注意,我们构建过程的一部分涉及将 复制.so
到输出文件夹以准备构建最终的 tarball 工件。因此,使用-rpath=${ORIGIN}
既适用于构建树中的测试,也适用于 Docker 容器中可执行文件的最终安装。
我已经在 OEL7 上使用 CMake 和 CPack 3.13.4 构建 RPM 几个月了,没有出现任何问题。我的 CMake 配置包含以下几行:
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
Run Code Online (Sandbox Code Playgroud)
这使我能够确保在任何安装的版本之前使用该库的本地构建版本。如果不对这些行进行任何更改,我突然无法再构建 RPM。我现在收到此错误消息:
+ /usr/lib/rpm/check-rpaths
*******************************************************************************
*
* WARNING: 'check-rpaths' detected a broken RPATH and will cause 'rpmbuild'
* to fail. To ignore these errors, you can set the '$QA_RPATHS'
* environment variable which is a bitmask allowing the values
* below. The current value of QA_RPATHS is 0x0000.
*
* 0x0001 ... standard RPATHs (e.g. /usr/lib); such RPATHs are a …
Run Code Online (Sandbox Code Playgroud) 我尝试在cgo中导入dylib动态库,但失败。这是我的代码。
\n\npackage main\n//#cgo CFLAGS: -I./yun2txt/include\n//#cgo LDFLAGS: -L./yun2txt/lib -ltotxt\n//\n//#include <library.h>\nimport "C"\n\nfunc main() {\n C.hello()\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n\n也有错误。
\n\ndyld: Library not loaded: @rpath/libtotxt.dylib\n Referenced from: /private/var/folders/2n/k70s3c1j08q2z_6kw06n13nh0000gn/T/___go_build_cgo\n Reason: image not found\n\n
Run Code Online (Sandbox Code Playgroud)\n\n我该如何解决这个问题\xef\xbc\x9f
\n我有以下 MWE,其中 Conan 用于安装fmt
库(共享)。
cmake_minimum_required(VERSION 3.21)
project(Test CXX)
set(CMAKE_MACOSX_RPATH ON)
set(CMAKE_CXX_STANDARD 17)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR})
if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/v0.16.1/conan.cmake"
"${CMAKE_BINARY_DIR}/conan.cmake"
EXPECTED_HASH SHA256=396e16d0f5eabdc6a14afddbcfff62a54a7ee75c6da23f32f7a31bc85db23484
TLS_VERIFY ON)
endif()
include(${CMAKE_BINARY_DIR}/conan.cmake)
conan_cmake_configure(REQUIRES fmt/6.1.2
OPTIONS fmt:shared=True
GENERATORS cmake_find_package)
conan_cmake_autodetect(settings)
conan_cmake_install(PATH_OR_REFERENCE .
BUILD missing
REMOTE conancenter
SETTINGS ${settings})
find_package(fmt)
add_executable(main main.cpp)
target_link_libraries(main fmt::fmt)
Run Code Online (Sandbox Code Playgroud)
当我检查可执行文件时,otool -l main
我发现该fmt
库没有绝对路径,这是我希望发生的情况。因此,executbale 也无法运行,因为它找不到libfmtd.6.dylib
.
问题是,这里设置错误是什么?为什么可执行文件中没有编码完整路径?
输出otool
:
cmake_minimum_required(VERSION 3.21)
project(Test CXX)
set(CMAKE_MACOSX_RPATH ON)
set(CMAKE_CXX_STANDARD 17) …
Run Code Online (Sandbox Code Playgroud) onnxruntime
我正在构建一个在底层使用的库(Ubuntu 22) 。反过来,onnxruntime
使用 CUDA,动态加载一些专用的“后端”。我构建了除 CUDA 库之外的整个代码堆栈,并且没有一个库具有其RPATH
或RUNPATH
设置(使用 进行双重检查readelf -d
)。
我构建了两个应用程序,一个是 C++,并直接链接到我的库。该应用程序有其RPATH
设置,一切正常。如果我运行它,LD_DEBUG=libs
我会看到类似这样的内容(请注意,路径已被编辑,并且我仅显示调试输出的一小部分):
158834: calling init: .../install/bin/../lib/libonnxruntime_providers_cuda.so
158834:
158834: find library=libcudnn_ops_infer.so.8 [0]; searching
158834: search path=.../install/bin/../lib (RPATH from file .../install/bin/test)
158834: trying file=.../install/bin/../lib/libcudnn_ops_infer.so.8
158834:
158834:
158834: calling init: .../install/bin/../lib/libcudnn_ops_infer.so.8
158834:
Run Code Online (Sandbox Code Playgroud)
这就是我所期待的,我很高兴。
但是,我还需要通过一些链接到它的 python 绑定来使用相同的库。为了让它工作,我需要在这种情况下设置RPATH
python 绑定(至少在我看来,它只是一个在运行时加载的共享库)。请注意,Python 可执行文件既没有RPATH
也没有RUNPATH
设置。这仅部分有效。也就是说,RPATH
传播似乎在沿着依赖关系树向下移动时起作用,直到开始搜索 CUDA 库,此时它不再起作用。这是以相同的方式、相同的构建运行完全相同的 onnxruntime API,并在与上面相同的文件夹中使用相同的文件。唯一的区别是 python 扩展层。输出LD_DEBUG
如下所示:
159602: find library=libonnxruntime.so.1.15.1 [0]; searching
159602: search path=.../install/lib/../lib …
Run Code Online (Sandbox Code Playgroud)