cmake: support git worktree

Use rev-parse to get the HEAD directory instead of manually looking for
it. This method works in the main repository, worktrees and submodules.

Closes https://github.com/espressif/esp-idf/issues/4136
This commit is contained in:
Renz Christian Bagaporo 2019-11-04 20:19:13 +08:00
parent 308e4fcce1
commit e4137cc6ca
2 changed files with 88 additions and 79 deletions

View file

@ -554,6 +554,14 @@ endmenu\n" >> ${IDF_PATH}/Kconfig;
mv CMakeLists.txt.bak CMakeLists.txt mv CMakeLists.txt.bak CMakeLists.txt
rm -rf CMakeLists.txt.bak rm -rf CMakeLists.txt.bak
print_status "Supports git worktree"
clean_build_dir
git branch test_build_system
git worktree add ../esp-idf-template-test test_build_system
diff <(idf.py reconfigure | grep "Project version") <(cd ../esp-idf-template-test && idf.py reconfigure | grep "Project version") \
|| failure "Version on worktree should have been properly resolved"
git worktree remove ../esp-idf-template-test
print_status "All tests completed" print_status "All tests completed"
if [ -n "${FAILURES}" ]; then if [ -n "${FAILURES}" ]; then
echo "Some failures were detected:" echo "Some failures were detected:"

View file

@ -34,7 +34,7 @@
# to get revision of other repositories # to get revision of other repositories
if(__get_git_revision_description) if(__get_git_revision_description)
return() return()
endif() endif()
set(__get_git_revision_description YES) set(__get_git_revision_description YES)
@ -43,95 +43,96 @@ set(__get_git_revision_description YES)
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
function(get_git_head_revision _refspecvar _hashvar _repo_dir) function(get_git_head_revision _refspecvar _hashvar _repo_dir)
set(GIT_PARENT_DIR "${_repo_dir}") execute_process(COMMAND
set(GIT_DIR "${GIT_PARENT_DIR}/.git") "${GIT_EXECUTABLE}"
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories rev-parse
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") --git-dir
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) WORKING_DIRECTORY
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) ${_repo_dir}
# We have reached the root directory, we are not in git RESULT_VARIABLE
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) res
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) OUTPUT_VARIABLE
return() GIT_DIR
endif() ERROR_QUIET
set(GIT_DIR "${GIT_PARENT_DIR}/.git") OUTPUT_STRIP_TRAILING_WHITESPACE)
endwhile()
# check if this is a submodule if(NOT res EQUAL 0)
if(NOT IS_DIRECTORY ${GIT_DIR}) return()
file(READ ${GIT_DIR} submodule) endif()
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(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") get_filename_component(GIT_DIR "${GIT_DIR}" ABSOLUTE BASE_DIR "${_repo_dir}")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
"${GIT_DATA}/grabRef.cmake" if(NOT EXISTS "${GIT_DATA}")
@ONLY) file(MAKE_DIRECTORY "${GIT_DATA}")
include("${GIT_DATA}/grabRef.cmake") endif()
set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) if(NOT EXISTS "${GIT_DIR}/HEAD")
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) 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() endfunction()
function(git_describe _var _repo_dir) function(git_describe _var _repo_dir)
if(NOT GIT_FOUND) if(NOT GIT_FOUND)
find_package(Git QUIET) find_package(Git QUIET)
endif() endif()
get_git_head_revision(refspec hash "${_repo_dir}") get_git_head_revision(refspec hash "${_repo_dir}")
if(NOT GIT_FOUND) if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return() return()
endif() endif()
if(NOT hash) if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return() return()
endif()
endif()
# TODO sanitize # TODO sanitize
#if((${ARGN}" MATCHES "&&") OR #if((${ARGN}" MATCHES "&&") OR
# (ARGN MATCHES "||") OR # (ARGN MATCHES "||") OR
# (ARGN MATCHES "\\;")) # (ARGN MATCHES "\\;"))
# message("Please report the following error to the project!") # message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif() #endif()
#message(STATUS "Arguments to execute_process: ${ARGN}") #message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(COMMAND execute_process(COMMAND
"${GIT_EXECUTABLE}" "${GIT_EXECUTABLE}"
"-C" "-C"
${_repo_dir} ${_repo_dir}
describe describe
"--always" "--always"
"--tags" "--tags"
"--dirty" "--dirty"
${ARGN} ${ARGN}
WORKING_DIRECTORY WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE RESULT_VARIABLE
res res
OUTPUT_VARIABLE OUTPUT_VARIABLE
out out
ERROR_QUIET ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE) OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0) if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND") set(out "${out}-${res}-NOTFOUND")
endif() endif()
set(${_var} "${out}" PARENT_SCOPE) set(${_var} "${out}" PARENT_SCOPE)
endfunction() endfunction()
function(git_get_exact_tag _var _repo_dir) function(git_get_exact_tag _var _repo_dir)
git_describe(out "${_repo_dir}" --exact-match ${ARGN}) git_describe(out "${_repo_dir}" --exact-match ${ARGN})
set(${_var} "${out}" PARENT_SCOPE) set(${_var} "${out}" PARENT_SCOPE)
endfunction() endfunction()