C++ 编译C++;转换成可移植的linux二进制文件

C++ 编译C++;转换成可移植的linux二进制文件,c++,portability,static-linking,portable-executable,C++,Portability,Static Linking,Portable Executable,好的,这个问题是关于便携式的,如无依赖项(即“我可以将二进制文件放入USB密钥中,随身携带,通过电子邮件发送给朋友等”) 我听说过静态链接,但我不知道它的确切后果是什么;哪些可以静态链接,哪些不可以静态链接(即Qt、OpenGL、libstdc++),以及二进制文件在以后的“可移植”程度 我也听说过LSB(Linux标准库),但我不知道它到底是什么,也不知道它在这个意义上是否有帮助。静态链接适用于大多数库,但不适用于使用动态加载模块的库。试试看它是否管用。您可能仍然存在内核兼容性问题;您的程序可

好的,这个问题是关于便携式的,如无依赖项(即“我可以将二进制文件放入USB密钥中,随身携带,通过电子邮件发送给朋友等”)

我听说过静态链接,但我不知道它的确切后果是什么;哪些可以静态链接,哪些不可以静态链接(即Qt、OpenGL、libstdc++),以及二进制文件在以后的“可移植”程度


我也听说过LSB(Linux标准库),但我不知道它到底是什么,也不知道它在这个意义上是否有帮助。

静态链接适用于大多数库,但不适用于使用动态加载模块的库。试试看它是否管用。您可能仍然存在内核兼容性问题;您的程序可能正在使用旧内核中不可用的系统调用

Linux标准库由一些Linux发行版支持,但在(我认为也是Ubuntu)上,它必须从软件包中安装。它还处理大多数管理事务,如启动脚本,尽管它有一些二进制兼容性的东西。有关信息,请参阅


对于“带上USB密钥并在任何地方运行”的要求,请查看。

使用gcc进行静态链接时要小心,因为它实际上不再有效。
您不必以相同的方式链接所有库。我想要 一定要坚持libc和其他应用程序的动态链接 系统库。并使用C++语言进行静态链接;这个 二进制API确实会时不时地发生变化,您需要 确保库的版本与版本相同 你反对——最可靠的方法就是 静态地将库链接到可执行文件中。如果有的话 你使用的其他库是用C++编写的,你可能会 也希望在本地编译它们,而不是使用 预编译发行版,以确保它们已编译 针对相同的二进制API,并静态链接它们。这个 C的二进制API是固定的,因此您有更多的自由:如果 库将出现在每个安装中,并且必须 具有与操作系统版本兼容的版本,链接
动态地;否则,静态地说。

会让你失望:没有解决办法。静态链接就在那里,您可以(如果愿意)将所有内容链接到static=>删除其他库中的所有依赖项。但是,还有其他无法避免的依赖性:首先是架构。这里有PowerPC上的linux、ARM上的linux、Microblaze上的linux、32位x86上的linux和64位x86上的linux。其次是ABI和系统调用。这些可以(事实上在过去)改变(例如,旧系统上不存在外来/新的系统调用-如果您在二进制文件中得到这些调用,您的程序将无法工作)


LSB只是不同发行版的一个标准(或更好的标准,不是每个人都遵循它),通过定义文件的存储位置,使管理、使用和维护(有时是开发)更容易。它的目的不是使可执行文件更具可移植性。

我在那篇文章中没有看到任何东西说它不起作用。恰恰相反:对于他所要求的,我会静态链接除了标准系统库(libc等)之外的所有东西。我特别静态地连接任何C++,因为安装在其他机器上的动态库可能没有我编译的版本。它说,您不能再可靠地静态链接LIbSTDc++。但是,这意味着他将有一些依赖项(好的,系统依赖项),但这确实意味着他需要确保目标机器上有libstdc++的最新版本。正如其中一条评论所说,这有一个32/64位的问题。这与没有外部依赖项不同。看看有没有问题,没有。它表示,如果动态加载的组件使用某个静态链接,则无法对其进行静态链接。如果您使用libstdc++静态链接所有内容,就不会有问题。(事实上,IIRC,他所声称的并不完全正确,但您确实需要一个特殊的选项,使可执行文件中的符号从动态链接库中可见。)我的观点是GCC并没有达到您期望的效果
-static
不会生成静态二进制文件,您必须添加
-static libgcc
-static libstdc++
,即使这样做,您也可能无法获得静态二进制文件或有效的二进制文件(或者错误,如果您做了傻事)。PS:您提到的特殊选项是什么?更一般地说,您必须为每个库指定静态链接还是动态链接。(至少,我一直是这么看的。)回答得好。除了libc?libm之外,您能举一些可能保持动态的“系统库”的例子吗。任何X窗口库。实现Posix函数的任何库。关键的一点是,它们将出现在您想要运行代码的机器上,并且它们不依赖于编译它们的gcc/g++版本。(对于C,通常为true,对于C++,通常为false)。-1。GNULIBC的设计显然不是为了向前兼容;如果您链接到最近的libc,您的程序将在启动时检查该版本或更新版本,因此它不会在任何较旧的Linux发行版上运行。好的,那么我应该根据我将支持的最旧libc/libm进行编译?@James,很遗憾,但这是真的:。我最近在这个问题上是站在双方的立场上的。(顺便说一句,这不是动态链接的唯一目的,另一个目的是减少二进制大小和内存占用。由于glibc不断被扩展,“增加的功能”可能是他们选择此设置的原因。)只要选项很小,我就可以分发多个二进制文件(两个用于32/64位不会有任何影响),因为我已经在Windows/MacOS上这么做了。@Helltone:当你不得不使用多个二进制文件时,你可以避免体系结构问题(例如32/64位),但这并不能解决问题