I have a C++ project in which I have the following line:
#include <curl/curl.h>
I am using the CURL
library to access IMU data from a sensor. I prepared a CMakeLists.txt
file that looks like this:
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. I am assuming this is due to target_link_libraries
line.
How to know whether a library should be included using include_directories
or target_link_libraries
? If the package/library has a .so
file can we simply ignore include_directories
for that package/library?
Edit: How to know whether a library should be included using include_directories
vs. target_link_libraries
?
How to know whether a library should be included using
include_directories
ortarget_link_libraries
?
Unless a library is a header-only library, call to target_link_libraries
is required for use it.
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
).
Propagating include directories through the target_link_libraries
occurred in case of IMPORTED target, usually named as <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. But find_package
is intended to work even with non-system installations.
A good practice is to use target_include_directories()
instead of 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
. 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.
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. But it can be an IMPORTED library, where it can contain more information, such as include directories (for example, Boost and Qt do that).
In the case of cURL, the documentation indicates that CURL_LIBRARIES
contains the list of 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With