为啥在我的 Mac 上编译的 C++ 库不能在服务器上运行?

Posted

技术标签:

【中文标题】为啥在我的 Mac 上编译的 C++ 库不能在服务器上运行?【英文标题】:Why is a C++ library compiled on my Mac not working on the server?为什么在我的 Mac 上编译的 C++ 库不能在服务器上运行? 【发布时间】:2016-03-13 08:14:50 【问题描述】:

我正在为一个项目编写一个 C++ 库。它基本上包含一个源文件。我在我的 Mac 上编写了源文件并用g++ -c source.cpp -o source.o 编译它,并用ar rcs libmylib.a source.o 创建了一个静态库。还有一个头文件,定义了几个函数接口。

我可以在我自己的 Mac 上使用这个库编译程序,通过发出g++ myprogram.cpp -o myprogram -lmylib -L .,它可以编译和运行而没有任何错误。但是,当我只是将静态库复制到服务器并尝试使用该库编译一些代码时,它不起作用。编译器抱怨某些函数的定义未定义。显然,链接器成功找到了库,但它根本找不到定义。

然后我尝试在服务器上编译库源文件并在服务器上编译我的项目。一切都很好。但是当我将在服务器上编译的库复制到我的 Mac 并尝试使用该库编译我的本地测试程序时,编译器投诉 ld: warning: ignoring file ./libmylib.a, file was built for archive which is not the architecture being linked (x86_64): ./libmylib.a 并且它拒绝链接。

让我感到困惑的是,我的 Mac 和服务器的 架构 应该是相同的(又名 x86_64),但在它们上编译的源文件相同两台机器不能互换使用。这可能是什么原因?库不应该在基于相同架构的机器上兼容吗?

有关系统和编译器的更多详细信息:

我的电脑:

AdvancedMage-3:encryption Andy$ uname -a
Darwin AdvancedMage-3.local 15.3.0 Darwin Kernel Version 15.3.0: Thu Dec 10 18:40:58 PST 2015; root:xnu-3248.30.4~1/RELEASE_X86_64 x86_64
AdvancedMage-3:encryption Andy$ g++ -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/c++/4.2.1
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.3.0
Thread model: posix

服务器:

[Andy@localhost ~]$ uname -a
Linux localhost.localdomain 3.10.0-327.4.4.el7.x86_64 #1 SMP Tue Jan 5 16:07:00 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
[Andy@localhost ~]$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)

【问题讨论】:

【参考方案1】:

Mac 和 RHEL Linux 不兼容二进制。可悲的事实是,即使这些系统可能基于相同的 CPU,它们也不共享相同的库和动态库链接语义。 (Mac 基于 FreeBSD+Mach,而 RHEL 则基于 Linux)。

但是,可以从 mac 交叉编译到 linux,但我建议你,除非你对偏头痛发痒,你最好让一个虚拟机来运行 linux 来做你的本地您希望部署到您的服务器的开发。

【讨论】:

谢谢 -- 编辑回复以反映马赫。 实际上,即使在不同的 Linux 版本之间构建二进制文件也很痛苦;如果可能,最简单的方法是在目标机器(或具有相同 Linux 发行版和发行版的机器上)构建二进制文件。 是的,这就是我推荐虚拟机的原因。我以前做过交叉编译,它们真的不值得付出努力(即使是学术练习)。现在尤其如此,因为使用 VirtualBox 等人很容易获得虚拟机。

以上是关于为啥在我的 Mac 上编译的 C++ 库不能在服务器上运行?的主要内容,如果未能解决你的问题,请参考以下文章

Discord 在我的 GitHub 上编译的 dll 中找到了机器人令牌

为啥在 Intel 机器上编译的 VB.NET DLL Addin for Inventor 可以在 Intel 机器上工作,但不能在 AMD 上工作?

为啥在两台略有不同的机器上编译的库的行为略有不同?

在 AXP 服务器上编译的问题

链接在 cygwin 上编译的 .lib 文件

C++ 在 Mac OS X 上编译代码并在 Linux x86 上运行