include(VersionFromVCS)
option(LLVM_APPEND_VC_REV
- "Embed the version control system revision id in LLVM" ON)
+ "Embed the version control system revision in LLVM" ON)
set(PACKAGE_NAME LLVM)
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(LLVM_SRPM_BINARY_SPECFILE ${CMAKE_CURRENT_BINARY_DIR}/llvm.spec)
set(LLVM_SRPM_DIR "${CMAKE_CURRENT_BINARY_DIR}/srpm")
-# SVN_REVISION and GIT_COMMIT get set by the call to add_version_info_from_vcs.
-# DUMMY_VAR contains a version string which we don't care about.
-add_version_info_from_vcs(DUMMY_VAR)
-if ( SVN_REVISION )
- set(LLVM_RPM_SPEC_REVISION "r${SVN_REVISION}")
-elseif ( GIT_COMMIT )
- set (LLVM_RPM_SPEC_REVISION "g${GIT_COMMIT}")
+get_source_info(${CMAKE_CURRENT_SOURCE_DIR} revision repository)
+string(LENGTH "${revision}" revision_length)
+if(revision MATCHES "^[0-9]+$" AND revision_length LESS 40)
+ set(LLVM_RPM_SPEC_REVISION "r${revision}")
+else()
+ set(LLVM_RPM_SPEC_REVISION "${revision}")
endif()
configure_file(
set_target_properties(${name} PROPERTIES RULE_LAUNCH_COMPILE ${sandbox_command})
endfunction()
-# Figure out if we can track VC revisions.
-function(find_first_existing_file out_var)
- foreach(file ${ARGN})
- if(EXISTS "${file}")
- set(${out_var} "${file}" PARENT_SCOPE)
- return()
- endif()
- endforeach()
-endfunction()
-
-macro(find_first_existing_vc_file out_var path)
- find_program(git_executable NAMES git git.exe git.cmd)
- # Run from a subdirectory to force git to print an absolute path.
- execute_process(COMMAND ${git_executable} rev-parse --git-dir
- WORKING_DIRECTORY ${path}/cmake
- RESULT_VARIABLE git_result
- OUTPUT_VARIABLE git_dir
- ERROR_QUIET)
- if(git_result EQUAL 0)
- string(STRIP "${git_dir}" git_dir)
- set(${out_var} "${git_dir}/logs/HEAD")
- # some branchless cases (e.g. 'repo') may not yet have .git/logs/HEAD
- if (NOT EXISTS "${git_dir}/logs/HEAD")
- file(WRITE "${git_dir}/logs/HEAD" "")
+function(find_first_existing_vc_file path out_var)
+ if(EXISTS "${path}/.svn")
+ set(svn_files
+ "${path}/.svn/wc.db" # SVN 1.7
+ "${path}/.svn/entries" # SVN 1.6
+ )
+ foreach(file IN LISTS svn_files)
+ if(EXISTS "${file}")
+ set(${out_var} "${file}" PARENT_SCOPE)
+ return()
+ endif()
+ endforeach()
+ else()
+ find_package(Git)
+ if(GIT_FOUND)
+ execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir
+ WORKING_DIRECTORY ${path}
+ RESULT_VARIABLE git_result
+ OUTPUT_VARIABLE git_output
+ ERROR_QUIET)
+ if(git_result EQUAL 0)
+ string(STRIP "${git_output}" git_output)
+ get_filename_component(git_dir ${git_output} ABSOLUTE BASE_DIR ${path})
+ # Some branchless cases (e.g. 'repo') may not yet have .git/logs/HEAD
+ if (NOT EXISTS "${git_dir}/logs/HEAD")
+ file(WRITE "${git_dir}/logs/HEAD" "")
+ endif()
+ set(${out_var} "${git_dir}/logs/HEAD" PARENT_SCOPE)
endif()
- else()
- find_first_existing_file(${out_var}
- "${path}/.svn/wc.db" # SVN 1.7
- "${path}/.svn/entries" # SVN 1.6
- )
endif()
-endmacro()
+ endif()
+endfunction()
+++ /dev/null
-# CMake project that writes Subversion revision information to a header.
-#
-# Input variables:
-# SRC - Source directory
-# HEADER_FILE - The header file to write
-#
-# The output header will contain macros FIRST_REPOSITORY and FIRST_REVISION,
-# and SECOND_REPOSITORY and SECOND_REVISION if requested, where "FIRST" and
-# "SECOND" are substituted with the names specified in the input variables.
-
-
-
-# Chop off cmake/modules/GetSVN.cmake
-get_filename_component(LLVM_DIR "${CMAKE_SCRIPT_MODE_FILE}" PATH)
-get_filename_component(LLVM_DIR "${LLVM_DIR}" PATH)
-get_filename_component(LLVM_DIR "${LLVM_DIR}" PATH)
-
-set(CMAKE_MODULE_PATH
- ${CMAKE_MODULE_PATH}
- "${LLVM_DIR}/cmake/modules")
-include(VersionFromVCS)
-
-# Handle strange terminals
-set(ENV{TERM} "dumb")
-
-function(append_info name path)
- add_version_info_from_vcs(REVISION ${path})
- string(STRIP "${REVISION}" REVISION)
- file(APPEND "${HEADER_FILE}.txt"
- "#define ${name} \"${REVISION}\"\n")
-endfunction()
-
-append_info(${NAME} "${SOURCE_DIR}")
-
-# Copy the file only if it has changed.
-execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
- "${HEADER_FILE}.txt" "${HEADER_FILE}")
-file(REMOVE "${HEADER_FILE}.txt")
-
--- /dev/null
+# CMake script that writes version control information to a header.
+#
+# Input variables:
+# NAMES - A list of names for each of the source directories.
+# <NAME>_SOURCE_DIR - A path to source directory for each name in NAMES.
+# HEADER_FILE - The header file to write
+#
+# The output header will contain macros <NAME>_REPOSITORY and <NAME>_REVISION,
+# where "<NAME>" is substituted with the names specified in the input variables,
+# for each of the <NAME>_SOURCE_DIR given.
+
+get_filename_component(LLVM_DIR "${CMAKE_SCRIPT_MODE_FILE}" PATH)
+get_filename_component(LLVM_DIR "${LLVM_DIR}" PATH)
+get_filename_component(LLVM_DIR "${LLVM_DIR}" PATH)
+
+list(APPEND CMAKE_MODULE_PATH "${LLVM_DIR}/cmake/modules")
+
+include(VersionFromVCS)
+
+# Handle strange terminals
+set(ENV{TERM} "dumb")
+
+function(append_info name path)
+ if(path)
+ get_source_info("${path}" revision repository)
+ endif()
+ if(revision)
+ file(APPEND "${HEADER_FILE}.tmp"
+ "#define ${name}_REVISION \"${revision}\"\n")
+ else()
+ file(APPEND "${HEADER_FILE}.tmp"
+ "#undef ${name}_REVISION\n")
+ endif()
+ if(repository)
+ file(APPEND "${HEADER_FILE}.tmp"
+ "#define ${name}_REPOSITORY \"${repository}\"\n")
+ else()
+ file(APPEND "${HEADER_FILE}.tmp"
+ "#undef ${name}_REPOSITORY\n")
+ endif()
+endfunction()
+
+foreach(name IN LISTS NAMES)
+ if(NOT DEFINED ${name}_SOURCE_DIR)
+ message(FATAL_ERROR "${name}_SOURCE_DIR is not defined")
+ endif()
+ append_info(${name} "${${name}_SOURCE_DIR}")
+endforeach()
+
+# Copy the file only if it has changed.
+execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "${HEADER_FILE}.tmp" "${HEADER_FILE}")
+file(REMOVE "${HEADER_FILE}.tmp")
+++ /dev/null
-# CMake project that writes Subversion revision information to a header.
-#
-# Input variables:
-# SOURCE_DIRS - A list of source directories.
-# NAMES - A list of macro prefixes for each of the source directories.
-# HEADER_FILE - The header file to write
-#
-# The output header will contain macros <NAME>_REPOSITORY and <NAME>_REVISION,
-# where "<NAME>" and is substituted with the names specified in the input
-# variables, for each of the SOURCE_DIRS given.
-
-# Chop off cmake/modules/GetSVN.cmake
-get_filename_component(LLVM_DIR "${CMAKE_SCRIPT_MODE_FILE}" PATH)
-get_filename_component(LLVM_DIR "${LLVM_DIR}" PATH)
-get_filename_component(LLVM_DIR "${LLVM_DIR}" PATH)
-
-# Handle strange terminals
-set(ENV{TERM} "dumb")
-
-macro(get_source_info_svn path revision repository)
- # If svn is a bat file, find_program(Subversion) doesn't find it.
- # Explicitly search for that here; Subversion_SVN_EXECUTABLE will override
- # the find_program call in FindSubversion.cmake.
- find_program(Subversion_SVN_EXECUTABLE NAMES svn svn.bat)
-
- # FindSubversion does not work with symlinks. See PR 8437
- if (NOT IS_SYMLINK "${path}")
- find_package(Subversion)
- endif()
- if (Subversion_FOUND)
- subversion_wc_info( ${path} Project )
- if (Project_WC_REVISION)
- set(${revision} ${Project_WC_REVISION} PARENT_SCOPE)
- endif()
- if (Project_WC_URL)
- set(${repository} ${Project_WC_URL} PARENT_SCOPE)
- endif()
- endif()
-endmacro()
-
-macro(get_source_info_git_svn path revision repository)
- find_program(git_executable NAMES git git.exe git.cmd)
- if (git_executable)
- execute_process(COMMAND ${git_executable} svn info
- WORKING_DIRECTORY ${path}
- TIMEOUT 5
- RESULT_VARIABLE git_result
- OUTPUT_VARIABLE git_output)
- if (git_result EQUAL 0)
- string(REGEX REPLACE "^(.*\n)?Revision: ([^\n]+).*"
- "\\2" git_svn_rev "${git_output}")
- set(${revision} ${git_svn_rev} PARENT_SCOPE)
- string(REGEX REPLACE "^(.*\n)?URL: ([^\n]+).*"
- "\\2" git_url "${git_output}")
- set(${repository} ${git_url} PARENT_SCOPE)
- endif()
- endif()
-endmacro()
-
-macro(get_source_info_git path revision repository)
- find_program(git_executable NAMES git git.exe git.cmd)
- if (git_executable)
- execute_process(COMMAND ${git_executable} log -1 --pretty=format:%H
- WORKING_DIRECTORY ${path}
- TIMEOUT 5
- RESULT_VARIABLE git_result
- OUTPUT_VARIABLE git_output)
- if (git_result EQUAL 0)
- set(${revision} ${git_output} PARENT_SCOPE)
- endif()
- execute_process(COMMAND ${git_executable} remote -v
- WORKING_DIRECTORY ${path}
- TIMEOUT 5
- RESULT_VARIABLE git_result
- OUTPUT_VARIABLE git_output)
- if (git_result EQUAL 0)
- string(REGEX REPLACE "^(.*\n)?[^ \t]+[ \t]+([^ \t\n]+)[ \t]+\\(fetch\\).*"
- "\\2" git_url "${git_output}")
- set(${repository} "${git_url}" PARENT_SCOPE)
- endif()
- endif()
-endmacro()
-
-function(get_source_info path revision repository)
- if (EXISTS "${path}/.svn")
- get_source_info_svn("${path}" revision repository)
- elseif (EXISTS "${path}/.git/svn/refs")
- get_source_info_git_svn("${path}" revision repository)
- elseif (EXISTS "${path}/.git")
- get_source_info_git("${path}" revision repository)
- endif()
-endfunction()
-
-function(append_info name path)
- get_source_info("${path}" revision repository)
- string(STRIP "${revision}" revision)
- string(STRIP "${repository}" repository)
- file(APPEND "${HEADER_FILE}.txt"
- "#define ${name}_REVISION \"${revision}\"\n")
- file(APPEND "${HEADER_FILE}.txt"
- "#define ${name}_REPOSITORY \"${repository}\"\n")
-endfunction()
-
-function(validate_inputs source_dirs names)
- list(LENGTH source_dirs source_dirs_length)
- list(LENGTH names names_length)
- if (NOT source_dirs_length EQUAL names_length)
- message(FATAL_ERROR
- "GetSVN.cmake takes two arguments: a list of source directories, "
- "and a list of names. Expected two lists must be of equal length, "
- "but got ${source_dirs_length} source directories and "
- "${names_length} names.")
- endif()
-endfunction()
-
-if (DEFINED SOURCE_DIRS AND DEFINED NAMES)
- validate_inputs("${SOURCE_DIRS}" "${NAMES}")
-
- list(LENGTH SOURCE_DIRS source_dirs_length)
- math(EXPR source_dirs_max_index ${source_dirs_length}-1)
- foreach(index RANGE ${source_dirs_max_index})
- list(GET SOURCE_DIRS ${index} source_dir)
- list(GET NAMES ${index} name)
- append_info(${name} ${source_dir})
- endforeach()
-endif()
-
-# Allow -DFIRST_SOURCE_DIR arguments until Clang migrates to the new
-# -DSOURCE_DIRS argument.
-if(DEFINED FIRST_SOURCE_DIR)
- append_info(${FIRST_NAME} "${FIRST_SOURCE_DIR}")
- if(DEFINED SECOND_SOURCE_DIR)
- append_info(${SECOND_NAME} "${SECOND_SOURCE_DIR}")
- endif()
-endif()
-
-# Copy the file only if it has changed.
-execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
- "${HEADER_FILE}.txt" "${HEADER_FILE}")
-file(REMOVE "${HEADER_FILE}.txt")
-
# existence of certain subdirectories under SOURCE_DIR (if provided as an
# extra argument, otherwise uses CMAKE_CURRENT_SOURCE_DIR).
-function(add_version_info_from_vcs VERS)
- SET(SOURCE_DIR ${ARGV1})
- if("${SOURCE_DIR}" STREQUAL "")
- SET(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
- endif()
- string(REPLACE "svn" "" result "${${VERS}}")
- if( EXISTS "${SOURCE_DIR}/.svn" )
- set(result "${result}svn")
- # FindSubversion does not work with symlinks. See PR 8437
- if( NOT IS_SYMLINK "${SOURCE_DIR}" )
- find_package(Subversion)
+function(get_source_info_svn path revision repository)
+ # If svn is a bat file, find_program(Subversion) doesn't find it.
+ # Explicitly search for that here; Subversion_SVN_EXECUTABLE will override
+ # the find_program call in FindSubversion.cmake.
+ find_program(Subversion_SVN_EXECUTABLE NAMES svn svn.bat)
+ find_package(Subversion)
+
+ # Subversion module does not work with symlinks, see PR8437.
+ get_filename_component(realpath ${path} REALPATH)
+ if(Subversion_FOUND)
+ subversion_wc_info(${realpath} Project)
+ if(Project_WC_REVISION)
+ set(${revision} ${Project_WC_REVISION} PARENT_SCOPE)
endif()
- if( Subversion_FOUND )
- subversion_wc_info( ${SOURCE_DIR} Project )
- if( Project_WC_REVISION )
- set(SVN_REVISION ${Project_WC_REVISION} PARENT_SCOPE)
- set(result "${result}-r${Project_WC_REVISION}")
- endif()
- if( Project_WC_URL )
- set(LLVM_REPOSITORY ${Project_WC_URL} PARENT_SCOPE)
- endif()
+ if(Project_WC_URL)
+ set(${repository} ${Project_WC_URL} PARENT_SCOPE)
endif()
- else()
- find_program(git_executable NAMES git git.exe git.cmd)
-
- if( git_executable )
- # Run from a subdirectory to force git to print an absoute path.
- execute_process(COMMAND ${git_executable} rev-parse --git-dir
- WORKING_DIRECTORY ${SOURCE_DIR}/cmake
- RESULT_VARIABLE git_result
- OUTPUT_VARIABLE git_dir
- ERROR_QUIET)
- if(git_result EQUAL 0)
- # Try to get a ref-id
- string(STRIP "${git_dir}" git_dir)
- set(result "${result}git")
- if( EXISTS ${git_dir}/svn )
- # Get the repository URL
- execute_process(COMMAND
- ${git_executable} svn info
- WORKING_DIRECTORY ${SOURCE_DIR}
- TIMEOUT 5
- RESULT_VARIABLE git_result
- OUTPUT_VARIABLE git_output
- ERROR_QUIET)
- if( git_result EQUAL 0 )
- string(REGEX MATCH "URL: ([^ \n]*)" svn_url ${git_output})
- if(svn_url)
- set(LLVM_REPOSITORY ${CMAKE_MATCH_1} PARENT_SCOPE)
- endif()
- endif()
+ endif()
+endfunction()
- # Get the svn revision number for this git commit if one exists.
- execute_process(COMMAND ${git_executable} svn find-rev HEAD
- WORKING_DIRECTORY ${SOURCE_DIR}
- TIMEOUT 5
- RESULT_VARIABLE git_result
- OUTPUT_VARIABLE git_head_svn_rev_number
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if( git_result EQUAL 0 AND git_output)
- set(SVN_REVISION ${git_head_svn_rev_number} PARENT_SCOPE)
- set(git_svn_rev "-svn-${git_head_svn_rev_number}")
- else()
- set(git_svn_rev "")
- endif()
+function(get_source_info_git path revision repository)
+ find_package(Git)
+ if(GIT_FOUND)
+ execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir
+ WORKING_DIRECTORY ${path}
+ RESULT_VARIABLE git_result
+ OUTPUT_VARIABLE git_output
+ ERROR_QUIET)
+ if(git_result EQUAL 0)
+ string(STRIP "${git_output}" git_output)
+ get_filename_component(git_dir ${git_output} ABSOLUTE BASE_DIR ${path})
+ if(EXISTS "${git_dir}/svn/refs")
+ execute_process(COMMAND ${GIT_EXECUTABLE} svn info
+ WORKING_DIRECTORY ${path}
+ RESULT_VARIABLE git_result
+ OUTPUT_VARIABLE git_output)
+ if(git_result EQUAL 0)
+ string(REGEX REPLACE "^(.*\n)?Revision: ([^\n]+).*"
+ "\\2" git_svn_rev "${git_output}")
+ set(${revision} ${git_svn_rev} PARENT_SCOPE)
+ string(REGEX REPLACE "^(.*\n)?URL: ([^\n]+).*"
+ "\\2" git_url "${git_output}")
+ set(${repository} ${git_url} PARENT_SCOPE)
endif()
-
- # Get the git ref id
- execute_process(COMMAND
- ${git_executable} rev-parse --short HEAD
- WORKING_DIRECTORY ${SOURCE_DIR}
- TIMEOUT 5
+ else()
+ execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
+ WORKING_DIRECTORY ${path}
RESULT_VARIABLE git_result
- OUTPUT_VARIABLE git_ref_id
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-
- if( git_result EQUAL 0 )
- set(GIT_COMMIT ${git_ref_id} PARENT_SCOPE)
- set(result "${result}${git_svn_rev}-${git_ref_id}")
+ OUTPUT_VARIABLE git_output)
+ if(git_result EQUAL 0)
+ string(STRIP "${git_output}" git_output)
+ set(${revision} ${git_output} PARENT_SCOPE)
+ endif()
+ execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref --symbolic-full-name @{upstream}
+ WORKING_DIRECTORY ${path}
+ RESULT_VARIABLE git_result
+ OUTPUT_VARIABLE git_output)
+ if(git_result EQUAL 0)
+ string(REPLACE "/" ";" branch ${git_output})
+ list(GET branch 0 remote)
+ execute_process(COMMAND ${GIT_EXECUTABLE} remote get-url ${remote}
+ WORKING_DIRECTORY ${path}
+ RESULT_VARIABLE git_result
+ OUTPUT_VARIABLE git_output)
+ if(git_result EQUAL 0)
+ string(STRIP "${git_output}" git_output)
+ set(${repository} ${git_output} PARENT_SCOPE)
+ endif()
else()
- set(result "${result}${git_svn_rev}")
+ set(${repository} ${path} PARENT_SCOPE)
endif()
endif()
endif()
endif()
- set(${VERS} ${result} PARENT_SCOPE)
-endfunction(add_version_info_from_vcs)
+endfunction()
+
+function(get_source_info path revision repository)
+ if(EXISTS "${path}/.svn")
+ get_source_info_svn("${path}" revision_info repository_info)
+ else()
+ get_source_info_git("${path}" revision_info repository_info)
+ endif()
+ set(${repository} "${repository_info}" PARENT_SCOPE)
+ set(${revision} "${revision_info}" PARENT_SCOPE)
+endfunction()
-find_first_existing_vc_file(llvm_vc "${LLVM_MAIN_SRC_DIR}")
+find_first_existing_vc_file("${LLVM_MAIN_SRC_DIR}" llvm_vc)
# The VC revision include that we want to generate.
set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/VCSRevision.h")
-set(get_svn_script "${LLVM_CMAKE_PATH}/GenerateVersionFromCVS.cmake")
+set(get_svn_script "${LLVM_CMAKE_PATH}/GenerateVersionFromVCS.cmake")
-file(WRITE "${version_inc}.undef" "#undef LLVM_REVISION\n")
-if((DEFINED llvm_vc) AND LLVM_APPEND_VC_REV)
-
- execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files
- "${version_inc}.undef" "${version_inc}"
- RESULT_VARIABLE files_not_equal
- OUTPUT_QUIET
- ERROR_QUIET)
- # Remove ${version_inc} if it doesn't define a revision. This will force it
- # to be regenerated when toggling LLVM_APPEND_VC_REV from OFF to ON.
- if(NOT files_not_equal)
- file(REMOVE "${version_inc}")
- endif()
-
- # Create custom target to generate the VC revision include.
- add_custom_command(OUTPUT "${version_inc}"
- DEPENDS "${llvm_vc}" "${get_svn_script}"
- COMMAND
- ${CMAKE_COMMAND} "-DSOURCE_DIR=${LLVM_MAIN_SRC_DIR}"
- "-DNAME=LLVM_REVISION"
- "-DHEADER_FILE=${version_inc}"
- -P "${get_svn_script}")
-else()
- # Make sure ${version_inc} doesn't define a revision
- execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
- "${version_inc}.undef" "${version_inc}")
+if(llvm_vc AND LLVM_APPEND_VC_REV)
+ set(llvm_source_dir ${LLVM_MAIN_SRC_DIR})
endif()
-file(REMOVE "${version_inc}.undef")
+
+# Create custom target to generate the VC revision include.
+add_custom_command(OUTPUT "${version_inc}"
+ DEPENDS "${llvm_vc}" "${get_svn_script}"
+ COMMAND ${CMAKE_COMMAND} "-DNAMES=LLVM"
+ "-DLLVM_SOURCE_DIR=${llvm_source_dir}"
+ "-DHEADER_FILE=${version_inc}"
+ -P "${get_svn_script}")
# Mark the generated header as being generated.
set_source_files_properties("${version_inc}"