1. 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. 注意事项
-
全局性与不可控性 :
link_directories()
修改的是"目录"搜索路径,对之后的所有 target 都会生效,很可能导致不必要的污染或冲突。 -
不会指定库名 :
它只是告诉编译器去哪里找库,并不指定链接哪个库。实际链接要用:
cmaketarget_link_libraries(my_target libname)
注意不要把路径放在
target_link_libraries()
里(那是另一种方法)。 -
顺序很重要 :
先调用
link_directories()
,再调用target_link_libraries()
,否则不会生效。 -
跨平台差异:
- Windows 一般库是
.lib
/.dll
(dll 不直接链接,还是使用.lib
导入库)。 - macOS 是
.dylib
/.a
- Linux 是
.so
/.a
- Windows 一般库是
-
CMake 现代用法不推荐 :
官方建议使用 基于 target 的函数 (见下一节)代替
link_directories()
。
6. 现代 CMake 推荐替代方案
不使用 link_directories()
,直接为 target 指定库的完整路径或使用 target_link_directories()
(CMake 3.13+):
用 target_link_directories()
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()
以保持兼容。