链接cmath与AMD数学库遇符号冲突:AMD库覆盖cmath函数
解决AMD数学库覆盖cmath函数的问题
在C++项目中同时链接cmath与AMD数学库时,出现AMD库替换cmath所有函数的问题,即使调整库的链接顺序也无法解决,已通过GDB调试确认该问题。
测试代码
#include "amdlibm.h" #include "math.h" namespace amdfunc { void sqrttest() { printf("Calling amd func\n"); double val = 22.34; double val1; double val2; for (int i = 0; i < 5000000000; i++) { val1 = amd_sqrt(val); } } } namespace normalfunc { void sqrttest() { printf("Calling cmath func\n"); double val = 22.34; double val1; double val2; for (int i = 0; i < 5000000000; i++) { val1 = sqrt(val); } } } int main() { normalfunc::sqrttest(); amdfunc::sqrttest(); }
原编译命令
g++ test.cpp -g -o testinglib -L/usr/lib/x86_64-linux-gnu -L/usr/lib -I/usr/include -I/home/test/include -Wl,-rpath,/home/test/lib /home/test/lib/libalm.so -lm
解决方法
- 直接调用AMD库的前缀函数:AMD库本身提供了带
amd_前缀的函数(比如示例中的amd_sqrt),直接调用这类函数可以确保使用AMD库实现,不会和标准库函数冲突。 - 添加链接器选项限制符号覆盖:在编译时加入
-Wl,-Bsymbolic选项,让程序本地符号优先于库中的全局符号,避免AMD库的符号覆盖标准库:
也可以用g++ test.cpp -g -o testinglib -L/usr/lib/x86_64-linux-gnu -L/usr/lib -I/usr/include -I/home/test/include -Wl,-rpath,/home/test/lib,-Bsymbolic /home/test/lib/libalm.so -lm-Wl,--wrap=函数名逐个指定需要保留的标准库函数,比如-Wl,--wrap=sqrt,不过这种方式适合只需要少量函数不被覆盖的场景。 - 调整头文件包含顺序:先包含标准头文件
math.h,再包含AMD库的amdlibm.h,避免AMD头文件中的宏定义替换标准函数名。 - 检查AMD库编译配置:查看AMD AOCL libm的文档,确认是否有编译选项可以关闭全局符号替换,比如改用静态库,或者编译时指定不覆盖标准符号。
问题原因
AMD的AOCL libm为了性能优化,默认会导出和cmath同名的符号。动态链接器在解析符号时,会优先找到AMD库中的符号,而动态符号的解析是全局范围的,所以即使调整链接顺序,也会出现标准库函数被覆盖的情况。
内容的提问来源于stack exchange,提问作者Sai Krishna Sirimisetty
相关产品推荐
相关产品推荐

