贡献者: addis
Illegal Instruction
错误,也就是 SIGILL
信号。
-march=native
,也就是针对当前 cpu 的指令集编译,这里面就可能包含一些其他 cpu 没有的拓展。所以为了保证兼容性,应该用 -march=x86-64
。详见 gcc 文档。
-march=native
具体用的是什么设置,用 gcc -march=native -Q --help=target | grep march
即可。
参考这里的回答。
静态链接的程序一般没什么问题(除了 GLIBC)。但对于动态链接的程序,可以把所有非基础的 so 依赖库打包到一个文件夹里面并设置 rpath/runpath
或者 LD_LIBRARY_PATH
。但是这里面不能包括一些基础的系统库例如
linux-vdso.so
直接由内核提供,不存在于文件系统,见这里 和 vDSO - Wikipedia。
glibc
不兼容是链接时和运行时都很常见的问题,详见下文。
libm.so
是 GNU C library 的一部分,提供数学函数。
libgcc_s.so
是 GCC runtime library 例如在 32bit 系统中提供 64bit 整数运算。
ld-linux-x86-64.so
是 dynamic linker
libgomp.so
跟 openmp 有关。
libstdc++.so
是 C++ 库
libgfortran.so
是 fortran 库
libquadmath.so
是和 G++ 一起安装的四精度计算库。
最兼容的方法大概使用 chroot 或者 docker,可以把除了 vdso
以外的所有动态库都放到 fake root 文件夹里面。
libc.so/.a
(GLIBC
)是操作系统的核心库,如果不兼容比较难办。Ubuntu 只有升级版本才能升级 GLIBC 版本,一般是向下兼容的,所以只要保证足够新即可。GLIBC 是 GNU C library,提供 C 语言支持,包括 system call 的 wrapper。可以用 ldd --version
或者 ldconfig -v | grep libc
查看版本。
warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
。其中 dlopen
是 C 语言中用于动态加载动态链接库的函数。有可能你的代码中没有直接调用 dlopen
,但可能一些库的 .a 文件会使用,例如 sqlite3.a
。而且也并不是说运行时一定需要完全相同版本的 glibc 才可以兼容,由于 glibc 向后兼容一般只需要运行时 glibc 版本高于编译时即可。
其他库.a
文件不直接静态链接 glibc,而是等到你的程序最终链接时再一次性动态链接到 glibc。所以可能需要一些 hacking 重新编译 其他库.a
。