是否可以在基于 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 -static
或 g++ -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.so
)GCC linking options. See this & that
也许您首先应该尝试 link 静态地进行一些 SFML 演示....或者只是 scp
您的(动态 linked)二进制程序并尝试 运行 它远程(它可能能够 运行)。
使用 -static
编译似乎适用于基本的 c++ 程序,可能是所有标准库?
然而,当与其他库一起使用时,这可能不再有效。
我正在做一个项目,我希望能够 "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 -static
或 g++ -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.so
)GCC linking options. See this & that
也许您首先应该尝试 link 静态地进行一些 SFML 演示....或者只是 scp
您的(动态 linked)二进制程序并尝试 运行 它远程(它可能能够 运行)。
使用 -static
编译似乎适用于基本的 c++ 程序,可能是所有标准库?
然而,当与其他库一起使用时,这可能不再有效。