| 1 | = Build Systems |
| 2 | |
| 3 | The build system is the primary way for both developers and system integrators |
| 4 | to interact with the Git project. As such, being easy to use and extend for |
| 5 | those who are not directly developing Git itself is just as important as other |
| 6 | requirements we have on any potential build system. |
| 7 | |
| 8 | This document outlines the different requirements that we have for the build |
| 9 | system and then compares available build systems using these criteria. |
| 10 | |
| 11 | == Requirements |
| 12 | |
| 13 | The following subsections present a list of requirements that we have for any |
| 14 | potential build system. Sections are sorted by decreasing priority. |
| 15 | |
| 16 | === Platform support |
| 17 | |
| 18 | The build system must have support for all of our platforms that we continually |
| 19 | test against as outlined by our platform support policy. These platforms are: |
| 20 | |
| 21 | - Linux |
| 22 | - Windows |
| 23 | - macOS |
| 24 | |
| 25 | Furthermore, the build system should have support for the following platforms |
| 26 | that generally have somebody running test pipelines against regularly: |
| 27 | |
| 28 | - AIX |
| 29 | - FreeBSD |
| 30 | - NetBSD |
| 31 | - NonStop |
| 32 | - OpenBSD |
| 33 | |
| 34 | The platforms which must be supported by the tool should be aligned with our |
| 35 | platform support policy (see platform-support.adoc). |
| 36 | // once we lose AsciiDoc compatibility, we can start writing the above as: |
| 37 | // xref:platform-support.adoc#platform-support-policy[platform support policy] |
| 38 | // or something like that, but until then.... |
| 39 | |
| 40 | === Auto-detection of supported features |
| 41 | |
| 42 | The build system must support auto-detection of features which are or aren't |
| 43 | available on the current platform. Platform maintainers should not be required |
| 44 | to manually configure the complete build. |
| 45 | |
| 46 | Auto-detection of the following items is considered to be important: |
| 47 | |
| 48 | - Check for the existence of headers. |
| 49 | - Check for the existence of libraries. |
| 50 | - Check for the existence of executables. |
| 51 | - Check for the runtime behavior of specific functions. |
| 52 | - Check for specific link order requirements when multiple libraries are |
| 53 | involved. |
| 54 | |
| 55 | === Ease of use |
| 56 | |
| 57 | The build system should be both easy to use and easy to extend. While this is |
| 58 | naturally a subjective metric it is likely not controversial to say that some |
| 59 | build systems are considerably harder to use than others. |
| 60 | |
| 61 | === IDE support |
| 62 | |
| 63 | The build system should integrate with well-known IDEs. Well-known IDEs include: |
| 64 | |
| 65 | - Microsoft Visual Studio |
| 66 | - Visual Studio Code |
| 67 | - Xcode |
| 68 | |
| 69 | There are four levels of support: |
| 70 | |
| 71 | - Native integration into the IDE. |
| 72 | - Integration into the IDE via a plugin. |
| 73 | - Integration into the IDE via generating a project description with the build |
| 74 | system. |
| 75 | - No integration. |
| 76 | |
| 77 | Native integration is preferable, but integration via either a plugin or by |
| 78 | generating a project description via the build system are considered feasible |
| 79 | alternatives. |
| 80 | |
| 81 | Another important distinction is the level of integration. There are two |
| 82 | features that one generally wants to have: |
| 83 | |
| 84 | - Integration of build targets. |
| 85 | - Automatic setup of features like code completion with detected build |
| 86 | dependencies. |
| 87 | |
| 88 | The first bullet point is the bare minimum, but is not sufficient to be |
| 89 | considered proper integration. |
| 90 | |
| 91 | === Out-of-tree builds |
| 92 | |
| 93 | The build system should support out-of-tree builds. Out-of-tree builds allow a |
| 94 | developer to configure multiple different build directories with different |
| 95 | configuration, e.g. one "debug" build and one "release" build. |
| 96 | |
| 97 | === Cross-platform builds |
| 98 | |
| 99 | The build system should support cross-platform builds, e.g. building for arm on |
| 100 | an x86-64 host. |
| 101 | |
| 102 | === Language support |
| 103 | |
| 104 | The following languages and toolchains are of relevance and should be supported |
| 105 | by the build system: |
| 106 | |
| 107 | - C: the primary compiled language used by Git, must be supported. Relevant |
| 108 | toolchains are GCC, Clang and MSVC. |
| 109 | - Rust: candidate as a second compiled language, should be supported. Relevant |
| 110 | toolchains is the LLVM-based rustc. |
| 111 | |
| 112 | Built-in support for the respective languages is preferred over support that |
| 113 | needs to be wired up manually to avoid unnecessary complexity. Native support |
| 114 | includes the following features: |
| 115 | |
| 116 | - Compiling objects. |
| 117 | - Dependency tracking. |
| 118 | - Detection of available features. |
| 119 | - Discovery of relevant toolchains. |
| 120 | - Linking libraries and executables. |
| 121 | - Templating placeholders in scripts. |
| 122 | |
| 123 | === Test integration |
| 124 | |
| 125 | It should be possible to integrate tests into the build system such that it is |
| 126 | possible to build and test Git within the build system. Features which are nice |
| 127 | to have: |
| 128 | |
| 129 | - Track build-time dependencies for respective tests. Unit tests have |
| 130 | different requirements than integration tests. |
| 131 | - Allow filtering of which tests to run. |
| 132 | - Allow running tests such that utilities like `test_pause` or `debug` work. |
| 133 | |
| 134 | == Comparison |
| 135 | |
| 136 | The following list of build systems are considered: |
| 137 | |
| 138 | - GNU Make |
| 139 | - autoconf |
| 140 | - CMake |
| 141 | - Meson |
| 142 | |
| 143 | === GNU Make |
| 144 | |
| 145 | - Platform support: ubiquitous on all platforms, but not well-integrated into Windows. |
| 146 | - Auto-detection: no built-in support for auto-detection of features. |
| 147 | - Ease of use: easy to use, but discovering available options is hard. Makefile |
| 148 | rules can quickly get out of hand once reaching a certain scope. |
| 149 | - IDE support: execution of Makefile targets is supported by many IDEs |
| 150 | - Out-of-tree builds: supported in theory, not wired up in practice. |
| 151 | - Cross-platform builds: supported in theory, not wired up in practice. |
| 152 | - Language support: |
| 153 | - C: Limited built-in support, many parts need to be wired up manually. |
| 154 | - Rust: No built-in support, needs to be wired up manually. |
| 155 | - Test integration: partially supported, many parts need to be wired up |
| 156 | manually. |
| 157 | |
| 158 | === autoconf |
| 159 | |
| 160 | - Platform support: ubiquitous on all platforms, but not well-integrated into Windows. |
| 161 | - Auto-detection: supported. |
| 162 | - Ease of use: easy to use, discovering available options is comparatively |
| 163 | easy. The autoconf syntax is prohibitively hard to extend though due to its |
| 164 | complex set of interacting files and the hard-to-understand M4 language. |
| 165 | - IDE support: no integration into IDEs at generation time. The generated |
| 166 | Makefiles have the same level of support as GNU Make. |
| 167 | - Out-of-tree builds: supported in theory, not wired up in practice. |
| 168 | - Cross-platform builds: supported. |
| 169 | - Language support: |
| 170 | - C: Limited built-in support, many parts need to be wired up manually. |
| 171 | - Rust: No built-in support, needs to be wired up manually. |
| 172 | - Test integration: partially supported, many parts need to be wired up |
| 173 | manually. |
| 174 | |
| 175 | === CMake |
| 176 | |
| 177 | - Platform support: not as extensive as GNU Make or autoconf, but all major |
| 178 | platforms are supported. |
| 179 | - AIX |
| 180 | - Cygwin |
| 181 | - FreeBSD |
| 182 | - Linux |
| 183 | - OpenBSD |
| 184 | - Solaris |
| 185 | - Windows |
| 186 | - macOS |
| 187 | - Ease of use: easy to use, discovering available options is not always |
| 188 | trivial. The scripting language used by CMake is somewhat cumbersome to use, |
| 189 | but extending CMake build instructions is doable. |
| 190 | - IDE support: natively integrated into Microsoft Visual Studio. Can generate |
| 191 | project descriptions for Xcode. An extension is available for Visual Studio |
| 192 | Code. Many other IDEs have plugins for CMake. |
| 193 | - Out-of-tree builds: supported. |
| 194 | - Cross-platform builds: supported. |
| 195 | - Language support: |
| 196 | - C: Supported for GCC, Clang, MSVC and other toolchains. |
| 197 | - Rust: No built-in support, needs to be wired up manually. |
| 198 | - Test integration: supported, even though test dependencies are a bit |
| 199 | cumbersome to use via "test fixtures". Interactive test runs are not |
| 200 | supported. |
| 201 | |
| 202 | === Meson |
| 203 | |
| 204 | - Platform: not as extensive as GNU Make or autoconf, but all major platforms |
| 205 | and some smaller ones are supported. |
| 206 | - AIX |
| 207 | - Cygwin |
| 208 | - DragonflyBSD |
| 209 | - FreeBSD |
| 210 | - Haiku |
| 211 | - Linux |
| 212 | - NetBSD |
| 213 | - OpenBSD |
| 214 | - Solaris |
| 215 | - Windows |
| 216 | - macOS |
| 217 | - Ease of use: easy to use, discovering available options is easy. The |
| 218 | scripting language is straight-forward to use. |
| 219 | - IDE support: Supports generating build instructions for Xcode and Microsoft |
| 220 | Visual Studio, a plugin exists for Visual Studio Code. |
| 221 | - Out-of-tree builds: supported. |
| 222 | - Cross-platform builds: supported. |
| 223 | - Language support: |
| 224 | - C: Supported for GCC, Clang, MSVC and other toolchains. |
| 225 | - Rust: Supported for rustc. |
| 226 | - Test integration: supported. Interactive tests are supported starting with |
| 227 | Meson 1.5.0 via the `--interactive` flag. |