Issue
I am still learning cmake and am struggling with a dependency I am trying to set up.
I discovered FetchContent while setting up googletest, and that worked fine so I am trying to do the same thing for a new dependency I am trying to configure for can-utils.
In the CMakeLists.txt file in the source directory for the code that I want to use can-utils with, I added:
include(FetchContent)
FetchContent_Declare(
can-utils
GIT_REPOSITORY https://github.com/linux-can/can-utils.git
GIT_TAG e602e391a56e681b03506c2f0890eb128192ec3d
)
FetchContent_MakeAvailable(can-utils)
The project configures and builds,and I can see that cmake put the can-utils repo in to my build directory... However, unlike with googletest, where after doing the FetchContent I was able to #include <gtest/gtest.h>
, I can't seem to #include "anything/resembling/can-utils"
I suspect that the difference is that googletest is set up with FetchContent in mind and can-utils is not. My question is: How would I know if I can use FetchContent for a given library?
Any guidance is very much appreciated!
Solution
FetchContent
eventually calls add_subdirectory
on the fetched content. The location of the downloaded contents is written to a variable named <lowercaseName>_SOURCE_DIR
, which IIRC is by default under a binary dir.
Looking at can-utils/CMakeLists.txt, it does the following at what is currently line 22:
include_directories (.)
include_directories (./include)
include_directories
is not attached to any target. See its docs:
The include directories are added to the
INCLUDE_DIRECTORIES
directory property for the current CMakeLists file. They are also added to theINCLUDE_DIRECTORIES
target property for each target in the current CMakeLists file. The target property values are the ones used by the generators.
Since (IIRC,) the default value of ${can-utils_SOURCE_DIR}
will be under some binary dir of your generated buildsystem, unless some crazy coincidence happens with an in-source build, your targets are probably not going to inherit those include_directories
values.
As a bandaid-solution, you should be able to do something like:
# this must go after the call to FetchContent_MakeAvailable and before your targets are created and in a same-or-parent directory of the directories of the CMakeLists.txt files creating your targets.
include_directories("${can-utils_SOURCE_DIR}/..")
Which should then allow you do include the headers like:
#include <value_of_can-utils_SOURCE_DIR/lib.h>
And if you don't like whatever ${can-utils_SOURCE_DIR}
is, I think you could do some symlinking to work around it.
A better bandaid-solution would be to use target_include_directories
to add it per-target of can-utils like they preferably should have done.
If you want, you can raise an issue/PR to the maintainer of the project to switch from include_directories
to use target_include_directories
, which should be okay especially since they're using cmake_minimum_required(VERSION 3.3)
You could also ask/PR them to place their header files under a subdirectory named can-utils
inside their repo so that you don't have do either deal with the value of ${can-utils_SOURCE_DIR}
or do symlink workarounds.
Answered By - David Fong Answer Checked By - Timothy Miller (WPSolving Admin)