当前位置:  开发笔记 > 运维 > 正文

在32位模式下编译gcc原子操作时链接错误

如何解决《在32位模式下编译gcc原子操作时链接错误》经验,为你挑选了2个好方法。

我有以下程序:

~/test> cat test.cc
int main()
{
  int i = 3;
  int j = __sync_add_and_fetch(&i, 1);
  return 0;
}

我正在使用运行在多CPU 64位Intel机器上的Linux上的GCC 4.2.2编译该程序:

~/test> uname --all
Linux doom 2.6.9-67.ELsmp #1 SMP Wed Nov 7 13:56:44 EST 2007 x86_64 x86_64 x86_64 GNU/Linux

当我以64位模式编译程序时,它编译并链接正常:

~/test> /share/tools/gcc-4.2.2/bin/g++ test.cc
~/test>

当我在32位模式下编译它时,我收到以下错误:

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 test.cc
/tmp/ccEVHGkB.o(.text+0x27): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status
~/test>

虽然我永远不会在32位处理器上运行,但我确实需要一个32位可执行文件,所以我可以链接一些32位库.

我的两个问题是:

    在32位模式下编译时,为什么会出现链接错误?

    有没有办法让程序编译和链接,同时仍然能够与32位库链接?

Bruno Rijsma.. 24

Dan Udey的回答非常接近,事实上让我能够找到真正的解决方案.

根据手册页"-mcpu"是"-mtune"的弃用同义词,只是表示"针对特定CPU进行优化(但仍然在较旧的CPU上运行,尽管不太理想)".我尝试了这个,但它没有解决问题.

但是," - march ="表示"为特定CPU生成代码(并且不在较旧的CPU上运行)".当我尝试这个时它解决了问题:指定一个i486或更好的CPU摆脱了链接错误.

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32  test.cc
/tmp/ccYnYLj6.o(.text+0x27): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i386 test.cc
/tmp/ccOr3ww8.o(.text+0x22): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i486 test.cc

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=pentium test.cc


Dan Udey.. 15

从Atomic Builtins的GCC页面:

并非所有目标处理器都支持所有操作.如果无法在目标处理器上实现特定操作,则将生成警告并将生成调用外部函数.外部函数将带有与内置函数相同的名称,后缀为"_n",其中n是数据类型的大小.

从你的编译器输出来看__sync_add_and_fetch_4,这就是正在发生的事情.由于某种原因,GCC没有正确生成外部功能.

这可能是您在32位模式下只出现错误的原因 - 在编译64位模式时,它会更紧密地编译处理器.在编译32位时,它可能正在使用通用的arch(例如i386),它本身不支持这些功能.尝试通过-mcpu为您的芯片系列(Xeon,Core 2等)指定特定的架构,看看是否有效.

如果没有,你将不得不弄清楚为什么GCC不包括它应该产生的适当功能.



1> Bruno Rijsma..:

Dan Udey的回答非常接近,事实上让我能够找到真正的解决方案.

根据手册页"-mcpu"是"-mtune"的弃用同义词,只是表示"针对特定CPU进行优化(但仍然在较旧的CPU上运行,尽管不太理想)".我尝试了这个,但它没有解决问题.

但是," - march ="表示"为特定CPU生成代码(并且不在较旧的CPU上运行)".当我尝试这个时它解决了问题:指定一个i486或更好的CPU摆脱了链接错误.

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32  test.cc
/tmp/ccYnYLj6.o(.text+0x27): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i386 test.cc
/tmp/ccOr3ww8.o(.text+0x22): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i486 test.cc

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=pentium test.cc



2> Dan Udey..:

从Atomic Builtins的GCC页面:

并非所有目标处理器都支持所有操作.如果无法在目标处理器上实现特定操作,则将生成警告并将生成调用外部函数.外部函数将带有与内置函数相同的名称,后缀为"_n",其中n是数据类型的大小.

从你的编译器输出来看__sync_add_and_fetch_4,这就是正在发生的事情.由于某种原因,GCC没有正确生成外部功能.

这可能是您在32位模式下只出现错误的原因 - 在编译64位模式时,它会更紧密地编译处理器.在编译32位时,它可能正在使用通用的arch(例如i386),它本身不支持这些功能.尝试通过-mcpu为您的芯片系列(Xeon,Core 2等)指定特定的架构,看看是否有效.

如果没有,你将不得不弄清楚为什么GCC不包括它应该产生的适当功能.


这个答案非常接近,足够接近让我找到真正的解决方案,我已单独发布.
推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有