Linux c++ 可移植二进制问题
Linux c++ portable binary issue
我尝试将我的二进制文件及其所有共享库打包到一个存档中。我希望用户只提取存档以使二进制文件工作。可执行文件是通过 shell 脚本启动的,我将 LD_LIBRARY_PATH 设置为存档中包含的共享库路径。
我第一次想让它在 RHEL 6.7 发行版上运行,所以我用这个发行版编译了我的二进制文件,当我测试它时它运行良好。
问题是我现在必须让它在 RHEL 7.2 上工作(并保持 RHEL 6.7 工作)并且当我启动二进制文件时它不起作用......它在 glibc 函数内崩溃(isspace 没有参数中的垃圾) .
我看到这两个 RHEL 版本后面的 glibc 版本发生了变化。
在存档中包含的共享库中,没有 glibc 共享库,因此我尝试添加它,但现在出现以下错误:
./XXX: ���:ELF: zR: Error 892688562
这似乎是一个 ELF 错误(每次启动时都会出现详细信息),我检查了我所有的共享库,它们是 x64 库(如二进制文件)...
我不想在 RHEL 7.2 上编译,因为我有很多依赖项,我不想编译所有这些,而且维护一个版本对我来说更容易。
我尝试了很多东西,比如 Statifier 和 Ermine,它们都可以工作,但第一个有一个错误,必须禁用地址 Space 布局随机化,第二个是共享软件,我更喜欢免费的解决方案。我也试过CDE也可以,但是生成这么大的包,有点乱...
为什么这种解决方案有效,而我自制的解决方案却无效?我哪里做的不好?
感谢您的阅读,
我希望有人能给我解决方案,因为我搜索了很长时间...
编辑:
我找到了解决方案,之前我的 shell 脚本是这样的:
# Binary location
LOCATION=$(dirname [=12=])
# Shared libraries directory
BINDIR=${LOCATION}/bin/
# Define LD_LIBRARY_PATH
export LD_LIBRARY_PATH=${BINDIR}:${LD_LIBRARY_PATH}
# Launch binary
${LOCATION}/XXX $*
我改变了:
# Binary location
LOCATION=$(dirname [=13=])
# Shared libraries directory
BINDIR=${LOCATION}/bin/
# Changed shared library default location and launch binary
${BINDIR}/ld-linux-x86-64.so.2 --library-path ${BINDIR} ${LOCATION}/XXX $*
我真的不明白为什么但它有效,有人可以解释一下吗? (ld-linux-x86-64.so.2 来自 RHEL 6.7 发行版)
I don't really understand why but it works, someone can explain me please ?
已解释here. Your solution is "explicit loader invocation" mentioned here。
顺便说一句,这是错误的:${LOCATION}/XXX $*
你应该这样做:
${LOCATION}/XXX "$@"
(您的变体将无法正确处理带有嵌入空格的参数。)
我尝试将我的二进制文件及其所有共享库打包到一个存档中。我希望用户只提取存档以使二进制文件工作。可执行文件是通过 shell 脚本启动的,我将 LD_LIBRARY_PATH 设置为存档中包含的共享库路径。
我第一次想让它在 RHEL 6.7 发行版上运行,所以我用这个发行版编译了我的二进制文件,当我测试它时它运行良好。 问题是我现在必须让它在 RHEL 7.2 上工作(并保持 RHEL 6.7 工作)并且当我启动二进制文件时它不起作用......它在 glibc 函数内崩溃(isspace 没有参数中的垃圾) . 我看到这两个 RHEL 版本后面的 glibc 版本发生了变化。 在存档中包含的共享库中,没有 glibc 共享库,因此我尝试添加它,但现在出现以下错误:
./XXX: ���:ELF: zR: Error 892688562
这似乎是一个 ELF 错误(每次启动时都会出现详细信息),我检查了我所有的共享库,它们是 x64 库(如二进制文件)... 我不想在 RHEL 7.2 上编译,因为我有很多依赖项,我不想编译所有这些,而且维护一个版本对我来说更容易。
我尝试了很多东西,比如 Statifier 和 Ermine,它们都可以工作,但第一个有一个错误,必须禁用地址 Space 布局随机化,第二个是共享软件,我更喜欢免费的解决方案。我也试过CDE也可以,但是生成这么大的包,有点乱...
为什么这种解决方案有效,而我自制的解决方案却无效?我哪里做的不好?
感谢您的阅读, 我希望有人能给我解决方案,因为我搜索了很长时间...
编辑:
我找到了解决方案,之前我的 shell 脚本是这样的:
# Binary location
LOCATION=$(dirname [=12=])
# Shared libraries directory
BINDIR=${LOCATION}/bin/
# Define LD_LIBRARY_PATH
export LD_LIBRARY_PATH=${BINDIR}:${LD_LIBRARY_PATH}
# Launch binary
${LOCATION}/XXX $*
我改变了:
# Binary location
LOCATION=$(dirname [=13=])
# Shared libraries directory
BINDIR=${LOCATION}/bin/
# Changed shared library default location and launch binary
${BINDIR}/ld-linux-x86-64.so.2 --library-path ${BINDIR} ${LOCATION}/XXX $*
我真的不明白为什么但它有效,有人可以解释一下吗? (ld-linux-x86-64.so.2 来自 RHEL 6.7 发行版)
I don't really understand why but it works, someone can explain me please ?
已解释here. Your solution is "explicit loader invocation" mentioned here。
顺便说一句,这是错误的:${LOCATION}/XXX $*
你应该这样做:
${LOCATION}/XXX "$@"
(您的变体将无法正确处理带有嵌入空格的参数。)