You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CMake C项目中无法链接预构建LAPACKE库的问题

CMake管理的C项目链接LAPACKE时出现链接器错误

项目背景

我要通过CI构建一个CMake管理的C项目,项目会通过CBLAS和LAPACKE大量调用Fortran实现的BLAS和LAPACK。采用的方式是:在单独的CI任务中构建LAPACK包,生成的静态库(Linux下的.a文件)和头文件放在项目的<PROJECT_ROOT>/deps/lapack-3.12.0/build/目录下,包含lib和include子目录;另一个CI任务负责编译C项目并链接这些预构建产物。之前用add_subdirectory()链接纯Fortran可执行文件时一切正常,但对CBLAS和LAPACKE不太熟悉。

当前CMakeLists.txt配置

cmake_minimum_required(VERSION 3.20)
project(collision-detection
    C
    Fortran
)

#include_directories(${CMAKE_SOURCE_DIR}/deps/lapack-3.12.0/build/include)
#link_directories(${CMAKE_SOURCE_DIR}/deps/lapack-3.12.0/build/lib)
message("${CMAKE_SOURCE_DIR}/deps/lapack-3.12.0/build/lib")

add_executable(helloworld_lapacke src/helloworld_lapacke.c)
target_include_directories(helloworld_lapacke PRIVATE ${CMAKE_SOURCE_DIR}/deps/lapack-3.12.0/build/include/)
target_link_directories(helloworld_lapacke PRIVATE ${CMAKE_SOURCE_DIR}/deps/lapack-3.12.0/build/lib/)
target_link_libraries(helloworld_lapacke PRIVATE
    blas cblas
    lapack lapacke
)

链接器错误信息

myproject/deps/lapack-3.12.0/build/lib/liblapacke.a(lapacke_dgels_work.c.o): in function `LAPACKE_dgels_work':
lapacke_dgels_work.c:(.text+0x1c3): undefined reference to `dgels_'
/usr/bin/ld: lapacke_dgels_work.c:(.text+0x2ee): undefined reference to `dgels_'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/helloworld_lapacke.dir/build.make:97: helloworld_lapacke] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/helloworld_lapacke.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

测试用C代码

#include <stdio.h>
#include <lapacke.h>

int main(int argc, const char *argv[])
{
   double a[5][3] = {1, 1, 1, 2, 3, 4, 3, 5, 2, 4, 2, 5, 5, 4, 3};
   double b[5][2] = {-10, -3, 12, 14, 14, 12, 16, 16, 18, 16};
   lapack_int info, m, n, lda, ldb, nrhs;
   int i, j;

   m = 5;
   n = 3;
   nrhs = 2;
   lda = 3;
   ldb = 2;

   info = LAPACKE_dgels(LAPACK_ROW_MAJOR, 'N', m, n, nrhs, *a, lda, *b, ldb);

   for (i = 0; i < n; i++)
   {
      for (j = 0; j < nrhs; j++)
      {
         printf("%lf ", b[i][j]);
      }
      printf("\n");
   }
   return (info);
}

解决方案

1. 调整链接库顺序

链接器按顺序处理库,依赖其他库的库要放在被依赖库的前面。LAPACKE依赖LAPACK,LAPACK又依赖BLAS,调整后的链接顺序如下:

target_link_libraries(helloworld_lapacke PRIVATE
    lapacke lapack
    cblas blas
)

2. 显式链接Fortran运行时库

由于LAPACK/BLAS是Fortran实现,C项目链接时需确保Fortran运行时库被包含。可添加以下配置:

find_package(Fortran REQUIRED)
target_link_libraries(helloworld_lapacke PRIVATE ${Fortran_LIBRARIES})

3. 验证预构建LAPACK库的完整性

检查静态库中是否包含dgels_符号,确认CI构建的LAPACK库完整:

nm myproject/deps/lapack-3.12.0/build/lib/liblapack.a | grep dgels_

若没有输出,说明LAPACK构建不完整,需检查CI构建脚本,确保启用所有必要组件。

4. 使用更可靠的库查找方式(可选)

替代直接指定target_link_directories,用find_library定位库,让CMake更准确处理依赖:

find_library(LAPACKE_LIB lapacke PATHS ${CMAKE_SOURCE_DIR}/deps/lapack-3.12.0/build/lib NO_DEFAULT_PATH)
find_library(LAPACK_LIB lapack PATHS ${CMAKE_SOURCE_DIR}/deps/lapack-3.12.0/build/lib NO_DEFAULT_PATH)
find_library(CBLAS_LIB cblas PATHS ${CMAKE_SOURCE_DIR}/deps/lapack-3.12.0/build/lib NO_DEFAULT_PATH)
find_library(BLAS_LIB blas PATHS ${CMAKE_SOURCE_DIR}/deps/lapack-3.12.0/build/lib NO_DEFAULT_PATH)

target_link_libraries(helloworld_lapacke PRIVATE
    ${LAPACKE_LIB} ${LAPACK_LIB}
    ${CBLAS_LIB} ${BLAS_LIB}
    ${Fortran_LIBRARIES}
)

内容的提问来源于stack exchange,提问作者rbaleksandar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 11:43:20