Browse Source

build: run git-describe for dev version during build (#11117)

This avoids invoking CMake after a new commit, which might take 15s on
some systems.

Skipped on CMake < 3.2.0 (missing BYPRODUCTS support).

Co-Authored-By: Justin M. Keyes <justinkz@gmail.com>
tags/nightly
Daniel Hahler 1 month ago
parent
commit
b18b84df5e
No account linked to committer's email address

+ 0
- 13
CMakeLists.txt View File

@@ -122,19 +122,6 @@ set(NVIM_API_LEVEL 6) # Bump this after any API change.
set(NVIM_API_LEVEL_COMPAT 0) # Adjust this after a _breaking_ API change.
set(NVIM_API_PRERELEASE false)

file(TO_CMAKE_PATH ${CMAKE_CURRENT_LIST_DIR}/.git FORCED_GIT_DIR)
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REFSPEC NVIM_VERSION_COMMIT)
if(NVIM_VERSION_COMMIT) # is a git repo
git_describe(NVIM_VERSION_MEDIUM)
# `git describe` annotates the most recent tagged release; for pre-release
# builds we must replace that with the unreleased version.
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.[0-9]+"
"v${NVIM_VERSION_MAJOR}.${NVIM_VERSION_MINOR}.${NVIM_VERSION_PATCH}"
NVIM_VERSION_MEDIUM
${NVIM_VERSION_MEDIUM})
endif()

set(NVIM_VERSION_BUILD_TYPE "${CMAKE_BUILD_TYPE}")
# NVIM_VERSION_CFLAGS set further below.


+ 1
- 1
ci/before_install.sh View File

@@ -52,7 +52,7 @@ nvm use --lts

if [[ -n "$CMAKE_URL" ]]; then
echo "Installing custom CMake: $CMAKE_URL"
curl --retry 5 --silent --fail -o /tmp/cmake-installer.sh "$CMAKE_URL"
curl --retry 5 --silent --show-error --fail -o /tmp/cmake-installer.sh "$CMAKE_URL"
mkdir -p "$HOME/.local/bin" /opt/cmake-custom
bash /tmp/cmake-installer.sh --prefix=/opt/cmake-custom --skip-license
ln -sfn /opt/cmake-custom/bin/cmake "$HOME/.local/bin/cmake"

+ 0
- 180
cmake/GetGitRevisionDescription.cmake View File

@@ -1,180 +0,0 @@
# https://github.com/rpavlik/cmake-modules
#
# - Returns a version string from Git
#
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
#
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
#
# Returns the refspec and sha hash of the current head revision
#
# git_describe(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
#
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)

if(__get_git_revision_description)
return()
endif()
set(__get_git_revision_description YES)

# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)

function(get_git_dir _gitdir)
# check FORCED_GIT_DIR first
if(FORCED_GIT_DIR)
set(${_gitdir} ${FORCED_GIT_DIR} PARENT_SCOPE)
return()
endif()

# check GIT_DIR in environment
set(GIT_DIR $ENV{GIT_DIR})
if(NOT GIT_DIR)
set(GIT_PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(GIT_DIR ${GIT_PARENT_DIR}/.git)
endif()
# .git dir not found, search parent directories
while(NOT EXISTS ${GIT_DIR})
set(GIT_PREVIOUS_PARENT ${GIT_PARENT_DIR})
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
return()
endif()
set(GIT_DIR ${GIT_PARENT_DIR}/.git)
endwhile()
# check if this is a submodule
if(NOT IS_DIRECTORY ${GIT_DIR})
file(READ ${GIT_DIR} submodule)
string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
endif()
set(${_gitdir} ${GIT_DIR} PARENT_SCOPE)
endfunction()

function(get_git_head_revision _refspecvar _hashvar)
get_git_dir(GIT_DIR)
if(NOT GIT_DIR)
return()
endif()

set(GIT_DATA ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data)
if(NOT EXISTS ${GIT_DATA})
file(MAKE_DIRECTORY ${GIT_DATA})
endif()

if(NOT EXISTS ${GIT_DIR}/HEAD)
return()
endif()
set(HEAD_FILE ${GIT_DATA}/HEAD)
configure_file(${GIT_DIR}/HEAD ${HEAD_FILE} COPYONLY)

configure_file(${_gitdescmoddir}/GetGitRevisionDescription.cmake.in
${GIT_DATA}/grabRef.cmake
@ONLY)
include(${GIT_DATA}/grabRef.cmake)

set(${_refspecvar} ${HEAD_REF} PARENT_SCOPE)
set(${_hashvar} ${HEAD_HASH} PARENT_SCOPE)
endfunction()

function(git_describe _var)
get_git_dir(GIT_DIR)
if(NOT GIT_DIR)
return()
endif()

if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()

get_git_head_revision(refspec hash)
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()

execute_process(COMMAND
${GIT_EXECUTABLE}
describe
${hash}
${ARGN}
WORKING_DIRECTORY
${GIT_DIR}
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()

set(${_var} ${out} PARENT_SCOPE)
endfunction()

function(git_timestamp _var)
get_git_dir(GIT_DIR)
if(NOT GIT_DIR)
return()
endif()

if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
if(NOT GIT_FOUND)
return()
endif()

get_git_head_revision(refspec hash)
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()

execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format="%ci" ${hash} ${ARGN}
WORKING_DIRECTORY ${GIT_DIR}
RESULT_VARIABLE res
OUTPUT_VARIABLE out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(res EQUAL 0)
string(REGEX REPLACE "[-\" :]" "" out ${out})
string(SUBSTRING ${out} 0 12 out)
else()
set(out "${out}-${res}-NOTFOUND")
endif()

set(${_var} ${out} PARENT_SCOPE)
endfunction()

function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
set(${_var} ${out} PARENT_SCOPE)
endfunction()

+ 0
- 38
cmake/GetGitRevisionDescription.cmake.in View File

@@ -1,38 +0,0 @@
#
# Internal file for GetGitRevisionDescription.cmake
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)

set(HEAD_HASH)

file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)

