QtCreator中CMake项目链接GSL出现函数未定义引用问题
GSL链接错误问题排查与解决
问题场景
在QtCreator中用CMake构建大型C++项目,引入GNU Scientific Library (GSL)函数时,CMake配置通过但构建报错:
...path.../utilities.hpp:27: error: undefined reference to `gsl_sf_coulomb_wave_FG_e'
最初通过源码编译安装GSL,shell环境下测试代码可正常运行,但QtCreator无法识别;安装libgsl-dev后QtCreator能识别GSL并支持补全,但构建仍出现上述链接错误。提取调用GSL的代码单独用g++ test -lgsl编译可正常运行。
项目的CMakeLists.txt内容如下:
project(numerics LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED YES) set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) set(INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/include/maths ${CMAKE_CURRENT_SOURCE_DIR}/include/maths/vectors_matrices ${CMAKE_CURRENT_SOURCE_DIR}/include/physics ${CMAKE_CURRENT_SOURCE_DIR}/include/physics/alpha-d_potentials ${CMAKE_CURRENT_SOURCE_DIR}/include/physics/NN_potentials ${CMAKE_CURRENT_SOURCE_DIR}/include/physics/four_vectors_tensors ${CMAKE_CURRENT_SOURCE_DIR}/tests ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_master_thesis ${CMAKE_CURRENT_SOURCE_DIR}/tests/av18 ) set (GSL_INCLUDE_DIR /home/alessandro/gsl/lib ) set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/src/maths ${CMAKE_CURRENT_SOURCE_DIR}/src/maths/vectors_matrices ${CMAKE_CURRENT_SOURCE_DIR}/src/physics ${CMAKE_CURRENT_SOURCE_DIR}/src/physics/four_vectors_tensors) set(HEADERS include/maths/Angle.hpp include/maths/Matrix.hpp include/maths/Complex.hpp include/physics/Physics_constants.hpp include/physics/Physics_utils.hpp include/maths/Row.hpp include/maths/Column.hpp include/maths/LU_decomposition.hpp include/maths/CG-3J-6J.hpp include/maths/SphericalBesselJ.hpp include/maths/Function.hpp include/maths/Laguerre.hpp include/physics/SphericalHarmonics.hpp include/physics/alpha-d_potentials/alpha-d_potential_Hammache.hpp include/physics/alpha-d_potentials/alpha-d_potential_Tursunov.hpp include/physics/alpha-d_potentials/alpha-d_potential_Mukhamedzhanov.hpp include/physics/alpha-d_potentials/alpha-d_potential_Dubovichenko.hpp include/maths/Numerov.hpp include/maths/DerivativeFixedStep.hpp include/maths/Factorial.hpp include/maths/utilities.hpp include/maths/Integration_Trapezoidal.hpp include/maths/find_zero_Newton.h include/maths/abs.hpp include/maths/norm.hpp include/physics/NN_potentials/av18.hpp include/maths/Variational_bound.hpp include/maths/Integration_B5.hpp include/maths/Phochammer.hpp include/physics/Potentials.hpp include/physics/PotentialData.hpp src/physics/PotentialData.cpp ) SET(SOURCES src/physics/NN_potentials/av18.cpp ) include_directories(${INCLUDE_DIR} ${SRC_DIR}) add_executable(Physics main.cpp ${SOURCES} ${HEADERS}) add_executable(tests ${SOURCES} tests/tests.cpp tests/zip.hpp tests/test_numerov.hpp tests/test_CG_3J_6J.hpp tests/test_spherical_bessel_j.hpp tests/test_Laguerre.hpp tests/test_ylm.h tests/test_master_thesis/test_numerov_lithium_Hammache.hpp tests/test_master_thesis/test_numerov_lithium_Tursunov.hpp tests/test_master_thesis/test_numerov_lithium_Mukhamedzhanov.hpp tests/test_master_thesis/test_numerov_lithium_Dubovichenko.hpp tests/test_derivative_fixed_step.hpp tests/av18/test_numerov_AV18.hpp tests/test_master_thesis/test_variational_lithium_Hammache.hpp tests/test_master_thesis/test_variational_lithium_Tursunov.hpp tests/test_master_thesis/test_variational_lithium_Mukhamedzhanov.hpp tests/test_master_thesis/test_variational_lithium_Dubovichenko.hpp tests/av18/test_variational_AV18.hpp ) find_package(GSL REQUIRED) find_package(LAPACK REQUIRED) target_compile_features(Physics PRIVATE cxx_std_17) target_include_directories(Physics PRIVATE ${INCLUDE_DIR} ${GSL_INCLUDE_DIR}) target_link_libraries(Physics GSL::gsl GSL::gslcblas ${lapackblas_libraries} ${LAPACKE_LIBRARIES} ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES}) install(TARGETS Physics LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) target_include_directories(tests PRIVATE ${INCLUDE_DIRS}) target_compile_options(tests PRIVATE -Wall) find_package(GTest REQUIRED) target_link_libraries(tests GTest::GTest pthread ${lapackblas_libraries} ${LAPACKE_LIBRARIES} ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES})
测试代码如下:
#include <cmath> #include "gsl/gsl_sf_coulomb.h" template<class T> struct CoulombSolutions { T F; T G; T Fp; T Gp; double l; double eta; CoulombSolutions( T F, T G, T Fp, T Gp, double l, double eta) : F(F),G(G), Fp(Fp), Gp(Gp), l(l), eta(eta) {} }; template<class T> CoulombSolutions<T> coulomb(T eta, int l, double x) { gsl_sf_result F, Fp, G, Gp; double l_F = (double) l; double k_l_G = 0, expF, expG; gsl_sf_coulomb_wave_FG_e(eta,x,l_F,k_l_G,&F,&Fp,&G,&Gp,&expF,&expG); return CoulombSolutions<T>(F.val,G.val,Fp.val,Gp.val,l_F,eta); } int main() { double eta = 2.15; int l = 0; double x = 5.; auto res = coulomb<double>(eta,l,x); std::cout << res.F << std::endl; }
问题原因
tests目标未链接GSL库:报错的utilities.hpp被tests目标引用,但CMake中仅给Physics目标添加了GSL链接依赖,tests目标的target_link_libraries里缺少GSL::gsl和GSL::gslcblas,导致链接阶段找不到GSL函数的实现。GSL_INCLUDE_DIR路径错误:你设置的GSL_INCLUDE_DIR是/home/alessandro/gsl/lib,这是库文件目录,而非头文件目录,正确路径应为/home/alessandro/gsl/include。不过安装libgsl-dev后系统能自动找到头文件,所以这个错误未导致编译报错,但属于无效配置。tests目标头文件目录拼写错误:target_include_directories(tests PRIVATE ${INCLUDE_DIRS})中的INCLUDE_DIRS是笔误,应该是INCLUDE_DIR,不过这只会影响头文件查找,和当前链接错误无关。
修复方案
- 给
tests目标添加GSL链接依赖,修改tests的target_link_libraries行:target_link_libraries(tests GTest::GTest pthread GSL::gsl GSL::gslcblas ${lapackblas_libraries} ${LAPACKE_LIBRARIES} ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES}) - 修正
GSL_INCLUDE_DIR为正确的头文件路径,或者直接删除这个变量,因为find_package(GSL REQUIRED)会自动设置GSL_INCLUDE_DIRS,无需手动指定:# 移除错误的GSL_INCLUDE_DIR设置,或者修改为正确路径 # set (GSL_INCLUDE_DIR /home/alessandro/gsl/include) - 修正
tests目标的头文件目录变量:target_include_directories(tests PRIVATE ${INCLUDE_DIR})
完成以上修改后,重新运行CMake配置并构建项目,链接错误即可解决。
内容的提问来源于stack exchange,提问作者Alessandro
相关产品推荐
相关产品推荐

