CMAKE_PROJECT__INCLUDE_BEFORE cannot set variables for project(…)
Summary
CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE fails to provide variables for the parameter of project() (e.g. VERSION or DESCRIPTION). Variables set in the include_before script are undefined when project() parses its VERSION argument, despite documentation suggesting the include happens before project().
Here is the minimal example:
# CMakeLists.txt
cmake_minimum_required(VERSION 4.1)
include(CMakePrintHelpers)
variable_watch(TB_VERSION)
variable_watch(PROJECT_VERSION)
list(APPEND CMAKE_PROJECT_test_INCLUDE_BEFORE
"${CMAKE_CURRENT_SOURCE_DIR}/set_version.cmake")
project(test VERSION ${TB_VERSION})
cmake_print_variables(TB_VERSION PROJECT_VERSION CMAKE_PROJECT_VERSION)
# set_version.cmake
message(STATUS "include_before running...")
set(TB_VERSION "1.2.3")
cmake_print_variables(TB_VERSION)
Log:
❯ cmake .
CMake Debug Log at CMakeLists.txt:11 (project):
Variable "TB_VERSION" was accessed using UNKNOWN_READ_ACCESS with value "".
-- include_before running...
CMake Debug Log at set_version.cmake:3 (set):
Variable "TB_VERSION" was accessed using MODIFIED_ACCESS with value
"1.2.3".
Call Stack (most recent call first):
CMakeLists.txt:11 (project)
CMake Debug Log at C:/Users/e_gleba/scoop/apps/cmake/current/share/cmake-4.2/Modules/CMakePrintHelpers.cmake:94 (string):
Variable "TB_VERSION" was accessed using READ_ACCESS with value "1.2.3".
Call Stack (most recent call first):
set_version.cmake:5 (cmake_print_variables)
CMakeLists.txt:11 (project)
-- TB_VERSION="1.2.3"
CMake Warning at CMakeLists.txt:11 (project):
VERSION keyword not followed by a value or was followed by a value that
expanded to nothing.
CMake Debug Log at CMakeLists.txt:11 (project):
Variable "PROJECT_VERSION" was accessed using MODIFIED_ACCESS with value
"".
CMake Debug Log at C:/Users/e_gleba/scoop/apps/cmake/current/share/cmake-4.2/Modules/CMakePrintHelpers.cmake:94 (string):
Variable "TB_VERSION" was accessed using READ_ACCESS with value "1.2.3".
Call Stack (most recent call first):
CMakeLists.txt:13 (cmake_print_variables)
CMake Debug Log at C:/Users/e_gleba/scoop/apps/cmake/current/share/cmake-4.2/Modules/CMakePrintHelpers.cmake:94 (string):
Variable "PROJECT_VERSION" was accessed using READ_ACCESS with value "".
Call Stack (most recent call first):
CMakeLists.txt:13 (cmake_print_variables)
-- TB_VERSION="1.2.3" ; PROJECT_VERSION="" ; CMAKE_PROJECT_VERSION=""
-- Configuring done (0.0s)
-- Generating done (0.1s)
-- Build files have been written to: C:/Users/e_gleba/testbed
This contradicts the documented behavior from “Professional CMake” 22nd edition, which states the code is equivalent to:
# CMake 3.15 or later only
if(DEFINED CMAKE_PROJECT_INCLUDE_BEFORE)
include(${CMAKE_PROJECT_INCLUDE_BEFORE})
endif()
# CMake 3.17 or later only
if(DEFINED CMAKE_PROJECT_SomeProj_INCLUDE_BEFORE)
include(${CMAKE_PROJECT_SomeProj_INCLUDE_BEFORE})
endif()
project(SomeProj)
However, manually placing include() before project() does work correctly