[CMake] Passing CMake Arguments to FetchContent

Craig Scott craig.scott at crascit.com
Sat Mar 23 02:55:29 EDT 2019


On Sat, Mar 23, 2019 at 1:58 PM Jason Beach <jason.m.beach at gmail.com> wrote:

> I'm upgrading from cmake 3.5.1 and am trying to understand the new
> FetchContent command. So far I have:
>
> cmake_minimum_required(VERSION 3.14)
> project (json_test)
>
> include(FetchContent)
> set(JSON_BuildTests OFF) #if I try this I get a warning as it appears to
> be deprecated
>
> FetchContent_Declare(
>     nlohmann_json_fc
>     GIT_REPOSITORY https://github.com/nlohmann/json.git
>     GIT_TAG v3.6.1
>     GIT_SHALLOW TRUE
> #    CMAKE_ARGS -DJSON_BuildTests=OFF #doesn't work
> )
> FetchContent_MakeAvailable(nlohmann_json_fc)
> add_executable(main src/main.cpp)
> target_link_libraries(main nlohmann_json::nlohmann_json)
>
>
> I first tried sending in the JSON_BuildTests=OFF with CMAKE_ARGS in the
> FetchContent_Declare command but that didn't work.  On this post
> https://cmake.org/pipermail/cmake/2018-July/067804.html it appears this
> is because only the download portion of FetchContent_Declare is enabled
> with the intent to not do too much during configure time. How does
> specifying how the external project is configured fit that rationale?  If I
> execute
>
> cmake -DJSON_BuildTests=OFF ..
>
> the argument successfully makes it through to the external project. I
> guess I'm trying to understand why it's ok to specify it on the command
> line but not permanently in the CMakeLists.txt, particularly if you have
> many libraries each potentially with their options that need to be
> configured.
>

The warning you are getting is due to the behavior of the option() command,
which was changed in CMake 3.13. The first time you run CMake, the
JSON_BuildTests variable is not in the cache. With CMake 3.12 and earlier,
the option command will then ignore any non-cache variable of the same name
and set the cache variable to the default value. This has the side-effect
of also removing/updating the local variable, which means any non-cache
variable you set before the call to option() will have no effect the first
time you run CMake, but then it WILL have an effect for subsequent runs.
This is unintuitive and easy to miss. In CMake 3.13, the behavior was
changed to not create a cache variable if there was already a non-cache
variable set. This is intuitively what developers typically expect, but it
is only done if the CMP0077 policy is set to new. Inside the nlohmann/json
project's CMakeLists.txt file, it uses cmake_minimum_required(VERSION 3.1),
which means the CMP0077 policy is not set to NEW, hence the warning you are
seeing.

To prevent this problem in your case, you will need to set JSON_BuildTests
as a cache variable in your example project rather than just a regular
non-cache variable. Then the option() command in the nlohmann/json project
sees that the cache variable has already been set and it does nothing
instead of forcing it to have the default value on the first run. I
typically handle this situation in my projects by setting such variables to
an INTERNAL type where the main project is forcing the value and it won't
be available to the developer to change (so you don't want to show it to
them in the GUI, etc.). If you still want the developer to be able to
override it, just put an option command with your own preferred default
here instead. For your case, the modified example would be the following:

cmake_minimum_required(VERSION 3.14)
project (json_test)

include(FetchContent)
set(JSON_BuildTests OFF CACHE INTERNAL "")  # Forces the value

#option(JSON_BuildTests "" OFF)   # Different default, but dev can still
change it


FetchContent_Declare(
    nlohmann_json_fc
    GIT_REPOSITORY https://github.com/nlohmann/json.git
    GIT_TAG v3.6.1
    GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(nlohmann_json_fc)
add_executable(main src/main.cpp)
target_link_libraries(main nlohmann_json::nlohmann_json)



-- 
Craig Scott
Melbourne, Australia
https://crascit.com

Get the hand-book for every CMake user: Professional CMake: A Practical
Guide <https://crascit.com/professional-cmake/>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20190323/749da242/attachment.html>


More information about the CMake mailing list