具体错误:
[cc] Starting link [cc] /usr/bin/ld: libtest1.so: no symbol version section for versioned symbol `memcpy@GLIBC_2.0' [cc] /usr/bin/ld: 最后的链结失败: nonrepresentable section on output [cc] collect2: error: ld returned 1 exit status 关于此类错误,吾有不少博文。这意思就是没有这个函数。具体来说: tsit@tsit-loong:~/jogamp232-loongarch64/gluegen$ strings /usr/lib/loongarch64-linux-gnu/libc.so.6 | grep GLIBCGLIBC_2.27 GLIBC_2.28 GLIBC_PRIVATE GNU C Library (Debian GLIBC 2.28-10.lnd.26) stable release version 2.28. sit@tsit-loong:~/jogamp232-loongarch64/gluegen$ objdump -T /usr/lib/loongarch64-linux-gnu/libc.so.6 | fgrep memcpy 000000000008d328 w DF .text 0000000000000008 GLIBC_2.27 wmemcpy 00000000000eeb78 g DF .text 000000000000001c GLIBC_2.27 __wmemcpy_chk 0000000000086588 g DF .text 00000000000003f4 GLIBC_2.27 memcpy 00000000000ed228 g DF .text 0000000000000014 GLIBC_2.27 __memcpy_chk
也就是链接时要求使用2.0,实际上是2.27。
解决办法一
加链接库,下文中三个逐个加试试:
g++ -o main main.c -lm -ldl -lrt
有时确实可以解决问题。
解决办法二
g++ -Wl,--no-as-needed -o main main.c -lm -ldl -lrt
终极解决办法
回到问题本身。我们平常调用函数memcpy,不管怎么编译,并不会出现这个问题。出问题的都是下载的源码编译时。这就有意思了,为什么会出现这个错误?一定是代码写法不同导致的。
基于这个思路,我们来搜索一下GLIBC,果然发现了一个文件glibc-compat-symbols.h,内容是:
#ifndef __GLIBC_COMPAT_SYMBOLS_H__ #define __GLIBC_COMPAT_SYMBOLS_H__ 1 /** * * Note: Patching a specific glibc symbol version is only required if *not* statically linking glibc, * which should be preferred. * * Note: JogAmp's minimum GLIBC is 2.4 due to '__stack_chk_fail' (stack overflow checking) * * GLIBC 2.4 - March 2006 - Standard for LSB 4.0, Used in SLES 10 * * We could add compile/link option '-fno-stack-protector', however stack protection seems reasonable * and a pre 2006 distribution a bit too 'far fetched' for our multimedia bindings anyway. * * Check build-in macro definitions via 'gcc -dM -E - < /dev/null' */ #if defined(__linux__) /* Actually we like to test whether we link against GLIBC .. */ #if defined(__GNUC__) #if defined(__aarch64__) #define GLIBC_COMPAT_SYMBOL(FFF) __asm__(".symver " #FFF "," #FFF "@GLIBC_2.4"); #elif defined(__arm__) #define GLIBC_COMPAT_SYMBOL(FFF) __asm__(".symver " #FFF "," #FFF "@GLIBC_2.4"); #elif defined(__amd64__) #define GLIBC_COMPAT_SYMBOL(FFF) __asm__(".symver " #FFF "," #FFF "@GLIBC_2.2.5"); #else #define GLIBC_COMPAT_SYMBOL(FFF) __asm__(".symver " #FFF "," #FFF "@GLIBC_2.0"); #endif /*__amd64__*/ #elif defined(__clang__) #if defined(__aarch64__) #define GLIBC_COMPAT_SYMBOL(FFF) asm(".symver " #FFF "," #FFF "@GLIBC_2.4"); #elif defined(__arm__) #define GLIBC_COMPAT_SYMBOL(FFF) asm(".symver " #FFF "," #FFF "@GLIBC_2.4"); #elif defined(__amd64__) #define GLIBC_COMPAT_SYMBOL(FFF) asm(".symver " #FFF "," #FFF "@GLIBC_2.2.5"); #else #define GLIBC_COMPAT_SYMBOL(FFF) asm(".symver " #FFF "," #FFF "@GLIBC_2.0"); #endif /*__amd64__*/ #else #warning GLIBC_COMPAT_SYMBOL not supported with current compiler on GNU/Linux #define GLIBC_COMPAT_SYMBOL(FFF) #endif #else #warning GLIBC_COMPAT_SYMBOL not supported with target OS #define GLIBC_COMPAT_SYMBOL(FFF) #endif GLIBC_COMPAT_SYMBOL(memcpy) #endif /*__GLIBC_COMPAT_SYMBOLS_H__*/
其中果然有一个字串叫GLIBC_2.0。这不就好办了嘛。
办法一:把2.0改成2.27(或相应的字串)。
办法二:干脆改为""。这样到哪里编译都皆大欢喜。