为啥在我的 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 上工作?