我正在尝试编译一个非常基本的程序并在多个操作系统上运行。该程序只是尝试使用 boost::filesystem
将其文件名打印到流中,以便我可以验证加载 .so
是否按预期工作。
我在 Ubuntu 机器上编译它:
$ uname -a
Linux ubuntu 3.13.0-48-generic #80-Ubuntu SMP Thu Mar 12 11:16:15 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
我有一个 CentOS 盒子,我试图在上面运行它:
$ uname -a
Linux localhost.localdomain 3.10.0-123.20.1.el7.x86_64 #1 SMP Thu Jan 29 18:05:33 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
我使用 $ORIGIN
编译可执行文件,以便从我的目录中获取链接的 boost 库,然后我ldd
boost 库和 cp
他们变成一样的。因此,lib 目录如下所示:
deliverable/
deliverable/hello
deliverable/.lib/
deliverable/.lib/libc.so.6
deliverable/.lib/libboost_system.so.1.58.0
deliverable/.lib/libpthread.so.0
deliverable/.lib/libm.so.6
deliverable/.lib/libstdc++.so.6
deliverable/.lib/libboost_filesystem.so.1.58.0
deliverable/.lib/libboost_filesystem.so
deliverable/.lib/libfoo.so
deliverable/.lib/libboost_system.so
deliverable/.lib/libgcc_s.so.1
其中 hello
是我要运行的可执行文件。但是,在 CentOs 盒子上,我收到以下错误:
$ ./hello
$ ./hello: relocation error: ~/deliverable/.lib/libc.so.6: symbol _dl_find_dso_for_object, version GLIBC_PRIVATE not defined in file ld-linux-x86-64.so.2 with link time reference
如何解决这个问题?我还想知道这种模式是否违反了有关在 Linux 机器之间传送编译代码的最佳实践。 . .
更多信息(如果相关):
$ cat Makefile
CXX = g++
CPPFLAGS := -Wall -g -Wfatal-errors -std=c++11 -I./inc -fPIC
DELIVERABLE = $(CURDIR)/deliverable
LIB = $(DELIVERABLE)/.lib
all: $(DELIVERABLE)/hello
$(DELIVERABLE)/hello: main.o $(LIB)/libfoo.so
$(CXX) -L./deliverable/.lib -Wl,--allow-shlib-undefined -Wl,-rpath='$$ORIGIN/.lib' -o $@ $< -lfoo
main.o: main.cc
$(CXX) $(CPPFLAGS) -c $< -o $@
$(LIB)/libfoo.so: foo.o
$(CXX) -L./deliverable/.lib -Wl,--allow-shlib-undefined -Wl,-rpath='$$ORIGIN/.lib' -shared -o $@ $^ -lboost_system -lboost_filesystem
foo.o: foo.cc
$(CXX) $(CPPFLAGS) -c $< -o $@
clean:
rm -f *.o $(LIB)/libfoo.so $(DELIVERABLE)/hello
$ cat main.cc
#include "foo.hh"
int main()
{
hello();
}
$ cat foo.hh
#ifndef FOO_HH
#define FOO_HH
void hello();
#endif
$ cat foo.cc
#include "foo.hh"
#include <boost/filesystem.hpp>
#include <iostream>
void hello()
{
boost::filesystem::path p{__FILE__};
std::cout << "p.parent_path() " << p.parent_path() << '\n';
std::cout << "p.string() " << p.string() << '\n';
std::cout << "__FILE__ " << __FILE__ << '\n';
}
我还在 RHEL 机器上试过这个,它给出了一个更糟糕的错误:
$ uname -a
Linux localhost.localdomain 2.6.18-164.6.1.el5 #1 SMP Tue Nov 3 ... EXT 2009 x86_64 x86_64 GNU/Linux
在这台机器上运行它崩溃了:
$./hello
./hello: error while loading shared libraries: ~/deliverable/.lib/libm.so.6: unexpected PLT reloc type 0x25
最佳答案
我想,在系统安装了额外的 .so
文件后,您必须“告诉”ld 它们在那里吗?
ldconfig 是我想到的命令:
ldconfig 创建必要的链接和缓存(供运行时链接器 ld.so 使用)到在命令行指定的目录中找到的最新共享库,在文件/etc/ld 中.so.conf,以及受信任的目录(/usr/lib 和/lib)。 ldconfig 在确定应更新其链接的版本时检查它遇到的库的 header 和文件名。 ldconfig 在扫描库时忽略符号链接(symbolic link)。
http://linux.about.com/od/commands/l/blcmdl8_ldconfi.htm
关于c++ - 让可执行文件在多个 Linux 操作系统的 : 上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29541522/