mdbx-cmake: экспорт/импорт информации о версии в VERSION.json

This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2024-11-12 12:25:51 +03:00
parent 871bb7f56c
commit ab4bf2d7f0
2 changed files with 197 additions and 116 deletions

View File

@ -677,7 +677,7 @@ if(MDBX_BUILD_CXX)
endif()
# Get version
fetch_version(MDBX "${CMAKE_CURRENT_SOURCE_DIR}" FALSE)
fetch_version(MDBX "${CMAKE_CURRENT_SOURCE_DIR}" FALSE "${CMAKE_CURRENT_BINARY_DIR}")
message(STATUS "libmdbx version is ${MDBX_VERSION}")
# sources list

View File

@ -73,201 +73,282 @@ macro(set_source_files_compile_flags)
unset(_lang)
endmacro(set_source_files_compile_flags)
macro(fetch_version name source_root_directory parent_scope)
set(${name}_VERSION "")
set(${name}_GIT_DESCRIBE "")
set(${name}_GIT_TIMESTAMP "")
set(${name}_GIT_TREE "")
set(${name}_GIT_COMMIT "")
set(${name}_GIT_REVISION 0)
set(${name}_GIT_VERSION "")
if(GIT AND EXISTS "${source_root_directory}/.git")
execute_process(COMMAND ${GIT} show --no-patch --format=%cI HEAD
OUTPUT_VARIABLE ${name}_GIT_TIMESTAMP
macro(fetch_version name source_root_directory parent_scope build_directory_for_json_output)
set(_version_4dot "")
set(_git_describe "")
set(_git_timestamp "")
set(_git_tree "")
set(_git_commit "")
set(_git_revision 0)
set(_git_version "")
set(_version_from "")
set(_git_root FALSE)
find_program(GIT git)
if(GIT)
execute_process(COMMAND ${GIT} rev-parse --show-toplevel
OUTPUT_VARIABLE _git_root
ERROR_VARIABLE _git_root_error
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE rc)
if(rc OR "${name}_GIT_TIMESTAMP" STREQUAL "%cI")
RESULT_VARIABLE _rc)
if(_rc OR _git_root STREQUAL "")
if(EXISTS "${source_root_directory}/.git")
message(ERROR "`git rev-parse --show-toplevel` failed '${_git_root_error}'")
else()
message(VERBOSE "`git rev-parse --show-toplevel` failed '${_git_root_error}'")
endif()
else()
set(_source_root "${source_root_directory}")
if(NOT CMAKE_VERSION VERSION_LESS 3.20)
cmake_path(NORMAL_PATH _git_root)
cmake_path(NORMAL_PATH _source_root)
endif()
if(_source_root STREQUAL _git_root AND EXISTS "${_git_root}/VERSION.json")
message(FATAL_ERROR "Несколько источников информации о версии, допустим только один из: репозиторий git, либо файл VERSION.json")
endif()
endif()
endif()
if(EXISTS "${source_root_directory}/VERSION.json")
set(_version_from "${source_root_directory}/VERSION.json")
if(CMAKE_VERSION VERSION_LESS 3.19)
message(FATAL_ERROR "Требуется CMake версии >= 3.19 для чтения VERSION.json")
endif()
file(STRINGS "${_version_from}" _versioninfo_json NEWLINE_CONSUME LIMIT_COUNT 9 LIMIT_INPUT 999 ENCODING UTF-8)
string(JSON _git_describe GET ${_versioninfo_json} git_describe)
string(JSON _git_timestamp GET "${_versioninfo_json}" "git_timestamp")
string(JSON _git_tree GET "${_versioninfo_json}" "git_tree")
string(JSON _git_commit GET "${_versioninfo_json}" "git_commit")
string(JSON _version_4dot GET "${_versioninfo_json}" "version_4dot")
unset(_json_object)
string(REPLACE "." ";" _version_list "${_version_4dot}")
if(NOT _version_4dot)
message(ERROR "Unable to retrieve ${name} version from \"${_version_from}\" file.")
set(_version_list ${_git_version})
string(REPLACE ";" "." _version_4dot "${_git_version}")
else()
string(REPLACE "." ";" _version_list ${_version_4dot})
endif()
elseif(_git_root AND _source_root STREQUAL _git_root)
set(_version_from git)
execute_process(COMMAND ${GIT} show --no-patch --format=%cI HEAD
OUTPUT_VARIABLE _git_timestamp
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE _rc)
if(_rc OR _git_timestamp STREQUAL "%cI")
execute_process(COMMAND ${GIT} show --no-patch --format=%ci HEAD
OUTPUT_VARIABLE ${name}_GIT_TIMESTAMP
OUTPUT_VARIABLE _git_timestamp
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE rc)
if(rc OR "${name}_GIT_TIMESTAMP" STREQUAL "%ci")
RESULT_VARIABLE _rc)
if(_rc OR _git_timestamp STREQUAL "%ci")
message(FATAL_ERROR "Please install latest version of git (`show --no-patch --format=%cI HEAD` failed)")
endif()
endif()
execute_process(COMMAND ${GIT} show --no-patch --format=%T HEAD
OUTPUT_VARIABLE ${name}_GIT_TREE
OUTPUT_VARIABLE _git_tree
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE rc)
if(rc OR "${name}_GIT_TREE" STREQUAL "")
RESULT_VARIABLE _rc)
if(_rc OR _git_tree STREQUAL "")
message(FATAL_ERROR "Please install latest version of git (`show --no-patch --format=%T HEAD` failed)")
endif()
execute_process(COMMAND ${GIT} show --no-patch --format=%H HEAD
OUTPUT_VARIABLE ${name}_GIT_COMMIT
OUTPUT_VARIABLE _git_commit
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE rc)
if(rc OR "${name}_GIT_COMMIT" STREQUAL "")
RESULT_VARIABLE _rc)
if(_rc OR _git_commit STREQUAL "")
message(FATAL_ERROR "Please install latest version of git (`show --no-patch --format=%H HEAD` failed)")
endif()
execute_process(COMMAND ${GIT} rev-list --tags --count
OUTPUT_VARIABLE tag_count
execute_process(COMMAND ${GIT} status --untracked-files=no --porcelain
OUTPUT_VARIABLE _git_status
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE rc)
if(rc)
RESULT_VARIABLE _rc)
if(_rc)
message(FATAL_ERROR "Please install latest version of git (`status --untracked-files=no --porcelain` failed)")
endif()
if(NOT _git_status STREQUAL "")
set(_git_commit "${_git_commit}-dirty")
endif()
unset(_git_status)
execute_process(COMMAND ${GIT} rev-list --tags --count
OUTPUT_VARIABLE _tag_count
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE _rc)
if(_rc)
message(FATAL_ERROR "Please install latest version of git (`git rev-list --tags --count` failed)")
endif()
if(tag_count EQUAL 0)
if(_tag_count EQUAL 0)
execute_process(COMMAND ${GIT} rev-list --all --count
OUTPUT_VARIABLE whole_count
OUTPUT_VARIABLE _whole_count
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE rc)
if(rc)
RESULT_VARIABLE _rc)
if(_rc)
message(FATAL_ERROR "Please install latest version of git (`git rev-list --all --count` failed)")
endif()
if(whole_count GREATER 42)
message(FATAL_ERROR "Please fetch tags (no any tags for ${whole_count} commits)")
if(_whole_count GREATER 42)
message(FATAL_ERROR "Please fetch tags (no any tags for ${_whole_count} commits)")
endif()
set(${name}_GIT_VERSION "0;0;0")
set(_git_version "0;0;0")
execute_process(COMMAND ${GIT} rev-list --count --all --no-merges
OUTPUT_VARIABLE ${name}_GIT_REVISION
OUTPUT_VARIABLE _git_revision
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE rc)
if(rc OR "${name}_GIT_REVISION" STREQUAL "")
RESULT_VARIABLE _rc)
if(_rc OR _git_revision STREQUAL "")
message(FATAL_ERROR "Please install latest version of git (`rev-list --count --all --no-merges` failed)")
endif()
else(tag_count EQUAL 0)
else(_tag_count EQUAL 0)
execute_process(COMMAND ${GIT} describe --tags --long --dirty=-dirty "--match=v[0-9]*"
OUTPUT_VARIABLE ${name}_GIT_DESCRIBE
OUTPUT_VARIABLE _git_describe
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE rc)
if(rc OR "${name}_GIT_DESCRIBE" STREQUAL "")
RESULT_VARIABLE _rc)
if(_rc OR _git_describe STREQUAL "")
execute_process(COMMAND ${GIT} rev-list --all --count
OUTPUT_VARIABLE _whole_count
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE _rc)
if(_rc)
message(FATAL_ERROR "Please install latest version of git (`git rev-list --all --count` failed)")
endif()
if(_whole_count GREATER 42)
message(FATAL_ERROR "Please fetch tags (`describe --tags --long --dirty --match=v[0-9]*` failed)")
else()
execute_process(COMMAND ${GIT} describe --all --long --dirty=-dirty
OUTPUT_VARIABLE ${name}_GIT_DESCRIBE
OUTPUT_VARIABLE _git_describe
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE rc)
if(rc OR "${name}_GIT_DESCRIBE" STREQUAL "")
RESULT_VARIABLE _rc)
if(_rc OR _git_describe STREQUAL "")
message(FATAL_ERROR "Please install latest version of git (`git rev-list --tags --count` and/or `git rev-list --all --count` failed)")
endif()
endif()
endif()
execute_process(COMMAND ${GIT} describe --tags --abbrev=0 "--match=v[0-9]*"
OUTPUT_VARIABLE last_release_tag
OUTPUT_VARIABLE _last_release_tag
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE rc)
if(rc)
RESULT_VARIABLE _rc)
if(_rc)
message(FATAL_ERROR "Please install latest version of git (`describe --tags --abbrev=0 --match=v[0-9]*` failed)")
endif()
if (last_release_tag)
set(git_revlist_arg "${last_release_tag}..HEAD")
if (_last_release_tag)
set(_git_revlist_arg "${_last_release_tag}..HEAD")
else()
execute_process(COMMAND ${GIT} tag --sort=-version:refname
OUTPUT_VARIABLE tag_list
OUTPUT_VARIABLE _tag_list
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE rc)
if(rc)
RESULT_VARIABLE _rc)
if(_rc)
message(FATAL_ERROR "Please install latest version of git (`tag --sort=-version:refname` failed)")
endif()
string(REGEX REPLACE "\n" ";" tag_list "${tag_list}")
set(git_revlist_arg "HEAD")
foreach(tag IN LISTS tag_list)
if(NOT last_release_tag)
string(REGEX MATCH "^v[0-9]+(\.[0-9]+)+" last_release_tag "${tag}")
set(git_revlist_arg "${tag}..HEAD")
string(REGEX REPLACE "\n" ";" _tag_list "${_tag_list}")
set(_git_revlist_arg "HEAD")
foreach(_tag IN LISTS _tag_list)
if(NOT _last_release_tag)
string(REGEX MATCH "^v[0-9]+(\.[0-9]+)+" _last_release_tag "${_tag}")
set(_git_revlist_arg "${_tag}..HEAD")
endif()
endforeach(tag)
endforeach(_tag)
endif()
execute_process(COMMAND ${GIT} rev-list --count "${git_revlist_arg}"
OUTPUT_VARIABLE ${name}_GIT_REVISION
execute_process(COMMAND ${GIT} rev-list --count "${_git_revlist_arg}"
OUTPUT_VARIABLE _git_revision
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${source_root_directory}
RESULT_VARIABLE rc)
if(rc OR "${name}_GIT_REVISION" STREQUAL "")
message(FATAL_ERROR "Please install latest version of git (`rev-list --count ${git_revlist_arg}` failed)")
RESULT_VARIABLE _rc)
if(_rc OR _git_revision STREQUAL "")
message(FATAL_ERROR "Please install latest version of git (`rev-list --count ${_git_revlist_arg}` failed)")
endif()
string(REGEX MATCH "^(v)?([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)?" git_version_valid "${${name}_GIT_DESCRIBE}")
if(git_version_valid)
string(REGEX REPLACE "^(v)?([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)?" "\\2;\\3;\\4" ${name}_GIT_VERSION ${${name}_GIT_DESCRIBE})
string(REGEX MATCH "^(v)?([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)?" _git_version_valid "${_git_describe}")
if(_git_version_valid)
string(REGEX REPLACE "^(v)?([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)?" "\\2;\\3;\\4" _git_version ${_git_describe})
else()
string(REGEX MATCH "^(v)?([0-9]+)\\.([0-9]+)(.*)?" git_version_valid "${${name}_GIT_DESCRIBE}")
if(git_version_valid)
string(REGEX REPLACE "^(v)?([0-9]+)\\.([0-9]+)(.*)?" "\\2;\\3;0" ${name}_GIT_VERSION ${${name}_GIT_DESCRIBE})
string(REGEX MATCH "^(v)?([0-9]+)\\.([0-9]+)(.*)?" _git_version_valid "${_git_describe}")
if(_git_version_valid)
string(REGEX REPLACE "^(v)?([0-9]+)\\.([0-9]+)(.*)?" "\\2;\\3;0" _git_version ${_git_describe})
else()
message(AUTHOR_WARNING "Bad ${name} version \"${${name}_GIT_DESCRIBE}\"; falling back to 0.0.0 (have you made an initial release?)")
set(${name}_GIT_VERSION "0;0;0")
message(AUTHOR_WARNING "Bad ${name} version \"${_git_describe}\"; falling back to 0.0.0 (have you made an initial release?)")
set(_git_version "0;0;0")
endif()
endif()
endif(tag_count EQUAL 0)
endif()
endif(_tag_count EQUAL 0)
if(NOT ${name}_GIT_VERSION OR NOT ${name}_GIT_TIMESTAMP OR ${name}_GIT_REVISION STREQUAL "")
if(GIT AND EXISTS "${source_root_directory}/.git")
message(WARNING "Unable to retrieve ${name} version from git.")
endif()
set(${name}_GIT_VERSION "0;0;0;0")
set(${name}_GIT_TIMESTAMP "")
set(${name}_GIT_REVISION 0)
# Try to get version from VERSION file
set(version_file "${source_root_directory}/VERSION.txt")
if(NOT EXISTS "${version_file}")
set(version_file "${source_root_directory}/VERSION")
endif()
if(EXISTS "${version_file}")
file(STRINGS "${version_file}" ${name}_VERSION LIMIT_COUNT 1 LIMIT_INPUT 42)
endif()
if(NOT ${name}_VERSION)
message(WARNING "Unable to retrieve ${name} version from \"${version_file}\" file.")
set(${name}_VERSION_LIST ${${name}_GIT_VERSION})
string(REPLACE ";" "." ${name}_VERSION "${${name}_GIT_VERSION}")
else()
string(REPLACE "." ";" ${name}_VERSION_LIST ${${name}_VERSION})
endif()
list(APPEND _git_version "${_git_revision}")
set(_version_list "${_git_version}")
string(REPLACE ";" "." _version_4dot "${_version_list}")
elseif(GIT)
message(FATAL_ERROR "Нет источника информации о версии (${source_root_directory}), требуется один из: репозиторий git, либо VERSION.json")
else()
list(APPEND ${name}_GIT_VERSION ${${name}_GIT_REVISION})
set(${name}_VERSION_LIST ${${name}_GIT_VERSION})
string(REPLACE ";" "." ${name}_VERSION "${${name}_GIT_VERSION}")
message(FATAL_ERROR "Требуется git для получения информации о версии")
endif()
list(GET ${name}_VERSION_LIST 0 "${name}_VERSION_MAJOR")
list(GET ${name}_VERSION_LIST 1 "${name}_VERSION_MINOR")
list(GET ${name}_VERSION_LIST 2 "${name}_VERSION_RELEASE")
list(GET ${name}_VERSION_LIST 3 "${name}_VERSION_REVISION")
list(LENGTH _version_list _version_list_length)
list(GET _version_list 0 _version_major)
list(GET _version_list 1 _version_minor)
list(GET _version_list 2 _version_release)
list(GET _version_list 3 _version_revision)
if(NOT _git_describe OR NOT _git_timestamp OR NOT _git_tree OR NOT _git_commit OR _git_revision STREQUAL "" OR NOT _version_list_length EQUAL 4 OR _version_major STREQUAL "" OR _version_minor STREQUAL "" OR _version_release STREQUAL "" OR _version_revision STREQUAL "")
message(ERROR "Unable to retrieve ${name} version from ${_version_from}.")
else()
list(APPEND _git_version "${_git_revision}")
endif()
if(${parent_scope})
set(${name}_VERSION_MAJOR "${${name}_VERSION_MAJOR}" PARENT_SCOPE)
set(${name}_VERSION_MINOR "${${name}_VERSION_MINOR}" PARENT_SCOPE)
set(${name}_VERSION_RELEASE "${${name}_VERSION_RELEASE}" PARENT_SCOPE)
set(${name}_VERSION_REVISION "${${name}_VERSION_REVISION}" PARENT_SCOPE)
set(${name}_VERSION "${${name}_VERSION}" PARENT_SCOPE)
set(${name}_VERSION_MAJOR "${_version_major}" PARENT_SCOPE)
set(${name}_VERSION_MINOR "${_version_minor}" PARENT_SCOPE)
set(${name}_VERSION_RELEASE "${_version_release}" PARENT_SCOPE)
set(${name}_VERSION_REVISION "${_version_revision}" PARENT_SCOPE)
set(${name}_VERSION "${_version_4dot}" PARENT_SCOPE)
set(${name}_GIT_DESCRIBE "${${name}_GIT_DESCRIBE}" PARENT_SCOPE)
set(${name}_GIT_TIMESTAMP "${${name}_GIT_TIMESTAMP}" PARENT_SCOPE)
set(${name}_GIT_TREE "${${name}_GIT_TREE}" PARENT_SCOPE)
set(${name}_GIT_COMMIT "${${name}_GIT_COMMIT}" PARENT_SCOPE)
set(${name}_GIT_REVISION "${${name}_GIT_REVISION}" PARENT_SCOPE)
set(${name}_GIT_VERSION "${${name}_GIT_VERSION}" PARENT_SCOPE)
set(${name}_GIT_DESCRIBE "${_git_describe}" PARENT_SCOPE)
set(${name}_GIT_TIMESTAMP "${_git_timestamp}" PARENT_SCOPE)
set(${name}_GIT_TREE "${_git_tree}" PARENT_SCOPE)
set(${name}_GIT_COMMIT "${_git_commit}" PARENT_SCOPE)
set(${name}_GIT_REVISION "${_git_revision}" PARENT_SCOPE)
else()
set(${name}_VERSION_MAJOR "${_version_major}")
set(${name}_VERSION_MINOR "${_version_minor}")
set(${name}_VERSION_RELEASE "${_version_release}")
set(${name}_VERSION_REVISION "${_version_revision}")
set(${name}_VERSION "${_version_4dot}")
set(${name}_GIT_DESCRIBE "${_git_describe}")
set(${name}_GIT_TIMESTAMP "${_git_timestamp}")
set(${name}_GIT_TREE "${_git_tree}")
set(${name}_GIT_COMMIT "${_git_commit}")
set(${name}_GIT_REVISION "${_git_revision}")
endif()
if(_version_from STREQUAL "git")
string(CONFIGURE "{
\"git_describe\" : \"@_git_describe@\",
\"git_timestamp\" : \"@_git_timestamp@\",
\"git_tree\" : \"@_git_tree@\",
\"git_commit\" : \"@_git_commit@\",
\"version_4dot\" : \"@_version_4dot@\"\n}" _versioninfo_json @ONLY ESCAPE_QUOTES)
file(WRITE "${build_directory_for_json_output}/VERSION.json" "${_versioninfo_json}")
endif()
endmacro(fetch_version)