reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
# 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")