Skip to content

Commit 0e712a7

Browse files
committed
[CMake] Unify scripts for generating VCS headers
Previously, there were two different scripts for generating VCS headers: one used by LLVM and one used by Clang. They were both similar, but different. They were both broken in their own ways, for example the one used by Clang didn't properly handle monorepo resulting in an incorrect version information reported by Clang. This change unifies two the scripts by introducing a new script that's used from both LLVM and Clang, ensures that the new script supports both monorepo and standalone SVN and Git setups, and removes the old scripts. Differential Revision: https://reviews.llvm.org/D57063 llvm-svn: 352729
1 parent b37419e commit 0e712a7

File tree

9 files changed

+205
-366
lines changed

9 files changed

+205
-366
lines changed

clang/lib/Basic/CMakeLists.txt

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,34 @@ set(LLVM_LINK_COMPONENTS
44
Support
55
)
66

7-
find_first_existing_vc_file(llvm_vc "${LLVM_MAIN_SRC_DIR}")
8-
find_first_existing_vc_file(clang_vc "${CLANG_SOURCE_DIR}")
7+
find_first_existing_vc_file("${LLVM_MAIN_SRC_DIR}" llvm_vc)
8+
find_first_existing_vc_file("${CLANG_SOURCE_DIR}" clang_vc)
99

1010
# The VC revision include that we want to generate.
11-
set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/SVNVersion.inc")
11+
set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/VCSRevision.h")
1212

13-
set(get_svn_script "${LLVM_CMAKE_PATH}/GetSVN.cmake")
13+
set(get_svn_script "${LLVM_CMAKE_PATH}/GenerateVersionFromVCS.cmake")
1414

15-
if(DEFINED llvm_vc AND DEFINED clang_vc)
16-
# Create custom target to generate the VC revision include.
17-
add_custom_command(OUTPUT "${version_inc}"
18-
DEPENDS "${llvm_vc}" "${clang_vc}" "${get_svn_script}"
19-
COMMAND
20-
${CMAKE_COMMAND} "-DFIRST_SOURCE_DIR=${LLVM_MAIN_SRC_DIR}"
21-
"-DFIRST_NAME=LLVM"
22-
"-DSECOND_SOURCE_DIR=${CLANG_SOURCE_DIR}"
23-
"-DSECOND_NAME=SVN"
24-
"-DHEADER_FILE=${version_inc}"
25-
-P "${get_svn_script}")
26-
27-
# Mark the generated header as being generated.
28-
set_source_files_properties("${version_inc}"
29-
PROPERTIES GENERATED TRUE
30-
HEADER_FILE_ONLY TRUE)
15+
if(llvm_vc)
16+
set(llvm_source_dir ${LLVM_MAIN_SRC_DIR})
17+
endif()
18+
if(clang_vc)
19+
set(clang_source_dir ${CLANG_SOURCE_DIR})
20+
endif()
3121

32-
# Tell Version.cpp that it needs to build with -DHAVE_SVN_VERSION_INC.
33-
set_source_files_properties(Version.cpp
34-
PROPERTIES COMPILE_DEFINITIONS "HAVE_SVN_VERSION_INC")
35-
else()
36-
# Not producing a VC revision include.
37-
set(version_inc)
22+
# Create custom target to generate the VC revision include.
23+
add_custom_command(OUTPUT "${version_inc}"
24+
DEPENDS "${llvm_vc}" "${clang_vc}" "${get_svn_script}"
25+
COMMAND ${CMAKE_COMMAND} "-DNAMES=LLVM\;CLANG"
26+
"-DLLVM_SOURCE_DIR=${llvm_source_dir}"
27+
"-DCLANG_SOURCE_DIR=${clang_source_dir}"
28+
"-DHEADER_FILE=${version_inc}"
29+
-P "${get_svn_script}")
3830

39-
# Being able to force-set the SVN revision in cases where it isn't available
40-
# is useful for performance tracking, and matches compatibility from autoconf.
41-
if(SVN_REVISION)
42-
set_source_files_properties(Version.cpp
43-
PROPERTIES COMPILE_DEFINITIONS "SVN_REVISION=\"${SVN_REVISION}\"")
44-
endif()
45-
endif()
31+
# Mark the generated header as being generated.
32+
set_source_files_properties("${version_inc}"
33+
PROPERTIES GENERATED TRUE
34+
HEADER_FILE_ONLY TRUE)
4635

