CMake构建静态库报错:No rule to make target 求助
静态库构建链接错误排查与解决
错误信息
make[2]: *** No rule to make target '/libs/libgsl.a', needed by 'mylib'. Stop. make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/mylib.dir/all] Error 2 make: *** [Makefile:84: all] Error 2
我的CMakeLists.txt内容
cmake_minimum_required(VERSION 2.8) project(mylib) # find header & source file(GLOB_RECURSE SOURCE_C "src/*.c") file(GLOB_RECURSE SOURCE_CPP "src/*.cpp") file(GLOB_RECURSE HEADER "include/*.h") add_library(mylib ${SOURCE_C} ${SOURCE_CPP} ${HEADER} ) # includes include_directories( /include ) link_directories( /libs ) source_group("Header include" FILES ${HEADER}) source_group("Source src" FILES ${SOURCE_C}) source_group("Source src" FILES ${SOURCE_CPP}) # opencv package find_package( OpenCV REQUIRED) target_link_libraries(mylib PUBLIC opencv_highgui) # link libraries target_link_libraries(${PROJECT_NAME} PUBLIC m) target_link_libraries(${PROJECT_NAME} PUBLIC /libs/libgsl.a) target_link_libraries(${PROJECT_NAME} PUBLIC /libs/libz.a) target_link_libraries(${PROJECT_NAME} PUBLIC /libs/libpng16.a)
项目目录结构
mylib ├── build ├── CMakeLists.txt ├── include │ ├── 自定义头文件 │ └── gsl │ └── gsl_sort.h ├── libs │ ├── libgsl.a │ ├── libz.a │ └── libpng16.a └── src ├── 自定义.c和.cpp文件
头文件引入方式
#include "../include/gsl/gsl_sort.h"
问题排查与解决
1. 核心问题:路径错误
你写的/libs/libgsl.a是系统根目录的绝对路径,但你的libs目录是项目根目录(和CMakeLists.txt同级),并非系统根目录,导致CMake找不到库文件。有两种修正方式:
方式一:用CMake内置变量指定正确路径
利用${CMAKE_CURRENT_SOURCE_DIR}(指向当前CMakeLists.txt所在目录)来拼接库的路径,保证路径绝对正确:
target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/libs/libgsl.a) target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/libs/libz.a) target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/libs/libpng16.a)
方式二:修正link_directories后简化链接写法
先把link_directories的路径改对,之后链接时只需要写库名即可:
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/libs) # ... target_link_libraries(${PROJECT_NAME} PUBLIC gsl z png16)
CMake会自动在link_directories指定的路径下查找libgsl.a这类库文件。
2. 头文件引入优化
当前用../include的相对路径不够灵活,建议修改include_directories指向项目的include目录:
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
之后代码里可以直接写:
#include "gsl/gsl_sort.h"
不管源文件在哪个子目录,都能正确找到头文件。
3. 额外优化建议
- 尽量避免
file(GLOB_RECURSE),新增/删除文件时CMake不会自动检测到,建议手动列出源文件,或使用aux_source_directory。 - CMake 2.8版本过于老旧,建议升级到3.x版本,支持
target_include_directories等更现代的目标级配置方式,替代全局的include_directories。
内容的提问来源于stack exchange,提问作者Flippy
相关产品推荐
相关产品推荐

