CMake link_directories()详细介绍与使用指南

link_directories() 是 CMake 中的一个目录搜索路径设置命令 ,它告诉 CMake 在链接阶段(link stage)去哪些目录查找库文件(.lib.a.so.dylib等)。

它会在 当前 CMake 目录作用域 下生效(从调用它的 CMakeLists.txt 开始,影响该作用域以及子目录)。


2. 语法

cmake 复制代码
link_directories(directory1 [directory2 ...]
                 [BEFORE])
  • directory1 directory2 ...

    这是你存放静态库或动态库文件的文件夹路径 ,通常是绝对路径或相对路径(相对于当前 CMakeLists.txt 所在目录)。

  • BEFORE

    把新路径放到当前搜索目录列表的最前面(优先搜索)。缺省是放到后面。

📌 注意

CMake 的 link_directories() 会影响之后所有的 target_link_libraries() 去查找库文件的路径。


3. 基本用法示例

假设目录结构如下:

复制代码
project_root/
  CMakeLists.txt
  src/
    CMakeLists.txt
    main.cpp
  lib/
    mylib.lib   (Windows)
    libmylib.a  (Linux/macOS)

根目录的 CMakeLists.txt

cmake 复制代码
cmake_minimum_required(VERSION 3.10)
project(LinkDirExample)

# 添加子目录
add_subdirectory(src)

src/CMakeLists.txt

cmake 复制代码
add_executable(demo main.cpp)

# 添加库目录
link_directories(${CMAKE_SOURCE_DIR}/lib)

# 链接库
target_link_libraries(demo mylib)  # CMake 会在 lib/ 下查找 libmylib.a 或 mylib.lib

4. BEFORE 用法

如果你想覆盖系统库,或者优先用你自己编译的版本:

cmake 复制代码
link_directories(BEFORE ${CMAKE_SOURCE_DIR}/custom_lib)

这样,custom_lib 会在 CMake 的链接库搜索路径中排到最前面。


5. 注意事项

  1. 全局性与不可控性
    link_directories() 修改的是"目录"搜索路径,对之后的所有 target 都会生效,很可能导致不必要的污染或冲突。

  2. 不会指定库名

    它只是告诉编译器去哪里找库,并不指定链接哪个库。实际链接要用:

    cmake 复制代码
    target_link_libraries(my_target libname)

    注意不要把路径放在 target_link_libraries() 里(那是另一种方法)。

  3. 顺序很重要

    先调用 link_directories(),再调用 target_link_libraries(),否则不会生效。

  4. 跨平台差异

    • Windows 一般库是 .lib / .dll(dll 不直接链接,还是使用 .lib 导入库)。
    • macOS 是 .dylib / .a
    • Linux 是 .so / .a
  5. CMake 现代用法不推荐

    官方建议使用 基于 target 的函数 (见下一节)代替 link_directories()


6. 现代 CMake 推荐替代方案

不使用 link_directories(),直接为 target 指定库的完整路径或使用 target_link_directories()(CMake 3.13+):

cmake 复制代码
add_executable(demo main.cpp)

target_link_directories(demo PRIVATE ${CMAKE_SOURCE_DIR}/lib)

target_link_libraries(demo PRIVATE mylib)

这样不会影响其它 target,作用域更清晰。

直接写库的完整路径

cmake 复制代码
target_link_libraries(demo PRIVATE ${CMAKE_SOURCE_DIR}/lib/libmylib.a)

配合 find_library()

cmake 复制代码
find_library(MYLIB NAMES mylib PATHS ${CMAKE_SOURCE_DIR}/lib)

if(MYLIB)
    target_link_libraries(demo PRIVATE ${MYLIB})
endif()

这样跨平台和路径处理都更安全。


7. 完整示例

cmake 复制代码
cmake_minimum_required(VERSION 3.10)
project(LinkDirExample)

add_executable(demo main.cpp)

# 不推荐(全局)
# link_directories(${CMAKE_SOURCE_DIR}/lib)

# 推荐(局部作用域)
target_link_directories(demo PRIVATE ${CMAKE_SOURCE_DIR}/lib)

# 链接库,名称不带前缀/扩展名
target_link_libraries(demo PRIVATE mylib)

8. 总结

方法 优点 缺点 / 风险
link_directories() 语法简单,全局生效 作用域太大、易污染、顺序依赖
target_link_directories() 局部作用域、安全清晰 需要 CMake >= 3.13
find_library() + 完整路径 跨平台、文件检查、防止冲突 写法稍长
直接完整路径 不依赖搜索路径 不够灵活

建议 :在新项目中用 target_link_directories()find_library() + target_link_libraries()

仅在处理老项目或第三方代码时才用 link_directories() 以保持兼容。