在32位模式下编译gcc原子操作时出现链接错误
时间:2020-03-06 14:41:50 来源:igfitidea点击:
我有以下程序:
~/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位库链接?
解决方案
在"原子内建函数"的" GCC"页面上:
Not all operations are supported by all target processors. If a particular operation cannot be implemented on the target processor, a warning will be generated and a call an external function will be generated. The external function will carry the same name as the builtin, with an additional suffix `_n' where n is the size of the data type.
从引用__sync_add_and_fetch_4
的编译器输出来看,这就是正在发生的情况。由于某些原因,GCC无法正确生成外部功能。
这很可能就是为什么在为64位模式进行编译时仅在32位模式下出现错误的原因,它会更紧密地为处理器编译。当编译为32位时,很可能使用的是本机不支持这些功能的通用体系结构(例如i386)。尝试通过-mcpu为芯片系列(Xeon,Core 2等)指定特定的体系结构,看看是否可行。
如果没有,我们将不得不弄清楚为什么GCC没有包括它应该生成的适当功能。
丹·乌迪(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