diff --git a/CMakeLists.txt b/CMakeLists.txt index 54d647f1c7..87feb76437 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,27 +33,18 @@ if(WIN32) endif() # Read VERSION first (before project()) -if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION") - message(FATAL_ERROR "VERSION file not found at ${CMAKE_CURRENT_SOURCE_DIR}/VERSION") +include(cmake/Versions.cmake) +if(NOT DEFINED THEMIS_VERSION_NUMERIC OR "${THEMIS_VERSION_NUMERIC}" STREQUAL "") + message(FATAL_ERROR "Version metadata could not be resolved from ${CMAKE_CURRENT_SOURCE_DIR}/VERSION") endif() # Canonical dependency contract: strict in normal dev/release builds, # diagnostic-only fallback in bootstrap troubleshooting. include(cmake/DependencyContract.cmake) -file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" _ver_raw) -string(STRIP "${_ver_raw}" _ver_raw) - -# Parse semantic version -if(NOT _ver_raw MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") - message(FATAL_ERROR "Invalid VERSION format: '${_ver_raw}'. Expected: 1.2.3 or 1.2.3-alpha") -endif() - -string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" _ver_numeric "${_ver_raw}") - # Define project with numeric version (CMake requirement) project(Themis - VERSION ${_ver_numeric} + VERSION ${THEMIS_VERSION_NUMERIC} DESCRIPTION "ThemisDB - Enterprise Distributed Database" LANGUAGES CXX ) @@ -177,9 +168,6 @@ if(DEFINED CMAKE_TOOLCHAIN_FILE AND NOT "${CMAKE_TOOLCHAIN_FILE}" STREQUAL "" AN endif() endif() -# Store full semantic version -set(THEMIS_VERSION_STRING "${_ver_raw}") - # Default parallelism used by build wrappers and as a hint for developers. # This cache entry can be inspected by tools and users; wrappers default to this # value when no explicit `-j` is provided. diff --git a/cmake/BuildInfo.cmake b/cmake/BuildInfo.cmake index 0f5326ae43..e0529e15b2 100644 --- a/cmake/BuildInfo.cmake +++ b/cmake/BuildInfo.cmake @@ -64,6 +64,7 @@ set(THEMIS_BUILD_TIMESTAMP "${THEMIS_BUILD_TIMESTAMP}" CACHE INTERNAL "UTC build list(APPEND THEMIS_GLOBAL_COMPILE_DEFINITIONS THEMIS_BUILD_UUID="${THEMIS_BUILD_UUID}" THEMIS_BUILD_VERSION_STRING="${THEMIS_BUILD_VERSION_STRING}" + THEMIS_VERSION_TYPE="${THEMIS_VERSION_TYPE}" ) option(THEMIS_REQUIRE_REPRODUCIBLE_BUILD @@ -210,6 +211,7 @@ set(THEMIS_GENERATED_INCLUDE_DIR "${CMAKE_BINARY_DIR}/include" CACHE INTERNAL "G message(STATUS "[BuildInfo] version=${THEMIS_BUILD_VERSION_STRING} " + "type=${THEMIS_VERSION_TYPE} " "channel=${THEMIS_BUILD_CHANNEL} " "id=${THEMIS_BUILD_ID} " "uuid=${THEMIS_BUILD_UUID} " diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 8d4e3d4432..f4db514dc2 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -140,22 +140,12 @@ if(NOT THEMIS_ROOT_DIR) endif() # VERSION ist Single-Source-of-Truth: zwingend aus Datei lesen -if(NOT EXISTS "${THEMIS_ROOT_DIR}/VERSION") - message(FATAL_ERROR "VERSION file not found at project root. Please create and set semantic version (e.g., 1.2.3).") -endif() -file(READ "${THEMIS_ROOT_DIR}/VERSION" _ver) -string(STRIP "${_ver}" _ver) -# Accept semantic versions with optional pre-release/build suffixes, but sanitize for CMake's project(VERSION) -if(NOT _ver MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+(.*)?$") - message(FATAL_ERROR "Invalid VERSION content: '${_ver}'. Expected semantic version like 1.2.3") -endif() -# Extract numeric MAJOR.MINOR.PATCH for CMake's version field -string(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" _ver_numeric "${_ver}") -if(NOT _ver_numeric) - message(FATAL_ERROR "Failed to parse numeric version from '${_ver}'") +include("${CMAKE_CURRENT_SOURCE_DIR}/Versions.cmake") +if(NOT DEFINED THEMIS_VERSION_NUMERIC OR "${THEMIS_VERSION_NUMERIC}" STREQUAL "") + message(FATAL_ERROR "Version metadata could not be resolved from ${THEMIS_ROOT_DIR}/VERSION") endif() -project(Themis VERSION ${_ver_numeric} LANGUAGES CXX) +project(Themis VERSION ${THEMIS_VERSION_NUMERIC} LANGUAGES CXX) # Treat uncomponentized install() rules as runtime payload by default. # This keeps third-party DLLs in the runtime component instead of a parallel @@ -164,7 +154,11 @@ set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME runtime) # Make project version available to all translation units if(NOT THEMIS_VERSION_COMPILE_DEF_DEFINED) - add_compile_definitions(THEMIS_VERSION_STRING="${_ver}") + add_compile_definitions( + THEMIS_VERSION_STRING="${THEMIS_VERSION_STRING}" + THEMIS_VERSION="${THEMIS_VERSION}" + THEMIS_VERSION_TYPE="${THEMIS_VERSION_TYPE}" + ) set(THEMIS_VERSION_COMPILE_DEF_DEFINED ON) endif() diff --git a/cmake/Versions.cmake b/cmake/Versions.cmake index a7bd30a43f..c1d1daea2c 100644 --- a/cmake/Versions.cmake +++ b/cmake/Versions.cmake @@ -11,19 +11,43 @@ file(READ "${CMAKE_SOURCE_DIR}/VERSION" THEMIS_VERSION_STRING) string(STRIP "${THEMIS_VERSION_STRING}" THEMIS_VERSION_STRING) # Parse semantic version: MAJOR.MINOR.PATCH[-prerelease][+build] -if(NOT THEMIS_VERSION_STRING MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)$") +set(_themis_version_type_candidate "") +if(NOT THEMIS_VERSION_STRING MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(-([A-Za-z0-9.-]+))?(\\+.*)?$") message(FATAL_ERROR "Invalid VERSION format: '${THEMIS_VERSION_STRING}'\n" "Expected semantic version like: 1.4.0-alpha or 1.4.0+build123") endif() +if(DEFINED CMAKE_MATCH_5 AND NOT "${CMAKE_MATCH_5}" STREQUAL "") + set(_themis_version_type_candidate "${CMAKE_MATCH_5}") +endif() string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" THEMIS_VERSION_NUMERIC "${THEMIS_VERSION_STRING}") +if(NOT THEMIS_VERSION_NUMERIC) + message(FATAL_ERROR "Failed to parse numeric version from '${THEMIS_VERSION_STRING}'") +endif() + set(THEMIS_VERSION "${THEMIS_VERSION_NUMERIC}") +set(THEMIS_VERSION_MAJOR "${CMAKE_MATCH_1}") +set(THEMIS_VERSION_MINOR "${CMAKE_MATCH_2}") +set(THEMIS_VERSION_PATCH "${CMAKE_MATCH_3}") + +set(THEMIS_VERSION_TYPE "stable") + +if(NOT "${_themis_version_type_candidate}" STREQUAL "") + string(TOLOWER "${_themis_version_type_candidate}" _themis_version_type_raw) + string(REGEX REPLACE "[^a-z0-9]+" "" _themis_version_type_normalized "${_themis_version_type_raw}") + if(NOT "${_themis_version_type_normalized}" STREQUAL "") + set(THEMIS_VERSION_TYPE "${_themis_version_type_normalized}") + endif() +endif() # Make version available globally add_compile_definitions( THEMIS_VERSION_STRING="${THEMIS_VERSION_STRING}" THEMIS_VERSION="${THEMIS_VERSION}" + THEMIS_VERSION_TYPE="${THEMIS_VERSION_TYPE}" ) set(THEMIS_VERSION_COMPILE_DEF_DEFINED ON) -message(STATUS "ThemisDB ${THEMIS_VERSION} (${THEMIS_VERSION_STRING})") +set(THEMIS_VERSION_TYPE "${THEMIS_VERSION_TYPE}" CACHE STRING "ThemisDB version type" FORCE) +set(THEMIS_VERSION_NUMERIC "${THEMIS_VERSION_NUMERIC}" CACHE STRING "ThemisDB numeric version" FORCE) +message(STATUS "ThemisDB ${THEMIS_VERSION} (${THEMIS_VERSION_STRING}) [type=${THEMIS_VERSION_TYPE}]")