[英]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_directories
或target_link_libraries
包含库? 如果包/库有.so
文件,我们可以简单地忽略该包/库的include_directories
吗?
编辑:如何知道是否应该使用include_directories
和target_link_libraries
包含库?
如何知道是否应该使用
include_directories
或target_link_libraries
包含库?
除非库是仅限标头的库,否则需要调用target_link_libraries
才能使用它。
如果Find*
脚本(由find_package()
调用调用)使用include目录设置变量(此信息可以从脚本的文档中获得),则它假定将包含这些目录(通过include_directories
或target_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_DIRS
和package_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.