string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
# named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}")
configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
set(HEAD_HASH "${HEAD_REF}")
endif()
else()
# detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()

if(NOT HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()

+ 29
- 0
config/CMakeLists.txt View File

@@ -121,6 +121,35 @@ configure_file (
)

# generate version definitions
if(NVIM_VERSION_MEDIUM)
message(STATUS "NVIM_VERSION_MEDIUM: ${NVIM_VERSION_MEDIUM}")
elseif(${CMAKE_VERSION} VERSION_LESS "3.2.0")
message(STATUS "Skipping version-string generation (requires CMake 3.2.0+)")
elseif(EXISTS ${PROJECT_SOURCE_DIR}/.git)
find_program(GIT_EXECUTABLE git)
if(GIT_EXECUTABLE)
# Get current version.
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --dirty
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE NVIM_VERSION_MEDIUM
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "NVIM_VERSION_MEDIUM (from git): ${NVIM_VERSION_MEDIUM}")

# Create a update_version_stamp target to update the version during build.
file(RELATIVE_PATH relbuild "${PROJECT_SOURCE_DIR}" "${CMAKE_BINARY_DIR}")
add_custom_target(update_version_stamp ALL
COMMAND ${LUA_PRG} scripts/update_version_stamp.lua
${relbuild}/.version_stamp
${relbuild}/config/auto/versiondef.h
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
BYPRODUCTS ${CMAKE_BINARY_DIR}/config/auto/versiondef.h)
add_dependencies(nvim update_version_stamp)
else()
message(STATUS "Skipping version-string generation (cannot find git)")
endif()
endif()

configure_file (
"${PROJECT_SOURCE_DIR}/config/versiondef.h.in"
"${PROJECT_BINARY_DIR}/config/auto/versiondef.h"

+ 45
- 0
scripts/update_version_stamp.lua View File

@@ -0,0 +1,45 @@
#!/usr/bin/env lua
--
-- Script to update the Git version stamp during build.
-- This is called via the custom update_version_stamp target in
-- src/nvim/CMakeLists.txt.
--
-- arg[1]: file containing the last git-describe output
-- arg[2]: file in which to update the version string

local function die(msg)
print(string.format('%s: %s', arg[0], msg))
-- No error, fall back to using generated "-dev" version.
os.exit(0)
end

if #arg ~= 2 then
die(string.format("Expected two args, got %d", #arg))
end

local stampfile = arg[1]
local stamp = io.open(stampfile, 'r')
if stamp then
stamp = stamp:read('*l')
end

local current = io.popen('git describe --dirty'):read('*l')
if not current then
die('git-describe failed')
end

if stamp ~= current then
if stamp then
print(string.format('git version changed: %s -> %s', stamp, current))
end
local new_lines = {}
local versiondeffile = arg[2]
for line in io.lines(versiondeffile) do
if line:match("NVIM_VERSION_MEDIUM") then
line = '#define NVIM_VERSION_MEDIUM "'..current..'"'
end
new_lines[#new_lines + 1] = line
end
io.open(versiondeffile, 'w'):write(table.concat(new_lines, '\n') .. '\n')
io.open(stampfile, 'w'):write(current)
end

Loading…
Cancel
Save