编译时出现“undefined reference to `__sync_val_compare_and_swap_4'”错误,使用gcc 4.1.1和4.2.0编译Sparc v8目标。

3

我使用Cygwin下的crosstool脚本构建了以下针对Sparc架构的编译器:gcc-4.1.1和4.2.0 20061024(预发布版)。

$ ./sparc-unknown-linux-gnu-gcc -v
Using built-in specs.
Target: sparc-unknown-linux-gnu
Configured with: /crosstool-0.43/build/sparc-unknown-linux-gnu/gcc-4.1.1-glibc-2.3.6/gcc-4.1.1/configure --target=sparc-unknown-linux-gnu --host=i686-host_pc-cygwin --prefix=/opt/crosstool/gcc-4.1.1-glibc-2.3.6/sparc-unknown-linux-gnu --with-headers=/opt/crosstool/gcc-4.1.1-glibc-2.3.6/sparc-unknown-linux-gnu/sparc-unknown-linux-gnu/include --with-local-prefix=/opt/crosstool/gcc-4.1.1-glibc-2.3.6/sparc-unknown-linux-gnu/sparc-unknown-linux-gnu --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atexit --enable-languages=c,c++ --enable-shared --enable-c99 --enable-long-long
Thread model: posix
gcc version 4.1.1

并且

$ ./sparc-unknown-linux-gnu-gcc -v
Using built-in specs.
Target: sparc-unknown-linux-gnu
Configured with: /crosstool-0.43/build/sparc-unknown-linux-gnu/gcc-4.2-20061024-                           glibc-2.3.6/gcc-4.2-20061024/configure --target=sparc-unknown-linux-gnu --host=i                           686-host_pc-cygwin --prefix=/opt/crosstool/gcc-4.2-20061024-glibc-2.3.6/sparc-un                           known-linux-gnu --with-headers=/opt/crosstool/gcc-4.2-20061024-glibc-2.3.6/sparc                           -unknown-linux-gnu/sparc-unknown-linux-gnu/include --with-local-prefix=/opt/cros                           stool/gcc-4.2-20061024-glibc-2.3.6/sparc-unknown-linux-gnu/sparc-unknown-linux-g                           nu --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atex                           it --enable-languages=c,c++ --enable-shared --enable-c99 --enable-long-long
Thread model: posix
gcc version 4.2.0 20061024 (prerelease)

我需要在我的程序中使用与原子内建函数相关的__sync_val_compare_and_swap函数,该函数支持gcc 4.1.*版本。为此,我尝试编译简单的C代码:

long cmpxchg( long* value, long comp_val, long new_val )
{
    return __sync_val_compare_and_swap( value, comp_val, new_val );
}

int main()
{
    return 0;
}

但我遇到了以下错误:(在两个编译器上都出现):
$ ./sparc-unknown-linux-gnu-gcc test_cas.c -o test_cas
/tmp/ccREXHsP.o: In function `cmpxchg':
test_cas.c:(.text+0x24): undefined reference to `__sync_val_compare_and_swap_4'
collect2: ld returned 1 exit status

什么问题?也许是我错误地构建编译器?也许Sparc架构(SPARC v8)不支持此功能?我尝试编译我的另一个程序 - 一切都很好(已编译并执行)。
5个回答

6
这里所述,在某些目标平台上,__sync_val_compare_and_swap将导致函数调用(在直接代码生成不可用或尚未实现的情况下)。 在您的情况下正在发生这种情况。 假设此本身对您没有问题,则需要链接定义了__sync_val_compare_and_swap_4等的库,我猜测是libgcc_s(因此在链接行中添加-lgcc_s)。

使用 -lgcc_s 参数编译 test_cas.c 文件并执行 $ ./sparc-unknown-linux-gnu-gcc test_cas.c -lgcc_s -o test_cas 并不能解决问题。但是我尝试查找 "__sync_val_compare_and_swap_4" 文本,结果发现以下文件:sparc-unknown-linux-gnu\bits\stdc++.h.gch\O0g.gch、sparc-unknown-linux-gnu\bits\stdc++.h.gch\O2g.gch、gcc\builtins.def、cc1.exe、cc1plus.exe 等。 - G-71
你必须在输出之后放置库链接:./sparc-unknown-linux-gnu-gcc test_cas.c -o test_cas -lgcc_s - Coren
在交叉目标的 /usr/lib 中运行 nmobjdump 并搜索该函数,这个方案怎么样? - John Zwinck
我尝试查找并获得以下结果:$ nm -A *.so | grep __sync_val_compare_and_swap_4 nm: libc.so:文件格式无法识别 nm: libpthread.so:文件格式无法识别 - G-71
2
这些文件可能是链接器脚本或其他东西,而不是实际的共享库。libgcc_s.so 应该随 gcc 一起提供,并且不太可能在 /lib 或 /usr/lib 中(而是在 /usr/lib/gcc/[target]/[version]/ 或类似位置)。请确保 libgcc_s.so 存在;有时发行版会错过创建到实际库(可能是 libgcc_s.so.1)的符号链接。当然,除了 .so 之外还要检查 .a;它可能仅作为静态库可用。 - bdow

2

在编译基于V8引擎的NodeJS时,我遇到了类似的问题。通俗来说,你的GCC没有这些内置函数,可能是因为你使用的是旧版本,或者这些函数在你的平台上尚未实现,因此"-lgcc_s"甚至无法帮助解决问题。

经过几个小时的谷歌,我找到了这篇博客页面(http://vincesoft.blogspot.fr/2012/04/how-to-solve-undefined-reference-to.html),它相当清楚地解释了问题的原因并提供了一个解决方案:

从GCC代码中获取你的平台上这些函数的源代码,将代码构建成库,安装它,然后将你的应用程序与这个库链接。

虽然我没有按照博客中描述的确切步骤进行操作,但思路是一样的,而且它确实管用。

希望对你有所帮助。


你能否分享一下你是如何让NodeJS工作的?我目前也遇到了完全相同的问题。 - pms1969

2

最终我在Ubuntu 10.04上采纳了你的建议并解决了这个问题,非常感谢! - ransh

0
在Android上,我能够通过以下标志解决问题 LOCAL_CFLAGS += -O3 -fopenmp LOCAL_LDFLAGS += -O3 -fopenmp -lgcc -latomic -lgomp

0
对我来说,上述的失败意味着“你正在使用gcc/mingw交叉编译器,所以-march=native不起作用”(我猜测)。请参见https://dev59.com/G2035IYBdhLWcg3wW-ta#24213278(基本上,您可以通过手动指定-march设置来解决它)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接