CMake: Declare the project version in project()

libeigen/eigen!2850

Closes #3063

Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
This commit is contained in:
Rasmus Munk Larsen
2026-08-18 19:28:48 -07:00
co-authored by Rasmus Munk Larsen
parent 4e57e79dd8
commit f752349f69
3 changed files with 100 additions and 59 deletions
+62 -59
View File
@@ -42,11 +42,72 @@ if (POLICY CMP0074)
cmake_policy(SET CMP0074 NEW)
endif ()
#==============================================================================
# Version Info.
#==============================================================================
# If version information is not provided, automatically parse the version number
# from header files.
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/Eigen/Version" _eigen_version_header)
if (NOT DEFINED EIGEN_WORLD_VERSION)
string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen_world_version_match "${_eigen_version_header}")
set(EIGEN_WORLD_VERSION "${CMAKE_MATCH_1}" CACHE STRING "")
endif()
if (NOT DEFINED EIGEN_MAJOR_VERSION)
string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen_major_version_match "${_eigen_version_header}")
set(EIGEN_MAJOR_VERSION "${CMAKE_MATCH_1}" CACHE STRING "")
endif()
if (NOT DEFINED EIGEN_MINOR_VERSION)
string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen_minor_version_match "${_eigen_version_header}")
set(EIGEN_MINOR_VERSION "${CMAKE_MATCH_1}" CACHE STRING "")
endif()
if (NOT DEFINED EIGEN_PATCH_VERSION)
string(REGEX MATCH "define[ \t]+EIGEN_PATCH_VERSION[ \t]+([0-9]+)" _eigen_patch_version_match "${_eigen_version_header}")
set(EIGEN_PATCH_VERSION "${CMAKE_MATCH_1}" CACHE STRING "")
endif()
if (NOT DEFINED EIGEN_PRERELEASE_VERSION)
set(EIGEN_PRERELEASE_VERSION "dev")
endif()
# If we are in a git repo, extract a changeset.
if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.git)
# if the git program is absent or this will leave the EIGEN_GIT_REVNUM string empty,
# but won't stop CMake.
execute_process(COMMAND git ls-remote -q ${CMAKE_SOURCE_DIR} HEAD OUTPUT_VARIABLE EIGEN_GIT_OUTPUT)
endif()
# extract the git rev number from the git output...
if(EIGEN_GIT_OUTPUT)
string(REGEX MATCH "^([0-9;a-f]+).*" EIGEN_GIT_CHANGESET_MATCH "${EIGEN_GIT_OUTPUT}")
set(EIGEN_GIT_REVNUM "${CMAKE_MATCH_1}")
endif()
if (NOT DEFINED EIGEN_BUILD_VERSION AND DEFINED EIGEN_GIT_REVNUM)
string(SUBSTRING "${EIGEN_GIT_REVNUM}" 0 8 EIGEN_BUILD_VERSION)
else()
set(EIGEN_BUILD_VERSION "" CACHE STRING "")
endif()
# The EIGEN_VERSION_NUMBER must be of the form <major.minor.patch>.
# The EIGEN_VERSION_STRING can contain the preprelease/build strings.
set(EIGEN_VERSION_NUMBER "${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION}.${EIGEN_PATCH_VERSION}" CACHE STRING "")
set(EIGEN_VERSION_STRING "${EIGEN_VERSION_NUMBER}" CACHE STRING "")
if (NOT "x${EIGEN_PRERELEASE_VERSION}" STREQUAL "x")
set(EIGEN_VERSION_STRING "${EIGEN_VERSION_STRING}-${EIGEN_PRERELEASE_VERSION}" CACHE STRING "")
endif()
if (NOT "x${EIGEN_BUILD_VERSION}" STREQUAL "x")
set(EIGEN_VERSION_STRING "${EIGEN_VERSION_STRING}+${EIGEN_BUILD_VERSION}" CACHE STRING "")
endif()
#==============================================================================
# CMake Project.
#==============================================================================
project(Eigen3)
# The version is derived above so that project() can declare it here. Declaring
# it is what populates PROJECT_VERSION, Eigen3_VERSION and, for a top-level
# build, CMAKE_PROJECT_VERSION; all three are empty otherwise. See the
# cmake_project_version test.
project(Eigen3 VERSION ${EIGEN_VERSION_NUMBER})
# Remove this block after bumping CMake to v3.21.0
# PROJECT_IS_TOP_LEVEL is defined then by default
@@ -101,64 +162,6 @@ if (EIGEN_BUILD_TESTING OR EIGEN_BUILD_BLAS OR EIGEN_BUILD_LAPACK OR EIGEN_BUILD
set(EIGEN_IS_BUILDING_ ON)
endif()
#==============================================================================
# Version Info.
#==============================================================================
# If version information is not provided, automatically parse the version number
# from header files.
file(READ "${PROJECT_SOURCE_DIR}/Eigen/Version" _eigen_version_header)
if (NOT DEFINED EIGEN_WORLD_VERSION)
string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen_world_version_match "${_eigen_version_header}")
set(EIGEN_WORLD_VERSION "${CMAKE_MATCH_1}" CACHE STRING "")
endif()
if (NOT DEFINED EIGEN_MAJOR_VERSION)
string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen_major_version_match "${_eigen_version_header}")
set(EIGEN_MAJOR_VERSION "${CMAKE_MATCH_1}" CACHE STRING "")
endif()
if (NOT DEFINED EIGEN_MINOR_VERSION)
string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen_minor_version_match "${_eigen_version_header}")
set(EIGEN_MINOR_VERSION "${CMAKE_MATCH_1}" CACHE STRING "")
endif()
if (NOT DEFINED EIGEN_PATCH_VERSION)
string(REGEX MATCH "define[ \t]+EIGEN_PATCH_VERSION[ \t]+([0-9]+)" _eigen_patch_version_match "${_eigen_version_header}")
set(EIGEN_PATCH_VERSION "${CMAKE_MATCH_1}" CACHE STRING "")
endif()
if (NOT DEFINED EIGEN_PRERELEASE_VERSION)
set(EIGEN_PRERELEASE_VERSION "dev")
endif()
# If we are in a git repo, extract a changeset.
if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.git)
# if the git program is absent or this will leave the EIGEN_GIT_REVNUM string empty,
# but won't stop CMake.
execute_process(COMMAND git ls-remote -q ${CMAKE_SOURCE_DIR} HEAD OUTPUT_VARIABLE EIGEN_GIT_OUTPUT)
endif()
# extract the git rev number from the git output...
if(EIGEN_GIT_OUTPUT)
string(REGEX MATCH "^([0-9;a-f]+).*" EIGEN_GIT_CHANGESET_MATCH "${EIGEN_GIT_OUTPUT}")
set(EIGEN_GIT_REVNUM "${CMAKE_MATCH_1}")
endif()
if (NOT DEFINED EIGEN_BUILD_VERSION AND DEFINED EIGEN_GIT_REVNUM)
string(SUBSTRING "${EIGEN_GIT_REVNUM}" 0 8 EIGEN_BUILD_VERSION)
else()
set(EIGEN_BUILD_VERSION "" CACHE STRING "")
endif()
# The EIGEN_VERSION_NUMBER must be of the form <major.minor.patch>.
# The EIGEN_VERSION_STRING can contain the preprelease/build strings.
set(EIGEN_VERSION_NUMBER "${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION}.${EIGEN_PATCH_VERSION}" CACHE STRING "")
set(EIGEN_VERSION_STRING "${EIGEN_VERSION_NUMBER}" CACHE STRING "")
if (NOT "x${EIGEN_PRERELEASE_VERSION}" STREQUAL "x")
set(EIGEN_VERSION_STRING "${EIGEN_VERSION_STRING}-${EIGEN_PRERELEASE_VERSION}" CACHE STRING "")
endif()
if (NOT "x${EIGEN_BUILD_VERSION}" STREQUAL "x")
set(EIGEN_VERSION_STRING "${EIGEN_VERSION_STRING}+${EIGEN_BUILD_VERSION}" CACHE STRING "")
endif()
# Generate version file.
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/Version.in"
"${CMAKE_CURRENT_BINARY_DIR}/include/Eigen/Version")
+12
View File
@@ -254,6 +254,18 @@ endif()
set_property(GLOBAL PROPERTY EIGEN_CURRENT_SUBPROJECT "Official")
add_custom_target(BuildOfficial)
# Not an ei_add_test: this checks values produced by the configure step itself,
# so it compares what the enclosing project() call left in this scope.
add_test(NAME cmake_project_version
COMMAND ${CMAKE_COMMAND}
"-DEIGEN_EXPECTED_VERSION=${EIGEN_VERSION_NUMBER}"
"-DEIGEN_IS_TOP_LEVEL=${PROJECT_IS_TOP_LEVEL}"
"-DOBSERVED_PROJECT_VERSION=${PROJECT_VERSION}"
"-DOBSERVED_Eigen3_VERSION=${Eigen3_VERSION}"
"-DOBSERVED_CMAKE_PROJECT_VERSION=${CMAKE_PROJECT_VERSION}"
-P "${CMAKE_CURRENT_SOURCE_DIR}/cmake_project_version.cmake")
set_property(TEST cmake_project_version PROPERTY LABELS "Official")
ei_add_test(clz)
ei_add_test(rand)
ei_add_test(realview)
+26
View File
@@ -0,0 +1,26 @@
# SPDX-FileCopyrightText: The Eigen Authors
# SPDX-License-Identifier: MPL-2.0
# Checks the variables that project(Eigen3 VERSION ...) is responsible for
# populating. Their values as observed during Eigen's own configure are baked
# into the test command, so a variable that project() left unset arrives here as
# an empty string rather than as an undefined one.
if(NOT DEFINED EIGEN_EXPECTED_VERSION OR EIGEN_EXPECTED_VERSION STREQUAL "")
message(FATAL_ERROR "EIGEN_EXPECTED_VERSION was not passed to this script.")
endif()
set(names PROJECT_VERSION Eigen3_VERSION)
# CMAKE_PROJECT_VERSION belongs to the outermost project, which is Eigen3 only
# when Eigen is not being consumed as a sub-project.
if(EIGEN_IS_TOP_LEVEL)
list(APPEND names CMAKE_PROJECT_VERSION)
endif()
foreach(name IN LISTS names)
if(NOT "${OBSERVED_${name}}" STREQUAL "${EIGEN_EXPECTED_VERSION}")
message(FATAL_ERROR "${name} was \"${OBSERVED_${name}}\", expected "
"\"${EIGEN_EXPECTED_VERSION}\": the top-level project() call "
"must declare VERSION.")
endif()
endforeach()