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

标签 c++ linux gcc g++

我正在从事一个项目,我希望能够将其作为一个没有依赖项的完整可执行文件“发送”到其他基于 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)

最佳答案

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

视情况而定。

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

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

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

一些核心功能,特别是与 DNS 相关的功能(例如 getaddrinfo(3)getnameinfo(3) )在内部使用插件技术 à la dlopen(3) ,所以某种程度上需要一个动态 libc.so(更多信息请参见nsswitch.conf(5))。

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

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

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

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

您可以尝试通过使用 GCC linking options 来静态链接大多数库但不是全部(例如静态链接 libstdc++.a 和动态链接 libc.so) .参见 this & that

也许你首先应该尝试静态链接一些 SFML 演示....或者简单地 scp 你的(动态链接的)二进制程序并尝试远程运行它(它可能能够运行).

关于c++ - 是否可以在基于 Linux 的系统上使用 gcc 或 g++ 进行静态编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32224494/

相关文章:

c++ - std::remove_if 是否保证按顺序调用谓词?

c++ - C++ 中枚举数的作用域

linux - GCC 编译代码 : why integer declaration needs several statements?

c - 在每个 C 函数的开头自动运行代码

c++ - 是否有任何技术可以检测 GCC 的未定义行为?

c++ - 在引用限定符上重载成员函数的用例是什么?

c++ - 为什么我应该在 scanf() 系列成员中加入一个长度修饰符作为参数?有什么好处?带有长度修饰符的 scanf 有什么作用?

linux - Linux 操作系统可执行存档文件的选项 - 自安装程序

linux - 创建针对不同 Linux 发行版的 Qt 应用程序

gcc inline - 'cmp' 的操作数类型不匹配