[英]cmake - When to include include_directories in a CMakeLists.txt file
I have a C++ project in which I have the following line: 我有一个C ++项目,其中我有以下行:
#include <curl/curl.h>
I am using the CURL
library to access IMU data from a sensor. 我正在使用CURL
库从传感器访问IMU数据。 I prepared a CMakeLists.txt
file that looks like this: 我准备了一个如下所示的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})
This works very well. 这非常有效。 However, if I remove the include_directories
line and modify the add_executable
line to just use my imu_data_access.cpp
as source, the cmake
does not throw an error and everything still works. 但是,如果我删除include_directories
行并修改add_executable
行只是使用我的imu_data_access.cpp
作为源, cmake
不会抛出错误,一切仍然有效。 I am assuming this is due to target_link_libraries
line. 我假设这是由于target_link_libraries
行。
How to know whether a library should be included using include_directories
or target_link_libraries
? 如何知道是否应该使用include_directories
或target_link_libraries
包含库? If the package/library has a .so
file can we simply ignore include_directories
for that package/library? 如果包/库有.so
文件,我们可以简单地忽略该包/库的include_directories
吗?
Edit: How to know whether a library should be included using include_directories
vs. target_link_libraries
? 编辑:如何知道是否应该使用include_directories
和target_link_libraries
包含库?
How to know whether a library should be included using
include_directories
ortarget_link_libraries
? 如何知道是否应该使用include_directories
或target_link_libraries
包含库?
Unless a library is a header-only library, call to target_link_libraries
is required for use it. 除非库是仅限标头的库,否则需要调用target_link_libraries
才能使用它。
If Find*
script (called by find_package()
call) sets variable with include directories (this information can be obtained from the script's documentation), it assumes that these directories will be included (via include_directories
or target_include_directories
). 如果Find*
脚本(由find_package()
调用调用)使用include目录设置变量(此信息可以从脚本的文档中获得),则它假定将包含这些目录(通过include_directories
或target_include_directories
)。
Propagating include directories through the target_link_libraries
occurred in case of IMPORTED target, usually named as <namespace>::<name>
. 在IMPORTED目标的情况下,通过target_link_libraries
传播include目录,通常命名为<namespace>::<name>
。
In your specific case include_directories
have no effect only because given directory is searched by a compiler by default , this is usual when library is installed through package manager. 在您的特定情况下, include_directories
不起作用,因为默认情况下编译器搜索给定目录,这通常是通过包管理器安装库时。 But find_package
is intended to work even with non-system installations. 但find_package
即使在非系统安装时也能工作。
I see a couple of things that may help you improve your code. 我看到了一些可以帮助您改进代码的事情。
I generally like to make sure that my CMake scripts don't overspecify the version. 我通常希望确保我的CMake脚本不会过度指定版本。 It seems to me that in this script, anything more than version 3.1 would work. 在我看来,在这个脚本中,除了版本3.1之外的任何东西都可以工作。 So I'd be inclined to change that first line to this: 所以我倾向于改变第一行:
cmake_minimum_required(VERSION 3.1)
As you know, find_package()
generally sets the package_INCLUDE_DIRS
and package_LIBRARIES
for the package. 如您所知, find_package()
通常为包设置package_INCLUDE_DIRS
和package_LIBRARIES
。 I find that consistently using such variables is much better for simplifying maintenance of the CMake script than trimming to the bare minimum. 我发现一直使用这些变量对于简化CMake脚本的维护比修剪到最低限度要好得多。 Therefore I'd not worry about whether they're required or not and do this: 因此我不担心他们是否需要并且这样做:
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})
Note that I have omitted this line: 请注意,我省略了这一行:
set(SOURCES imu_data_access.cpp ${CURL_INCLUDE_DIRS}/curl/curl.h)
Not every library include file needs to be or should be listed as a source. 并非每个库都包含文件需要或应该作为源列出。 As a general rule, I only include my sources, and that's what I'd advice for your projects as well. 作为一般规则,我只包括我的来源,这也是我对你的项目的建议。
A good practice is to use target_include_directories()
instead of include_directories()
. 一个好的做法是使用target_include_directories()
而不是include_directories()
。 The benefit is that you can indicate the visibility of the include, for example if you configure a library with: 好处是您可以指示包含的可见性,例如,如果您使用以下内容配置库:
add_library(foo foo.cpp)
target_include_directories(foo PUBLIC foo_include)
target_include_directories(foo PRIVATE private_include)
Then, if you link foo
to an executable bar
, then bar
will have access to the foo_include
directory, but not to private_include
. 然后,如果将foo
链接到可执行bar
,则bar
将可以访问foo_include
目录,但不能访问private_include
。 Command include_directories()
apply to the directory where the CMakeLists.txt
contains the command, so it will apply to any library/executable declared in this directory and its sub-directories. 命令include_directories()
适用于CMakeLists.txt
包含命令的目录,因此它将应用于此目录及其子目录中声明的任何库/可执行文件。
For target_link_libraries()
, then the behavior varies, because it can be a list of libraries, in which case there is no notion of include directories. 对于target_link_libraries()
,行为会有所不同,因为它可以是库列表,在这种情况下,没有包含目录的概念。 But it can be an IMPORTED library, where it can contain more information, such as include directories (for example, Boost and Qt do that). 但它可以是一个IMPORTED库,它可以包含更多信息,例如include目录(例如,Boost和Qt这样做)。
In the case of cURL, the documentation indicates that CURL_LIBRARIES
contains the list of libraries. 对于cURL, 文档指出CURL_LIBRARIES
包含库列表。 In your case, the cURL headers are probably found because by default CMake will search for headers in standard locations, so target_link_libraries()
has no impact regarding the includes in this case. 在您的情况下,可能会找到cURL标头,因为默认情况下,CMake将在标准位置搜索标头,因此在这种情况下, target_link_libraries()
对包含没有影响。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.