为什么g ++不能链接静态程序?

时间:2017-06-04 13:19:15

标签: c++ ubuntu g++

我安装了Ubuntu 17.04 它们:

apt-get install libsdl2-dev`

以及所有额外内容 当我编译程序时:

g++ -o prg main.cpp -lSDL2 -lSDL2_gfx -lSDL2_image

申请仅在终端

工作
./prg

但在Ubuntu界面我看到窗口"没有程序可以打开文件共享库"我必须做什么?

1 个答案:

答案 0 :(得分:1)

在Ubuntu 17.04中,GCC工具链已经首次配置 在Ubuntu中 - 默认生成PIE(位置无关可执行)代码。

如果以详细模式编译程序 - g++ -v ... - 并捕获输出, 你会看到:

Configured with: ... --enable-default-pie ...

早期版本不是这样。

这意味着程序现在是可重定位的二进制文件,作为共享库 一直都是。您可以使用file上的prg命令明确检查:

$ file prg
prg: ELF 64-bit LSB shared object, x86-64,... 

结果,图形文件管理器不再能够 通过检查程序和当被要求打开程序时,将程序与共享库区分开来 你已经建立了自己认为你想要打开一个它不知道该怎么做的共享库。也许 将来文件管理器将被启用以区分它们 一个共享的库和一个PIE程序,但在那之前你必须运行你的 为此目的打开终端的程序。

我不知道这个工具链改变的动机,但我愿意 推测这是因为PIE可以从ASLR - Address Space Layout Randomization中受益 - 一个已经在Ubuntu和Linux中普遍启用的已建立的漏洞利用缓解防御很长一段时间但是 程序可执行文件是免除的,除非编译为PIE。

<强>后来

  

我要为[构建]静态应用程序做些什么?

如果您希望制作文件管理员可识别为的非PIE程序 一个程序并运行,然后将-no-pie添加到您的链接选项。

$ g++ -no-pie -o prg main.cpp -lSDL2 -lSDL2_gfx -lSDL2_image

或者如果你先编译并链接第二个,那么:

$ g++ -o main.o -c main.cpp
$ g++ -no-pie -o prg main.o -lSDL2 -lSDL2_gfx -lSDL2_image 

但请注意,非PIE程序与其不同 一个静态链接的程序,并且您的命令行永远不会 制作了一个静态链接的节目。你没有说明 为什么你想要一个静态链接的程序,可能不需要。