Passing CMake Arguments to FetchContent

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

Passing CMake Arguments to FetchContent

Jason Beach
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.

Thanks,
Jason
 


--

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: Passing CMake Arguments to FetchContent

Craig Scott-3


On Sat, Mar 23, 2019 at 1:58 PM Jason Beach <[hidden email]> 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_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

Get the hand-book for every CMake user: Professional CMake: A Practical Guide

--

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