How to link against projects added through FetchContent

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

How to link against projects added through FetchContent

Saad Khattak
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.

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

include(FetchContent)

FetchContent_Declare(
  Catch2
  TEST_COMMAND ""
  )

FetchContent_GetProperties(catch)
if(NOT Catch2_POPULATED)
  FetchContent_Populate(Catch2)
  add_subdirectory(${Catch2_SOURCE_DIR} ${Catch2_BINARY_DIR})
endif()

add_executable(testExe main.cpp)

target_link_libraries(testExe Catch2)
``````````````````````````````````````````````````````````````

CMake populates Catch2 with Catch2-NOTFOUND.

So, my question is, how do I link against projects added through FetchContent?

- Saad

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: How to link against projects added through FetchContent

Saad Khattak
I managed to find a solution myself:

``````````````````````````````````````````````````````````````
cmake_minimum_required(VERSION 3.11)

project(testProj)

include(FetchContent)

FetchContent_Declare(
  Catch2
  )

FetchContent_GetProperties(Catch2) #mispelled name in original post
if(NOT Catch2_POPULATED)
  FetchContent_Populate(Catch2)
  message(STATUS "Catch source dir: ${catch2_SOURCE_DIR}")
  message(STATUS "Catch binary dir: ${catch2_BINARY_DIR}")
  add_subdirectory(${catch2_SOURCE_DIR} ${catch2_BINARY_DIR}) #can be case insensitive
endif()

add_executable(testExe
  main.cpp
  )

message(STATUS "Catch include dir: ${catch2_SOURCE_DIR}/include")

target_link_libraries(testExe Catch) #name of library to link is case sensitive!
``````````````````````````````````````````````````````````````

On Sun, Mar 11, 2018 at 8:02 PM Saad Khattak <[hidden email]> 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.

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

include(FetchContent)

FetchContent_Declare(
  Catch2
  TEST_COMMAND ""
  )

FetchContent_GetProperties(catch)
if(NOT Catch2_POPULATED)
  FetchContent_Populate(Catch2)
  add_subdirectory(${Catch2_SOURCE_DIR} ${Catch2_BINARY_DIR})
endif()

add_executable(testExe main.cpp)

target_link_libraries(testExe Catch2)
``````````````````````````````````````````````````````````````

CMake populates Catch2 with Catch2-NOTFOUND.

So, my question is, how do I link against projects added through FetchContent?

- Saad

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: How to link against projects added through FetchContent

Craig Scott-3
In reply to this post by Saad Khattak
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 <[hidden email]> 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
  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

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: How to link against projects added through FetchContent

Saad Khattak
Thank you for the clarifications Craig! The confusion mainly stemmed from ${Catch2_SOURCE_DIR} where 'Catch2' should have been lowercase. I had originally started with the name 'catch' (which would explain why I accidentally left it unchanged in the _GetProperties function) but when that didn't work, I started assuming that perhaps it was conflicting with the actual library. It was all downhill from there :)

After your suggestions, I was successfully able to get it to work. For future reference for anyone stumbling on this answer, here's a minimum example of a working version: https://github.com/samaursa/cmake_fetch_content

>> I'm a little surprised CMake didn't complain about that, it does for me when I tested this just now

CMake did not warn me about it. I am on CMake Version 3.11.0-rc3. It would be great if this warning could be emphasized by CMake as without it, it is difficult to tell what went wrong since `target_link_libraries` also fails and I simply get compile errors for missing headers.

On Sun, Mar 11, 2018 at 8:55 PM Craig Scott <[hidden email]> wrote:
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 <[hidden email]> 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
  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

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake