c++ - 让可执行文件在多个 Linux 操作系统的 : 上运行

标签 c++ linux ubuntu centos

我正在尝试编译一个非常基本的程序并在多个操作系统上运行。该程序只是尝试使用 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/

相关文章:

c++ - 将 boost.log 与 printf 样式的宏一起使用

linux - Bash:解析 CSV 并编辑单元格值

python - 向 Python 脚本发送消息

shell - ubuntu 中的 echo -e 选项不起作用

Apache Rewrite 规则未按预期工作

C++ 方法线程

c++ - Nullptr 并检查指针是否指向有效对象

c++ - g++ 编译器为表达式提供 << 类型错误,但在 Visual Studio 中有效

linux - 如何在 Unix 中的嵌套循环中读取两个文件

ubuntu - 无法使用 localhost :8080/nifi 连接到 Nifi