Context
I have a super build CMake project which integrate a foo
CMake project (think of FetchContent()
or add_subdirectory()
).
I want to be able to change the value of a cached variable inside foo (i.e. don't like the default value)
question: How I can do that ?
Here a simple test.
note: I also test for an "option()" to see how smooth it is in this case.
Protocol
layout CMakeLists.txt:
# This is a super build project
cmake_minimum_required(VERSION 3.0)
project(SuperBuild VERSION 1.0 LANGUAGES CXX)
# Trying to override the FOO option of "third party" foo
set(FOO OFF)
# Trying to override the BAR cache variable of "third party" foo
set(BAR "foo")
# Incorporate the Foo third party project.
# Should be done using FetchContent(GIT_REPOSITORY .../foo.git) but, here
# I used add_subdirectory(foo) to keep it simple...
add_subdirectory(foo)
foo/CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
# option() honors normal variables.
# without this policy, cmake will "clear" the super build variable value
# and will use the option defualt value -_-
# see: https://cmake.org/cmake/help/git-stage/policy/CMP0077.html
if(POLICY CMP0077)
cmake_policy(SET CMP0077 NEW)
endif()
# An option ON by default
option(FOO "My FOO option" ON)
message(WARNING "FOO: ${FOO}")
# A string variable cached with default "bar"
# we can override it on command line using for example -DBAR:STRING="foo"
# but here since we are in a super build we want to override it in the super
# build CMakeLists.txt directly
set(BAR "bar" CACHE STRING "My cache entry with default 'bar'")
message(WARNING "BAR: ${BAR}")
Test 1
echo "First run"
cmake -S. -Bbuild
echo "Second run"
cmake -S. -Bbuild
Observed
First run
-- The CXX compiler identification is GNU 10.1.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Warning at foo/CMakeLists.txt:13 (message):
FOO: OFF
CMake Warning at foo/CMakeLists.txt:20 (message):
BAR: bar
-- Configuring done
-- Generating done
-- Build files have been written to: build
Second run
CMake Warning at foo/CMakeLists.txt:13 (message):
FOO: OFF
CMake Warning at foo/CMakeLists.txt:20 (message):
BAR: foo
-- Configuring done
-- Generating done
-- Build files have been written to: build
So first run, option FOO is correctly override by the super build variable thanks to CMP0077, while BAR cache variable is set to its default value.
During the second run, strangely (any explanation welcome, IMHO is BAR is already in the cache so the super build set will update it) BAR take the value of the super build...
Side Test
From scratch, just test we can override value in the cmdline (not my case but still interesting)
rm -rf build
cmake -S. -Bbuild -DBAR:STRING=plop
CMake Warning at foo/CMakeLists.txt:13 (message):
FOO: OFF
CMake Warning at foo/CMakeLists.txt:20 (message):
BAR: plop
-- Configuring done
-- Generating done
-- Build files have been written to: build
cmake -S. -Bbuild -DBAR:STRING=plop
CMake Warning at foo/CMakeLists.txt:13 (message):
FOO: OFF
CMake Warning at foo/CMakeLists.txt:20 (message):
BAR: plop
-- Configuring done
-- Generating done
-- Build files have been written to: build
ps: Sorry for the non syntax highlighting, contrary to github, SO doesn't recognize cmake
...