[CMake] How to link against projects added through FetchContent

Craig Scott craig.scott at crascit.com
Sun Mar 11 20:55:18 EDT 2018


Thanks for trying out the new FetchContent module. Comments on your
question interspersed below.


On Mon, Mar 12, 2018 at 11:02 AM, Saad Khattak <saadrustam at gmail.com> wrote:

> Hi,
>
> I would like to know how to use the FetchContent properly so that I can
> link against downloaded (CMake enabled) projects. I have looked at the
> CMake docs, which although are quite thorough, almost always fail to list a
> complete example which is incredibly crucial to get up and running quickly.
>
> With ExternalProject_Add, we use add_dependencies(...) but that doesn't
> seem to be the case for FetchContent. Since I can immediately call
> add_subdirectory(...), I assumed that I can simply link to the library. But
> that doesn't seem to do anything.
>

This is indeed how it should work. After you've called add_subdirectory(),
the targets defined by the project being added should be immediately
available just like any other target your own project would define.



>
> Here's my CMakeLists.txt
> ``````````````````````````````````````````````````````````````
> cmake_minimum_required(VERSION 3.5)
>

Your minimum CMake version will be 3.11 if you want to use FetchContent, so
consider specifying that as the minimum version here.




> project(testProj)
>
> include(FetchContent)
>
> FetchContent_Declare(
>   Catch2
>   GIT_REPOSITORY "https://github.com/catchorg/Catch2"
>   TEST_COMMAND ""
>   )
>

As stated in the docs, TEST_COMMAND will be ignored, so don't set it here.
FetchContent only downloads, it doesn't build (you're in control of that,
see further comments below). The ExternalProject_Add() docs also recommend
you set GIT_TAG to the specific git hash you want to use (apart from being
more robust, it saves having to contact the remote each time CMake is run
after it has been cloned). FetchContent delegates all downloading to
ExternalProject, so the comments apply here as well.



>
> FetchContent_GetProperties(catch)
>

This needs to be the same as the first argument to FetchContent_Declare()
above, i.e. Catch2


> if(NOT Catch2_POPULATED)
>   FetchContent_Populate(Catch2)
>   add_subdirectory(${Catch2_SOURCE_DIR} ${Catch2_BINARY_DIR})
>

The documentation for the FetchContent_Populate() function state that the
variable names use lowercased names of the content name (i.e.
catch2_SOURCE_DIR rather than Catch2_SOURCE_DIR), so both of these
variables used here will be empty. I'm a little surprised CMake didn't
complain about that, it does for me when I tested this just now. Same for
the variable name used in the if test (i.e. use catch2_POPULATED rather
than Catch2_POPULATED).

The reason for the lowercasing is that it was found during the 2 years or
so when we were dog-fooding this module that while people usually got the
name right, there would be variations in upper/lowercase which made things
less reliable.



> endif()
>
> add_executable(testExe main.cpp)
>
> target_link_libraries(testExe Catch2)
>

If the Catch2 project defines a library called Catch2, then this line
should work fine once you fix the above problems. I think you want Catch
rather than Catch2 though.




> ``````````````````````````````````````````````````````````````
>
> CMake populates Catch2 with Catch2-NOTFOUND.
>
> So, my question is, how do I link against projects added through
> FetchContent?
>





-- 
Craig Scott
Melbourne, Australia
https://crascit.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20180312/6fc570f3/attachment.html>


More information about the CMake mailing list