是否可以在基于Linux的系统上使用gcc或g ++进行静态编译?

时间:2015-08-26 10:43:49

标签: c++ linux gcc g++

我正在开展一个项目,我希望能够“#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)

2 个答案:

答案 0 :(得分:8)

  

是否可以在基于Linux的系统上使用gcc或g ++进行静态编译?

取决于。

您可以尝试使用gcc -staticg++ -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 ++程序,可能是所有标准库?

但是,当与其他库一起使用时,这可能不再有效。