[CMake] CMAKE_ARGS for FetchContent

Craig Scott craig.scott at crascit.com
Fri Jul 6 07:53:03 EDT 2018


On Fri, Jul 6, 2018 at 9:49 PM, Mads Andreasen <temp1 at andreasen.cc> wrote:

> Hi Craig
>
> Thanks for getting back to me.
> I was hoping to be able to build the library with fetch content, so that
> the FindXXX would automatically work.
>

If you want to use FindXXX, you need to use ExternalProject and a
superbuild structure. The things that FindXXX modules look for don't exist
until after they have been built. It sounds like a superbuild is really
what you should be doing here.

If you choose to incorporate jsoncpp via add_subdirectory() instead, then
instead of using FindXXX modules you can refer directly to the CMake target
names that jsoncpp defines. This is one of the main reasons for
FetchContent and using add_subdirectory(), since you can directly refer to
things that CMake knows about instead of having to find anything.




>
> If I use your proposed approach:
>
> if(NOT jsoncpp_POPULATED)
>
>   FetchContent_Populate(jsoncpp)
>
>   add_subdirectory(${jsoncpp_SOURCE_DIR} ${jsoncpp_BINARY_DIR})
>
> endif()
>
>
> Should I then set the -DJSONCPP_XXX options when running the main cmake
> configure?
>
> Best regards,
> Mads
>
>
> On Fri, Jul 6, 2018 at 12:41 PM Craig Scott <craig.scott at crascit.com>
> wrote:
>
>>
>>
>> On Fri, Jul 6, 2018 at 8:25 PM, Mads Andreasen <temp1 at andreasen.cc>
>> wrote:
>>
>>> Hi,
>>>
>>> I am trying to work with FetchContent in cmake 3.11.
>>> I want to use the jsoncpp library and use FetchContent to get and build
>>> it.
>>>
>>
>> FetchContent can only download it. You need to build it as a separate
>> step (you should avoid building things during the configure phase as much
>> as possible). The expected pattern is to add the downloaded contents to
>> your existing build via add_subdirectory(). If you want to keep the build
>> isolated from your main build, then use ExternalProject directly rather
>> than FetchContent.
>>
>>
>>
>>>
>>> I also want to configure the jsoncpp build with some cmake arguments and
>>> I can't seem to get that right.
>>>
>>> My CMakeLists.txt looks like this:
>>> **************************************************************
>>> cmake_minimum_required(VERSION 3.11)
>>> project(Foo)
>>>
>>> include(FetchContent)
>>>
>>> FetchContent_Declare(jsoncpp
>>>   URL "c:/project/jsoncpp-src"
>>>     CMAKE_ARGS "-DJSONCPP_WITH_CMAKE_PACKAGE=
>>> ON;-DJSONCPP_WITH_PKGCONFIG_SUPPORT=OFF"
>>> )
>>>
>>> FetchContent_Populate(jsoncpp)
>>>
>>> add_executable(Foo main.cpp)
>>> **************************************************************
>>>
>>
>> The configure, build, test and install steps of ExternalProject do not
>> apply to FetchContent, that's why CMAKE_ARGS has no effect.
>>
>>
>>
>>
>>
>>>
>>>
>>> FetchContent downloads and configures the jsoncpp as an ExternalProject.
>>>
>>
>> No, it only downloads, not configures.
>>
>>
>>
>>> That part looks like this:
>>> *********************************************
>>> ExternalProject_Add(jsoncpp-populate
>>>                      "UPDATE_DISCONNECTED" "False" "URL"
>>> "c:/project/jsoncpp-src" "CMAKE_ARGS" "-DJSONCPP_WITH_CMAKE_PACKAGE=ON"
>>> "-DJSONCPP_WITH_PKGCONFIG_SUPPORT=OFF"
>>>                     SOURCE_DIR          "C:/temp/foo/build/_deps/
>>> jsoncpp-src"
>>>                     BINARY_DIR          "C:/temp/foo/build/_deps/
>>> jsoncpp-build"
>>>                     CONFIGURE_COMMAND   ""
>>>                     BUILD_COMMAND       ""
>>>                     INSTALL_COMMAND     ""
>>>                     TEST_COMMAND        ""
>>> )
>>> *******************************************************
>>>
>>> For the external project - the CMAKE_ARGS are no longer a list, but
>>> individual arguments.
>>>
>>> I have tried different things, like escaping the ; with \\; and stuff
>>> like that, and I can't get it to work.
>>> I'm thinking there is something obvious I am missing?
>>>
>>
>> Assuming jsoncpp doesn't assume it is a top level project (I haven't
>> checked), the canonical pattern as explained in the docs
>> <https://cmake.org/cmake/help/latest/module/FetchContent.html#overview>
>> would be:
>>
>> FetchContent_Declare(jsoncpp
>>    URL "c:/project/jsoncpp-src"
>> )
>>
>> FetchContent_GetProperties(jsoncpp)
>>
>> if(NOT jsoncpp_POPULATED)
>>
>>   FetchContent_Populate(jsoncpp)
>>
>>   add_subdirectory(${jsoncpp_SOURCE_DIR} ${jsoncpp_BINARY_DIR})
>>
>> endif()
>>
>>
>> The reason why FetchContent has all but download steps disabled is the
>> projects should avoid doing time-consuming things during the configure
>> stage. A configure stage will be inherently non-parallel as well, so it
>> hurts you twice. Build steps should be deferred to the build stage as much
>> as possible. If you find yourself wanting to pull some external project's
>> build earlier into the configure stage, chances are you really should be
>> using a superbuild if you truly need a build to be complete before the
>> configure logic of a different project is executed.
>>
>> --
>> Craig Scott
>> Melbourne, Australia
>> https://crascit.com
>>
>


-- 
Craig Scott
Melbourne, Australia
https://crascit.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20180706/991b7f73/attachment-0001.html>


More information about the CMake mailing list