r308205 - [Basic] Detect Git submodule version in CMake

Brian Gesiak via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 17 12:22:57 PDT 2017

Author: modocache
Date: Mon Jul 17 12:22:57 2017
New Revision: 308205

URL: http://llvm.org/viewvc/llvm-project?rev=308205&view=rev
[Basic] Detect Git submodule version in CMake

When searching for Git version control information, libBasic's CMake
checks for the path '.git/logs/HEAD'. However, when LLVM is included as
a Git submodule, this path does not exist. Instead, it contains a '.git'
file with the following:

gitdir: ../../.git/modules/external/llvm

Where '../..' is the relative path to the root repository that contains
the LLVM Git submodule.

Because of this discrepancy, `clang --version` does not output source
control information if built from a Git submodule.

To fix, check whether '.git' is a directory or a file. If it's a
directory, simply use the '.git/logs/HEAD' path. If it's a file, read it
and check for the tell-tale sign of a Git submodule: the text "gitdir:".
If it exists, follow that path and use the 'logs/HEAD' at that location
instead. This allows not only the correct revision information to be
retrieved, but also uses a file that will change with each source
control revision.

Test Plan:
1. Before applying this change, build Clang as a Git submodule in a repository
   that places it in external/clang, and confirm no revision information
   is output when `clang --version` is invoked (just "clang 5.0.0" is
   output, no Git hashes).
2. Apply these changes and build Clang as a Git repository nested under
   llvm/tools/clang, and confirm that `clang --version` displays correct
   version information.
3. Apply these changes and build Clang as a Git submodule using the
   structure described in (1), and confirm version control information
   is output as in (2).

Reviewers: jordan_rose, beanz, probinson

Reviewed By: jordan_rose

Subscribers: chapuni, mgorny, cfe-commits

Differential Revision: https://reviews.llvm.org/D34955


Modified: cfe/trunk/lib/Basic/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/CMakeLists.txt?rev=308205&r1=308204&r2=308205&view=diff
--- cfe/trunk/lib/Basic/CMakeLists.txt (original)
+++ cfe/trunk/lib/Basic/CMakeLists.txt Mon Jul 17 12:22:57 2017
@@ -15,8 +15,23 @@ function(find_first_existing_file out_va
 macro(find_first_existing_vc_file out_var path)
+  set(git_path "${path}/.git")
+  # Normally '.git' is a directory that contains a 'logs/HEAD' file that
+  # is updated as modifications are made to the repository. In case the
+  # repository is a Git submodule, '.git' is a file that contains text that
+  # indicates where the repository's Git directory exists.
+  if (EXISTS "${git_path}" AND NOT IS_DIRECTORY "${git_path}")
+    FILE(READ "${git_path}" file_contents)
+    if("${file_contents}" MATCHES "^gitdir: ([^\n]+)")
+      # '.git' is indeed a link to the submodule's Git directory.
+      # Use the path to that Git directory.
+      set(git_path "${path}/${CMAKE_MATCH_1}")
+    endif()
+  endif()
-    "${path}/.git/logs/HEAD" # Git
+    "${git_path}/logs/HEAD"  # Git or Git submodule
     "${path}/.svn/wc.db"     # SVN 1.7
     "${path}/.svn/entries"   # SVN 1.6

More information about the cfe-commits mailing list