繁体   English   中英

cmake - 何时在CMakeLists.txt文件中包含include_directories

[英]cmake - When to include include_directories in a CMakeLists.txt file

我有一个C ++项目,其中我有以下行:

#include <curl/curl.h>

我正在使用CURL库从传感器访问IMU数据。 我准备了一个如下所示的CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.5.1)
project(imu_data_access_cmake_test)
set(CMAKE_CXX_STANDARD 11)
find_package(CURL REQUIRED)
include_directories(${CURL_INCLUDE_DIRS})
set(SOURCES imu_data_access.cpp ${CURL_INCLUDE_DIRS}/curl/curl.h)
add_executable(imu_data_access_cmake_test ${SOURCES})
#add_executable(imu_data_access_cmake_test imu_data_access.cpp)
target_link_libraries(imu_data_access_cmake_test ${CURL_LIBRARIES})

这非常有效。 但是,如果我删除include_directories行并修改add_executable行只是使用我的imu_data_access.cpp作为源, cmake不会抛出错误,一切仍然有效。 我假设这是由于target_link_libraries行。

如何知道是否应该使用include_directoriestarget_link_libraries包含库? 如果包/库有.so文件,我们可以简单地忽略该包/库的include_directories吗?

编辑:如何知道是否应该使用include_directoriestarget_link_libraries包含库?

如何知道是否应该使用include_directoriestarget_link_libraries包含库?

除非库是仅限标头的库,否则需要调用target_link_libraries才能使用它。

如果Find*脚本(由find_package()调用调用)使用include目录设置变量(此信息可以从脚本的文档中获得),则它假定将包含这些目录(通过include_directoriestarget_include_directories )。

IMPORTED目标的情况下,通过target_link_libraries传播include目录,通常命名为<namespace>::<name>


在您的特定情况下, include_directories不起作用,因为默认情况下编译器搜索给定目录,这通常是通过包管理器安装库时。 find_package即使在非系统安装时也能工作。

我看到了一些可以帮助您改进代码的事情。

避免过度指定最低版本

我通常希望确保我的CMake脚本不会过度指定版本。 在我看来,在这个脚本中,除了版本3.1之外的任何东西都可以工作。 所以我倾向于改变第一行:

cmake_minimum_required(VERSION 3.1)

始终如一地处理包裹

如您所知, find_package()通常为包设置package_INCLUDE_DIRSpackage_LIBRARIES 我发现一直使用这些变量对于简化CMake脚本的维护比修剪到最低限度要好得多。 因此我不担心他们是否需要并且这样做:

find_package(CURL REQUIRED)
include_directories(${CURL_INCLUDE_DIRS})
add_executable(imu_data_access_cmake_test imu_data_access.cpp)
target_link_libraries(imu_data_access_cmake_test ${CURL_LIBRARIES})

不要将系统包含在源中

请注意,我省略了这一行:

set(SOURCES imu_data_access.cpp ${CURL_INCLUDE_DIRS}/curl/curl.h)

并非每个库都包含文件需要或应该作为源列出。 作为一般规则,我只包括我的来源,这也是我对你的项目的建议。

一个好的做法是使用target_include_directories()而不是include_directories() 好处是您可以指示包含的可见性,例如,如果您使用以下内容配置库:

add_library(foo foo.cpp)
target_include_directories(foo PUBLIC foo_include)
target_include_directories(foo PRIVATE private_include)

然后,如果将foo链接到可执行bar ,则bar将可以访问foo_include目录,但不能访问private_include 命令include_directories()适用于CMakeLists.txt包含命令的目录,因此它将应用于此目录及其子目录中声明的任何库/可执行文件。

对于target_link_libraries() ,行为会有所不同,因为它可以是库列表,在这种情况下,没有包含目录的概念。 但它可以是一个IMPORTED库,它可以包含更多信息,例如include目录(例如,Boost和Qt这样做)。

对于cURL, 文档指出CURL_LIBRARIES包含库列表。 在您的情况下,可能会找到cURL标头,因为默认情况下,CMake将在标准位置搜索标头,因此在这种情况下, target_link_libraries()对包含没有影响。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM