首页 > 解决方案 > 在 Xubuntu 19.04 中编译 c++ 是否应该与在 Ubuntu 18.04 中编译 c++ 不同

问题描述

是否会出现 C++ 代码在 Ubuntu 18.04 中编译没有错误而在 Xubuntu 19.04 中无法编译的情况。我最初的猜测是没有,但后来一位教授告诉我有一些链接器问题可能会导致这种情况。另外让我补充一点,代码是使用相同的标准和使用 g++ 编译的。

标签: c++linuxubuntu

解决方案


是否会出现 C++ 代码在 Ubuntu 18.04 中编译没有错误而在 Xubuntu 19.04 中无法编译的情况。

可能,但它只出现在极端情况下。大多数 C++ 代码不会受到影响。

我认为这取决于 GCC 版本。大约在那个时候,GCC 开始默认启用 PIE,这导致了一些链接问题。例如,参见第 2 轮的初始 SUPERCOP Haswell 结果。从邮件列表消息中:

...此消息的其余部分解释了上面的 -fPIC -fPIE。在完全相同的长期支持版本的 Ubuntu 上,如果你运行的话,应该是兼容的系统提供的 gcc 和 clang 版本

   gcc -c x.c; clang -c y.c; gcc -o x x.o y.o

xc 在哪里说

   #include <stdio.h>
   extern int thenumber(void);
   int main() { printf("%d\n",thenumber()); return 0; }

和 yc 说

   static int myconstant = 5;
   int thenumber(void) { return myconstant; }

然后编译失败,同时做

   gcc -c x.c; clang -c y.c; clang -o x x.o y.o

或者

   gcc -c x.c; gcc -c y.c; gcc -o x x.o y.o

或者

   clang -c x.c; clang -c y.c; clang -o x x.o y.o

工作正常。潜在的问题是编译器编写者对正在进行的过渡的管理不善

  • -fPIC:将库编译为“与位置无关的代码”(这通常被宣传为对共享库很重要);

  • -fPIE:将 main() 等编译为与位置无关的代码(这通常被宣传为对地址空间布局随机化所声称的安全优势很重要);和

  • -pie:链接与位置无关的可执行文件。

编译为与位置无关的代码的代码可以链接到与位置相关的可执行文件或与位置无关的可执行文件。正确管理的过渡将包括

  • 默认开启 -fPIC 和 -fPIE,

  • 对任何与位置相关的代码发出自动警告,

  • 等待指定的年数让人们摆脱任何以前编译的位置相关代码,最后

  • 默认开启 -pie。

相反,gcc 突然打开 -pie,笨拙地破坏了所有现有的依赖于位置的代码,甚至设法破坏了与同一系统上的 clang 的兼容性——clang 仍然产生依赖于位置的代码,然后 gcc 无法生成可执行文件. 这也是 gcc 现在破坏 crypto_kem/ntruhrss701/avx2 的原因。


推荐阅读