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

Is it possible to compile statically with gcc or g++ on Linux based systems?

我正在做一个项目,我希望能够 "ship" 其他基于 Linux 的计算机作为一个没有依赖关系的完整可执行文件。 (为了我可以只将 1 个文件复制到其他系统,然后 运行 这些系统上的那个文件。)

在 windows 世界中,我认为静态链接只是通过将 -static 传递给编译器来完成,如果您使用的是 [=41=,可能还有一些针对特定库的其他选项* ].

*例如:使用 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)

Is it possible to compile statically with gcc or g++ on Linux based systems?

视情况而定。

您可以尝试使用 gcc -staticg++ -static 编译和 link 所有代码。在某些情况下(例如纯命令行应用程序,如您的 hello world),它会起作用。

Linux 像很多共享库一样的发行版。他们中的大多数人广泛使用共享库(尤其是图形应用程序)。阅读 Drepper 的 How to Write Shared Libraries 论文了解更多。

您可能遇到了一些许可问题。为了简单起见,将代码 静态 link 发送到某些 LGPL(或 GPL)库可能是非法的(违反 LGPL 许可)。细节决定成败。

一些核心功能,尤其是与 DNS 相关的功能(例如 getaddrinfo(3) & getnameinfo(3)) are internally using plugin techniques à la dlopen(3), so sort-of requires a dynamic libc.so (see nsswitch.conf(5) 更多)。

一些 X11 东西,特别是字体相关的东西,也需要插件相关的东西(IIRC,Xft);也许 SFML 使用它们。顺便说一句,SFML 很可能作为共享库安装,因此您需要从源代码重建 SFML...

最后,静态 linked 的程序可能比动态 linked 的程序更依赖于某个特定的内核版本(原则上,情况并非如此)。您可能会与非常旧的或未来的内核不兼容(但通常不会)。

另见 ldd(1), file(1), pmap(1), proc(5), vdso(7)

将源代码发送到目标系统实际上可能更简单,让系统管理员安装所需的依赖项,然后在远程目标上构建代码(例如使用 ssh

您可以尝试 link 静态地使用 GCC linking options. See this & that[ 但不是所有库(例如 link 静态 libstdc++.a 和动态 libc.soGCC linking options. See this & that

也许您首先应该尝试 link 静态地进行一些 SFML 演示....或者只是 scp 您的(动态 linked)二进制程序并尝试 运行 它远程(它可能能够 运行)。

使用 -static 编译似乎适用于基本的 c++ 程序,可能是所有标准库?

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