include_directories 、 link_directories 、link_libraries之间区别

在使用 CMake 构建项目时,管理路径和链接库是非常重要的。CMake 提供了多个命令来设置头文件路径、库文件路径及链接库。其中,include_directorieslink_directorieslink_libraries 是最常用的三个命令。它们的作用分别是:设置头文件搜索路径、设置库文件搜索路径以及指定需要链接的库文件。


1. include_directories

功能

include_directories 用于指定编译阶段头文件的搜索路径。

用法

include_directories(path1 path2 ...)

  • 作用阶段:编译阶段。
  • 作用对象:头文件(如 .h.hpp)。
  • 作用范围:默认全局,影响当前 CMakeLists.txt 文件中所有的目标。
影响

告诉编译器在查找 #include 的头文件时,除了默认路径,还可以从指定路径中查找。

示例

include_directories(${CMAKE_SOURCE_DIR}/include)

add_executable(my_target main.cpp)

在上述示例中,main.cpp 可以通过 #include 使用 ${CMAKE_SOURCE_DIR}/include 下的头文件。

现代替代方案

在现代 CMake 中,推荐使用目标作用域的 target_include_directories,以精确控制头文件路径的作用范围。

target_include_directories(my_target PUBLIC ${CMAKE_SOURCE_DIR}/include)


2. link_directories

功能

link_directories 用于指定链接阶段库文件的搜索路径。

用法

link_directories(directory1 directory2 ...)

  • 作用阶段:链接阶段。
  • 作用对象:库文件(如 .so.a.lib 等)。
  • 作用范围:全局,影响当前 CMakeLists.txt 文件中所有的目标。
影响

告诉链接器在查找目标库文件时,除了默认路径,还可以从指定路径中查找。

示例

link_directories(${CMAKE_SOURCE_DIR}/libs)

add_executable(my_target main.cpp)

target_link_libraries(my_target my_library)

在上述示例中,链接器会在 ${CMAKE_SOURCE_DIR}/libs 中查找名为 my_library 的库文件。

注意事项
  • 仅指定库的搜索路径,并不会直接将库文件链接到目标。
  • 如果可能,优先使用绝对路径或通过 find_package 指定库。
现代替代方案

建议直接在 target_link_libraries 中使用库的完整路径,避免使用 link_directories


3. link_libraries

功能

link_libraries 用于指定全局或局部范围的链接库。

用法

link_libraries(library1 library2 ...)

  • 作用阶段:链接阶段。
  • 作用对象:库文件(如 .so.a.lib 等)。
  • 作用范围
    • 全局:直接使用 link_libraries,会影响当前 CMakeLists.txt 中定义的所有目标。
    • 局部:通过作用域关键字限制作用范围(例如 PUBLICPRIVATE)。
影响

在链接目标时,自动添加指定的库文件。

示例

link_libraries(my_library)

add_executable(target1 main.cpp)

add_executable(target2 other.cpp)

上述代码中,my_library 会被自动添加到 target1target2 的链接阶段。

局部范围控制

可以通过作用域关键字限制库的作用范围:

link_libraries(PUBLIC my_library)

现代替代方案

现代 CMake 更推荐直接使用 target_link_libraries,为目标精确设置所需的库。

target_link_libraries(my_target PRIVATE my_library)


三者的区别

命令作用作用阶段作用范围现代替代方案
include_directories指定头文件搜索路径编译阶段默认全局target_include_directories
link_directories指定库文件搜索路径链接阶段默认全局避免使用,直接指定完整路径
link_libraries为所有后续目标指定链接库链接阶段默认全局或局部作用域target_link_libraries

如何选择正确的命令?

  1. 优先使用目标作用域命令

    • 如果仅需对单个目标进行设置,直接使用 target_include_directoriestarget_link_libraries
    • 避免全局命令(如 link_librariesinclude_directories),以减少潜在的冲突。
  2. 尽量避免使用 link_directories

    • 在现代 CMake 中,直接通过 target_link_libraries 指定库的完整路径更安全。
    • 如果必须使用,请确保路径唯一并清晰。
  3. 控制依赖传播

    • 通过 PRIVATEPUBLICINTERFACE 等关键字明确依赖的传播规则。

示例:完整的现代 CMake 使用方式

cmake_minimum_required(VERSION 3.20)
project(MyProject)

# 指定头文件和库的路径
set(MY_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include)
set(MY_LIBRARY_DIR ${CMAKE_SOURCE_DIR}/libs)
set(MY_LIBRARY my_library)

# 定义目标
add_executable(my_target main.cpp)

# 为目标设置头文件路径
target_include_directories(my_target PRIVATE ${MY_INCLUDE_DIR})

# 直接设置库文件
target_link_libraries(my_target PRIVATE ${MY_LIBRARY_DIR}/${MY_LIBRARY})

总结

  • include_directories 用于头文件路径,link_directories 用于库文件路径,而 link_libraries 用于全局设置链接库。
  • 在现代 CMake 中,更推荐使用目标作用域的命令如 target_include_directoriestarget_link_libraries
  • 避免全局命令可以提高配置的可维护性和可读性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值