What is the correct way to set options of a project before Fetch Content?

I want to disable some of the properties that the project I need to fetch, so I set the options just before the FetchContent declarations in my project/tests/CMakeLists.txt:

  set(XXX_BUILD_TESTING OFF)
  set(XXX_ENABLE_COVERAGE_INFO OFF)
  set(XXX_INSTALL_DOCS OFF)
  
  include(FetchContent)

  FetchContent_Declare(yyy
      QUITE
      GIT_REPOSITORY https://github.com/xxx/yyy
      GIT_TAG v9.9.9
      GIT_PROGRESS OFF
      GIT_SHALLOW ON )

But when I make ccmake -S project -B build , the options appears in default. I tried to set the options on top level CMakeLists.txt, but nothing change. I’m using the CMake version 3.15.5. Any pointer about what I’m doing wrong is really welcome. Thanks you kindly…

In your code snippet I don’t see the call to FetchContent_MakeAvailable which behind the scenes will call add_subdirectory which will enable your variables in the project.

This is how Hunter works:

cmake_minimum_required(VERSION 3.14)

set(HUNTER_PACKAGES ZLIB)

include(FetchContent)
FetchContent_Declare(SetupHunter GIT_REPOSITORY https://github.com/cpp-pm/gate)
FetchContent_MakeAvailable(SetupHunter)

project(SetupHunter)
2 Likes

Moved this discussion to Code category.

I have success with setting options when I use CACHE INTERNAL:

set (XXX_BUILD_TESTING OFF CACHE INTERNAL "Turn off tests")

I also use CACHE variables to propagate from top-level project to FetchContent subprojects. I also use CACHE BOOL etc. as relevant

CMP0077 is relevant here, if that policy is turned on (it was added in 3.13) then setting variables before calling FetchContent_MakeAvailable will cause calls to option in the subproject to basically do nothing. This is nice as it means users of your project don’t even get cache entries for the subproject options you’re forcing.

Note that if the subproject calls cmake_minimum_required with some old version it may cause CMP0077 to have the OLD behavior, you can use cmake_policy(SET) to avoid this if I recall