Index: clang/lib/Basic/CMakeLists.txt =================================================================== --- clang/lib/Basic/CMakeLists.txt +++ clang/lib/Basic/CMakeLists.txt @@ -8,42 +8,46 @@ find_first_existing_vc_file(clang_vc "${CLANG_SOURCE_DIR}") # The VC revision include that we want to generate. -set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/SVNVersion.inc") +set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/VCSRevision.h") -set(get_svn_script "${LLVM_CMAKE_PATH}/GetSVN.cmake") +set(get_svn_script "${LLVM_CMAKE_PATH}/GenerateVersionFromVCS.cmake") +file(WRITE "${version_inc}.undef" + "#undef LLVM_REVISION\n" + "#undef LLVM_REPOSITORY\n" + "#undef CLANG_REVISION\n" + "#undef CLANG_REPOSITORY\n") if(DEFINED llvm_vc AND DEFINED clang_vc) + 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. + 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}" "${clang_vc}" "${get_svn_script}" COMMAND - ${CMAKE_COMMAND} "-DFIRST_SOURCE_DIR=${LLVM_MAIN_SRC_DIR}" - "-DFIRST_NAME=LLVM" - "-DSECOND_SOURCE_DIR=${CLANG_SOURCE_DIR}" - "-DSECOND_NAME=SVN" + ${CMAKE_COMMAND} "-DSOURCE_DIRS=${LLVM_MAIN_SRC_DIR}\;${CLANG_SOURCE_DIR}" + "-DNAMES=LLVM\;CLANG" "-DHEADER_FILE=${version_inc}" -P "${get_svn_script}") - - # Mark the generated header as being generated. - set_source_files_properties("${version_inc}" - PROPERTIES GENERATED TRUE - HEADER_FILE_ONLY TRUE) - - # Tell Version.cpp that it needs to build with -DHAVE_SVN_VERSION_INC. - set_source_files_properties(Version.cpp - PROPERTIES COMPILE_DEFINITIONS "HAVE_SVN_VERSION_INC") else() - # Not producing a VC revision include. - set(version_inc) - - # Being able to force-set the SVN revision in cases where it isn't available - # is useful for performance tracking, and matches compatibility from autoconf. - if(SVN_REVISION) - set_source_files_properties(Version.cpp - PROPERTIES COMPILE_DEFINITIONS "SVN_REVISION=\"${SVN_REVISION}\"") - endif() + # Make sure ${version_inc} doesn't define a revision + execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${version_inc}.undef" "${version_inc}") endif() +# Mark the generated header as being generated. +set_source_files_properties("${version_inc}" + PROPERTIES GENERATED TRUE + HEADER_FILE_ONLY TRUE) + add_clang_library(clangBasic Attributes.cpp Builtins.cpp Index: clang/lib/Basic/Version.cpp =================================================================== --- clang/lib/Basic/Version.cpp +++ clang/lib/Basic/Version.cpp @@ -14,26 +14,23 @@ #include "clang/Basic/LLVM.h" #include "clang/Config/config.h" #include "llvm/Support/raw_ostream.h" +#include "VCSRevision.h" #include #include -#ifdef HAVE_SVN_VERSION_INC -# include "SVNVersion.inc" -#endif - namespace clang { std::string getClangRepositoryPath() { #if defined(CLANG_REPOSITORY_STRING) return CLANG_REPOSITORY_STRING; #else -#ifdef SVN_REPOSITORY - StringRef URL(SVN_REPOSITORY); +#ifdef CLANG_REPOSITORY + StringRef URL(CLANG_REPOSITORY); #else StringRef URL(""); #endif - // If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us + // If the CLANG_REPOSITORY is empty, try to use the SVN keyword. This helps us // pick up a tag in an SVN export, for example. StringRef SVNRepository("$URL$"); if (URL.empty()) { @@ -71,8 +68,8 @@ } std::string getClangRevision() { -#ifdef SVN_REVISION - return SVN_REVISION; +#ifdef CLANG_REVISION + return CLANG_REVISION; #else return ""; #endif Index: llvm/CMakeLists.txt =================================================================== --- llvm/CMakeLists.txt +++ llvm/CMakeLists.txt @@ -752,13 +752,11 @@ 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) +if (revision MATCHES "[0-9]+") + set(LLVM_RPM_SPEC_REVISION "r${revision}") +else() + set(LLVM_RPM_SPEC_REVISION "${revision}") endif() configure_file( Index: llvm/cmake/modules/GenerateVersionFromCVS.cmake =================================================================== --- llvm/cmake/modules/GenerateVersionFromCVS.cmake +++ /dev/null @@ -1,39 +0,0 @@ -# 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") - Index: llvm/cmake/modules/GenerateVersionFromVCS.cmake =================================================================== --- /dev/null +++ llvm/cmake/modules/GenerateVersionFromVCS.cmake @@ -0,0 +1,54 @@ +# CMake project that writes version control 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. + +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}) + 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() + +if (DEFINED SOURCE_DIRS AND DEFINED NAMES) + list(LENGTH SOURCE_DIRS source_dirs_length) + list(LENGTH NAMES names_length) + if (NOT source_dirs_length EQUAL names_length) + message(FATAL_ERROR + "GenerateVersionFromVCS.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() + + 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() + +# 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") Index: llvm/cmake/modules/GetSVN.cmake =================================================================== --- llvm/cmake/modules/GetSVN.cmake +++ /dev/null @@ -1,141 +0,0 @@ -# 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 _REPOSITORY and _REVISION, -# where "" 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") - Index: llvm/cmake/modules/VersionFromVCS.cmake =================================================================== --- llvm/cmake/modules/VersionFromVCS.cmake +++ llvm/cmake/modules/VersionFromVCS.cmake @@ -3,90 +3,99 @@ # 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}) +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() - 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) + if (Subversion_FOUND) + subversion_wc_info(${path} 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) + endif() +endmacro() - 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() +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() - # 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() +macro(get_source_info_git path revision repository) + find_package(Git) + if (GIT_FOUND) + # Run from a subdirectory to force git to print an absoute 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) + if (EXISTS "${git_dir}/svn/refs") + 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() - - # Get the git ref id - execute_process(COMMAND - ${git_executable} rev-parse --short HEAD - WORKING_DIRECTORY ${SOURCE_DIR} + else() + execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:%H + WORKING_DIRECTORY ${path} TIMEOUT 5 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}") - else() - set(result "${result}${git_svn_rev}") + 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() endif() endif() - set(${VERS} ${result} PARENT_SCOPE) -endfunction(add_version_info_from_vcs) +endmacro() + +function(get_source_info path revision repository) + if (EXISTS "${path}/.svn") + get_source_info_svn("${path}" revision repository) + else() + get_source_info_git("${path}" revision repository) + endif() +endfunction() Index: llvm/include/llvm/Support/CMakeLists.txt =================================================================== --- llvm/include/llvm/Support/CMakeLists.txt +++ llvm/include/llvm/Support/CMakeLists.txt @@ -3,11 +3,12 @@ # 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") +file(WRITE "${version_inc}.undef" + "#undef LLVM_REVISION\n" + "#undef LLVM_REPOSITORY\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 @@ -23,8 +24,8 @@ add_custom_command(OUTPUT "${version_inc}" DEPENDS "${llvm_vc}" "${get_svn_script}" COMMAND - ${CMAKE_COMMAND} "-DSOURCE_DIR=${LLVM_MAIN_SRC_DIR}" - "-DNAME=LLVM_REVISION" + ${CMAKE_COMMAND} "-DSOURCE_DIRS=${LLVM_MAIN_SRC_DIR}" + "-DNAMES=LLVM" "-DHEADER_FILE=${version_inc}" -P "${get_svn_script}") else()