尝试构建使用 .so 使用其他 .so 文件的 C++ exe
Trying to build C++ exe that uses .so that uses other .so files
我正在尝试构建一个 link 具有共享库 libA.so 的 C++ 可执行文件。 libA.so 已构建并 link 与另一个共享库 libB.so 编辑。 libB.so 是使用 -rpath 构建的,用于在我的主目录 (liblapack.so) 中查找系统库的自定义构建。如果我在 libB.so 上执行“readelf -d”,我会看到 liblapack.so 是“NEEDED”,而且我还会看到“RPATH”下列出的自定义构建路径。如果我在 libA.so 上执行“readelf -d”,我只会看到 libB.so 列为“NEEDED”;没有 RPATH 条目。然后,当我尝试使用 libA.so 构建我的 exe 时,它没有在 libB.so 中指定的自定义路径中查找;它在系统位置选择了一个,它没有正确的功能,所以 linking 失败了。有谁知道实现我想在这里做的事情的方法吗?有没有办法让 libB 的 RPATH 条目传播到 libA?
我在 RHEL 7 上使用 GCC 9。
提前致谢。
预计到达时间:应用程序、libA 和 libB 都是独立的包,所以我更愿意将它们的构建过程和不寻常的 rpath 信息保留给他们自己。我可以更改每个黑框的 link 标志。它们也是已建立的包,所以我无法更改为 autoconf 或类似的东西。
ETA2:重申一下,当我使用 libB 构建 libA 和 link 时,它确实将 libA 标记为需要 libB,这很棒。然后应用程序可以 link 使用 libA 并隐式获取 libB,libA 需要它才能运行。但是为什么 linking libB with libA 会丢弃 libB 的 rpath 信息?或者,当应用程序正在 linking 时,为什么它看不到,因为 libA 需要 libB,link 与 libB 并保留 libB 的 rpath 规范?底线是 libB 的 rpath 规范在某处丢失了,看起来不应该丢失。 (顺便说一句:这对我来说是新事物,所以我不怀疑我认为它应该工作的方式存在问题。但从逻辑上讲,这对我来说听起来是对的。)
在 linking 时使用 -rpath-link
并指定您的自定义库位置。
gcc -o app source.o -lA -Wl,-rpath-link=$HOME
这将导致 link 用户在 $HOME
中查找其他共享库引用的共享库。但是只有在linking的时候。在 运行 时,当动态 linking 完成时,rpath-link 选项无效,使用正常的 RPATH、LD_LIBRARY_PATH 等搜索顺序。
已搜索共享库中的 DT_RPATH
或 DT_RUNPATH
。但它们并不是搜索顺序中的第一位。您的 libB 的替代版本必须位于最先出现的路径中,因此会找到它而不是您想要的。尝试重命名它,看看会发生什么,或者检查您的 LD_LIBRARY_PATH
和 LD_RUN_PATH
变量。
无法更改顺序,但 -rpath-link
排在第一位,因此可以解决问题。
要使 libB 独立,请使用类似 pkgconfig 文件的文件,其中包含使用该库所需的选项。这也适用于查找头文件或静态库。
您也可以将 libA 重命名为 libMyA,以避免与同时安装的替代版本发生名称冲突。
或者,可以通过使用 --allow-shlib-undefined
linker 选项来避免 link 失败,而无需真正解决问题。那么它是否找到错误的版本应该无关紧要,因为缺少的符号不会出错。
我正在尝试构建一个 link 具有共享库 libA.so 的 C++ 可执行文件。 libA.so 已构建并 link 与另一个共享库 libB.so 编辑。 libB.so 是使用 -rpath 构建的,用于在我的主目录 (liblapack.so) 中查找系统库的自定义构建。如果我在 libB.so 上执行“readelf -d”,我会看到 liblapack.so 是“NEEDED”,而且我还会看到“RPATH”下列出的自定义构建路径。如果我在 libA.so 上执行“readelf -d”,我只会看到 libB.so 列为“NEEDED”;没有 RPATH 条目。然后,当我尝试使用 libA.so 构建我的 exe 时,它没有在 libB.so 中指定的自定义路径中查找;它在系统位置选择了一个,它没有正确的功能,所以 linking 失败了。有谁知道实现我想在这里做的事情的方法吗?有没有办法让 libB 的 RPATH 条目传播到 libA?
我在 RHEL 7 上使用 GCC 9。
提前致谢。
预计到达时间:应用程序、libA 和 libB 都是独立的包,所以我更愿意将它们的构建过程和不寻常的 rpath 信息保留给他们自己。我可以更改每个黑框的 link 标志。它们也是已建立的包,所以我无法更改为 autoconf 或类似的东西。
ETA2:重申一下,当我使用 libB 构建 libA 和 link 时,它确实将 libA 标记为需要 libB,这很棒。然后应用程序可以 link 使用 libA 并隐式获取 libB,libA 需要它才能运行。但是为什么 linking libB with libA 会丢弃 libB 的 rpath 信息?或者,当应用程序正在 linking 时,为什么它看不到,因为 libA 需要 libB,link 与 libB 并保留 libB 的 rpath 规范?底线是 libB 的 rpath 规范在某处丢失了,看起来不应该丢失。 (顺便说一句:这对我来说是新事物,所以我不怀疑我认为它应该工作的方式存在问题。但从逻辑上讲,这对我来说听起来是对的。)
在 linking 时使用 -rpath-link
并指定您的自定义库位置。
gcc -o app source.o -lA -Wl,-rpath-link=$HOME
这将导致 link 用户在 $HOME
中查找其他共享库引用的共享库。但是只有在linking的时候。在 运行 时,当动态 linking 完成时,rpath-link 选项无效,使用正常的 RPATH、LD_LIBRARY_PATH 等搜索顺序。
已搜索共享库中的 DT_RPATH
或 DT_RUNPATH
。但它们并不是搜索顺序中的第一位。您的 libB 的替代版本必须位于最先出现的路径中,因此会找到它而不是您想要的。尝试重命名它,看看会发生什么,或者检查您的 LD_LIBRARY_PATH
和 LD_RUN_PATH
变量。
无法更改顺序,但 -rpath-link
排在第一位,因此可以解决问题。
要使 libB 独立,请使用类似 pkgconfig 文件的文件,其中包含使用该库所需的选项。这也适用于查找头文件或静态库。
您也可以将 libA 重命名为 libMyA,以避免与同时安装的替代版本发生名称冲突。
或者,可以通过使用 --allow-shlib-undefined
linker 选项来避免 link 失败,而无需真正解决问题。那么它是否找到错误的版本应该无关紧要,因为缺少的符号不会出错。