buildinfo.cmake 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. # This is called by cmake as an external process from
  2. # ./source/creator/CMakeLists.txt to write ./source/creator/buildinfo.h
  3. # Caller must define:
  4. # SOURCE_DIR
  5. # Optional overrides:
  6. # BUILD_DATE
  7. # BUILD_TIME
  8. # Extract working copy information for SOURCE_DIR into MY_XXX variables
  9. # with a default in case anything fails, for example when using git-svn
  10. set(MY_WC_HASH "unknown")
  11. set(MY_WC_BRANCH "unknown")
  12. set(MY_WC_COMMIT_TIMESTAMP 0)
  13. # Guess if this is a git working copy and then look up the revision
  14. if(EXISTS ${SOURCE_DIR}/.git)
  15. execute_process(COMMAND git rev-parse --abbrev-ref HEAD
  16. WORKING_DIRECTORY ${SOURCE_DIR}
  17. OUTPUT_VARIABLE MY_WC_BRANCH
  18. OUTPUT_STRIP_TRAILING_WHITESPACE)
  19. if(MY_WC_BRANCH STREQUAL "HEAD")
  20. # Detached HEAD, check whether commit hash is reachable
  21. # in the master branch
  22. execute_process(COMMAND git rev-parse --short HEAD
  23. WORKING_DIRECTORY ${SOURCE_DIR}
  24. OUTPUT_VARIABLE MY_WC_HASH
  25. OUTPUT_STRIP_TRAILING_WHITESPACE)
  26. execute_process(COMMAND git branch --list master blender-v* --contains ${MY_WC_HASH}
  27. WORKING_DIRECTORY ${SOURCE_DIR}
  28. OUTPUT_VARIABLE _git_contains_check
  29. OUTPUT_STRIP_TRAILING_WHITESPACE)
  30. if(NOT _git_contains_check STREQUAL "")
  31. set(MY_WC_BRANCH "master")
  32. else()
  33. execute_process(COMMAND git show-ref --tags -d
  34. WORKING_DIRECTORY ${SOURCE_DIR}
  35. OUTPUT_VARIABLE _git_tag_hashes
  36. OUTPUT_STRIP_TRAILING_WHITESPACE)
  37. execute_process(COMMAND git rev-parse HEAD
  38. WORKING_DIRECTORY ${SOURCE_DIR}
  39. OUTPUT_VARIABLE _git_head_hash
  40. OUTPUT_STRIP_TRAILING_WHITESPACE)
  41. if(_git_tag_hashes MATCHES "${_git_head_hash}")
  42. set(MY_WC_BRANCH "master")
  43. else()
  44. execute_process(COMMAND git branch --contains ${MY_WC_HASH}
  45. WORKING_DIRECTORY ${SOURCE_DIR}
  46. OUTPUT_VARIABLE _git_contains_branches
  47. OUTPUT_STRIP_TRAILING_WHITESPACE)
  48. string(REGEX REPLACE "^\\*[ \t]+" "" _git_contains_branches "${_git_contains_branches}")
  49. string(REGEX REPLACE "[\r\n]+" ";" _git_contains_branches "${_git_contains_branches}")
  50. string(REGEX REPLACE ";[ \t]+" ";" _git_contains_branches "${_git_contains_branches}")
  51. foreach(_branch ${_git_contains_branches})
  52. if(NOT "${_branch}" MATCHES "\\(HEAD.*")
  53. set(MY_WC_BRANCH "${_branch}")
  54. break()
  55. endif()
  56. endforeach()
  57. unset(_branch)
  58. unset(_git_contains_branches)
  59. endif()
  60. unset(_git_tag_hashes)
  61. unset(_git_head_hashs)
  62. endif()
  63. unset(_git_contains_check)
  64. else()
  65. execute_process(COMMAND git log HEAD..@{u}
  66. WORKING_DIRECTORY ${SOURCE_DIR}
  67. OUTPUT_VARIABLE _git_below_check
  68. OUTPUT_STRIP_TRAILING_WHITESPACE
  69. ERROR_QUIET)
  70. if(NOT _git_below_check STREQUAL "")
  71. # If there're commits between HEAD and upstream this means
  72. # that we're reset-ed to older revision. Use it's hash then.
  73. execute_process(COMMAND git rev-parse --short HEAD
  74. WORKING_DIRECTORY ${SOURCE_DIR}
  75. OUTPUT_VARIABLE MY_WC_HASH
  76. OUTPUT_STRIP_TRAILING_WHITESPACE)
  77. else()
  78. execute_process(COMMAND git rev-parse --short @{u}
  79. WORKING_DIRECTORY ${SOURCE_DIR}
  80. OUTPUT_VARIABLE MY_WC_HASH
  81. OUTPUT_STRIP_TRAILING_WHITESPACE
  82. ERROR_QUIET)
  83. if(MY_WC_HASH STREQUAL "")
  84. # Local branch, not set to upstream.
  85. # Well, let's use HEAD for now
  86. execute_process(COMMAND git rev-parse --short HEAD
  87. WORKING_DIRECTORY ${SOURCE_DIR}
  88. OUTPUT_VARIABLE MY_WC_HASH
  89. OUTPUT_STRIP_TRAILING_WHITESPACE)
  90. endif()
  91. endif()
  92. if(MY_WC_BRANCH MATCHES "^blender-v")
  93. set(MY_WC_BRANCH "master")
  94. endif()
  95. unset(_git_below_check)
  96. endif()
  97. execute_process(COMMAND git log -1 --format=%ct
  98. WORKING_DIRECTORY ${SOURCE_DIR}
  99. OUTPUT_VARIABLE MY_WC_COMMIT_TIMESTAMP
  100. OUTPUT_STRIP_TRAILING_WHITESPACE)
  101. # May fail in rare cases
  102. if(MY_WC_COMMIT_TIMESTAMP STREQUAL "")
  103. set(MY_WC_COMMIT_TIMESTAMP 0)
  104. endif()
  105. # Update GIT index before getting dirty files
  106. execute_process(COMMAND git update-index -q --refresh
  107. WORKING_DIRECTORY ${SOURCE_DIR}
  108. OUTPUT_STRIP_TRAILING_WHITESPACE)
  109. execute_process(COMMAND git diff-index --name-only HEAD --
  110. WORKING_DIRECTORY ${SOURCE_DIR}
  111. OUTPUT_VARIABLE _git_changed_files
  112. OUTPUT_STRIP_TRAILING_WHITESPACE)
  113. if(NOT _git_changed_files STREQUAL "")
  114. set(MY_WC_BRANCH "${MY_WC_BRANCH} (modified)")
  115. else()
  116. # Unpushed commits are also considered local modifications
  117. execute_process(COMMAND git log @{u}..
  118. WORKING_DIRECTORY ${SOURCE_DIR}
  119. OUTPUT_VARIABLE _git_unpushed_log
  120. OUTPUT_STRIP_TRAILING_WHITESPACE
  121. ERROR_QUIET)
  122. if(NOT _git_unpushed_log STREQUAL "")
  123. set(MY_WC_BRANCH "${MY_WC_BRANCH} (modified)")
  124. endif()
  125. unset(_git_unpushed_log)
  126. endif()
  127. unset(_git_changed_files)
  128. endif()
  129. # BUILD_PLATFORM and BUILD_PLATFORM are taken from CMake
  130. # but BUILD_DATE and BUILD_TIME are platform dependent
  131. if(UNIX)
  132. if(NOT BUILD_DATE)
  133. execute_process(COMMAND date "+%Y-%m-%d" OUTPUT_VARIABLE BUILD_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
  134. endif()
  135. if(NOT BUILD_TIME)
  136. execute_process(COMMAND date "+%H:%M:%S" OUTPUT_VARIABLE BUILD_TIME OUTPUT_STRIP_TRAILING_WHITESPACE)
  137. endif()
  138. elseif(WIN32)
  139. if(NOT BUILD_DATE)
  140. execute_process(COMMAND cmd /c date /t OUTPUT_VARIABLE BUILD_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
  141. endif()
  142. if(NOT BUILD_TIME)
  143. execute_process(COMMAND cmd /c time /t OUTPUT_VARIABLE BUILD_TIME OUTPUT_STRIP_TRAILING_WHITESPACE)
  144. endif()
  145. endif()
  146. # Write a file with the BUILD_HASH define
  147. file(WRITE buildinfo.h.txt
  148. "#define BUILD_HASH \"${MY_WC_HASH}\"\n"
  149. "#define BUILD_COMMIT_TIMESTAMP ${MY_WC_COMMIT_TIMESTAMP}\n"
  150. "#define BUILD_BRANCH \"${MY_WC_BRANCH}\"\n"
  151. "#define BUILD_DATE \"${BUILD_DATE}\"\n"
  152. "#define BUILD_TIME \"${BUILD_TIME}\"\n"
  153. )
  154. # cleanup
  155. unset(MY_WC_HASH)
  156. unset(MY_WC_COMMIT_TIMESTAMP)
  157. unset(MY_WC_BRANCH)
  158. unset(BUILD_DATE)
  159. unset(BUILD_TIME)
  160. # Copy the file to the final header only if the version changes
  161. # and avoid needless rebuilds
  162. # TODO: verify this comment is true, as BUILD_TIME probably changes
  163. execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
  164. buildinfo.h.txt buildinfo.h)