使用Artix Linux发行版ArrayFire二进制包编译示例遇链接错误
使用Artix Linux(无Systemd的Arch衍生版)提供的ArrayFire二进制包编译示例时出现链接错误,具体环境与操作如下:
库安装路径
> ls /usr/lib/libaf* /usr/lib/libaf.debug /usr/lib/libaf.so.3.9.0 /usr/lib/libafcpu.so.3 /usr/lib/libafcuda.so /usr/lib/libafopencl.debug /usr/lib/libafopencl.so.3.9.0 /usr/lib/libaf.so /usr/lib/libafcpu.debug /usr/lib/libafcpu.so.3.9.0 /usr/lib/libafcuda.so.3 /usr/lib/libafopencl.so /usr/lib/libaf.so.3 /usr/lib/libafcpu.so /usr/lib/libafcuda.debug /usr/lib/libafcuda.so.3.9.0 /usr/lib/libafopencl.so.3
构建步骤
采用源外构建结构:
~/examples ~/examples_build
执行CMake配置:
examples_build> cmake -DArrayFire_DIR=/usr/lib/ ../examples/ -- The CXX compiler identification is GNU 13.2.1 -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /usr/bin/c++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Configuring done (0.9s) -- Generating done (0.4s) -- Build files have been written to: /home/pietrom/Documents/arrayfire_examples/examples_build
链接错误信息
执行make时出现大量未定义引用错误:
examples_build> make [ 0%] Building CXX object benchmarks/CMakeFiles/blas_cpu.dir/blas.cpp.o [ 0%] Linking CXX executable blas_cpu /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `fmt::v8::detail::basic_data<void>::signs' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `fmt::v8::detail::basic_data<void>::hex_digits' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `fmt::v8::format_error::~format_error()' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `vtable for fmt::v8::format_error' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `int fmt::v8::detail::snprintf_float<long double>(long double, int, fmt::v8::detail::float_specs, fmt::v8::detail::buffer<char>&)' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `fmt::v8::detail::assert_fail(char const*, int, char const*)' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `fmt::v8::detail::dragonbox::decimal_fp<double> fmt::v8::detail::dragonbox::to_decimal<double>(double)' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `int fmt::v8::detail::format_float<double>(double, int, fmt::v8::detail::float_specs, fmt::v8::detail::buffer<char>&)' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `fmt::v8::detail::error_handler::on_error(char const*)' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `int fmt::v8::detail::format_float<long double>(long double, int, fmt::v8::detail::float_specs, fmt::v8::detail::buffer<char>&)' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `int fmt::v8::detail::snprintf_float<double>(double, int, fmt::v8::detail::float_specs, fmt::v8::detail::buffer<char>&)' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `fmt::v8::detail::basic_data<void>::left_padding_shifts' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `typeinfo for fmt::v8::format_error' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `fmt::v8::vformat[abi:cxx11](fmt::v8::basic_string_view<char>, fmt::v8::basic_format_args<fmt::v8::basic_format_context<fmt::v8::appender, char> >)' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `fmt::v8::detail::basic_data<void>::right_padding_shifts' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `spdlog::details::log_msg::log_msg(spdlog::source_loc, fmt::v8::basic_string_view<char>, spdlog::level::level_enum, fmt::v8::basic_string_view<char>)' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `char fmt::v8::detail::decimal_point_impl<char>(fmt::v8::detail::locale_ref)' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `fmt::v8::detail::thousands_sep_result<char> fmt::v8::detail::thousands_sep_impl<char>(fmt::v8::detail::locale_ref)' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `fmt::v8::detail::dragonbox::decimal_fp<float> fmt::v8::detail::dragonbox::to_decimal<float>(float)' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `fmt::v8::detail::basic_data<void>::prefixes' /usr/bin/ld: /usr/lib/libafcpu.so.3.9.0: undefined reference to `fmt::v8::detail::basic_data<void>::digits' collect2: error: ld returned 1 exit status make[2]: *** [benchmarks/CMakeFiles/blas_cpu.dir/build.make:98: benchmarks/blas_cpu] Error 1 make[1]: *** [CMakeFiles/Makefile2:576: benchmarks/CMakeFiles/blas_cpu.dir/all] Error 2 make: *** [Makefile:91: all] Error 2
这些错误大概率与发行版包的构建缺陷有关,也可能是配置或版本兼容问题,具体如下:
发行版打包缺陷:Artix提供的ArrayFire包编译时依赖
fmt(v8版本)和spdlog库,但打包时未正确声明这些依赖,或者CMake配置文件缺失了链接这些库的规则,导致编译示例时无法自动链接到依赖库。CMake配置路径错误:ArrayFire的CMake配置文件通常不在
/usr/lib/,而是在/usr/lib/cmake/ArrayFire/目录下。你指定的-DArrayFire_DIR=/usr/lib/可能没有加载到完整的依赖配置,导致CMake不知道需要链接fmt和spdlog。库版本不兼容:系统中安装的
fmt库版本不是v8,或者spdlog版本与ArrayFire编译时使用的版本不匹配,导致符号不兼容。比如Artix仓库的fmt库已更新到更高版本,而ArrayFire是基于旧版v8编译的,链接时就会找不到对应符号。
修正CMake配置路径:尝试指定正确的ArrayFire CMake配置目录,执行:
cmake -DArrayFire_DIR=/usr/lib/cmake/ArrayFire/ ../examples/然后重新执行
make。手动补充依赖链接:临时修改示例的CMakeLists.txt,在目标链接库中添加fmt和spdlog,比如针对
blas_cpu目标添加:target_link_libraries(blas_cpu fmt spdlog)验证是否能正常链接。
检查库版本匹配:执行
pacman -Q fmt查看当前fmt版本,如果不是v8,可尝试安装Artix仓库中的fmt8包(若存在),或考虑从源码编译ArrayFire,使用系统当前的fmt和spdlog版本。检查包依赖:执行
pacman -Qi arrayfire查看ArrayFire包的声明依赖,若未包含fmt和spdlog,说明打包时遗漏了依赖,可向Artix包维护者反馈。
内容的提问来源于stack exchange,提问作者Pietro

