Merge topic 'cxx-checks-tolerate-unused-arguments'
[kiteware-cmake.git] / Modules / FindGit.cmake
blob08a386a74b92306bd62ceb26da92578132bc6fd6
1 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
4 #[=======================================================================[.rst:
5 FindGit
6 -------
8 The module defines the following variables:
10 ``GIT_EXECUTABLE``
11   Path to Git command-line client.
12 ``Git_FOUND``, ``GIT_FOUND``
13   True if the Git command-line client was found.
14 ``GIT_VERSION_STRING``
15   The version of Git found.
17 .. versionadded:: 3.14
18   The module defines the following ``IMPORTED`` targets (when
19   :prop_gbl:`CMAKE_ROLE` is ``PROJECT``):
21 ``Git::Git``
22   Executable of the Git command-line client.
24 Example usage:
26 .. code-block:: cmake
28    find_package(Git)
29    if(Git_FOUND)
30      message("Git found: ${GIT_EXECUTABLE}")
31    endif()
32 #]=======================================================================]
34 # Look for 'git'
36 set(git_names git)
38 # Prefer .cmd variants on Windows unless running in a Makefile
39 # in the MSYS shell.
41 if(CMAKE_HOST_WIN32)
42   if(NOT CMAKE_GENERATOR MATCHES "MSYS")
43     set(git_names git.cmd git)
44     # GitHub search path for Windows
45     file(GLOB github_path
46       "$ENV{LOCALAPPDATA}/Github/PortableGit*/cmd"
47       "$ENV{LOCALAPPDATA}/Github/PortableGit*/bin"
48       )
49     # SourceTree search path for Windows
50     set(_git_sourcetree_path "$ENV{LOCALAPPDATA}/Atlassian/SourceTree/git_local/bin")
51   endif()
52 endif()
54 # First search the PATH and specific locations.
55 find_program(GIT_EXECUTABLE
56   NAMES ${git_names}
57   PATHS ${github_path} ${_git_sourcetree_path}
58   DOC "Git command line client"
59   )
61 if(CMAKE_HOST_WIN32)
62   # Now look for installations in Git/ directories under typical installation
63   # prefixes on Windows.  Exclude PATH from this search because VS 2017's
64   # command prompt happens to have a PATH entry with a Git/ subdirectory
65   # containing a minimal git not meant for general use.
66   find_program(GIT_EXECUTABLE
67     NAMES ${git_names}
68     PATH_SUFFIXES Git/cmd Git/bin
69     NO_SYSTEM_ENVIRONMENT_PATH
70     DOC "Git command line client"
71     )
72 endif()
74 mark_as_advanced(GIT_EXECUTABLE)
76 unset(git_names)
77 unset(_git_sourcetree_path)
79 if(GIT_EXECUTABLE)
80   # Avoid querying the version if we've already done that this run. For
81   # projects that use things like ExternalProject or FetchContent heavily,
82   # this saving can be measurable on some platforms.
83   #
84   # This is an internal property, projects must not try to use it.
85   # We don't want this stored in the cache because it might still change
86   # between CMake runs, but it shouldn't change during a run for a given
87   # git executable location.
88   set(__doGitVersionCheck TRUE)
89   get_property(__gitVersionProp GLOBAL
90     PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION
91   )
92   if(__gitVersionProp)
93     list(GET __gitVersionProp 0 __gitExe)
94     list(GET __gitVersionProp 1 __gitVersion)
95     if(__gitExe STREQUAL GIT_EXECUTABLE AND NOT __gitVersion STREQUAL "")
96       set(GIT_VERSION_STRING "${__gitVersion}")
97       set(__doGitVersionCheck FALSE)
98     endif()
99     unset(__gitExe)
100     unset(__gitVersion)
101   endif()
102   unset(__gitVersionProp)
104   if(__doGitVersionCheck)
105     execute_process(COMMAND ${GIT_EXECUTABLE} --version
106                     OUTPUT_VARIABLE git_version
107                     ERROR_QUIET
108                     OUTPUT_STRIP_TRAILING_WHITESPACE)
109     if (git_version MATCHES "^git version [0-9]")
110       string(REPLACE "git version " "" GIT_VERSION_STRING "${git_version}")
111       set_property(GLOBAL PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION
112         "${GIT_EXECUTABLE};${GIT_VERSION_STRING}"
113       )
114     endif()
115     unset(git_version)
116   endif()
117   unset(__doGitVersionCheck)
119   get_property(_findgit_role GLOBAL PROPERTY CMAKE_ROLE)
120   if(_findgit_role STREQUAL "PROJECT" AND NOT TARGET Git::Git)
121     add_executable(Git::Git IMPORTED)
122     set_property(TARGET Git::Git PROPERTY IMPORTED_LOCATION "${GIT_EXECUTABLE}")
123   endif()
124   unset(_findgit_role)
125 endif()
127 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
128 find_package_handle_standard_args(Git
129                                   REQUIRED_VARS GIT_EXECUTABLE
130                                   VERSION_VAR GIT_VERSION_STRING)