Ruby C/C++扩展用OpenMP编译运行时遇GOMP_parallel未定义符号错误
Ruby C/C++扩展OpenMP并行循环链接错误解决
问题描述
我在Ruby C/C++扩展中使用OpenMP实现简单并行for循环,代码如下:
#pragma omp parallel for for (int j = 0; j < 100; j++) { }
对应的初始extconf.rb配置:
require 'mkmf' extension_name = 'stridx' $CFLAGS << " -Wall -fopenmp " $CXXFLAGS << " -Wall -O1 -g -fopenmp" have_library( 'stdc++', 'gomp' ); dir_config(extension_name) create_makefile(extension_name)
扩展编译正常,但运行调用脚本时出现错误:
ruby: symbol lookup error: ... ext/stridx/stridx.so: undefined symbol: GOMP_parallel
使用LD_PRELOAD临时加载libgomp.so可临时解决:
LD_PRELOAD=/usr/lib/gcc/x86_64-linux-gnu/12/libgomp.so ./test.rb
但该方法属于临时 workaround,会增加gem分发复杂度,需要正规解决方式。
解决方法
原extconf.rb中have_library的写法存在错误,正确写法需分开检查并链接两个库:
require 'mkmf' extension_name = 'stridx' $CFLAGS << " -Wall -fopenmp " $CXXFLAGS << " -Wall -O1 -g -fopenmp" have_library('stdc++') have_library('gomp') dir_config(extension_name) create_makefile(extension_name)
原理说明
- 错误的
have_library('stdc++', 'gomp')是尝试在stdc++库中查找gomp相关符号,逻辑完全错误。 - 分开调用
have_library('stdc++')和have_library('gomp')后,mkmf会分别检查并链接这两个库,确保扩展在运行时能自动找到GOMP_parallel等OpenMP相关符号,无需依赖LD_PRELOAD环境变量。
内容的提问来源于stack exchange,提问作者Sami Sieranoja
相关产品推荐
相关产品推荐

