The seventh batch
[git.git] / meson.build
blobd54184befcf646f4f768dfcd80afd910a70010f4
1 # Meson build system
2 # ==================
4 # The Meson build system is an alternative to our Makefile that you can use to
5 # build, test and install Git. Using Meson results in a couple of benefits:
7 #  - Out-of-tree builds.
8 #  - Better integration into IDEs.
9 #  - Easy-to-use autoconfiguration of available features on your system.
11 # To use Meson from the command line you need to have both Meson and Ninja
12 # installed. Alternatively, if you do not have Python available on your system,
13 # you can also use Muon instead of Meson and Samurai instead of Ninja, both of
14 # which are drop-ins replacement that only depend on C.
16 # Basic usage
17 # ===========
19 # In the most trivial case, you can configure, build and install Git like this:
21 #  1. Set up the build directory. This only needs to happen once per build
22 #     directory you want to have. You can also configure multiple different
23 #     build directories with different configurations.
25 #      $ meson setup build/
27 #     The build directory gets ignored by Git automatically as Meson will write
28 #     a ".gitignore" file into it. From hereon, we will assume that you execute
29 #     commands inside this build directory.
31 # 2. Compile Git. You can either use Meson, Ninja or Samurai to do this, so all
32 #    of the following invocations are equivalent:
34 #      $ meson compile
35 #      $ ninja
36 #      $ samu
38 #   The different invocations should ultimately not make much of a difference.
39 #   Using Meson also works with other generators though, like when the build
40 #   directory has been set up for use with Microsoft Visual Studio.
42 #   Ninja and Samurai use multiple jobs by default, scaling with the number of
43 #   processor cores available. You can pass the `-jN` flag to change this.
45 #   Meson automatically picks up ccache and sccache when these are installed
46 #   when setting up the build directory. You can override this behaviour when
47 #   setting up the build directory by setting the `CC` environment variable to
48 #   your desired compiler.
50 # 3. Execute tests. Again, you can either use Meson, Ninja or Samurai to do this:
52 #      $ meson test
53 #      $ ninja test
54 #      $ samu test
56 #   It is recommended to use Meson in this case though as it also provides you
57 #   additional features that the other build systems don't have available.
58 #   You can e.g. pass additional arguments to the test executables or run
59 #   individual tests:
61 #      # Execute the t0000-basic integration test and t-reftable-stack unit test.
62 #      $ meson test t0000-basic t-reftable-stack
64 #      # Execute all reftable unit tests.
65 #      $ meson test t-reftable-*
67 #      # Execute all tests and stop with the first failure.
68 #      $ meson test --maxfail 1
70 #      # Execute single test interactively such that features like `debug ()` work.
71 #      $ meson test -i --test-args='-ix' t1400-update-ref
73 #   Test execution is parallelized by default and scales with the number of
74 #   processor cores available. You can change the number of processes by passing
75 #   the `-jN` flag to `meson test`.
77 # 4. Install the Git distribution. Again, this can be done via Meson, Ninja or
78 #    Samurai:
80 #      $ meson install
81 #      $ ninja install
82 #      $ samu install
84 #    The prefix into which Git shall be installed is defined when setting up
85 #    the build directory. More on that in the "Configuration" section.
87 # Meson supports multiple backends. The default backend generates Ninja build
88 # instructions, but it also supports the generation of Microsoft Visual
89 # Studio solutions as well as Xcode projects by passing the `--backend` option
90 # to `meson setup`. IDEs like Eclipse and Visual Studio Code provide plugins to
91 # import Meson files directly.
93 # Configuration
94 # =============
96 # The exact configuration of Git is determined when setting up the build
97 # directory via `meson setup`. Unless told otherwise, Meson will automatically
98 # detect the availability of various bits and pieces. There are two different
99 # kinds of options that can be used to further tweak the build:
101 #   - Built-in options provided by Meson.
103 #   - Options defined by the project in the "meson_options.txt" file.
105 # Both kinds of options can be inspected by running `meson configure` in the
106 # build directory, which will give you a list of the current value for all
107 # options.
109 # Options can be configured either when setting up the build directory or can
110 # be changed in preexisting build directories:
112 #      # Set up a new build directory with optimized settings that will be
113 #      # installed into an alternative prefix.
114 #      $ meson setup --buildtype release --optimization 3 --strip --prefix=/home/$USER build
116 #      # Set up a new build directory with a higher warning level. Level 2 is
117 #      # mostly equivalent to setting DEVELOPER=1, level 3 and "everything"
118 #      # will enable even more warnings.
119 #      $ meson setup -Dwarning_level=2 build
121 #      # Set up a new build directory with 'address' and 'undefined' sanitizers
122 #      # using Clang.
123 #      $ CC=clang meson setup -Db_sanitize=address,undefined build
125 #      # Disable tests in a preexisting build directory.
126 #      $ meson configure -Dtests=false
128 #      # Disable features based on Python
129 #      $ meson configure -Dpython=disabled
131 # Options have a type like booleans, choices, strings or features. Features are
132 # somewhat special as they can have one of three values: enabled, disabled or
133 # auto. While the first two values are self-explanatory, "auto" will enable or
134 # disable the feature based on the availability of prerequisites to support it.
135 # Python-based features for example will be enabled automatically when a Python
136 # interpreter could be found. The default value of such features can be changed
137 # via `meson setup --auto-features={enabled,disabled,auto}`, which will set the
138 # value of all features with a value of "auto" to the provided one by default.
140 # It is also possible to store a set of configuration options in machine files.
141 # This can be useful in case you regularly want to reuse the same set of options:
143 #   [binaries]
144 #   c = ['clang']
145 #   ar = ['ar']
147 #   [project options]
148 #   gettext = 'disabled'
149 #   default_editor = 'vim'
151 #   [built-in options]
152 #   b_lto = true
153 #   b_sanitize = 'address,undefined'
155 # These machine files can be passed to `meson setup` via the `--native-file`
156 # option.
158 # Subproject wrappers
159 # ===================
161 # Subproject wrappers are a feature provided by Meson that allows the automatic
162 # fallback to a "wrapped" dependency in case the dependency is not provided by
163 # the system. For example if the system is lacking curl, then Meson will use
164 # "subprojects/curl.wrap" to set up curl as a subproject and compile and link
165 # the dependency into Git itself. This is especially helpful on systems like
166 # Windows, where you typically don't have such dependencies installed.
168 # The use of subproject wrappers can be disabled by executing `meson setup`
169 # with the `--wrap-mode nofallback` option.
171 project('git', 'c',
172   meson_version: '>=0.61.0',
173   # The version is only of cosmetic nature, so if we cannot find a shell yet we
174   # simply don't set up a version at all. This may be the case for example on
175   # Windows systems, where we first have to bootstrap the host environment.
176   version: find_program('sh', required: false).found() ? run_command(
177     'GIT-VERSION-GEN', meson.current_source_dir(), '--format=@GIT_VERSION@',
178     capture: true,
179     check: true,
180   ).stdout().strip() : 'unknown',
181   default_options: [
182     # Git requires C99 with GNU extensions, which of course isn't supported by
183     # MSVC. Funny enough, C99 doesn't work with MSVC either, as it has only
184     # learned to define __STDC_VERSION__ with C11 and later. We thus require
185     # GNU C99 and fall back to C11. Meson only learned to handle the fallback
186     # with version 1.3.0, so on older versions we use GNU C99 unconditionally.
187     'c_std=' + (meson.version().version_compare('>=1.3.0') ? 'gnu99,c11' : 'gnu99'),
188   ],
191 fs = import('fs')
193 program_path = []
194 # Git for Windows provides all the tools we need to build Git.
195 if host_machine.system() == 'windows'
196   program_path += [ 'C:/Program Files/Git/bin', 'C:/Program Files/Git/usr/bin' ]
197 endif
199 cygpath = find_program('cygpath', dirs: program_path, required: false)
200 diff = find_program('diff', dirs: program_path)
201 shell = find_program('sh', dirs: program_path)
202 tar = find_program('tar', dirs: program_path)
204 script_environment = environment()
205 foreach tool : ['cat', 'cut', 'grep', 'sed', 'sort', 'tr', 'uname']
206   program = find_program(tool, dirs: program_path)
207   script_environment.prepend('PATH', fs.parent(program.full_path()))
208 endforeach
210 git = find_program('git', dirs: program_path, required: false)
211 if git.found()
212   script_environment.prepend('PATH', fs.parent(git.full_path()))
213 endif
215 if get_option('sane_tool_path') != ''
216   script_environment.prepend('PATH', get_option('sane_tool_path'))
217 endif
219 # The environment used by GIT-VERSION-GEN. Note that we explicitly override
220 # environment variables that might be set by the user. This is by design so
221 # that we always use whatever Meson has configured instead of what is present
222 # in the environment.
223 version_gen_environment = script_environment
224 version_gen_environment.set('GIT_BUILT_FROM_COMMIT', get_option('built_from_commit'))
225 version_gen_environment.set('GIT_DATE', get_option('build_date'))
226 version_gen_environment.set('GIT_USER_AGENT', get_option('user_agent'))
227 version_gen_environment.set('GIT_VERSION', get_option('version'))
229 compiler = meson.get_compiler('c')
231 libgit_sources = [
232   'abspath.c',
233   'add-interactive.c',
234   'add-patch.c',
235   'advice.c',
236   'alias.c',
237   'alloc.c',
238   'apply.c',
239   'archive-tar.c',
240   'archive-zip.c',
241   'archive.c',
242   'attr.c',
243   'base85.c',
244   'bisect.c',
245   'blame.c',
246   'blob.c',
247   'bloom.c',
248   'branch.c',
249   'bulk-checkin.c',
250   'bundle-uri.c',
251   'bundle.c',
252   'cache-tree.c',
253   'cbtree.c',
254   'chdir-notify.c',
255   'checkout.c',
256   'chunk-format.c',
257   'color.c',
258   'column.c',
259   'combine-diff.c',
260   'commit-graph.c',
261   'commit-reach.c',
262   'commit.c',
263   'compat/nonblock.c',
264   'compat/obstack.c',
265   'compat/terminal.c',
266   'compat/zlib-uncompress2.c',
267   'config.c',
268   'connect.c',
269   'connected.c',
270   'convert.c',
271   'copy.c',
272   'credential.c',
273   'csum-file.c',
274   'ctype.c',
275   'date.c',
276   'decorate.c',
277   'delta-islands.c',
278   'diagnose.c',
279   'diff-delta.c',
280   'diff-merges.c',
281   'diff-lib.c',
282   'diff-no-index.c',
283   'diff.c',
284   'diffcore-break.c',
285   'diffcore-delta.c',
286   'diffcore-order.c',
287   'diffcore-pickaxe.c',
288   'diffcore-rename.c',
289   'diffcore-rotate.c',
290   'dir-iterator.c',
291   'dir.c',
292   'editor.c',
293   'entry.c',
294   'environment.c',
295   'ewah/bitmap.c',
296   'ewah/ewah_bitmap.c',
297   'ewah/ewah_io.c',
298   'ewah/ewah_rlw.c',
299   'exec-cmd.c',
300   'fetch-negotiator.c',
301   'fetch-pack.c',
302   'fmt-merge-msg.c',
303   'fsck.c',
304   'fsmonitor.c',
305   'fsmonitor-ipc.c',
306   'fsmonitor-settings.c',
307   'gettext.c',
308   'git-zlib.c',
309   'gpg-interface.c',
310   'graph.c',
311   'grep.c',
312   'hash-lookup.c',
313   'hashmap.c',
314   'help.c',
315   'hex.c',
316   'hex-ll.c',
317   'hook.c',
318   'ident.c',
319   'json-writer.c',
320   'kwset.c',
321   'levenshtein.c',
322   'line-log.c',
323   'line-range.c',
324   'linear-assignment.c',
325   'list-objects-filter-options.c',
326   'list-objects-filter.c',
327   'list-objects.c',
328   'lockfile.c',
329   'log-tree.c',
330   'loose.c',
331   'ls-refs.c',
332   'mailinfo.c',
333   'mailmap.c',
334   'match-trees.c',
335   'mem-pool.c',
336   'merge-blobs.c',
337   'merge-ll.c',
338   'merge-ort.c',
339   'merge-ort-wrappers.c',
340   'merge-recursive.c',
341   'merge.c',
342   'midx.c',
343   'midx-write.c',
344   'name-hash.c',
345   'negotiator/default.c',
346   'negotiator/noop.c',
347   'negotiator/skipping.c',
348   'notes-cache.c',
349   'notes-merge.c',
350   'notes-utils.c',
351   'notes.c',
352   'object-file-convert.c',
353   'object-file.c',
354   'object-name.c',
355   'object.c',
356   'oid-array.c',
357   'oidmap.c',
358   'oidset.c',
359   'oidtree.c',
360   'pack-bitmap-write.c',
361   'pack-bitmap.c',
362   'pack-check.c',
363   'pack-mtimes.c',
364   'pack-objects.c',
365   'pack-revindex.c',
366   'pack-write.c',
367   'packfile.c',
368   'pager.c',
369   'parallel-checkout.c',
370   'parse.c',
371   'parse-options-cb.c',
372   'parse-options.c',
373   'patch-delta.c',
374   'patch-ids.c',
375   'path.c',
376   'path-walk.c',
377   'pathspec.c',
378   'pkt-line.c',
379   'preload-index.c',
380   'pretty.c',
381   'prio-queue.c',
382   'progress.c',
383   'promisor-remote.c',
384   'prompt.c',
385   'protocol.c',
386   'protocol-caps.c',
387   'prune-packed.c',
388   'pseudo-merge.c',
389   'quote.c',
390   'range-diff.c',
391   'reachable.c',
392   'read-cache.c',
393   'rebase-interactive.c',
394   'rebase.c',
395   'ref-filter.c',
396   'reflog-walk.c',
397   'reflog.c',
398   'refs.c',
399   'refs/debug.c',
400   'refs/files-backend.c',
401   'refs/reftable-backend.c',
402   'refs/iterator.c',
403   'refs/packed-backend.c',
404   'refs/ref-cache.c',
405   'refspec.c',
406   'reftable/basics.c',
407   'reftable/error.c',
408   'reftable/block.c',
409   'reftable/blocksource.c',
410   'reftable/iter.c',
411   'reftable/merged.c',
412   'reftable/pq.c',
413   'reftable/reader.c',
414   'reftable/record.c',
415   'reftable/stack.c',
416   'reftable/system.c',
417   'reftable/tree.c',
418   'reftable/writer.c',
419   'remote.c',
420   'replace-object.c',
421   'repo-settings.c',
422   'repository.c',
423   'rerere.c',
424   'reset.c',
425   'resolve-undo.c',
426   'revision.c',
427   'run-command.c',
428   'send-pack.c',
429   'sequencer.c',
430   'serve.c',
431   'server-info.c',
432   'setup.c',
433   'shallow.c',
434   'sideband.c',
435   'sigchain.c',
436   'sparse-index.c',
437   'split-index.c',
438   'stable-qsort.c',
439   'statinfo.c',
440   'strbuf.c',
441   'streaming.c',
442   'string-list.c',
443   'strmap.c',
444   'strvec.c',
445   'sub-process.c',
446   'submodule-config.c',
447   'submodule.c',
448   'symlinks.c',
449   'tag.c',
450   'tempfile.c',
451   'thread-utils.c',
452   'tmp-objdir.c',
453   'trace.c',
454   'trace2.c',
455   'trace2/tr2_cfg.c',
456   'trace2/tr2_cmd_name.c',
457   'trace2/tr2_ctr.c',
458   'trace2/tr2_dst.c',
459   'trace2/tr2_sid.c',
460   'trace2/tr2_sysenv.c',
461   'trace2/tr2_tbuf.c',
462   'trace2/tr2_tgt_event.c',
463   'trace2/tr2_tgt_normal.c',
464   'trace2/tr2_tgt_perf.c',
465   'trace2/tr2_tls.c',
466   'trace2/tr2_tmr.c',
467   'trailer.c',
468   'transport-helper.c',
469   'transport.c',
470   'tree-diff.c',
471   'tree-walk.c',
472   'tree.c',
473   'unpack-trees.c',
474   'upload-pack.c',
475   'url.c',
476   'urlmatch.c',
477   'usage.c',
478   'userdiff.c',
479   'utf8.c',
480   'varint.c',
481   'versioncmp.c',
482   'walker.c',
483   'wildmatch.c',
484   'worktree.c',
485   'wrapper.c',
486   'write-or-die.c',
487   'ws.c',
488   'wt-status.c',
489   'xdiff-interface.c',
490   'xdiff/xdiffi.c',
491   'xdiff/xemit.c',
492   'xdiff/xhistogram.c',
493   'xdiff/xmerge.c',
494   'xdiff/xpatience.c',
495   'xdiff/xprepare.c',
496   'xdiff/xutils.c',
499 libgit_sources += custom_target(
500   input: 'command-list.txt',
501   output: 'command-list.h',
502   command: [shell, meson.current_source_dir() + '/generate-cmdlist.sh', meson.current_source_dir(), '@OUTPUT@'],
503   env: script_environment,
506 builtin_sources = [
507   'builtin/add.c',
508   'builtin/am.c',
509   'builtin/annotate.c',
510   'builtin/apply.c',
511   'builtin/archive.c',
512   'builtin/bisect.c',
513   'builtin/blame.c',
514   'builtin/branch.c',
515   'builtin/bugreport.c',
516   'builtin/bundle.c',
517   'builtin/cat-file.c',
518   'builtin/check-attr.c',
519   'builtin/check-ignore.c',
520   'builtin/check-mailmap.c',
521   'builtin/check-ref-format.c',
522   'builtin/checkout--worker.c',
523   'builtin/checkout-index.c',
524   'builtin/checkout.c',
525   'builtin/clean.c',
526   'builtin/clone.c',
527   'builtin/column.c',
528   'builtin/commit-graph.c',
529   'builtin/commit-tree.c',
530   'builtin/commit.c',
531   'builtin/config.c',
532   'builtin/count-objects.c',
533   'builtin/credential-cache--daemon.c',
534   'builtin/credential-cache.c',
535   'builtin/credential-store.c',
536   'builtin/credential.c',
537   'builtin/describe.c',
538   'builtin/diagnose.c',
539   'builtin/diff-files.c',
540   'builtin/diff-index.c',
541   'builtin/diff-tree.c',
542   'builtin/diff.c',
543   'builtin/difftool.c',
544   'builtin/fast-export.c',
545   'builtin/fast-import.c',
546   'builtin/fetch-pack.c',
547   'builtin/fetch.c',
548   'builtin/fmt-merge-msg.c',
549   'builtin/for-each-ref.c',
550   'builtin/for-each-repo.c',
551   'builtin/fsck.c',
552   'builtin/fsmonitor--daemon.c',
553   'builtin/gc.c',
554   'builtin/get-tar-commit-id.c',
555   'builtin/grep.c',
556   'builtin/hash-object.c',
557   'builtin/help.c',
558   'builtin/hook.c',
559   'builtin/index-pack.c',
560   'builtin/init-db.c',
561   'builtin/interpret-trailers.c',
562   'builtin/log.c',
563   'builtin/ls-files.c',
564   'builtin/ls-remote.c',
565   'builtin/ls-tree.c',
566   'builtin/mailinfo.c',
567   'builtin/mailsplit.c',
568   'builtin/merge-base.c',
569   'builtin/merge-file.c',
570   'builtin/merge-index.c',
571   'builtin/merge-ours.c',
572   'builtin/merge-recursive.c',
573   'builtin/merge-tree.c',
574   'builtin/merge.c',
575   'builtin/mktag.c',
576   'builtin/mktree.c',
577   'builtin/multi-pack-index.c',
578   'builtin/mv.c',
579   'builtin/name-rev.c',
580   'builtin/notes.c',
581   'builtin/pack-objects.c',
582   'builtin/pack-redundant.c',
583   'builtin/pack-refs.c',
584   'builtin/patch-id.c',
585   'builtin/prune-packed.c',
586   'builtin/prune.c',
587   'builtin/pull.c',
588   'builtin/push.c',
589   'builtin/range-diff.c',
590   'builtin/read-tree.c',
591   'builtin/rebase.c',
592   'builtin/receive-pack.c',
593   'builtin/reflog.c',
594   'builtin/refs.c',
595   'builtin/remote-ext.c',
596   'builtin/remote-fd.c',
597   'builtin/remote.c',
598   'builtin/repack.c',
599   'builtin/replace.c',
600   'builtin/replay.c',
601   'builtin/rerere.c',
602   'builtin/reset.c',
603   'builtin/rev-list.c',
604   'builtin/rev-parse.c',
605   'builtin/revert.c',
606   'builtin/rm.c',
607   'builtin/send-pack.c',
608   'builtin/shortlog.c',
609   'builtin/show-branch.c',
610   'builtin/show-index.c',
611   'builtin/show-ref.c',
612   'builtin/sparse-checkout.c',
613   'builtin/stash.c',
614   'builtin/stripspace.c',
615   'builtin/submodule--helper.c',
616   'builtin/symbolic-ref.c',
617   'builtin/tag.c',
618   'builtin/unpack-file.c',
619   'builtin/unpack-objects.c',
620   'builtin/update-index.c',
621   'builtin/update-ref.c',
622   'builtin/update-server-info.c',
623   'builtin/upload-archive.c',
624   'builtin/upload-pack.c',
625   'builtin/var.c',
626   'builtin/verify-commit.c',
627   'builtin/verify-pack.c',
628   'builtin/verify-tag.c',
629   'builtin/worktree.c',
630   'builtin/write-tree.c',
633 builtin_sources += custom_target(
634   output: 'config-list.h',
635   command: [
636     shell,
637     meson.current_source_dir() + '/generate-configlist.sh',
638     meson.current_source_dir(),
639     '@OUTPUT@',
640   ],
641   env: script_environment,
644 builtin_sources += custom_target(
645   input: 'Documentation/githooks.txt',
646   output: 'hook-list.h',
647   command: [
648     shell,
649     meson.current_source_dir() + '/generate-hooklist.sh',
650     meson.current_source_dir(),
651     '@OUTPUT@',
652   ],
653   env: script_environment,
656 # This contains the variables for GIT-BUILD-OPTIONS, which we use to propagate
657 # build options to our tests.
658 build_options_config = configuration_data()
659 build_options_config.set('GIT_INTEROP_MAKE_OPTS', '')
660 build_options_config.set('GIT_PERF_LARGE_REPO', '')
661 build_options_config.set('GIT_PERF_MAKE_COMMAND', '')
662 build_options_config.set('GIT_PERF_MAKE_OPTS', '')
663 build_options_config.set('GIT_PERF_REPEAT_COUNT', '')
664 build_options_config.set('GIT_PERF_REPO', '')
665 build_options_config.set('GIT_TEST_CMP_USE_COPIED_CONTEXT', '')
666 build_options_config.set('GIT_TEST_INDEX_VERSION', '')
667 build_options_config.set('GIT_TEST_OPTS', '')
668 build_options_config.set('GIT_TEST_PERL_FATAL_WARNINGS', '')
669 build_options_config.set('GIT_TEST_UTF8_LOCALE', '')
670 build_options_config.set_quoted('LOCALEDIR', fs.as_posix(get_option('prefix') / get_option('localedir')))
671 build_options_config.set('GITWEBDIR', fs.as_posix(get_option('prefix') / get_option('datadir') / 'gitweb'))
673 if get_option('breaking_changes')
674   build_options_config.set('WITH_BREAKING_CHANGES', 'YesPlease')
675 else
676   build_options_config.set('WITH_BREAKING_CHANGES', '')
677 endif
679 if get_option('sane_tool_path') != ''
680   build_options_config.set_quoted('BROKEN_PATH_FIX', 's|^\# @BROKEN_PATH_FIX@$|git_broken_path_fix "' + get_option('sane_tool_path') + '"|')
681 else
682   build_options_config.set_quoted('BROKEN_PATH_FIX', '/^\# @BROKEN_PATH_FIX@$/d')
683 endif
685 test_output_directory = get_option('test_output_directory')
686 if test_output_directory == ''
687   test_output_directory = meson.project_build_root() / 'test-output'
688 endif
690 # These variables are used for building libgit.a.
691 libgit_c_args = [
692   '-DBINDIR="' + get_option('bindir') + '"',
693   '-DDEFAULT_EDITOR="' + get_option('default_editor') + '"',
694   '-DDEFAULT_GIT_TEMPLATE_DIR="' + get_option('datadir') / 'git-core/templates' + '"',
695   '-DDEFAULT_HELP_FORMAT="' + get_option('default_help_format') + '"',
696   '-DDEFAULT_PAGER="' + get_option('default_pager') + '"',
697   '-DETC_GITATTRIBUTES="' + get_option('gitattributes') + '"',
698   '-DETC_GITCONFIG="' + get_option('gitconfig') + '"',
699   '-DFALLBACK_RUNTIME_PREFIX="' + get_option('prefix') + '"',
700   '-DGIT_EXEC_PATH="' + get_option('prefix') / get_option('libexecdir') / 'git-core"',
701   '-DGIT_HOST_CPU="' + host_machine.cpu_family() + '"',
702   '-DGIT_HTML_PATH="' + get_option('datadir') / 'doc/git-doc"',
703   '-DGIT_INFO_PATH="' + get_option('infodir') + '"',
704   '-DGIT_LOCALE_PATH="' + get_option('localedir') + '"',
705   '-DGIT_MAN_PATH="' + get_option('mandir') + '"',
706   '-DPAGER_ENV="' + get_option('pager_environment') + '"',
707   '-DSHELL_PATH="' + fs.as_posix(shell.full_path()) + '"',
709 libgit_include_directories = [ '.' ]
710 libgit_dependencies = [ ]
712 # Treat any warning level above 1 the same as we treat DEVELOPER=1 in our
713 # Makefile.
714 if get_option('warning_level') in ['2','3', 'everything'] and compiler.get_argument_syntax() == 'gcc'
715   foreach cflag : [
716     '-Wdeclaration-after-statement',
717     '-Wformat-security',
718     '-Wold-style-definition',
719     '-Woverflow',
720     '-Wpointer-arith',
721     '-Wstrict-prototypes',
722     '-Wunused',
723     '-Wvla',
724     '-Wwrite-strings',
725     '-fno-common',
726     '-Wtautological-constant-out-of-range-compare',
727     # If a function is public, there should be a prototype and the right
728     # header file should be included. If not, it should be static.
729     '-Wmissing-prototypes',
730     # These are disabled because we have these all over the place.
731     '-Wno-empty-body',
732     '-Wno-missing-field-initializers',
733   ]
734     if compiler.has_argument(cflag)
735       libgit_c_args += cflag
736     endif
737   endforeach
738 endif
740 if get_option('b_sanitize').contains('address')
741   build_options_config.set('SANITIZE_ADDRESS', 'YesCompiledWithIt')
742 else
743   build_options_config.set('SANITIZE_ADDRESS', '')
744 endif
745 if get_option('b_sanitize').contains('leak')
746   build_options_config.set('SANITIZE_LEAK', 'YesCompiledWithIt')
747 else
748   build_options_config.set('SANITIZE_LEAK', '')
749 endif
750 if get_option('b_sanitize').contains('undefined')
751   libgit_c_args += '-DSHA1DC_FORCE_ALIGNED_ACCESS'
752 endif
754 executable_suffix = ''
755 if host_machine.system() == 'cygwin' or host_machine.system() == 'windows'
756   executable_suffix = '.exe'
757   libgit_c_args += '-DSTRIP_EXTENSION="' + executable_suffix + '"'
758 endif
759 build_options_config.set_quoted('X', executable_suffix)
761 python = import('python').find_installation('python3', required: get_option('python'))
762 if python.found()
763   build_options_config.set('NO_PYTHON', '')
764 else
765   libgit_c_args += '-DNO_PYTHON'
766   build_options_config.set('NO_PYTHON', '1')
767 endif
769 # Perl is used for two different things: our test harness and to provide some
770 # features. It is optional if you want to neither execute tests nor use any of
771 # these optional features.
772 perl_required = get_option('perl')
773 if get_option('tests') or get_option('gitweb').enabled()
774   perl_required = true
775 endif
777 # Note that we only set NO_PERL if the Perl features were disabled by the user.
778 # It may not be set when we have found Perl, but only use it to run tests.
779 perl = find_program('perl', version: '>=5.8.1', dirs: program_path, required: perl_required)
780 perl_features_enabled = perl.found() and get_option('perl').allowed()
781 if perl_features_enabled
782   build_options_config.set('NO_PERL', '')
784   if get_option('runtime_prefix')
785     build_options_config.set('PERL_LOCALEDIR', '')
786   else
787     build_options_config.set_quoted('PERL_LOCALEDIR', fs.as_posix(get_option('prefix') / get_option('localedir')))
788   endif
790   if get_option('perl_cpan_fallback')
791     build_options_config.set('NO_PERL_CPAN_FALLBACKS', '')
792   else
793     build_options_config.set_quoted('NO_PERL_CPAN_FALLBACKS', 'YesPlease')
794   endif
795 else
796   libgit_c_args += '-DNO_PERL'
797   build_options_config.set('NO_PERL', '1')
798   build_options_config.set('PERL_LOCALEDIR', '')
799   build_options_config.set('NO_PERL_CPAN_FALLBACKS', '')
800 endif
802 zlib = dependency('zlib', default_options: ['default_library=static', 'tests=disabled'])
803 if zlib.version().version_compare('<1.2.0')
804   libgit_c_args += '-DNO_DEFLATE_BOUND'
805 endif
806 libgit_dependencies += zlib
808 threads = dependency('threads', required: false)
809 if threads.found()
810   libgit_dependencies += threads
811   build_options_config.set('NO_PTHREADS', '')
812 else
813   libgit_c_args += '-DNO_PTHREADS'
814   build_options_config.set('NO_PTHREADS', '1')
815 endif
817 msgfmt = find_program('msgfmt', dirs: program_path, required: false)
818 gettext_option = get_option('gettext').disable_auto_if(not msgfmt.found())
819 if not msgfmt.found() and gettext_option.enabled()
820   error('Internationalization via libintl requires msgfmt')
821 endif
823 if gettext_option.allowed() and host_machine.system() == 'darwin' and get_option('macos_use_homebrew_gettext')
824   if host_machine.cpu_family() == 'x86_64'
825     libintl_prefix = '/usr/local'
826   elif host_machine.cpu_family() == 'aarch64'
827     libintl_prefix = '/opt/homebrew'
828   else
829     error('Homebrew workaround not supported on current architecture')
830   endif
832   intl = compiler.find_library('intl', dirs: libintl_prefix / 'lib', required: gettext_option)
833   if intl.found()
834     intl = declare_dependency(
835       dependencies: intl,
836       include_directories: libintl_prefix / 'include',
837     )
838   endif
839 else
840   intl = dependency('intl', required: gettext_option)
841 endif
842 if intl.found()
843   libgit_dependencies += intl
844   build_options_config.set('NO_GETTEXT', '')
845   build_options_config.set('USE_GETTEXT_SCHEME', '')
847   # POSIX nowadays requires `nl_langinfo()`, but some systems still don't have
848   # the function available. On such systems we instead fall back to libcharset.
849   # On native Windows systems we use our own emulation.
850   if host_machine.system() != 'windows' and not compiler.has_function('nl_langinfo')
851     libcharset = compiler.find_library('charset', required: true)
852     libgit_dependencies += libcharset
853     libgit_c_args += '-DHAVE_LIBCHARSET_H'
854   endif
855 else
856   libgit_c_args += '-DNO_GETTEXT'
857   build_options_config.set('NO_GETTEXT', '1')
858   build_options_config.set('USE_GETTEXT_SCHEME', 'fallthrough')
859 endif
861 iconv = dependency('iconv', required: get_option('iconv'))
862 if iconv.found()
863   libgit_dependencies += iconv
864   build_options_config.set('NO_ICONV', '')
866   have_old_iconv = false
867   if not compiler.compiles('''
868     #include <iconv.h>
870     extern size_t iconv(iconv_t cd,
871                         char **inbuf, size_t *inbytesleft,
872                         char **outbuf, size_t *outbytesleft);
873   ''', name: 'old iconv interface', dependencies: [iconv])
874     libgit_c_args += '-DOLD_ICONV'
875     have_old_iconv = true
876   endif
878   iconv_omits_bom_source = '''#
879     #include <iconv.h>
881     int main(int argc, const char **argv)
882     {
883   '''
884   if have_old_iconv
885     iconv_omits_bom_source += '''
886       typedef const char *iconv_ibp;
887     '''
888   else
889     iconv_omits_bom_source += '''
890       typedef char *iconv_ibp;
891     '''
892   endif
893   iconv_omits_bom_source += '''
894       int v;
895       iconv_t conv;
896       char in[] = "a"; iconv_ibp pin = in;
897       char out[20] = ""; char *pout = out;
898       size_t isz = sizeof in;
899       size_t osz = sizeof out;
901       conv = iconv_open("UTF-16", "UTF-8");
902       iconv(conv, &pin, &isz, &pout, &osz);
903       iconv_close(conv);
904       v = (unsigned char)(out[0]) + (unsigned char)(out[1]);
905       return v != 0xfe + 0xff;
906     }
907   '''
909   if compiler.run(iconv_omits_bom_source,
910     dependencies: iconv,
911     name: 'iconv omits BOM',
912   ).returncode() != 0
913     libgit_c_args += '-DICONV_OMITS_BOM'
914   endif
915 else
916   libgit_c_args += '-DNO_ICONV'
917   build_options_config.set('NO_ICONV', '1')
918 endif
920 pcre2 = dependency('libpcre2-8', required: get_option('pcre2'), default_options: ['default_library=static', 'test=false'])
921 if pcre2.found()
922   libgit_dependencies += pcre2
923   libgit_c_args += '-DUSE_LIBPCRE2'
924   build_options_config.set('USE_LIBPCRE2', '1')
925 else
926   build_options_config.set('USE_LIBPCRE2', '')
927 endif
929 curl = dependency('libcurl', version: '>=7.21.3', required: get_option('curl'), default_options: ['default_library=static', 'tests=disabled', 'tool=disabled'])
930 use_curl_for_imap_send = false
931 if curl.found()
932   if curl.version().version_compare('>=7.34.0')
933     libgit_c_args += '-DUSE_CURL_FOR_IMAP_SEND'
934     use_curl_for_imap_send = true
935   endif
937   libgit_dependencies += curl
938   libgit_c_args += '-DCURL_DISABLE_TYPECHECK'
939   build_options_config.set('NO_CURL', '')
940 else
941   libgit_c_args += '-DNO_CURL'
942   build_options_config.set('NO_CURL', '1')
943 endif
945 expat = dependency('expat', required: get_option('expat'), default_options: ['default_library=static', 'build_tests=false'])
946 if expat.found()
947   libgit_dependencies += expat
949   if expat.version().version_compare('<=1.2')
950     libgit_c_args += '-DEXPAT_NEEDS_XMLPARSE_H'
951   endif
952   build_options_config.set('NO_EXPAT', '')
953 else
954   libgit_c_args += '-DNO_EXPAT'
955   build_options_config.set('NO_EXPAT', '1')
956 endif
958 if not compiler.has_header('sys/select.h')
959   libgit_c_args += '-DNO_SYS_SELECT_H'
960 endif
962 has_poll_h = compiler.has_header('poll.h')
963 if not has_poll_h
964   libgit_c_args += '-DNO_POLL_H'
965 endif
967 has_sys_poll_h = compiler.has_header('sys/poll.h')
968 if not has_sys_poll_h
969   libgit_c_args += '-DNO_SYS_POLL_H'
970 endif
972 if not has_poll_h and not has_sys_poll_h
973   libgit_c_args += '-DNO_POLL'
974   libgit_sources += 'compat/poll/poll.c'
975   libgit_include_directories += 'compat/poll'
976 endif
978 if not compiler.has_header('inttypes.h')
979   libgit_c_args += '-DNO_INTTYPES_H'
980 endif
982 if compiler.has_header('alloca.h')
983   libgit_c_args += '-DHAVE_ALLOCA_H'
984 endif
986 if compiler.has_header('sys/sysinfo.h')
987   libgit_c_args += '-DHAVE_SYSINFO'
988 endif
990 # Windows has libgen.h and a basename implementation, but we still need our own
991 # implementation to threat things like drive prefixes specially.
992 if host_machine.system() == 'windows' or not compiler.has_header('libgen.h')
993   libgit_c_args += '-DNO_LIBGEN_H'
994   libgit_sources += 'compat/basename.c'
995 endif
997 if compiler.has_header('paths.h')
998   libgit_c_args += '-DHAVE_PATHS_H'
999 endif
1001 if compiler.has_header('strings.h')
1002   libgit_c_args += '-DHAVE_STRINGS_H'
1003 endif
1005 networking_dependencies = [ ]
1006 if host_machine.system() == 'windows'
1007   winsock = compiler.find_library('ws2_32', required: false)
1008   if winsock.found()
1009     networking_dependencies += winsock
1010   endif
1011 else
1012   libresolv = compiler.find_library('resolv', required: false)
1013   if libresolv.found()
1014     networking_dependencies += libresolv
1015   endif
1016 endif
1017 libgit_dependencies += networking_dependencies
1019 foreach symbol : ['inet_ntop', 'inet_pton', 'strerror']
1020   if not compiler.has_function(symbol, dependencies: networking_dependencies)
1021     libgit_c_args += '-DNO_' + symbol.to_upper()
1022   endif
1023 endforeach
1025 has_ipv6 = compiler.has_function('getaddrinfo', dependencies: networking_dependencies)
1026 if not has_ipv6
1027   libgit_c_args += '-DNO_IPV6'
1028 endif
1030 if not compiler.compiles('''
1031   #ifdef _WIN32
1032   # include <winsock2.h>
1033   #else
1034   # include <sys/types.h>
1035   # include <sys/socket.h>
1036   #endif
1038   void func(void)
1039   {
1040     struct sockaddr_storage x;
1041   }
1042 ''', name: 'struct sockaddr_storage')
1043   if has_ipv6
1044     libgit_c_args += '-Dsockaddr_storage=sockaddr_in6'
1045   else
1046     libgit_c_args += '-Dsockaddr_storage=sockaddr_in'
1047   endif
1048 endif
1050 if compiler.has_function('socket', dependencies: networking_dependencies)
1051   libgit_sources += [
1052     'unix-socket.c',
1053     'unix-stream-server.c',
1054   ]
1055   build_options_config.set('NO_UNIX_SOCKETS', '')
1056 else
1057   libgit_c_args += '-DNO_UNIX_SOCKETS'
1058   build_options_config.set('NO_UNIX_SOCKETS', '1')
1059 endif
1061 if not compiler.has_function('pread')
1062   libgit_c_args += '-DNO_PREAD'
1063   libgit_sources += 'compat/pread.c'
1064 endif
1066 if host_machine.system() == 'darwin'
1067   libgit_sources += 'compat/precompose_utf8.c'
1068   libgit_c_args += '-DPRECOMPOSE_UNICODE'
1069   libgit_c_args += '-DPROTECT_HFS_DEFAULT'
1070 endif
1072 # Configure general compatibility wrappers.
1073 if host_machine.system() == 'cygwin'
1074   libgit_sources += [
1075     'compat/win32/path-utils.c',
1076   ]
1077 elif host_machine.system() == 'windows'
1078   libgit_sources += [
1079     'compat/mingw.c',
1080     'compat/winansi.c',
1081     'compat/win32/flush.c',
1082     'compat/win32/path-utils.c',
1083     'compat/win32/pthread.c',
1084     'compat/win32/syslog.c',
1085     'compat/win32/dirent.c',
1086     'compat/win32mmap.c',
1087     'compat/nedmalloc/nedmalloc.c',
1088   ]
1090   libgit_c_args += [
1091     '-DDETECT_MSYS_TTY',
1092     '-DENSURE_MSYSTEM_IS_SET',
1093     '-DNATIVE_CRLF',
1094     '-DNOGDI',
1095     '-DNO_POSIX_GOODIES',
1096     '-DWIN32',
1097     '-D_CONSOLE',
1098     '-D_CONSOLE_DETECT_MSYS_TTY',
1099     '-D__USE_MINGW_ANSI_STDIO=0',
1100   ]
1102   libgit_dependencies += compiler.find_library('ntdll')
1103   libgit_include_directories += 'compat/win32'
1104   if compiler.get_id() == 'msvc'
1105     libgit_include_directories += 'compat/vcbuild/include'
1106   endif
1107 endif
1109 if host_machine.system() == 'linux'
1110   libgit_sources += 'compat/linux/procinfo.c'
1111 elif host_machine.system() == 'windows'
1112   libgit_sources += 'compat/win32/trace2_win32_process_info.c'
1113 else
1114   libgit_sources += 'compat/stub/procinfo.c'
1115 endif
1117 if host_machine.system() == 'cygwin' or host_machine.system() == 'windows'
1118   libgit_c_args += [
1119     '-DUNRELIABLE_FSTAT',
1120     '-DMMAP_PREVENTS_DELETE',
1121     '-DOBJECT_CREATION_MODE=1',
1122   ]
1123 endif
1125 # Configure the simple-ipc subsystem required fro the fsmonitor.
1126 if host_machine.system() == 'windows'
1127   libgit_sources += [
1128     'compat/simple-ipc/ipc-shared.c',
1129     'compat/simple-ipc/ipc-win32.c',
1130   ]
1131   libgit_c_args += '-DSUPPORTS_SIMPLE_IPC'
1132 else
1133   libgit_sources += [
1134     'compat/simple-ipc/ipc-shared.c',
1135     'compat/simple-ipc/ipc-unix-socket.c',
1136   ]
1137   libgit_c_args += '-DSUPPORTS_SIMPLE_IPC'
1138 endif
1140 fsmonitor_backend = ''
1141 if host_machine.system() == 'windows'
1142   fsmonitor_backend = 'win32'
1143 elif host_machine.system() == 'darwin'
1144   fsmonitor_backend = 'darwin'
1145   libgit_dependencies += dependency('CoreServices')
1146 endif
1147 if fsmonitor_backend != ''
1148   libgit_c_args += '-DHAVE_FSMONITOR_DAEMON_BACKEND'
1149   libgit_c_args += '-DHAVE_FSMONITOR_OS_SETTINGS'
1151   libgit_sources += [
1152     'compat/fsmonitor/fsm-health-' + fsmonitor_backend + '.c',
1153     'compat/fsmonitor/fsm-ipc-' + fsmonitor_backend + '.c',
1154     'compat/fsmonitor/fsm-listen-' + fsmonitor_backend + '.c',
1155     'compat/fsmonitor/fsm-path-utils-' + fsmonitor_backend + '.c',
1156     'compat/fsmonitor/fsm-settings-' + fsmonitor_backend + '.c',
1157   ]
1158 endif
1159 build_options_config.set_quoted('FSMONITOR_DAEMON_BACKEND', fsmonitor_backend)
1160 build_options_config.set_quoted('FSMONITOR_OS_SETTINGS', fsmonitor_backend)
1162 if not get_option('b_sanitize').contains('address') and get_option('regex').allowed() and compiler.has_header('regex.h') and compiler.get_define('REG_STARTEND', prefix: '#include <regex.h>') != ''
1163   build_options_config.set('NO_REGEX', '')
1165   if compiler.get_define('REG_ENHANCED', prefix: '#include <regex.h>') != ''
1166     libgit_c_args += '-DUSE_ENHANCED_BASIC_REGULAR_EXPRESSIONS'
1167     libgit_sources += 'compat/regcomp_enhanced.c'
1168   endif
1169 elif not get_option('regex').enabled()
1170   libgit_c_args += [
1171     '-DNO_REGEX',
1172     '-DGAWK',
1173     '-DNO_MBSUPPORT',
1174   ]
1175   build_options_config.set('NO_REGEX', '1')
1176   libgit_sources += 'compat/regex/regex.c'
1177   libgit_include_directories += 'compat/regex'
1178 else
1179     error('Native regex support requested but not found')
1180 endif
1182 # setitimer and friends are provided by compat/mingw.c.
1183 if host_machine.system() != 'windows'
1184   if not compiler.compiles('''
1185     #include <sys/time.h>
1186     void func(void)
1187     {
1188       struct itimerval value;
1189     }
1190   ''', name: 'struct itimerval')
1191     libgit_c_args += '-DNO_STRUCT_ITIMERVAL'
1192     libgit_c_args += '-DNO_SETITIMER'
1193   elif not compiler.has_function('setitimer')
1194     libgit_c_args += '-DNO_SETITIMER'
1195   endif
1196 endif
1198 if compiler.has_member('struct stat', 'st_mtimespec.tv_nsec', prefix: '#include <sys/stat.h>')
1199   libgit_c_args += '-DUSE_ST_TIMESPEC'
1200 elif not compiler.has_member('struct stat', 'st_mtim.tv_nsec', prefix: '#include <sys/stat.h>')
1201   libgit_c_args += '-DNO_NSEC'
1202 endif
1204 if not compiler.has_member('struct stat', 'st_blocks', prefix: '#include <sys/stat.h>')
1205   libgit_c_args += '-DNO_ST_BLOCKS_IN_STRUCT_STAT'
1206 endif
1208 if not compiler.has_member('struct dirent', 'd_type', prefix: '#include <dirent.h>')
1209   libgit_c_args += '-DNO_D_TYPE_IN_DIRENT'
1210 endif
1212 if not compiler.has_member('struct passwd', 'pw_gecos', prefix: '#include <pwd.h>')
1213   libgit_c_args += '-DNO_GECOS_IN_PWENT'
1214 endif
1216 if compiler.has_function('sync_file_range')
1217   libgit_c_args += '-DHAVE_SYNC_FILE_RANGE'
1218 endif
1220 if not compiler.has_function('strcasestr')
1221   libgit_c_args += '-DNO_STRCASESTR'
1222   libgit_sources += 'compat/strcasestr.c'
1223 endif
1225 if not compiler.has_function('memmem')
1226   libgit_c_args += '-DNO_MEMMEM'
1227   libgit_sources += 'compat/memmem.c'
1228 endif
1230 if not compiler.has_function('strlcpy')
1231   libgit_c_args += '-DNO_STRLCPY'
1232   libgit_sources += 'compat/strlcpy.c'
1233 endif
1235 if not compiler.has_function('strdup')
1236   libgit_c_args += '-DOVERRIDE_STRDUP'
1237   libgit_sources += 'compat/strdup.c'
1238 endif
1240 if not compiler.has_function('strtoumax')
1241   libgit_c_args += '-DNO_STRTOUMAX'
1242   libgit_sources += [
1243     'compat/strtoumax.c',
1244     'compat/strtoimax.c',
1245   ]
1246 endif
1248 if not compiler.has_function('strtoull')
1249   libgit_c_args += '-DNO_STRTOULL'
1250 endif
1252 if not compiler.has_function('setenv')
1253   libgit_c_args += '-DNO_SETENV'
1254   libgit_sources += 'compat/setenv.c'
1255 endif
1257 if not compiler.has_function('qsort')
1258   libgit_c_args += '-DINTERNAL_QSORT'
1259 endif
1260 libgit_sources += 'compat/qsort_s.c'
1262 # unsetenv is provided by compat/mingw.c.
1263 if host_machine.system() != 'windows' and not compiler.has_function('unsetenv')
1264   libgit_c_args += '-DNO_UNSETENV'
1265   libgit_sources += 'compat/unsetenv.c'
1266 endif
1268 if not compiler.has_function('mkdtemp')
1269   libgit_c_args += '-DNO_MKDTEMP'
1270   libgit_sources += 'compat/mkdtemp.c'
1271 endif
1273 if not compiler.has_function('initgroups')
1274   libgit_c_args += '-DNO_INITGROUPS'
1275 endif
1277 if compiler.has_function('getdelim')
1278   libgit_c_args += '-DHAVE_GETDELIM'
1279 endif
1281 if host_machine.system() == 'windows'
1282   libgit_c_args += '-DUSE_WIN32_MMAP'
1283 elif not compiler.has_function('mmap')
1284   libgit_c_args += '-DNO_MMAP'
1285   libgit_sources += 'compat/mmap.c'
1286 endif
1288 if compiler.has_function('clock_gettime')
1289   libgit_c_args += '-DHAVE_CLOCK_GETTIME'
1290 endif
1292 if compiler.compiles('''
1293   #include <time.h>
1295   void func(void)
1296   {
1297     clockid_t id = CLOCK_MONOTONIC;
1298   }
1299 ''', name: 'monotonic clock')
1300   libgit_c_args += '-DHAVE_CLOCK_MONOTONIC'
1301 endif
1303 if not compiler.compiles('''
1304   #include <inttypes.h>
1306   void func(void)
1307   {
1308     uintmax_t x = 0;
1309   }
1310 ''', name: 'uintmax_t')
1311   libgit_c_args += '-DNO_UINTMAX_T'
1312 endif
1314 has_bsd_sysctl = false
1315 if compiler.has_header('sys/sysctl.h')
1316   if compiler.compiles('''
1317     #include <stddef.h>
1318     #include <sys/sysctl.h>
1320     void func(void)
1321     {
1322       int val, mib[2] = { 0 };
1323       size_t len = sizeof(val);
1324       sysctl(mib, 2, &val, &len, NULL, 0);
1325     }
1326   ''', name: 'BSD sysctl')
1327     libgit_c_args += '-DHAVE_BSD_SYSCTL'
1328     has_bsd_sysctl = true
1329   endif
1330 endif
1332 if not meson.is_cross_build() and compiler.run('''
1333   #include <stdio.h>
1335   int main(int argc, const char **argv)
1336   {
1337     FILE *f = fopen(".", "r");
1338     return f ? 0 : 1;
1339   }
1340 ''', name: 'fread reads directories').returncode() == 0
1341   libgit_c_args += '-DFREAD_READS_DIRECTORIES'
1342   libgit_sources += 'compat/fopen.c'
1343 endif
1345 if not meson.is_cross_build() and fs.exists('/dev/tty')
1346   libgit_c_args += '-DHAVE_DEV_TTY'
1347 endif
1349 csprng_backend = get_option('csprng_backend')
1350 https_backend = get_option('https_backend')
1351 sha1_backend = get_option('sha1_backend')
1352 sha1_unsafe_backend = get_option('sha1_unsafe_backend')
1353 sha256_backend = get_option('sha256_backend')
1355 security_framework = dependency('Security', required: 'CommonCrypto' in [https_backend, sha1_backend, sha1_unsafe_backend])
1356 core_foundation_framework = dependency('CoreFoundation', required: security_framework.found())
1357 if https_backend == 'auto' and security_framework.found()
1358   https_backend = 'CommonCrypto'
1359 endif
1361 openssl_required = 'openssl' in [csprng_backend, https_backend, sha1_backend, sha1_unsafe_backend, sha256_backend]
1362 openssl = dependency('openssl', required: openssl_required, default_options: ['default_library=static'])
1363 if https_backend == 'auto' and openssl.found()
1364   https_backend = 'openssl'
1365 endif
1367 if https_backend == 'CommonCrypto'
1368   libgit_dependencies += security_framework
1369   libgit_dependencies += core_foundation_framework
1370   libgit_c_args += '-DAPPLE_COMMON_CRYPTO'
1371 elif https_backend == 'openssl'
1372   libgit_dependencies += openssl
1373 else
1374   # We either couldn't find any dependencies with 'auto' or the user requested
1375   # 'none'. Both cases are benign.
1376 endif
1378 if https_backend != 'openssl'
1379   libgit_c_args += '-DNO_OPENSSL'
1380 endif
1382 if sha1_backend == 'sha1dc'
1383   libgit_c_args += '-DSHA1_DC'
1384   libgit_c_args += '-DSHA1DC_NO_STANDARD_INCLUDES=1'
1385   libgit_c_args += '-DSHA1DC_INIT_SAFE_HASH_DEFAULT=0'
1386   libgit_c_args += '-DSHA1DC_CUSTOM_INCLUDE_SHA1_C="git-compat-util.h"'
1387   libgit_c_args += '-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C="git-compat-util.h"'
1389   libgit_sources += [
1390     'sha1dc_git.c',
1391     'sha1dc/sha1.c',
1392     'sha1dc/ubc_check.c',
1393   ]
1394 endif
1395 if sha1_backend == 'CommonCrypto' or sha1_unsafe_backend == 'CommonCrypto'
1396   if sha1_backend == 'CommonCrypto'
1397     libgit_c_args += '-DSHA1_APPLE'
1398   endif
1399   if sha1_unsafe_backend == 'CommonCrypto'
1400     libgit_c_args += '-DSHA1_APPLE_UNSAFE'
1401   endif
1403   libgit_c_args += '-DCOMMON_DIGEST_FOR_OPENSSL'
1404   # Apple CommonCrypto requires chunking
1405   libgit_c_args += '-DSHA1_MAX_BLOCK_SIZE=1024L*1024L*1024L'
1406 endif
1407 if sha1_backend == 'openssl' or sha1_unsafe_backend == 'openssl'
1408   if sha1_backend == 'openssl'
1409     libgit_c_args += '-DSHA1_OPENSSL'
1410   endif
1411   if sha1_unsafe_backend == 'openssl'
1412     libgit_c_args += '-DSHA1_OPENSSL_UNSAFE'
1413   endif
1415   libgit_dependencies += openssl
1416 endif
1417 if sha1_backend == 'block' or sha1_unsafe_backend == 'block'
1418   if sha1_backend == 'block'
1419     libgit_c_args += '-DSHA1_BLK'
1420   endif
1421   if sha1_unsafe_backend == 'block'
1422     libgit_c_args += '-DSHA1_BLK_UNSAFE'
1423   endif
1425   libgit_sources += 'block-sha1/sha1.c'
1426 endif
1428 if sha256_backend == 'openssl'
1429   libgit_c_args += '-DSHA256_OPENSSL'
1430   libgit_dependencies += openssl
1431 elif sha256_backend == 'nettle'
1432   nettle = dependency('nettle')
1433   libgit_dependencies += nettle
1434   libgit_c_args += '-DSHA256_NETTLE'
1435 elif sha256_backend == 'gcrypt'
1436   gcrypt = dependency('gcrypt')
1437   libgit_dependencies += gcrypt
1438   libgit_c_args += '-DSHA256_GCRYPT'
1439 elif sha256_backend == 'block'
1440   libgit_c_args += '-DSHA256_BLK'
1441   libgit_sources += 'sha256/block/sha256.c'
1442 else
1443   error('Unhandled SHA256 backend ' + sha256_backend)
1444 endif
1446 # Backends are ordered to reflect our preference for more secure and faster
1447 # ones over the ones that are less so.
1448 if csprng_backend in ['auto', 'arc4random'] and compiler.has_header_symbol('stdlib.h', 'arc4random_buf', required: csprng_backend == 'arc4random')
1449   libgit_c_args += '-DHAVE_ARC4RANDOM'
1450   csprng_backend = 'arc4random'
1451 elif csprng_backend in ['auto', 'arc4random_bsd'] and compiler.has_header_symbol('bsd/stdlib.h', 'arc4random_buf', required: csprng_backend == 'arc4random_bsd')
1452   libgit_c_args += '-DHAVE_ARC4RANDOM_BSD'
1453   csprng_backend = 'arc4random_bsd'
1454 elif csprng_backend in ['auto', 'getrandom'] and compiler.has_header_symbol('sys/random.h', 'getrandom', required: csprng_backend == 'getrandom')
1455   libgit_c_args += '-DHAVE_GETRANDOM'
1456   csprng_backend = 'getrandom'
1457 elif csprng_backend in ['auto', 'getentropy'] and compiler.has_header_symbol('unistd.h', 'getentropy', required: csprng_backend == 'getentropy')
1458   libgit_c_args += '-DHAVE_GETENTROPY'
1459   csprng_backend = 'getentropy'
1460 elif csprng_backend in ['auto', 'rtlgenrandom'] and compiler.has_header_symbol('ntsecapi.h', 'RtlGenRandom', prefix: '#include <windows.h>', required: csprng_backend == 'rtlgenrandom')
1461   libgit_c_args += '-DHAVE_RTLGENRANDOM'
1462   csprng_backend = 'rtlgenrandom'
1463 elif csprng_backend in ['auto', 'openssl'] and openssl.found()
1464   libgit_c_args += '-DHAVE_OPENSSL_CSPRNG'
1465   csprng_backend = 'openssl'
1466 elif csprng_backend in ['auto', 'urandom']
1467   csprng_backend = 'urandom'
1468 else
1469   error('Unsupported CSPRNG backend: ' + csprng_backend)
1470 endif
1472 if get_option('runtime_prefix')
1473   libgit_c_args += '-DRUNTIME_PREFIX'
1474   build_options_config.set('RUNTIME_PREFIX', 'true')
1476   if compiler.has_header('mach-o/dyld.h')
1477     libgit_c_args += '-DHAVE_NS_GET_EXECUTABLE_PATH'
1478   endif
1480   if has_bsd_sysctl and compiler.compiles('''
1481     #include <sys/sysctl.h>
1483     void func(void)
1484     {
1485       KERN_PROC_PATHNAME; KERN_PROC;
1486     }
1487   ''', name: 'BSD KERN_PROC_PATHNAME')
1488     libgit_c_args += '-DHAVE_NS_GET_EXECUTABLE_PATH'
1489   endif
1491   if host_machine.system() == 'linux'
1492     libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="/proc/self/exe' + '"'
1493   elif host_machine.system() == 'openbsd'
1494     libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="' + '/proc/curproc/file' + '"'
1495   elif host_machine.system() == 'netbsd'
1496     libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="' + '/proc/curproc/exe' + '"'
1497   endif
1499   if host_machine.system() == 'windows' and compiler.compiles('''
1500     #include <stdlib.h>
1502     void func(void)
1503     {
1504       _wpgmptr;
1505     }
1506   ''', name: 'Win32 _wpgmptr')
1507     libgit_c_args += '-DHAVE_WPGMPTR'
1508   endif
1509 else
1510   build_options_config.set('RUNTIME_PREFIX', 'false')
1511 endif
1513 git_version_file = custom_target(
1514   command: [
1515     shell,
1516     meson.current_source_dir() / 'GIT-VERSION-GEN',
1517     meson.current_source_dir(),
1518     '@INPUT@',
1519     '@OUTPUT@',
1520   ],
1521   input: meson.current_source_dir() / 'GIT-VERSION-FILE.in',
1522   output: 'GIT-VERSION-FILE',
1523   env: version_gen_environment,
1524   build_always_stale: true,
1527 version_def_h = custom_target(
1528   command: [
1529     shell,
1530     meson.current_source_dir() / 'GIT-VERSION-GEN',
1531     meson.current_source_dir(),
1532     '@INPUT@',
1533     '@OUTPUT@',
1534   ],
1535   input: meson.current_source_dir() / 'version-def.h.in',
1536   output: 'version-def.h',
1537   # Depend on GIT-VERSION-FILE so that we don't always try to rebuild this
1538   # target for the same commit.
1539   depends: [git_version_file],
1540   env: version_gen_environment,
1543 # Build a separate library for "version.c" so that we do not have to rebuild
1544 # everything when the current Git commit changes.
1545 libgit_version_library = static_library('git-version',
1546   sources: [
1547     'version.c',
1548     version_def_h,
1549   ],
1550   c_args: libgit_c_args + [
1551     '-DGIT_VERSION_H="' + version_def_h.full_path() + '"',
1552   ],
1553   dependencies: libgit_dependencies,
1554   include_directories: libgit_include_directories,
1557 libgit_library = static_library('git',
1558   sources: libgit_sources,
1559   c_args: libgit_c_args,
1560   link_with: libgit_version_library,
1561   dependencies: libgit_dependencies,
1562   include_directories: libgit_include_directories,
1565 libgit = declare_dependency(
1566   compile_args: libgit_c_args,
1567   link_with: libgit_library,
1568   dependencies: libgit_dependencies,
1569   include_directories: libgit_include_directories,
1572 common_main_sources = ['common-main.c']
1573 common_main_link_args = [ ]
1574 if host_machine.system() == 'windows'
1575   git_rc = custom_target(
1576     command: [
1577       shell,
1578       meson.current_source_dir() / 'GIT-VERSION-GEN',
1579       meson.current_source_dir(),
1580       '@INPUT@',
1581       '@OUTPUT@',
1582     ],
1583     input: meson.current_source_dir() / 'git.rc.in',
1584     output: 'git.rc',
1585     depends: [git_version_file],
1586     env: version_gen_environment,
1587   )
1589   common_main_sources += import('windows').compile_resources(git_rc,
1590     include_directories: [meson.current_source_dir()],
1591   )
1592   if compiler.get_argument_syntax() == 'gcc'
1593     common_main_link_args += [
1594       '-municode',
1595       '-Wl,-nxcompat',
1596       '-Wl,-dynamicbase',
1597       '-Wl,-pic-executable,-e,mainCRTStartup',
1598     ]
1599   elif compiler.get_argument_syntax() == 'msvc'
1600     common_main_link_args += [
1601       '/ENTRY:wmainCRTStartup',
1602       'invalidcontinue.obj',
1603     ]
1604   else
1605     error('Unsupported compiler ' + compiler.get_id())
1606   endif
1607 endif
1608 common_main_library = static_library('common-main',
1609   sources: common_main_sources,
1610   c_args: libgit_c_args,
1611   dependencies: libgit_dependencies,
1612   include_directories: libgit_include_directories,
1614 common_main = declare_dependency(
1615   link_with: common_main_library,
1616   link_args: common_main_link_args,
1619 bin_wrappers = [ ]
1620 test_dependencies = [ ]
1622 git = executable('git',
1623   sources: builtin_sources + 'git.c',
1624   dependencies: [libgit, common_main],
1625   install: true,
1626   install_dir: get_option('libexecdir') / 'git-core',
1628 bin_wrappers += git
1630 test_dependencies += executable('git-daemon',
1631   sources: 'daemon.c',
1632   dependencies: [libgit, common_main],
1633   install: true,
1634   install_dir: get_option('libexecdir') / 'git-core',
1637 test_dependencies += executable('git-sh-i18n--envsubst',
1638   sources: 'sh-i18n--envsubst.c',
1639   dependencies: [libgit, common_main],
1640   install: true,
1641   install_dir: get_option('libexecdir') / 'git-core',
1644 bin_wrappers += executable('git-shell',
1645   sources: 'shell.c',
1646   dependencies: [libgit, common_main],
1647   install: true,
1648   install_dir: get_option('libexecdir') / 'git-core',
1651 test_dependencies += executable('git-http-backend',
1652   sources: 'http-backend.c',
1653   dependencies: [libgit, common_main],
1654   install: true,
1655   install_dir: get_option('libexecdir') / 'git-core',
1658 bin_wrappers += executable('scalar',
1659   sources: 'scalar.c',
1660   dependencies: [libgit, common_main],
1661   install: true,
1662   install_dir: get_option('libexecdir') / 'git-core',
1665 if get_option('curl').enabled()
1666   curl_sources = [
1667     'http.c',
1668     'http-walker.c',
1669   ]
1671   git_remote_http = executable('git-remote-http',
1672     sources: curl_sources + 'remote-curl.c',
1673     dependencies: [libgit, common_main],
1674     install: true,
1675     install_dir: get_option('libexecdir') / 'git-core',
1676   )
1677   test_dependencies += git_remote_http
1679   test_dependencies += executable('git-http-fetch',
1680     sources: curl_sources + 'http-fetch.c',
1681     dependencies: [libgit, common_main],
1682     install: true,
1683     install_dir: get_option('libexecdir') / 'git-core',
1684   )
1686   if expat.found()
1687     test_dependencies += executable('git-http-push',
1688       sources: curl_sources + 'http-push.c',
1689       dependencies: [libgit, common_main],
1690       install: true,
1691       install_dir: get_option('libexecdir') / 'git-core',
1692     )
1693   endif
1695   foreach alias : [ 'git-remote-https', 'git-remote-ftp', 'git-remote-ftps' ]
1696     test_dependencies += executable(alias,
1697       objects: git_remote_http.extract_all_objects(recursive: false),
1698       dependencies: [libgit, common_main],
1699     )
1701     install_symlink(alias + executable_suffix,
1702       install_dir: get_option('libexecdir') / 'git-core',
1703       pointing_to: 'git-remote-http',
1704     )
1705   endforeach
1706 endif
1708 imap_send_sources = ['imap-send.c']
1709 if use_curl_for_imap_send
1710   imap_send_sources += curl_sources
1711 endif
1713 test_dependencies += executable('git-imap-send',
1714   sources: imap_send_sources,
1715   dependencies: [libgit, common_main],
1716   install: true,
1717   install_dir: get_option('libexecdir') / 'git-core',
1720 foreach alias : [ 'git-receive-pack', 'git-upload-archive', 'git-upload-pack' ]
1721   bin_wrappers += executable(alias,
1722     objects: git.extract_all_objects(recursive: false),
1723     dependencies: [libgit, common_main],
1724   )
1726   install_symlink(alias + executable_suffix,
1727     install_dir: get_option('libexecdir') / 'git-core',
1728     pointing_to: 'git',
1729   )
1730 endforeach
1732 foreach symlink : [
1733   'git',
1734   'git-receive-pack',
1735   'git-shell',
1736   'git-upload-archive',
1737   'git-upload-pack',
1738   'scalar',
1740   if meson.version().version_compare('>=1.3.0')
1741     pointing_to = fs.relative_to(get_option('libexecdir') / 'git-core' / symlink, get_option('bindir'))
1742   else
1743     pointing_to = '../libexec/git-core' / symlink
1744   endif
1746   install_symlink(symlink,
1747     install_dir: get_option('bindir'),
1748     pointing_to: pointing_to,
1749   )
1750 endforeach
1752 scripts_sh = [
1753   'git-difftool--helper.sh',
1754   'git-filter-branch.sh',
1755   'git-merge-octopus.sh',
1756   'git-merge-one-file.sh',
1757   'git-merge-resolve.sh',
1758   'git-mergetool--lib.sh',
1759   'git-mergetool.sh',
1760   'git-quiltimport.sh',
1761   'git-request-pull.sh',
1762   'git-sh-i18n.sh',
1763   'git-sh-setup.sh',
1764   'git-submodule.sh',
1765   'git-web--browse.sh',
1767 if perl_features_enabled
1768   scripts_sh += 'git-instaweb.sh'
1769 endif
1771 foreach script : scripts_sh
1772   test_dependencies += custom_target(
1773     input: script,
1774     output: fs.stem(script),
1775     command: [
1776       shell,
1777       meson.project_source_root() / 'generate-script.sh',
1778       '@INPUT@',
1779       '@OUTPUT@',
1780       meson.project_build_root() / 'GIT-BUILD-OPTIONS',
1781     ],
1782     install: true,
1783     install_dir: get_option('libexecdir') / 'git-core',
1784   )
1785 endforeach
1787 if perl_features_enabled
1788   scripts_perl = [
1789     'git-archimport.perl',
1790     'git-cvsexportcommit.perl',
1791     'git-cvsimport.perl',
1792     'git-cvsserver.perl',
1793     'git-send-email.perl',
1794     'git-svn.perl',
1795   ]
1797   pathsep = ':'
1798   if host_machine.system() == 'windows'
1799     pathsep = ';'
1800   endif
1802   perl_header_template = 'perl/header_templates/fixed_prefix.template.pl'
1803   if get_option('runtime_prefix')
1804     perl_header_template = 'perl/header_templates/runtime_prefix.template.pl'
1805   endif
1807   perl_header = configure_file(
1808     input: perl_header_template,
1809     output: 'GIT-PERL-HEADER',
1810     configuration: {
1811       'GITEXECDIR_REL': get_option('libexecdir') / 'git-core',
1812       'PERLLIBDIR_REL': get_option('datadir') / 'perl5',
1813       'LOCALEDIR_REL': get_option('datadir') / 'locale',
1814       'INSTLIBDIR': get_option('datadir') / 'perl5',
1815       'PATHSEP': pathsep,
1816     },
1817   )
1819   generate_perl_command = [
1820     shell,
1821     meson.project_source_root() / 'generate-perl.sh',
1822     meson.project_build_root() / 'GIT-BUILD-OPTIONS',
1823     git_version_file.full_path(),
1824     perl_header,
1825     '@INPUT@',
1826     '@OUTPUT@',
1827   ]
1829   foreach script : scripts_perl
1830     generated_script = custom_target(
1831       input: script,
1832       output: fs.stem(script),
1833       command: generate_perl_command,
1834       install: true,
1835       install_dir: get_option('libexecdir') / 'git-core',
1836       depends: [git_version_file],
1837     )
1838     test_dependencies += generated_script
1840     if script == 'git-cvsserver.perl'
1841       bin_wrappers += generated_script
1843       if meson.version().version_compare('>=1.3.0')
1844         pointing_to = fs.relative_to(get_option('libexecdir') / 'git-core' / fs.stem(script), get_option('bindir'))
1845       else
1846         pointing_to = '../libexec/git-core' / fs.stem(script)
1847       endif
1849       install_symlink(fs.stem(script),
1850         install_dir: get_option('bindir'),
1851         pointing_to: pointing_to,
1852       )
1853     endif
1854   endforeach
1856   subdir('perl')
1857 endif
1859 if python.found()
1860   scripts_python = [
1861     'git-p4.py'
1862   ]
1864   foreach script : scripts_python
1865     generated_python = custom_target(
1866       input: script,
1867       output: fs.stem(script),
1868       command: [
1869         shell,
1870         meson.project_source_root() / 'generate-python.sh',
1871         meson.project_build_root() / 'GIT-BUILD-OPTIONS',
1872         '@INPUT@',
1873         '@OUTPUT@',
1874       ],
1875       install: true,
1876       install_dir: get_option('libexecdir') / 'git-core',
1877     )
1878     test_dependencies += generated_python
1879   endforeach
1880 endif
1882 mergetools = [
1883   'mergetools/araxis',
1884   'mergetools/bc',
1885   'mergetools/codecompare',
1886   'mergetools/deltawalker',
1887   'mergetools/diffmerge',
1888   'mergetools/diffuse',
1889   'mergetools/ecmerge',
1890   'mergetools/emerge',
1891   'mergetools/examdiff',
1892   'mergetools/guiffy',
1893   'mergetools/gvimdiff',
1894   'mergetools/kdiff3',
1895   'mergetools/kompare',
1896   'mergetools/meld',
1897   'mergetools/nvimdiff',
1898   'mergetools/opendiff',
1899   'mergetools/p4merge',
1900   'mergetools/smerge',
1901   'mergetools/tkdiff',
1902   'mergetools/tortoisemerge',
1903   'mergetools/vimdiff',
1904   'mergetools/vscode',
1905   'mergetools/winmerge',
1906   'mergetools/xxdiff',
1909 foreach mergetool : mergetools
1910   install_data(mergetool, install_dir: get_option('libexecdir') / 'git-core' / 'mergetools')
1911 endforeach
1913 if intl.found()
1914   subdir('po')
1915 endif
1917 # Gitweb requires Perl, so we disable the auto-feature if Perl was not found.
1918 # We make sure further up that Perl is required in case the gitweb option is
1919 # enabled.
1920 gitweb_option = get_option('gitweb').disable_auto_if(not perl.found())
1921 if gitweb_option.allowed()
1922   subdir('gitweb')
1923   build_options_config.set('NO_GITWEB', '')
1924 else
1925   build_options_config.set('NO_GITWEB', '1')
1926 endif
1928 subdir('templates')
1930 # Everything but the bin-wrappers need to come before this target such that we
1931 # can properly set up test dependencies. The bin-wrappers themselves are set up
1932 # at configuration time, so these are fine.
1933 if get_option('tests')
1934   subdir('t')
1935 endif
1937 if get_option('fuzzers')
1938   subdir('oss-fuzz')
1939 endif
1941 subdir('bin-wrappers')
1942 if get_option('docs') != []
1943   subdir('Documentation')
1944 endif
1946 subdir('contrib')
1948 foreach key, value : {
1949   'DIFF': diff.full_path(),
1950   'GIT_TEST_CMP': diff.full_path() + ' -u',
1951   'GIT_TEST_GITPERLLIB': meson.project_build_root() / 'perl',
1952   'GIT_TEST_MERGE_TOOLS_DIR': meson.project_source_root() / 'mergetools',
1953   'GIT_TEST_POPATH': meson.project_source_root() / 'po',
1954   'GIT_TEST_TEMPLATE_DIR': meson.project_build_root() / 'templates',
1955   'GIT_TEST_TEXTDOMAINDIR': meson.project_build_root() / 'po',
1956   'PAGER_ENV': get_option('pager_environment'),
1957   'PERL_PATH': perl.found() ? perl.full_path() : '',
1958   'PYTHON_PATH': python.found () ? python.full_path() : '',
1959   'SHELL_PATH': shell.full_path(),
1960   'TAR': tar.full_path(),
1961   'TEST_OUTPUT_DIRECTORY': test_output_directory,
1962   'TEST_SHELL_PATH': shell.full_path(),
1964   if value != '' and cygpath.found()
1965     value = run_command(cygpath, value, check: true).stdout().strip()
1966   endif
1967   build_options_config.set_quoted(key, value)
1968 endforeach
1970 configure_file(
1971   input: 'GIT-BUILD-OPTIONS.in',
1972   output: 'GIT-BUILD-OPTIONS',
1973   configuration: build_options_config,
1976 # Development environments can be used via `meson devenv -C <builddir>`. This
1977 # allows you to execute test scripts directly with the built Git version and
1978 # puts the built version of Git in your PATH.
1979 devenv = environment()
1980 devenv.set('GIT_BUILD_DIR', meson.current_build_dir())
1981 devenv.prepend('PATH', meson.current_build_dir() / 'bin-wrappers')
1982 meson.add_devenv(devenv)
1984 # Generate the 'version' file in the distribution tarball. This is used via
1985 # `meson dist -C <builddir>` to populate the source archive with the Git
1986 # version that the archive is being generated from.
1987 meson.add_dist_script(
1988   shell,
1989   '-c',
1990   '"$1" "$2" "$3" --format="@GIT_VERSION@" "$MESON_DIST_ROOT/version"',
1991   'GIT-VERSION-GEN',
1992   shell,
1993   meson.current_source_dir() / 'GIT-VERSION-GEN',
1994   meson.current_source_dir(),
1997 summary({
1998   'curl': curl.found(),
1999   'expat': expat.found(),
2000   'gettext': intl.found(),
2001   'gitweb': gitweb_option.allowed(),
2002   'https': https_backend,
2003   'iconv': iconv.found(),
2004   'pcre2': pcre2.found(),
2005   'perl': perl_features_enabled,
2006   'python': python.found(),
2007 }, section: 'Auto-detected features')
2009 summary({
2010   'csprng': csprng_backend,
2011   'https': https_backend,
2012   'sha1': sha1_backend,
2013   'sha1_unsafe': sha1_unsafe_backend,
2014   'sha256': sha256_backend,
2015 }, section: 'Backends')