[PATCH] D34955: [Basic] Detect Git submodule version in CMake
modocache added a comment. Awesome, thanks @jordan_rose! https://reviews.llvm.org/D34955 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34955: [Basic] Detect Git submodule version in CMake
jordan_rose accepted this revision. jordan_rose added a comment. This revision is now accepted and ready to land. Whoops, yes, this new version looks good! https://reviews.llvm.org/D34955 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34955: [Basic] Detect Git submodule version in CMake
modocache added a comment. Friendly ping! I'm pretty excited about this change, it helps a pet project of mine, which builds Clang and LLVM checked out as submodules, display correct revision information. Let me know if I can modify this change at all, to make it easier to accept. https://reviews.llvm.org/D34955 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34955: [Basic] Detect Git submodule version in CMake
modocache updated this revision to Diff 106367. modocache added a comment. Use CMAKE_MATCH_0 instead of using REGEX REPLACE. Thanks for the suggestion! https://reviews.llvm.org/D34955 Files: lib/Basic/CMakeLists.txt Index: lib/Basic/CMakeLists.txt === --- lib/Basic/CMakeLists.txt +++ lib/Basic/CMakeLists.txt @@ -15,8 +15,23 @@ endfunction() 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() + find_first_existing_file(${out_var} -"${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 ) Index: lib/Basic/CMakeLists.txt === --- lib/Basic/CMakeLists.txt +++ lib/Basic/CMakeLists.txt @@ -15,8 +15,23 @@ endfunction() 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() + find_first_existing_file(${out_var} -"${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 ) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34955: [Basic] Detect Git submodule version in CMake
jordan_rose added inline comments. Comment at: lib/Basic/CMakeLists.txt:27 +STRING(REGEX REPLACE "\n" "" file_contents "${file_contents}") +if ("${file_contents}" MATCHES "^gitdir:") + # '.git' is indeed a link to the submodule's Git directory. How about ``` if("${file_contents}" MATCHES "^gitdir: ([^\n]+)") set(git_path "${git_path}${CMAKE_MATCH_0}") endif() ``` and then no stripping or replacing later at all? This admittedly doesn't handle some future submodule format that doesn't put `gitdir` on the first line, but neither does the code that's there. (This also doesn't handle absolute path submodule references, but looking around a bit makes it sound like those aren't supposed to occur in practice and are considered bugs when git does generate them. I could be wrong about that though.) https://reviews.llvm.org/D34955 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34955: [Basic] Detect Git submodule version in CMake
modocache updated this revision to Diff 105674. modocache edited the summary of this revision. modocache removed a subscriber: pcc. modocache added a comment. Update commit message. https://reviews.llvm.org/D34955 Files: lib/Basic/CMakeLists.txt Index: lib/Basic/CMakeLists.txt === --- lib/Basic/CMakeLists.txt +++ lib/Basic/CMakeLists.txt @@ -15,8 +15,25 @@ endfunction() 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) +STRING(REGEX REPLACE "\n" "" file_contents "${file_contents}") +if ("${file_contents}" MATCHES "^gitdir:") + # '.git' is indeed a link to the submodule's Git directory. + # Use the path to that Git directory. + STRING(REGEX REPLACE "gitdir: " "" file_contents ${file_contents}) + set(git_path "${git_path}${file_contents}") +endif() + endif() + find_first_existing_file(${out_var} -"${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 ) Index: lib/Basic/CMakeLists.txt === --- lib/Basic/CMakeLists.txt +++ lib/Basic/CMakeLists.txt @@ -15,8 +15,25 @@ endfunction() 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) +STRING(REGEX REPLACE "\n" "" file_contents "${file_contents}") +if ("${file_contents}" MATCHES "^gitdir:") + # '.git' is indeed a link to the submodule's Git directory. + # Use the path to that Git directory. + STRING(REGEX REPLACE "gitdir: " "" file_contents ${file_contents}) + set(git_path "${git_path}${file_contents}") +endif() + endif() + find_first_existing_file(${out_var} -"${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 ) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34955: [Basic] Detect Git submodule version in CMake
modocache updated this revision to Diff 105673. modocache added a comment. Use submodule's .git directory. https://reviews.llvm.org/D34955 Files: lib/Basic/CMakeLists.txt Index: lib/Basic/CMakeLists.txt === --- lib/Basic/CMakeLists.txt +++ lib/Basic/CMakeLists.txt @@ -15,8 +15,25 @@ endfunction() 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) +STRING(REGEX REPLACE "\n" "" file_contents "${file_contents}") +if ("${file_contents}" MATCHES "^gitdir:") + # '.git' is indeed a link to the submodule's Git directory. + # Use the path to that Git directory. + STRING(REGEX REPLACE "gitdir: " "" file_contents ${file_contents}) + set(git_path "${git_path}${file_contents}") +endif() + endif() + find_first_existing_file(${out_var} -"${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 ) Index: lib/Basic/CMakeLists.txt === --- lib/Basic/CMakeLists.txt +++ lib/Basic/CMakeLists.txt @@ -15,8 +15,25 @@ endfunction() 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) +STRING(REGEX REPLACE "\n" "" file_contents "${file_contents}") +if ("${file_contents}" MATCHES "^gitdir:") + # '.git' is indeed a link to the submodule's Git directory. + # Use the path to that Git directory. + STRING(REGEX REPLACE "gitdir: " "" file_contents ${file_contents}) + set(git_path "${git_path}${file_contents}") +endif() + endif() + find_first_existing_file(${out_var} -"${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 ) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34955: [Basic] Detect Git submodule version in CMake
jordan_rose added a comment. I'm not sure why we would care if a commit is made on a branch. The important information here is what commit is checked out, and that's what HEAD refers to. https://reviews.llvm.org/D34955 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34955: [Basic] Detect Git submodule version in CMake
pcc added a comment. FYI, I don't think `HEAD` on its own will work because it is not necessarily updated on every commit, see discussion on https://reviews.llvm.org/D31985. https://reviews.llvm.org/D34955 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34955: [Basic] Detect Git submodule version in CMake
modocache planned changes to this revision. modocache added a comment. Oh, nice catch @jordan_rose, you're absolutely right. I just tried updating my Git submodule reference for Clang and rebuilding my project, but the commit hash shown for Clang didn't change accordingly. I'll need to find a file that changes on every commit. Following the Git submodule path, `gitdir: ../../.git/modules/external/llvm` and checking for `../../.git/modules/external/llvm/HEAD` appears to work. I might rewrite the patch to do that, or try migrating this to use LLVM's source control checking (I think it exists in `llvm/cmake/modules/VersionFromVCS.cmake`). https://reviews.llvm.org/D34955 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34955: [Basic] Detect Git submodule version in CMake
jordan_rose requested changes to this revision. jordan_rose added a comment. This revision now requires changes to proceed. If I'm remembering correctly from when I set this up, this isn't just about detecting which version control system you're using; it's about finding a file //that will change on every commit.// Otherwise, the generated Version.cpp won't be rebuilt after you update. If you don't want to go looking for a better choice for this that would handle submodules, a stopgap answer would be to add a second entry that just looks for `.git` in addition to the one looking for `HEAD`. https://reviews.llvm.org/D34955 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34955: [Basic] Detect Git submodule version in CMake
modocache created this revision. Herald added a subscriber: mgorny. 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. The full '.git/logs/HEAD' path is only used to gate the invocation of LLVM CMake's GetSVN.cmake script, which is invoked using the `LLVM_MAIN_SRC_DIR` and `CLANG_SOURCE_DIR` paths, which point to the right places even when Clang is built as a submodule. Once invoked with these paths, GetSVN.cmake works just fine, and correct version control information is retrieved, even when Clang is built as a submodule. To work around the problem, truncate the path being checked for: just '.git' instead of '.git/logs/HEAD'. 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). https://reviews.llvm.org/D34955 Files: lib/Basic/CMakeLists.txt Index: lib/Basic/CMakeLists.txt === --- lib/Basic/CMakeLists.txt +++ lib/Basic/CMakeLists.txt @@ -16,7 +16,7 @@ macro(find_first_existing_vc_file out_var path) find_first_existing_file(${out_var} -"${path}/.git/logs/HEAD" # Git +"${path}/.git" # Git "${path}/.svn/wc.db" # SVN 1.7 "${path}/.svn/entries" # SVN 1.6 ) Index: lib/Basic/CMakeLists.txt === --- lib/Basic/CMakeLists.txt +++ lib/Basic/CMakeLists.txt @@ -16,7 +16,7 @@ macro(find_first_existing_vc_file out_var path) find_first_existing_file(${out_var} -"${path}/.git/logs/HEAD" # Git +"${path}/.git" # Git "${path}/.svn/wc.db" # SVN 1.7 "${path}/.svn/entries" # SVN 1.6 ) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits