我正在开展一个项目,我希望能够“#34;运送"其他基于Linux的计算机作为完整的可执行文件,没有依赖项。 (为了能够将1个文件只复制到其他系统,然后在这些系统上运行该文件。)
在windows世界中,我认为静态链接只是通过将-static
传递给编译器来完成的,如果你使用的是Visual Studio,可能还有一些特定库*的其他选项。
*例如:使用SFML还需要出于某种原因定义SFML_STATIC吗?
这可能是使用gcc / g ++,如果是这样的话怎么样?我试着寻找这个,但没有设法找到任何东西。我之前听说过这可能是一项非常重要的任务。
编辑:
BasileStarynkevitch建议使用标记-static
进行编译。
我不知道这是否是我想要的,但我写了一个测试程序来试试:
#include <iostream>
int main()
{
std::cout << "Link statically please" << std::endl;
return 0;
}
然后编译:
g++ main.cpp -o a.out -static
g++ main.cpp -o b.out
结果是:
-rwxr-xr-x 1 1653098 a.out
-rwxr-xr-x 1 9167 b.out
所以它看起来可能有效吗?
TonyD提出了一种检查方法:
ldd a.out
not a dynamic executable
ldd b.out
linux-vdso.so.1 => (0x00007fff3d5ac000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fce5e34a000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fce5df85000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fce5dc7e000)
/lib64/ld-linux-x86-64.so.2 (0x00007fce5e677000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fce5da67000)
答案 0 :(得分:8)
是否可以在基于Linux的系统上使用gcc或g ++进行静态编译?
取决于。
您可以尝试使用gcc -static
或g++ -static
编译和链接所有代码。在某些情况下(例如纯粹的命令行应用程序,比如你的hello世界),它可以工作。
Linux发行版像很多共享库。他们中的大多数都广泛使用共享库(特别是图形应用程序)。阅读Drepper的How to Write Shared Libraries论文了解更多信息。
您可能遇到一些许可问题。为简化起见,将某些LGPL(或GPL)库链接静态的代码发送到LGPL许可证可能是非法的。邪恶在于细节。
某些核心功能,特别是DNS相关(例如getaddrinfo(3)&amp; getnameinfo(3))在内部使用插件技术àdlopen(3),因此sort-of需要动态 libc.so
(有关详情,请参阅nsswitch.conf(5)。)
一些X11事物,特别是字体相关的事物,也期待与插件有关的事情(IIRC,Xft);也许SFML使用它们。顺便说一下,SFML很可能作为共享库安装,所以你需要从源代码重建SFML ......
最后,静态链接的程序可能与某个特定的内核版本绑定在一起,而动态链接的程序(原则上不是这种情况)。可能会发生与旧的或未来的内核不兼容(但通常不兼容)。
另请参阅ldd(1),file(1),pmap(1),proc(5),vdso(7)
将源代码发送到目标系统实际上可能更简单,要求sysadmin安装所需的依赖项,并在远程目标上构建代码(例如使用ssh
)
您可以尝试通过玩GCC linking options静态链接大多数库但不是全部(例如静态链接libstdc++.a
和动态libc.so
)。见this&amp; that
也许您首先应该尝试静态链接一些SFML演示....或者只是scp
您的(动态链接)二进制程序并尝试远程运行它(它可能能够运行)。 / p>
答案 1 :(得分:1)
使用-static
进行编译似乎适用于基本的c ++程序,可能是所有标准库?
但是,当与其他库一起使用时,这可能不再有效。