4736
add_clang_library(clangBasic
4837
Attributes.cpp

clang/lib/Basic/Version.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,27 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "VCSRevision.h"
1314
#include "clang/Basic/Version.h"
1415
#include "clang/Basic/LLVM.h"
1516
#include "clang/Config/config.h"
1617
#include "llvm/Support/raw_ostream.h"
1718
#include <cstdlib>
1819
#include <cstring>
1920

20-
#ifdef HAVE_SVN_VERSION_INC
21-
# include "SVNVersion.inc"
22-
#endif
23-
2421
namespace clang {
2522

2623
std::string getClangRepositoryPath() {
2724
#if defined(CLANG_REPOSITORY_STRING)
2825
return CLANG_REPOSITORY_STRING;
2926
#else
30-
#ifdef SVN_REPOSITORY
31-
StringRef URL(SVN_REPOSITORY);
27+
#ifdef CLANG_REPOSITORY
28+
StringRef URL(CLANG_REPOSITORY);
3229
#else
3330
StringRef URL("");
3431
#endif
3532

36-
// If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us
33+
// If the CLANG_REPOSITORY is empty, try to use the SVN keyword. This helps us
3734
// pick up a tag in an SVN export, for example.
3835
StringRef SVNRepository("$URL$");
3936
if (URL.empty()) {
@@ -71,8 +68,8 @@ std::string getLLVMRepositoryPath() {
7168
}
7269

7370
std::string getClangRevision() {
74-
#ifdef SVN_REVISION
75-
return SVN_REVISION;
71+
#ifdef CLANG_REVISION
72+
return CLANG_REVISION;
7673
#else
7774
return "";
7875
#endif

llvm/CMakeLists.txt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ endif()
200200
include(VersionFromVCS)
201201

202202
option(LLVM_APPEND_VC_REV
203-
"Embed the version control system revision id in LLVM" ON)
203+
"Embed the version control system revision in LLVM" ON)
204204

205205
set(PACKAGE_NAME LLVM)
206206
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
@@ -752,13 +752,12 @@ set(LLVM_SRPM_USER_BINARY_SPECFILE ${CMAKE_CURRENT_SOURCE_DIR}/llvm.spec.in
752752
set(LLVM_SRPM_BINARY_SPECFILE ${CMAKE_CURRENT_BINARY_DIR}/llvm.spec)
753753
set(LLVM_SRPM_DIR "${CMAKE_CURRENT_BINARY_DIR}/srpm")
754754

755-
# SVN_REVISION and GIT_COMMIT get set by the call to add_version_info_from_vcs.
756-
# DUMMY_VAR contains a version string which we don't care about.
757-
add_version_info_from_vcs(DUMMY_VAR)
758-
if ( SVN_REVISION )
759-
set(LLVM_RPM_SPEC_REVISION "r${SVN_REVISION}")
760-
elseif ( GIT_COMMIT )
761-
set (LLVM_RPM_SPEC_REVISION "g${GIT_COMMIT}")
755+
get_source_info(${CMAKE_CURRENT_SOURCE_DIR} revision repository)
756+
string(LENGTH "${revision}" revision_length)
757+
if(revision MATCHES "^[0-9]+$" AND revision_length LESS 40)
758+
set(LLVM_RPM_SPEC_REVISION "r${revision}")
759+
else()
760+
set(LLVM_RPM_SPEC_REVISION "${revision}")
762761
endif()
763762

764763
configure_file(

llvm/cmake/modules/AddLLVM.cmake

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,35 +1707,35 @@ function(setup_dependency_debugging name)
17071707
set_target_properties(${name} PROPERTIES RULE_LAUNCH_COMPILE ${sandbox_command})
17081708
endfunction()
17091709

1710-
# Figure out if we can track VC revisions.
1711-
function(find_first_existing_file out_var)
1712-
foreach(file ${ARGN})
1713-
if(EXISTS "${file}")
1714-
set(${out_var} "${file}" PARENT_SCOPE)
1715-
return()
1716-
endif()
1717-
endforeach()
1718-
endfunction()
1719-
1720-
macro(find_first_existing_vc_file out_var path)
1721-
find_program(git_executable NAMES git git.exe git.cmd)
1722-
# Run from a subdirectory to force git to print an absolute path.
1723-
execute_process(COMMAND ${git_executable} rev-parse --git-dir
1724-
WORKING_DIRECTORY ${path}/cmake
1725-
RESULT_VARIABLE git_result
1726-
OUTPUT_VARIABLE git_dir
1727-
ERROR_QUIET)
1728-
if(git_result EQUAL 0)
1729-
string(STRIP "${git_dir}" git_dir)
1730-
set(${out_var} "${git_dir}/logs/HEAD")
1731-
# some branchless cases (e.g. 'repo') may not yet have .git/logs/HEAD
1732-
if (NOT EXISTS "${git_dir}/logs/HEAD")
1733-
file(WRITE "${git_dir}/logs/HEAD" "")
1710+
function(find_first_existing_vc_file path out_var)
1711+
if(EXISTS "${path}/.svn")
1712+
set(svn_files
1713+
"${path}/.svn/wc.db" # SVN 1.7
1714+
"${path}/.svn/entries" # SVN 1.6
1715+
)
1716+
foreach(file IN LISTS svn_files)
1717+
if(EXISTS "${file}")
1718+
set(${out_var} "${file}" PARENT_SCOPE)
1719+
return()
1720+
endif()
1721+
endforeach()
1722+
else()
1723+
find_package(Git)
1724+
if(GIT_FOUND)
1725+
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir
1726+
WORKING_DIRECTORY ${path}
1727+
RESULT_VARIABLE git_result
1728+
OUTPUT_VARIABLE git_output
1729+
ERROR_QUIET)
1730+
if(git_result EQUAL 0)
1731+
string(STRIP "${git_output}" git_output)
1732+
get_filename_component(git_dir ${git_output} ABSOLUTE BASE_DIR ${path})
1733+
# Some branchless cases (e.g. 'repo') may not yet have .git/logs/HEAD
1734+
if (NOT EXISTS "${git_dir}/logs/HEAD")
1735+
file(WRITE "${git_dir}/logs/HEAD" "")
1736+
endif()
1737+
set(${out_var} "${git_dir}/logs/HEAD" PARENT_SCOPE)
17341738
endif()
1735-
else()
1736-
find_first_existing_file(${out_var}
1737-
"${path}/.svn/wc.db" # SVN 1.7
1738-
"${path}/.svn/entries" # SVN 1.6
1739-
)
17401739
endif()
1741-
endmacro()
1740+
endif()
1741+
endfunction()

llvm/cmake/modules/GenerateVersionFromCVS.cmake

Lines changed: 0 additions & 39 deletions
This file was deleted.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# CMake script that writes version control information to a header.
2+
#
3+
# Input variables:
4+
# NAMES - A list of names for each of the source directories.
5+
# <NAME>_SOURCE_DIR - A path to source directory for each name in NAMES.
6+
# HEADER_FILE - The header file to write
7+
#
8+
# The output header will contain macros <NAME>_REPOSITORY and <NAME>_REVISION,
9+
# where "<NAME>" is substituted with the names specified in the input variables,
10+
# for each of the <NAME>_SOURCE_DIR given.
11+
12+
get_filename_component(LLVM_DIR "${CMAKE_SCRIPT_MODE_FILE}" PATH)
13+
get_filename_component(LLVM_DIR "${LLVM_DIR}" PATH)
14+
get_filename_component(LLVM_DIR "${LLVM_DIR}" PATH)
15+
16+
list(APPEND CMAKE_MODULE_PATH "${LLVM_DIR}/cmake/modules")
17+
18+
include(VersionFromVCS)
19+
20+
# Handle strange terminals
21+
set(ENV{TERM} "dumb")
22+
23+
function(append_info name path)
24+
if(path)
25+
get_source_info("${path}" revision repository)
26+
endif()
27+
if(revision)
28+
file(APPEND "${HEADER_FILE}.tmp"
29+
"#define ${name}_REVISION \"${revision}\"\n")
30+
else()
31+
file(APPEND "${HEADER_FILE}.tmp"
32+
"#undef ${name}_REVISION\n")
33+
endif()
34+
if(repository)
35+
file(APPEND "${HEADER_FILE}.tmp"
36+
"#define ${name}_REPOSITORY \"${repository}\"\n")
37+
else()
38+
file(APPEND "${HEADER_FILE}.tmp"
39+
"#undef ${name}_REPOSITORY\n")
40+
endif()
41+
endfunction()
42+
43+
foreach(name IN LISTS NAMES)
44+
if(NOT DEFINED ${name}_SOURCE_DIR)
45+
message(FATAL_ERROR "${name}_SOURCE_DIR is not defined")
46+
endif()
47+
append_info(${name} "${${name}_SOURCE_DIR}")
48+
endforeach()
49+
50+
# Copy the file only if it has changed.
51+
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
52+
"${HEADER_FILE}.tmp" "${HEADER_FILE}")
53+
file(REMOVE "${HEADER_FILE}.tmp")

0 commit comments

Comments
 (0)