编译 C++转换为可移植的 Linux 二进制文件
好的,这个问题是关于便携式的,如无依赖项(即“我可以将二进制文件放入USB密钥中并随身携带,通过电子邮件将它们发送给朋友” ETC”)。
我听说过静态链接,但我对它的具体后果感到困惑;什么可以和什么不能静态链接(即 Qt、OpenGL、libstdc++ 呢?)以及二进制文件之后的“可移植性”程度。
我也听说过LSB(Linux Standard Base),但我不知道它到底是什么,也不知道它是否可以在这个意义上提供帮助。
Ok, this question is about portable as in no dependencies (i.e. "I can put the binaries in a USB key and bring it with me everywhere, e-mail them to friends etc").
I have heard of static linking but I'm confused to what are exactly the consequences of it; what can and what can't be static linked (i.e. what about Qt, OpenGL, libstdc++?) and to which degree the binary will be "portable" afterwards.
I've also heard of LSB (Linux Standard Base) but I don't know exactly what it is or if it can help in this sense.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
静态链接适用于大多数库,但不适用于那些使用动态加载模块的库。试试看是否有效。您可能仍然遇到内核兼容性问题;您的程序可能使用旧内核中不可用的系统调用。
Linux Standard Base 受到一些 Linux 发行版的支持,但在 Debian(我想还有 Ubuntu)上它有从包中安装。它还处理主要的管理事务,例如启动脚本,尽管它有一些二进制兼容性的东西。请参阅此页面了解一些信息。
对于“放置 USB 密钥并在任何地方运行”的要求,请查看 CDE。
Static linking works for most libraries, but not those that use dynamically loaded modules. Just try and see if it works. You may still have issues with kernel compatibility; your program may be using system calls not available in older kernels.
The Linux Standard Base is supported by some Linux distros, but on Debian (and I think also Ubuntu) it has to be installed from a package. It also handles mostly administrative things like startup scripts, though it has some binary compatibility stuff. See this page for some info.
For the "put on USB key and run anywhere" requirement, check out CDE.
您不必以相同的方式链接所有库。 ID
绝对坚持 libc 和其他的动态链接
系统库。对任何 C++ 都使用静态链接;这
二进制 API 确实会不时发生变化,您需要
确保库的版本与版本相同
你编译的对象——最可靠的方法是
将库静态链接到可执行文件中。如果有任何一个
您使用的其他库是用 C++ 编写的,您可能会
也想在本地编译它们,而不是使用
预编译发行版,以确保它们被编译
针对相同的二进制 API,并静态链接它们。这
C 的二进制 API 是固定的,因此您有更多的自由:如果
库将出现在每次安装中,并且必须
有一个与操作系统版本兼容的版本,链接
动态地;否则,静态。
You don't have to link all of the libraries the same way. I'd
definitely stick with dynamic linking for libc and the other
system libraries. And use static linking for anything C++; the
binary API does change from time to time, and you need to be
sure that the version of the library is the same as the version
you compiled against---the surest way of doing that is to
statically link the library into your executable. If any of
the other libraries you use are written in C++, you'll probably
want to compile them locally as well, rather than using
a precompiled distribution, to ensure that they are compiled
against the same binary API, and link them statically. The
binary API for C is fixed, so you have more freedom: if the
library is going to be present on every installation, and must
have a version compatible with the version of the OS, link
dynamically; otherwise, statically.
让你失望的是:没有解决办法。静态链接就在那里,您可以(如果您愿意)链接所有内容 static =>来自其他库的所有依赖项都将被删除。但还有其他无法避免的依赖关系:首先是架构。我们这里有 PowerPC 上的 linux、ARM 上的 linux、Microblaze 上的 linux、32 位 x86 上的 linux 和 64 位 x86 上的 linux。其次是 ABI 和系统调用。这些可以(并且过去确实已经)发生变化(例如,旧系统上不存在外来/新的系统调用 - 如果您在二进制文件中收到这些调用,您的程序将无法工作)。
LSB 只是不同发行版的一个标准(或者更好的是它试图成为 - 并不是每个人都遵循它),通过例如定义文件的存储位置来使管理、使用和维护(有时是开发)更容易。它的目的并不是使可执行文件更加可移植。
To disappoint you: there is no solution to it. That statically link is there, and you can (if you want) link everything static => all dependencies from other libraries are removed. But there are other dependencies, which cant be avoided: First there is the architecture. We have here linux on PowerPC, linux on ARM, linux on Microblaze, linux on 32-bit x86, and linux on 64-bit x86. Secondly there is the the ABI and there syscalls. Those can (and indeed have in the past) change (e.g. exotic/new syscalls does not exist on old systems - and if you got those calls in your binary your program wont work).
The LSB is just a a standard (or better it tries to be - not everyone follows it) for the different distros to make adminstration, usage, and maintaining (and sometimes developing) easier by e.g. defining where which files are stored. It does not aim to make executables more portable.
使用 gcc 进行静态链接时要小心,它不再真正起作用了。
参见
Be careful with static linking using gcc, it does not really work any more.
See