Git fork
at reftables-rust 2284 lines 67 kB view raw
1# Meson build system 2# ================== 3# 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: 6# 7# - Out-of-tree builds. 8# - Better integration into IDEs. 9# - Easy-to-use autoconfiguration of available features on your system. 10# 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. 15# 16# Basic usage 17# =========== 18# 19# In the most trivial case, you can configure, build and install Git like this: 20# 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. 24# 25# $ meson setup build/ 26# 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. 30# 31# 2. Compile Git. You can either use Meson, Ninja or Samurai to do this, so all 32# of the following invocations are equivalent: 33# 34# $ meson compile 35# $ ninja 36# $ samu 37# 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. 41# 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. 44# 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. 49# 50# 3. Execute tests. Again, you can either use Meson, Ninja or Samurai to do this: 51# 52# $ meson test 53# $ ninja test 54# $ samu test 55# 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: 60# 61# # Execute the t0000-basic integration test and t-reftable-stack unit test. 62# $ meson test t0000-basic t-reftable-stack 63# 64# # Execute all reftable unit tests. 65# $ meson test t-reftable-* 66# 67# # Execute all tests and stop with the first failure. 68# $ meson test --maxfail 1 69# 70# # Execute single test interactively such that features like `debug ()` work. 71# $ meson test -i --test-args='-ix' t1400-update-ref 72# 73# # Execute all benchmarks. 74# $ meson test -i --benchmark 75# 76# # Execute single benchmark. 77# $ meson test -i --benchmark p0000-* 78# 79# Test execution (but not benchmark execution) is parallelized by default and 80# scales with the number of processor cores available. You can change the 81# number of processes by passing the `-jN` flag to `meson test`. 82# 83# 4. Install the Git distribution. Again, this can be done via Meson, Ninja or 84# Samurai: 85# 86# $ meson install 87# $ ninja install 88# $ samu install 89# 90# The prefix into which Git shall be installed is defined when setting up 91# the build directory. More on that in the "Configuration" section. 92# 93# Meson supports multiple backends. The default backend generates Ninja build 94# instructions, but it also supports the generation of Microsoft Visual 95# Studio solutions as well as Xcode projects by passing the `--backend` option 96# to `meson setup`. IDEs like Eclipse and Visual Studio Code provide plugins to 97# import Meson files directly. 98# 99# Configuration 100# ============= 101# 102# The exact configuration of Git is determined when setting up the build 103# directory via `meson setup`. Unless told otherwise, Meson will automatically 104# detect the availability of various bits and pieces. There are two different 105# kinds of options that can be used to further tweak the build: 106# 107# - Built-in options provided by Meson. 108# 109# - Options defined by the project in the "meson_options.txt" file. 110# 111# Both kinds of options can be inspected by running `meson configure` in the 112# build directory, which will give you a list of the current value for all 113# options. 114# 115# Options can be configured either when setting up the build directory or can 116# be changed in preexisting build directories: 117# 118# # Set up a new build directory with optimized settings that will be 119# # installed into an alternative prefix. 120# $ meson setup --buildtype release --optimization 3 --strip --prefix=/home/$USER build 121# 122# # Set up a new build directory with a higher warning level. Level 2 is 123# # mostly equivalent to setting DEVELOPER=1, level 3 and "everything" 124# # will enable even more warnings. 125# $ meson setup -Dwarning_level=2 build 126# 127# # Set up a new build directory with 'address' and 'undefined' sanitizers 128# # using Clang. 129# $ CC=clang meson setup -Db_sanitize=address,undefined build 130# 131# # Disable tests in a preexisting build directory. 132# $ meson configure -Dtests=false 133# 134# # Disable features based on Python 135# $ meson configure -Dpython=disabled 136# 137# Options have a type like booleans, choices, strings or features. Features are 138# somewhat special as they can have one of three values: enabled, disabled or 139# auto. While the first two values are self-explanatory, "auto" will enable or 140# disable the feature based on the availability of prerequisites to support it. 141# Python-based features for example will be enabled automatically when a Python 142# interpreter could be found. The default value of such features can be changed 143# via `meson setup --auto-features={enabled,disabled,auto}`, which will set the 144# value of all features with a value of "auto" to the provided one by default. 145# 146# It is also possible to store a set of configuration options in machine files. 147# This can be useful in case you regularly want to reuse the same set of options: 148# 149# [binaries] 150# c = ['clang'] 151# ar = ['ar'] 152# 153# [project options] 154# gettext = 'disabled' 155# default_editor = 'vim' 156# 157# [built-in options] 158# b_lto = true 159# b_sanitize = 'address,undefined' 160# 161# These machine files can be passed to `meson setup` via the `--native-file` 162# option. 163# 164# Cross compilation 165# ================= 166# 167# Machine files can also be used in the context of cross-compilation to 168# describe the target machine as well as the cross-compiler toolchain that 169# shall be used. An example machine file could look like the following: 170# 171# [binaries] 172# c = 'x86_64-w64-mingw32-gcc' 173# cpp = 'x86_64-w64-mingw32-g++' 174# ar = 'x86_64-w64-mingw32-ar' 175# windres = 'x86_64-w64-mingw32-windres' 176# strip = 'x86_64-w64-mingw32-strip' 177# exe_wrapper = 'wine64' 178# sh = 'C:/Program Files/Git for Windows/usr/bin/sh.exe' 179# 180# [host_machine] 181# system = 'windows' 182# cpu_family = 'x86_64' 183# cpu = 'x86_64' 184# endian = 'little' 185# 186# These machine files can be passed to `meson setup` via the `--cross-file` 187# option. 188# 189# Note that next to the cross-compiler toolchain, the `[binaries]` section is 190# also used to locate a couple of binaries that will be built into Git. This 191# includes `sh`, `python` and `perl`, so when cross-compiling Git you likely 192# want to set these binary paths in addition to the cross-compiler toolchain 193# binaries. 194# 195# Subproject wrappers 196# =================== 197# 198# Subproject wrappers are a feature provided by Meson that allows the automatic 199# fallback to a "wrapped" dependency in case the dependency is not provided by 200# the system. For example if the system is lacking curl, then Meson will use 201# "subprojects/curl.wrap" to set up curl as a subproject and compile and link 202# the dependency into Git itself. This is especially helpful on systems like 203# Windows, where you typically don't have such dependencies installed. 204# 205# The use of subproject wrappers can be disabled by executing `meson setup` 206# with the `--wrap-mode nofallback` option. 207 208project('git', 'c', 209 meson_version: '>=0.61.0', 210 # The version is only of cosmetic nature, so if we cannot find a shell yet we 211 # simply don't set up a version at all. This may be the case for example on 212 # Windows systems, where we first have to bootstrap the host environment. 213 version: find_program('sh', native: true, required: false).found() ? run_command( 214 'GIT-VERSION-GEN', meson.current_source_dir(), '--format=@GIT_VERSION@', 215 capture: true, 216 check: true, 217 ).stdout().strip() : 'unknown', 218 # Git requires C99 with GNU extensions, which of course isn't supported by 219 # MSVC. Funny enough, C99 doesn't work with MSVC either, as it has only 220 # learned to define __STDC_VERSION__ with C11 and later. We thus require 221 # GNU C99 and fall back to C11. Meson only learned to handle the fallback 222 # with version 1.3.0, so on older versions we use GNU C99 unconditionally. 223 default_options: meson.version().version_compare('>=1.3.0') ? ['rust_std=2018', 'c_std=gnu99,c11'] : ['rust_std=2018', 'c_std=gnu99'], 224) 225 226fs = import('fs') 227 228program_path = [] 229if get_option('sane_tool_path').length() != 0 230 program_path = get_option('sane_tool_path') 231elif host_machine.system() == 'windows' 232 # Git for Windows provides all the tools we need to build Git. 233 program_path = [ 'C:/Program Files/Git/bin', 'C:/Program Files/Git/usr/bin' ] 234endif 235 236cygpath = find_program('cygpath', dirs: program_path, native: true, required: false) 237diff = find_program('diff', dirs: program_path, native: true) 238git = find_program('git', dirs: program_path, native: true, required: false) 239sed = find_program('sed', dirs: program_path, native: true) 240shell = find_program('sh', dirs: program_path, native: true) 241tar = find_program('tar', dirs: program_path, native: true) 242time = find_program('time', dirs: program_path, required: get_option('benchmarks')) 243 244# Detect the target shell that is used by Git at runtime. Note that we prefer 245# "/bin/sh" over a PATH-based lookup, which provides a working shell on most 246# supported systems. This path is also the default shell path used by our 247# Makefile. This lookup can be overridden via `program_path`. 248target_shell = find_program('/bin/sh', 'sh', dirs: program_path, native: false) 249 250# Sanity-check that programs required for the build exist. 251foreach tool : ['cat', 'cut', 'grep', 'sort', 'tr', 'uname'] 252 find_program(tool, dirs: program_path, native: true) 253endforeach 254 255script_environment = environment() 256foreach path : program_path 257 script_environment.prepend('PATH', path) 258endforeach 259 260# The environment used by GIT-VERSION-GEN. Note that we explicitly override 261# environment variables that might be set by the user. This is by design so 262# that we always use whatever Meson has configured instead of what is present 263# in the environment. 264version_gen_environment = script_environment 265version_gen_environment.set('GIT_BUILT_FROM_COMMIT', get_option('built_from_commit')) 266version_gen_environment.set('GIT_DATE', get_option('build_date')) 267version_gen_environment.set('GIT_USER_AGENT', get_option('user_agent')) 268version_gen_environment.set('GIT_VERSION', get_option('version')) 269 270compiler = meson.get_compiler('c') 271 272libgit_sources = [ 273 'abspath.c', 274 'add-interactive.c', 275 'add-patch.c', 276 'advice.c', 277 'alias.c', 278 'alloc.c', 279 'apply.c', 280 'archive-tar.c', 281 'archive-zip.c', 282 'archive.c', 283 'attr.c', 284 'base85.c', 285 'bisect.c', 286 'blame.c', 287 'blob.c', 288 'bloom.c', 289 'branch.c', 290 'bundle-uri.c', 291 'bundle.c', 292 'cache-tree.c', 293 'cbtree.c', 294 'chdir-notify.c', 295 'checkout.c', 296 'chunk-format.c', 297 'color.c', 298 'column.c', 299 'combine-diff.c', 300 'commit-graph.c', 301 'commit-reach.c', 302 'commit.c', 303 'common-exit.c', 304 'common-init.c', 305 'compat/nonblock.c', 306 'compat/obstack.c', 307 'compat/open.c', 308 'compat/terminal.c', 309 'compiler-tricks/not-constant.c', 310 'config.c', 311 'connect.c', 312 'connected.c', 313 'convert.c', 314 'copy.c', 315 'credential.c', 316 'csum-file.c', 317 'ctype.c', 318 'date.c', 319 'decorate.c', 320 'delta-islands.c', 321 'diagnose.c', 322 'diff-delta.c', 323 'diff-merges.c', 324 'diff-lib.c', 325 'diff-no-index.c', 326 'diff.c', 327 'diffcore-break.c', 328 'diffcore-delta.c', 329 'diffcore-order.c', 330 'diffcore-pickaxe.c', 331 'diffcore-rename.c', 332 'diffcore-rotate.c', 333 'dir-iterator.c', 334 'dir.c', 335 'editor.c', 336 'entry.c', 337 'environment.c', 338 'ewah/bitmap.c', 339 'ewah/ewah_bitmap.c', 340 'ewah/ewah_io.c', 341 'ewah/ewah_rlw.c', 342 'exec-cmd.c', 343 'fetch-negotiator.c', 344 'fetch-pack.c', 345 'fmt-merge-msg.c', 346 'fsck.c', 347 'fsmonitor.c', 348 'fsmonitor-ipc.c', 349 'fsmonitor-settings.c', 350 'gettext.c', 351 'git-zlib.c', 352 'gpg-interface.c', 353 'graph.c', 354 'grep.c', 355 'hash-lookup.c', 356 'hash.c', 357 'hashmap.c', 358 'help.c', 359 'hex.c', 360 'hex-ll.c', 361 'hook.c', 362 'ident.c', 363 'json-writer.c', 364 'kwset.c', 365 'levenshtein.c', 366 'line-log.c', 367 'line-range.c', 368 'linear-assignment.c', 369 'list-objects-filter-options.c', 370 'list-objects-filter.c', 371 'list-objects.c', 372 'lockfile.c', 373 'log-tree.c', 374 'loose.c', 375 'ls-refs.c', 376 'mailinfo.c', 377 'mailmap.c', 378 'match-trees.c', 379 'mem-pool.c', 380 'merge-blobs.c', 381 'merge-ll.c', 382 'merge-ort.c', 383 'merge-ort-wrappers.c', 384 'merge.c', 385 'midx.c', 386 'midx-write.c', 387 'name-hash.c', 388 'negotiator/default.c', 389 'negotiator/noop.c', 390 'negotiator/skipping.c', 391 'notes-cache.c', 392 'notes-merge.c', 393 'notes-utils.c', 394 'notes.c', 395 'object-file-convert.c', 396 'object-file.c', 397 'object-name.c', 398 'object.c', 399 'odb.c', 400 'oid-array.c', 401 'oidmap.c', 402 'oidset.c', 403 'oidtree.c', 404 'pack-bitmap-write.c', 405 'pack-bitmap.c', 406 'pack-check.c', 407 'pack-mtimes.c', 408 'pack-objects.c', 409 'pack-refs.c', 410 'pack-revindex.c', 411 'pack-write.c', 412 'packfile.c', 413 'pager.c', 414 'parallel-checkout.c', 415 'parse.c', 416 'parse-options-cb.c', 417 'parse-options.c', 418 'patch-delta.c', 419 'patch-ids.c', 420 'path.c', 421 'path-walk.c', 422 'pathspec.c', 423 'pkt-line.c', 424 'preload-index.c', 425 'pretty.c', 426 'prio-queue.c', 427 'progress.c', 428 'promisor-remote.c', 429 'prompt.c', 430 'protocol.c', 431 'protocol-caps.c', 432 'prune-packed.c', 433 'pseudo-merge.c', 434 'quote.c', 435 'range-diff.c', 436 'reachable.c', 437 'read-cache.c', 438 'rebase-interactive.c', 439 'rebase.c', 440 'ref-filter.c', 441 'reflog-walk.c', 442 'reflog.c', 443 'refs.c', 444 'refs/debug.c', 445 'refs/files-backend.c', 446 'refs/reftable-backend.c', 447 'refs/iterator.c', 448 'refs/packed-backend.c', 449 'refs/ref-cache.c', 450 'refspec.c', 451 'reftable/basics.c', 452 'reftable/error.c', 453 'reftable/block.c', 454 'reftable/blocksource.c', 455 'reftable/fsck.c', 456 'reftable/iter.c', 457 'reftable/merged.c', 458 'reftable/pq.c', 459 'reftable/record.c', 460 'reftable/stack.c', 461 'reftable/system.c', 462 'reftable/table.c', 463 'reftable/tree.c', 464 'reftable/writer.c', 465 'remote.c', 466 'replace-object.c', 467 'repo-settings.c', 468 'repository.c', 469 'rerere.c', 470 'reset.c', 471 'resolve-undo.c', 472 'revision.c', 473 'run-command.c', 474 'send-pack.c', 475 'sequencer.c', 476 'serve.c', 477 'server-info.c', 478 'setup.c', 479 'shallow.c', 480 'sideband.c', 481 'sigchain.c', 482 'sparse-index.c', 483 'split-index.c', 484 'stable-qsort.c', 485 'statinfo.c', 486 'strbuf.c', 487 'streaming.c', 488 'string-list.c', 489 'strmap.c', 490 'strvec.c', 491 'sub-process.c', 492 'submodule-config.c', 493 'submodule.c', 494 'symlinks.c', 495 'tag.c', 496 'tempfile.c', 497 'thread-utils.c', 498 'tmp-objdir.c', 499 'trace.c', 500 'trace2.c', 501 'trace2/tr2_cfg.c', 502 'trace2/tr2_cmd_name.c', 503 'trace2/tr2_ctr.c', 504 'trace2/tr2_dst.c', 505 'trace2/tr2_sid.c', 506 'trace2/tr2_sysenv.c', 507 'trace2/tr2_tbuf.c', 508 'trace2/tr2_tgt_event.c', 509 'trace2/tr2_tgt_normal.c', 510 'trace2/tr2_tgt_perf.c', 511 'trace2/tr2_tls.c', 512 'trace2/tr2_tmr.c', 513 'trailer.c', 514 'transport-helper.c', 515 'transport.c', 516 'tree-diff.c', 517 'tree-walk.c', 518 'tree.c', 519 'unpack-trees.c', 520 'upload-pack.c', 521 'url.c', 522 'urlmatch.c', 523 'usage.c', 524 'userdiff.c', 525 'utf8.c', 526 'version.c', 527 'versioncmp.c', 528 'walker.c', 529 'wildmatch.c', 530 'worktree.c', 531 'wrapper.c', 532 'write-or-die.c', 533 'ws.c', 534 'wt-status.c', 535 'xdiff-interface.c', 536 'xdiff/xdiffi.c', 537 'xdiff/xemit.c', 538 'xdiff/xhistogram.c', 539 'xdiff/xmerge.c', 540 'xdiff/xpatience.c', 541 'xdiff/xprepare.c', 542 'xdiff/xutils.c', 543] 544 545libgit_sources += custom_target( 546 input: 'command-list.txt', 547 output: 'command-list.h', 548 command: [shell, meson.current_source_dir() + '/generate-cmdlist.sh', meson.current_source_dir(), '@OUTPUT@'], 549 env: script_environment, 550) 551 552builtin_sources = [ 553 'builtin/add.c', 554 'builtin/am.c', 555 'builtin/annotate.c', 556 'builtin/apply.c', 557 'builtin/archive.c', 558 'builtin/backfill.c', 559 'builtin/bisect.c', 560 'builtin/blame.c', 561 'builtin/branch.c', 562 'builtin/bugreport.c', 563 'builtin/bundle.c', 564 'builtin/cat-file.c', 565 'builtin/check-attr.c', 566 'builtin/check-ignore.c', 567 'builtin/check-mailmap.c', 568 'builtin/check-ref-format.c', 569 'builtin/checkout--worker.c', 570 'builtin/checkout-index.c', 571 'builtin/checkout.c', 572 'builtin/clean.c', 573 'builtin/clone.c', 574 'builtin/column.c', 575 'builtin/commit-graph.c', 576 'builtin/commit-tree.c', 577 'builtin/commit.c', 578 'builtin/config.c', 579 'builtin/count-objects.c', 580 'builtin/credential-cache--daemon.c', 581 'builtin/credential-cache.c', 582 'builtin/credential-store.c', 583 'builtin/credential.c', 584 'builtin/describe.c', 585 'builtin/diagnose.c', 586 'builtin/diff-files.c', 587 'builtin/diff-index.c', 588 'builtin/diff-pairs.c', 589 'builtin/diff-tree.c', 590 'builtin/diff.c', 591 'builtin/difftool.c', 592 'builtin/fast-export.c', 593 'builtin/fast-import.c', 594 'builtin/fetch-pack.c', 595 'builtin/fetch.c', 596 'builtin/fmt-merge-msg.c', 597 'builtin/for-each-ref.c', 598 'builtin/for-each-repo.c', 599 'builtin/fsck.c', 600 'builtin/fsmonitor--daemon.c', 601 'builtin/gc.c', 602 'builtin/get-tar-commit-id.c', 603 'builtin/grep.c', 604 'builtin/hash-object.c', 605 'builtin/help.c', 606 'builtin/hook.c', 607 'builtin/index-pack.c', 608 'builtin/init-db.c', 609 'builtin/interpret-trailers.c', 610 'builtin/last-modified.c', 611 'builtin/log.c', 612 'builtin/ls-files.c', 613 'builtin/ls-remote.c', 614 'builtin/ls-tree.c', 615 'builtin/mailinfo.c', 616 'builtin/mailsplit.c', 617 'builtin/merge-base.c', 618 'builtin/merge-file.c', 619 'builtin/merge-index.c', 620 'builtin/merge-ours.c', 621 'builtin/merge-recursive.c', 622 'builtin/merge-tree.c', 623 'builtin/merge.c', 624 'builtin/mktag.c', 625 'builtin/mktree.c', 626 'builtin/multi-pack-index.c', 627 'builtin/mv.c', 628 'builtin/name-rev.c', 629 'builtin/notes.c', 630 'builtin/pack-objects.c', 631 'builtin/pack-refs.c', 632 'builtin/patch-id.c', 633 'builtin/prune-packed.c', 634 'builtin/prune.c', 635 'builtin/pull.c', 636 'builtin/push.c', 637 'builtin/range-diff.c', 638 'builtin/read-tree.c', 639 'builtin/rebase.c', 640 'builtin/receive-pack.c', 641 'builtin/reflog.c', 642 'builtin/refs.c', 643 'builtin/remote-ext.c', 644 'builtin/remote-fd.c', 645 'builtin/remote.c', 646 'builtin/repack.c', 647 'builtin/replace.c', 648 'builtin/replay.c', 649 'builtin/repo.c', 650 'builtin/rerere.c', 651 'builtin/reset.c', 652 'builtin/rev-list.c', 653 'builtin/rev-parse.c', 654 'builtin/revert.c', 655 'builtin/rm.c', 656 'builtin/send-pack.c', 657 'builtin/shortlog.c', 658 'builtin/show-branch.c', 659 'builtin/show-index.c', 660 'builtin/show-ref.c', 661 'builtin/sparse-checkout.c', 662 'builtin/stash.c', 663 'builtin/stripspace.c', 664 'builtin/submodule--helper.c', 665 'builtin/symbolic-ref.c', 666 'builtin/tag.c', 667 'builtin/unpack-file.c', 668 'builtin/unpack-objects.c', 669 'builtin/update-index.c', 670 'builtin/update-ref.c', 671 'builtin/update-server-info.c', 672 'builtin/upload-archive.c', 673 'builtin/upload-pack.c', 674 'builtin/var.c', 675 'builtin/verify-commit.c', 676 'builtin/verify-pack.c', 677 'builtin/verify-tag.c', 678 'builtin/worktree.c', 679 'builtin/write-tree.c', 680] 681 682third_party_excludes = [ 683 ':!contrib', 684 ':!compat/inet_ntop.c', 685 ':!compat/inet_pton.c', 686 ':!compat/nedmalloc', 687 ':!compat/obstack.*', 688 ':!compat/poll', 689 ':!compat/regex', 690 ':!sha1collisiondetection', 691 ':!sha1dc', 692 ':!t/unit-tests/clar', 693 ':!t/t[0-9][0-9][0-9][0-9]*', 694 ':!xdiff', 695] 696 697headers_to_check = [] 698if git.found() and fs.exists(meson.project_source_root() / '.git') 699 ls_headers = run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.h', third_party_excludes, check: false) 700 if ls_headers.returncode() == 0 701 foreach header : ls_headers.stdout().split() 702 headers_to_check += header 703 endforeach 704 else 705 warning('could not list headers, disabling static analysis targets') 706 endif 707endif 708 709if not get_option('breaking_changes') 710 builtin_sources += 'builtin/pack-redundant.c' 711endif 712 713builtin_sources += custom_target( 714 output: 'config-list.h', 715 command: [ 716 shell, 717 meson.current_source_dir() + '/generate-configlist.sh', 718 meson.current_source_dir(), 719 '@OUTPUT@', 720 ], 721 env: script_environment, 722) 723 724builtin_sources += custom_target( 725 input: 'Documentation/githooks.adoc', 726 output: 'hook-list.h', 727 command: [ 728 shell, 729 meson.current_source_dir() + '/generate-hooklist.sh', 730 meson.current_source_dir(), 731 '@OUTPUT@', 732 ], 733 env: script_environment, 734) 735 736# This contains the variables for GIT-BUILD-OPTIONS, which we use to propagate 737# build options to our tests. 738build_options_config = configuration_data() 739build_options_config.set('GIT_INTEROP_MAKE_OPTS', '') 740build_options_config.set_quoted('GIT_PERF_LARGE_REPO', get_option('benchmark_large_repo')) 741build_options_config.set('GIT_PERF_MAKE_COMMAND', '') 742build_options_config.set('GIT_PERF_MAKE_OPTS', '') 743build_options_config.set_quoted('GIT_PERF_REPEAT_COUNT', get_option('benchmark_repeat_count').to_string()) 744build_options_config.set_quoted('GIT_PERF_REPO', get_option('benchmark_repo')) 745build_options_config.set('GIT_TEST_CMP_USE_COPIED_CONTEXT', '') 746build_options_config.set('GIT_TEST_INDEX_VERSION', '') 747build_options_config.set('GIT_TEST_OPTS', '') 748build_options_config.set('GIT_TEST_PERL_FATAL_WARNINGS', '') 749build_options_config.set_quoted('GIT_TEST_UTF8_LOCALE', get_option('test_utf8_locale')) 750build_options_config.set_quoted('LOCALEDIR', fs.as_posix(get_option('prefix') / get_option('localedir'))) 751build_options_config.set_quoted('GITWEBDIR', fs.as_posix(get_option('prefix') / get_option('datadir') / 'gitweb')) 752 753if get_option('sane_tool_path').length() != 0 754 sane_tool_path = (host_machine.system() == 'windows' ? ';' : ':').join(get_option('sane_tool_path')) 755 build_options_config.set_quoted('BROKEN_PATH_FIX', 's|^\# @BROKEN_PATH_FIX@$|git_broken_path_fix "' + sane_tool_path + '"|') 756else 757 build_options_config.set_quoted('BROKEN_PATH_FIX', '/^\# @BROKEN_PATH_FIX@$/d') 758endif 759 760test_output_directory = get_option('test_output_directory') 761if test_output_directory == '' 762 test_output_directory = meson.project_build_root() / 'test-output' 763endif 764 765# These variables are used for building libgit.a. 766libgit_c_args = [ 767 '-DBINDIR="' + get_option('bindir') + '"', 768 '-DDEFAULT_GIT_TEMPLATE_DIR="' + get_option('datadir') / 'git-core/templates' + '"', 769 '-DFALLBACK_RUNTIME_PREFIX="' + get_option('prefix') + '"', 770 '-DGIT_HOST_CPU="' + host_machine.cpu_family() + '"', 771 '-DGIT_HTML_PATH="' + get_option('datadir') / 'doc/git-doc"', 772 '-DGIT_INFO_PATH="' + get_option('infodir') + '"', 773 '-DGIT_LOCALE_PATH="' + get_option('localedir') + '"', 774 '-DGIT_MAN_PATH="' + get_option('mandir') + '"', 775 '-DPAGER_ENV="' + get_option('pager_environment') + '"', 776 '-DSHELL_PATH="' + fs.as_posix(target_shell.full_path()) + '"', 777] 778 779system_attributes = get_option('gitattributes') 780if system_attributes != '' 781 libgit_c_args += '-DETC_GITATTRIBUTES="' + system_attributes + '"' 782else 783 libgit_c_args += '-DETC_GITATTRIBUTES="' + get_option('sysconfdir') / 'gitattributes"' 784endif 785 786system_config = get_option('gitconfig') 787if system_config != '' 788 libgit_c_args += '-DETC_GITCONFIG="' + system_config + '"' 789else 790 libgit_c_args += '-DETC_GITCONFIG="' + get_option('sysconfdir') / 'gitconfig"' 791endif 792 793editor_opt = get_option('default_editor') 794if editor_opt != '' and editor_opt != 'vi' 795 libgit_c_args += '-DDEFAULT_EDITOR="' + editor_opt + '"' 796endif 797 798pager_opt = get_option('default_pager') 799if pager_opt != '' and pager_opt != 'less' 800 libgit_c_args += '-DDEFAULT_PAGER="' + pager_opt + '"' 801endif 802 803help_format_opt = get_option('default_help_format') 804if help_format_opt == 'platform' 805 if host_machine.system() == 'windows' 806 help_format_opt = 'html' 807 else 808 help_format_opt = 'man' 809 endif 810endif 811if help_format_opt != 'man' 812 libgit_c_args += '-DDEFAULT_HELP_FORMAT="' + help_format_opt + '"' 813endif 814 815libgit_include_directories = [ '.' ] 816libgit_dependencies = [ ] 817 818# Treat any warning level above 1 the same as we treat DEVELOPER=1 in our 819# Makefile. 820if get_option('warning_level') in ['2','3', 'everything'] and compiler.get_argument_syntax() == 'gcc' 821 foreach cflag : [ 822 '-Wcomma', 823 '-Wdeclaration-after-statement', 824 '-Wformat-security', 825 '-Wold-style-definition', 826 '-Woverflow', 827 '-Wpointer-arith', 828 '-Wstrict-prototypes', 829 '-Wunreachable-code', 830 '-Wunused', 831 '-Wvla', 832 '-Wwrite-strings', 833 '-fno-common', 834 '-Wtautological-constant-out-of-range-compare', 835 # If a function is public, there should be a prototype and the right 836 # header file should be included. If not, it should be static. 837 '-Wmissing-prototypes', 838 # These are disabled because we have these all over the place. 839 '-Wno-empty-body', 840 '-Wno-missing-field-initializers', 841 ] 842 if compiler.has_argument(cflag) 843 libgit_c_args += cflag 844 endif 845 endforeach 846endif 847 848if get_option('breaking_changes') 849 build_options_config.set('WITH_BREAKING_CHANGES', 'YesPlease') 850 libgit_c_args += '-DWITH_BREAKING_CHANGES' 851else 852 build_options_config.set('WITH_BREAKING_CHANGES', '') 853endif 854 855if get_option('b_sanitize').contains('address') 856 build_options_config.set('SANITIZE_ADDRESS', 'YesCompiledWithIt') 857else 858 build_options_config.set('SANITIZE_ADDRESS', '') 859endif 860if get_option('b_sanitize').contains('leak') 861 build_options_config.set('SANITIZE_LEAK', 'YesCompiledWithIt') 862else 863 build_options_config.set('SANITIZE_LEAK', '') 864endif 865if get_option('b_sanitize').contains('undefined') 866 libgit_c_args += '-DSHA1DC_FORCE_ALIGNED_ACCESS' 867endif 868 869executable_suffix = '' 870if host_machine.system() == 'cygwin' or host_machine.system() == 'windows' 871 executable_suffix = '.exe' 872 libgit_c_args += '-DSTRIP_EXTENSION="' + executable_suffix + '"' 873endif 874build_options_config.set_quoted('X', executable_suffix) 875 876# Python is not used for our build system, but exclusively for git-p4. 877# Consequently we only need to determine whether Python is available for the 878# build target. 879target_python = find_program('python3', native: false, required: get_option('python')) 880if target_python.found() 881 build_options_config.set('NO_PYTHON', '') 882else 883 libgit_c_args += '-DNO_PYTHON' 884 build_options_config.set('NO_PYTHON', '1') 885endif 886 887# Perl is used for two different things: our test harness and to provide some 888# features. It is optional if you want to neither execute tests nor use any of 889# these optional features. 890perl_required = get_option('perl') 891if get_option('benchmarks').enabled() or get_option('gitweb').enabled() or 'netrc' in get_option('credential_helpers') 892 perl_required = true 893endif 894 895# Note that we only set NO_PERL if the Perl features were disabled by the user. 896# It may not be set when we have found Perl, but only use it to run tests. 897# 898# At the time of writing, executing `perl --version` results in a string 899# similar to the following output: 900# 901# This is perl 5, version 40, subversion 0 (v5.40.0) built for x86_64-linux-thread-multi 902# 903# Meson picks up the "40" as version number instead of using "v5.40.0" 904# due to the regular expression it uses. This got fixed in Meson 1.7.0, 905# but meanwhile we have to either use `-V:version` instead of `--version`, 906# which we can do starting with Meson 1.5.0 and newer, or we have to 907# match against the minor version. 908if meson.version().version_compare('>=1.5.0') 909 perl = find_program('perl', dirs: program_path, native: true, required: perl_required, version: '>=5.26.0', version_argument: '-V:version') 910 target_perl = find_program('perl', dirs: program_path, native: false, required: perl.found(), version: '>=5.26.0', version_argument: '-V:version') 911else 912 perl = find_program('perl', dirs: program_path, native: true, required: perl_required, version: '>=26') 913 target_perl = find_program('perl', dirs: program_path, native: false, required: perl.found(), version: '>=26') 914endif 915perl_features_enabled = perl.found() and get_option('perl').allowed() 916if perl_features_enabled 917 build_options_config.set('NO_PERL', '') 918 919 if get_option('runtime_prefix') 920 build_options_config.set('PERL_LOCALEDIR', '') 921 else 922 build_options_config.set_quoted('PERL_LOCALEDIR', fs.as_posix(get_option('prefix') / get_option('localedir'))) 923 endif 924 925 if get_option('perl_cpan_fallback') 926 build_options_config.set('NO_PERL_CPAN_FALLBACKS', '') 927 else 928 build_options_config.set_quoted('NO_PERL_CPAN_FALLBACKS', 'YesPlease') 929 endif 930else 931 libgit_c_args += '-DNO_PERL' 932 build_options_config.set('NO_PERL', '1') 933 build_options_config.set('PERL_LOCALEDIR', '') 934 build_options_config.set('NO_PERL_CPAN_FALLBACKS', '') 935endif 936 937zlib_backend = get_option('zlib_backend') 938if zlib_backend in ['auto', 'zlib-ng'] 939 zlib_ng = dependency('zlib-ng', required: zlib_backend == 'zlib-ng') 940 if zlib_ng.found() 941 zlib_backend = 'zlib-ng' 942 libgit_c_args += '-DHAVE_ZLIB_NG' 943 libgit_dependencies += zlib_ng 944 endif 945endif 946if zlib_backend in ['auto', 'zlib'] 947 zlib = dependency('zlib', default_options: ['default_library=static', 'tests=disabled']) 948 if zlib.version().version_compare('<1.2.0') 949 libgit_c_args += '-DNO_DEFLATE_BOUND' 950 endif 951 zlib_backend = 'zlib' 952 libgit_dependencies += zlib 953endif 954 955threads = dependency('threads', required: false) 956if threads.found() 957 libgit_dependencies += threads 958 build_options_config.set('NO_PTHREADS', '') 959else 960 libgit_c_args += '-DNO_PTHREADS' 961 build_options_config.set('NO_PTHREADS', '1') 962endif 963 964msgfmt = find_program('msgfmt', dirs: program_path, native: true, required: false) 965gettext_option = get_option('gettext').disable_auto_if(not msgfmt.found()) 966if not msgfmt.found() and gettext_option.enabled() 967 error('Internationalization via libintl requires msgfmt') 968endif 969 970if gettext_option.allowed() and host_machine.system() == 'darwin' and get_option('macos_use_homebrew_gettext') 971 if host_machine.cpu_family() == 'x86_64' 972 libintl_prefix = '/usr/local' 973 elif host_machine.cpu_family() == 'aarch64' 974 libintl_prefix = '/opt/homebrew' 975 else 976 error('Homebrew workaround not supported on current architecture') 977 endif 978 979 intl = compiler.find_library('intl', dirs: libintl_prefix / 'lib', required: gettext_option) 980 if intl.found() 981 intl = declare_dependency( 982 dependencies: intl, 983 include_directories: libintl_prefix / 'include', 984 ) 985 endif 986else 987 intl = dependency('intl', required: gettext_option) 988endif 989if intl.found() 990 libgit_dependencies += intl 991 build_options_config.set('NO_GETTEXT', '') 992 build_options_config.set('USE_GETTEXT_SCHEME', '') 993 994 # POSIX nowadays requires `nl_langinfo()`, but some systems still don't have 995 # the function available. On such systems we instead fall back to libcharset. 996 # On native Windows systems we use our own emulation. 997 if host_machine.system() != 'windows' and not compiler.has_function('nl_langinfo') 998 libcharset = compiler.find_library('charset', required: true) 999 libgit_dependencies += libcharset 1000 libgit_c_args += '-DHAVE_LIBCHARSET_H' 1001 endif 1002else 1003 libgit_c_args += '-DNO_GETTEXT' 1004 build_options_config.set('NO_GETTEXT', '1') 1005 build_options_config.set('USE_GETTEXT_SCHEME', 'fallthrough') 1006endif 1007 1008iconv = dependency('iconv', required: get_option('iconv')) 1009if iconv.found() 1010 libgit_dependencies += iconv 1011 build_options_config.set('NO_ICONV', '') 1012 1013 have_old_iconv = false 1014 if not compiler.compiles(''' 1015 #include <iconv.h> 1016 1017 extern size_t iconv(iconv_t cd, 1018 char **inbuf, size_t *inbytesleft, 1019 char **outbuf, size_t *outbytesleft); 1020 ''', name: 'old iconv interface', dependencies: [iconv]) 1021 libgit_c_args += '-DOLD_ICONV' 1022 have_old_iconv = true 1023 endif 1024 1025 iconv_omits_bom_source = '''# 1026 #include <iconv.h> 1027 1028 int main(int argc, const char **argv) 1029 { 1030 ''' 1031 if have_old_iconv 1032 iconv_omits_bom_source += ''' 1033 typedef const char *iconv_ibp; 1034 ''' 1035 else 1036 iconv_omits_bom_source += ''' 1037 typedef char *iconv_ibp; 1038 ''' 1039 endif 1040 iconv_omits_bom_source += ''' 1041 int v; 1042 iconv_t conv; 1043 char in[] = "a"; iconv_ibp pin = in; 1044 char out[20] = ""; char *pout = out; 1045 size_t isz = sizeof in; 1046 size_t osz = sizeof out; 1047 1048 conv = iconv_open("UTF-16", "UTF-8"); 1049 iconv(conv, &pin, &isz, &pout, &osz); 1050 iconv_close(conv); 1051 v = (unsigned char)(out[0]) + (unsigned char)(out[1]); 1052 return v != 0xfe + 0xff; 1053 } 1054 ''' 1055 1056 if compiler.run(iconv_omits_bom_source, 1057 dependencies: iconv, 1058 name: 'iconv omits BOM', 1059 ).returncode() != 0 1060 libgit_c_args += '-DICONV_OMITS_BOM' 1061 endif 1062else 1063 libgit_c_args += '-DNO_ICONV' 1064 build_options_config.set('NO_ICONV', '1') 1065endif 1066 1067# can't use enable_auto_if() because it is only available in meson 1.1 1068if host_machine.system() == 'windows' and get_option('pcre2').allowed() 1069 pcre2_feature = true 1070else 1071 pcre2_feature = get_option('pcre2') 1072endif 1073pcre2 = dependency('libpcre2-8', required: pcre2_feature, default_options: ['default_library=static', 'test=false']) 1074if pcre2.found() and pcre2.type_name() != 'internal' and host_machine.system() == 'darwin' 1075 # macOS installs a broken system package, double check 1076 if not compiler.has_header('pcre2.h', dependencies: pcre2) 1077 if pcre2_feature.enabled() 1078 pcre2_fallback = ['pcre2', 'libpcre2_8'] 1079 else 1080 pcre2_fallback = [] 1081 endif 1082 # Attempt to fallback or replace with not-found-dependency 1083 pcre2 = dependency('', required: false, fallback: pcre2_fallback, default_options: ['default_library=static', 'test=false']) 1084 if not pcre2.found() 1085 if pcre2_feature.enabled() 1086 error('only a broken pcre2 install found and pcre2 is required') 1087 else 1088 warning('broken pcre2 install found, disabling pcre2 feature') 1089 endif 1090 endif 1091 endif 1092endif 1093 1094if pcre2.found() 1095 libgit_dependencies += pcre2 1096 libgit_c_args += '-DUSE_LIBPCRE2' 1097 build_options_config.set('USE_LIBPCRE2', '1') 1098else 1099 build_options_config.set('USE_LIBPCRE2', '') 1100endif 1101 1102curl = dependency('libcurl', version: '>=7.21.3', required: get_option('curl'), default_options: ['default_library=static', 'tests=disabled', 'tool=disabled']) 1103use_curl_for_imap_send = false 1104if curl.found() 1105 if curl.version().version_compare('>=7.34.0') 1106 libgit_c_args += '-DUSE_CURL_FOR_IMAP_SEND' 1107 use_curl_for_imap_send = true 1108 endif 1109 1110 # Most executables don't have to link against libcurl, but we still need its 1111 # include directories so that we can resolve LIBCURL_VERSION in "help.c". 1112 libgit_dependencies += curl.partial_dependency(includes: true) 1113 build_options_config.set('NO_CURL', '') 1114else 1115 libgit_c_args += '-DNO_CURL' 1116 build_options_config.set('NO_CURL', '1') 1117endif 1118 1119expat = dependency('expat', required: get_option('expat'), default_options: ['default_library=static', 'build_tests=false']) 1120if expat.found() 1121 libgit_dependencies += expat 1122 1123 if expat.version().version_compare('<=1.2') 1124 libgit_c_args += '-DEXPAT_NEEDS_XMLPARSE_H' 1125 endif 1126 build_options_config.set('NO_EXPAT', '') 1127else 1128 libgit_c_args += '-DNO_EXPAT' 1129 build_options_config.set('NO_EXPAT', '1') 1130endif 1131 1132if not compiler.has_header('sys/select.h') 1133 libgit_c_args += '-DNO_SYS_SELECT_H' 1134endif 1135 1136has_poll_h = compiler.has_header('poll.h') 1137if not has_poll_h 1138 libgit_c_args += '-DNO_POLL_H' 1139endif 1140 1141has_sys_poll_h = compiler.has_header('sys/poll.h') 1142if not has_sys_poll_h 1143 libgit_c_args += '-DNO_SYS_POLL_H' 1144endif 1145 1146if not has_poll_h and not has_sys_poll_h 1147 libgit_c_args += '-DNO_POLL' 1148 libgit_sources += 'compat/poll/poll.c' 1149 libgit_include_directories += 'compat/poll' 1150endif 1151 1152if not compiler.has_header('inttypes.h') 1153 libgit_c_args += '-DNO_INTTYPES_H' 1154endif 1155 1156if compiler.has_header('alloca.h') 1157 libgit_c_args += '-DHAVE_ALLOCA_H' 1158endif 1159 1160# Windows has libgen.h and a basename implementation, but we still need our own 1161# implementation to threat things like drive prefixes specially. 1162if host_machine.system() == 'windows' or not compiler.has_header('libgen.h') 1163 libgit_c_args += '-DNO_LIBGEN_H' 1164 libgit_sources += 'compat/basename.c' 1165endif 1166 1167if compiler.has_header('paths.h') 1168 libgit_c_args += '-DHAVE_PATHS_H' 1169endif 1170 1171if compiler.has_header('strings.h') 1172 libgit_c_args += '-DHAVE_STRINGS_H' 1173endif 1174 1175networking_dependencies = [ ] 1176if host_machine.system() == 'windows' 1177 winsock = compiler.find_library('ws2_32', required: false) 1178 if winsock.found() 1179 networking_dependencies += winsock 1180 endif 1181else 1182 networking_dependencies += [ 1183 compiler.find_library('nsl', required: false), 1184 compiler.find_library('resolv', required: false), 1185 compiler.find_library('socket', required: false), 1186 ] 1187endif 1188libgit_dependencies += networking_dependencies 1189 1190if host_machine.system() != 'windows' 1191 foreach symbol : ['inet_ntop', 'inet_pton', 'hstrerror'] 1192 if not compiler.has_function(symbol, dependencies: networking_dependencies) 1193 libgit_c_args += '-DNO_' + symbol.to_upper() 1194 libgit_sources += 'compat/' + symbol + '.c' 1195 endif 1196 endforeach 1197endif 1198 1199has_ipv6 = compiler.has_function('getaddrinfo', dependencies: networking_dependencies) 1200if not has_ipv6 1201 libgit_c_args += '-DNO_IPV6' 1202endif 1203 1204if not compiler.compiles(''' 1205 #ifdef _WIN32 1206 # include <winsock2.h> 1207 #else 1208 # include <sys/types.h> 1209 # include <sys/socket.h> 1210 #endif 1211 1212 void func(void) 1213 { 1214 struct sockaddr_storage x; 1215 } 1216''', name: 'struct sockaddr_storage') 1217 if has_ipv6 1218 libgit_c_args += '-Dsockaddr_storage=sockaddr_in6' 1219 else 1220 libgit_c_args += '-Dsockaddr_storage=sockaddr_in' 1221 endif 1222endif 1223 1224if compiler.has_function('socket', dependencies: networking_dependencies) 1225 libgit_sources += [ 1226 'unix-socket.c', 1227 'unix-stream-server.c', 1228 ] 1229 build_options_config.set('NO_UNIX_SOCKETS', '') 1230else 1231 libgit_c_args += '-DNO_UNIX_SOCKETS' 1232 build_options_config.set('NO_UNIX_SOCKETS', '1') 1233endif 1234 1235if host_machine.system() == 'darwin' 1236 libgit_sources += 'compat/precompose_utf8.c' 1237 libgit_c_args += '-DPRECOMPOSE_UNICODE' 1238 libgit_c_args += '-DPROTECT_HFS_DEFAULT' 1239endif 1240 1241# Configure general compatibility wrappers. 1242if host_machine.system() == 'cygwin' 1243 libgit_sources += [ 1244 'compat/win32/path-utils.c', 1245 ] 1246elif host_machine.system() == 'windows' 1247 libgit_sources += [ 1248 'compat/winansi.c', 1249 'compat/win32/dirent.c', 1250 'compat/win32/flush.c', 1251 'compat/win32/path-utils.c', 1252 'compat/win32/pthread.c', 1253 'compat/win32/syslog.c', 1254 'compat/win32mmap.c', 1255 'compat/nedmalloc/nedmalloc.c', 1256 ] 1257 1258 libgit_c_args += [ 1259 '-DDETECT_MSYS_TTY', 1260 '-DENSURE_MSYSTEM_IS_SET', 1261 '-DNATIVE_CRLF', 1262 '-DNOGDI', 1263 '-DNO_POSIX_GOODIES', 1264 '-DWIN32', 1265 '-D_CONSOLE', 1266 '-D_CONSOLE_DETECT_MSYS_TTY', 1267 '-D__USE_MINGW_ANSI_STDIO=0', 1268 ] 1269 1270 libgit_dependencies += compiler.find_library('ntdll') 1271 libgit_include_directories += 'compat/win32' 1272 if compiler.get_id() == 'msvc' 1273 libgit_include_directories += 'compat/vcbuild/include' 1274 libgit_sources += 'compat/msvc.c' 1275 else 1276 libgit_sources += 'compat/mingw.c' 1277 endif 1278endif 1279 1280if host_machine.system() == 'linux' 1281 libgit_sources += 'compat/linux/procinfo.c' 1282elif host_machine.system() == 'windows' 1283 libgit_sources += 'compat/win32/trace2_win32_process_info.c' 1284else 1285 libgit_sources += 'compat/stub/procinfo.c' 1286endif 1287 1288if host_machine.system() == 'cygwin' or host_machine.system() == 'windows' 1289 libgit_c_args += [ 1290 '-DUNRELIABLE_FSTAT', 1291 '-DMMAP_PREVENTS_DELETE', 1292 '-DOBJECT_CREATION_MODE=1', 1293 ] 1294endif 1295 1296# Configure the simple-ipc subsystem required fro the fsmonitor. 1297if host_machine.system() == 'windows' 1298 libgit_sources += [ 1299 'compat/simple-ipc/ipc-shared.c', 1300 'compat/simple-ipc/ipc-win32.c', 1301 ] 1302 libgit_c_args += '-DSUPPORTS_SIMPLE_IPC' 1303else 1304 libgit_sources += [ 1305 'compat/simple-ipc/ipc-shared.c', 1306 'compat/simple-ipc/ipc-unix-socket.c', 1307 ] 1308 libgit_c_args += '-DSUPPORTS_SIMPLE_IPC' 1309endif 1310 1311fsmonitor_backend = '' 1312if host_machine.system() == 'windows' 1313 fsmonitor_backend = 'win32' 1314elif host_machine.system() == 'darwin' 1315 fsmonitor_backend = 'darwin' 1316 libgit_dependencies += dependency('CoreServices') 1317endif 1318if fsmonitor_backend != '' 1319 libgit_c_args += '-DHAVE_FSMONITOR_DAEMON_BACKEND' 1320 libgit_c_args += '-DHAVE_FSMONITOR_OS_SETTINGS' 1321 1322 libgit_sources += [ 1323 'compat/fsmonitor/fsm-health-' + fsmonitor_backend + '.c', 1324 'compat/fsmonitor/fsm-ipc-' + fsmonitor_backend + '.c', 1325 'compat/fsmonitor/fsm-listen-' + fsmonitor_backend + '.c', 1326 'compat/fsmonitor/fsm-path-utils-' + fsmonitor_backend + '.c', 1327 'compat/fsmonitor/fsm-settings-' + fsmonitor_backend + '.c', 1328 ] 1329endif 1330build_options_config.set_quoted('FSMONITOR_DAEMON_BACKEND', fsmonitor_backend) 1331build_options_config.set_quoted('FSMONITOR_OS_SETTINGS', fsmonitor_backend) 1332 1333if 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>') != '' 1334 build_options_config.set('NO_REGEX', '') 1335 1336 if compiler.get_define('REG_ENHANCED', prefix: '#include <regex.h>') != '' 1337 libgit_c_args += '-DUSE_ENHANCED_BASIC_REGULAR_EXPRESSIONS' 1338 libgit_sources += 'compat/regcomp_enhanced.c' 1339 endif 1340elif not get_option('regex').enabled() 1341 libgit_c_args += [ 1342 '-DNO_REGEX', 1343 '-DGAWK', 1344 '-DNO_MBSUPPORT', 1345 ] 1346 build_options_config.set('NO_REGEX', '1') 1347 libgit_sources += 'compat/regex/regex.c' 1348 libgit_include_directories += 'compat/regex' 1349else 1350 error('Native regex support requested but not found') 1351endif 1352 1353# setitimer and friends are provided by compat/mingw.c. 1354if host_machine.system() != 'windows' 1355 if not compiler.compiles(''' 1356 #include <sys/time.h> 1357 void func(void) 1358 { 1359 struct itimerval value; 1360 } 1361 ''', name: 'struct itimerval') 1362 libgit_c_args += '-DNO_STRUCT_ITIMERVAL' 1363 libgit_c_args += '-DNO_SETITIMER' 1364 elif not compiler.has_function('setitimer') 1365 libgit_c_args += '-DNO_SETITIMER' 1366 endif 1367endif 1368 1369if compiler.has_member('struct stat', 'st_mtimespec.tv_nsec', prefix: '#include <sys/stat.h>') 1370 libgit_c_args += '-DUSE_ST_TIMESPEC' 1371elif not compiler.has_member('struct stat', 'st_mtim.tv_nsec', prefix: '#include <sys/stat.h>') 1372 libgit_c_args += '-DNO_NSEC' 1373endif 1374 1375if not compiler.has_member('struct stat', 'st_blocks', prefix: '#include <sys/stat.h>') 1376 libgit_c_args += '-DNO_ST_BLOCKS_IN_STRUCT_STAT' 1377endif 1378 1379if not compiler.has_member('struct dirent', 'd_type', prefix: '#include <dirent.h>') 1380 libgit_c_args += '-DNO_D_TYPE_IN_DIRENT' 1381endif 1382 1383if not compiler.has_member('struct passwd', 'pw_gecos', prefix: '#include <pwd.h>') 1384 libgit_c_args += '-DNO_GECOS_IN_PWENT' 1385endif 1386 1387checkfuncs = { 1388 'strcasestr' : ['strcasestr.c'], 1389 'memmem' : ['memmem.c'], 1390 'strlcpy' : ['strlcpy.c'], 1391 'strtoull' : [], 1392 'setenv' : ['setenv.c'], 1393 'mkdtemp' : ['mkdtemp.c'], 1394 'initgroups' : [], 1395 'strtoumax' : ['strtoumax.c', 'strtoimax.c'], 1396 'pread' : ['pread.c'], 1397} 1398 1399if host_machine.system() == 'windows' 1400 libgit_c_args += '-DUSE_WIN32_MMAP' 1401else 1402 checkfuncs += { 1403 'mmap' : ['mmap.c'], 1404 # provided by compat/mingw.c. 1405 'unsetenv' : ['unsetenv.c'], 1406 # provided by compat/mingw.c. 1407 'getpagesize' : [], 1408 } 1409endif 1410 1411foreach func, impls : checkfuncs 1412 if not compiler.has_function(func) 1413 libgit_c_args += '-DNO_' + func.to_upper() 1414 foreach impl : impls 1415 libgit_sources += 'compat/' + impl 1416 endforeach 1417 endif 1418endforeach 1419 1420if compiler.has_function('sync_file_range') 1421 libgit_c_args += '-DHAVE_SYNC_FILE_RANGE' 1422endif 1423 1424if not compiler.has_function('strdup') 1425 libgit_c_args += '-DOVERRIDE_STRDUP' 1426 libgit_sources += 'compat/strdup.c' 1427endif 1428 1429if not compiler.has_function('qsort') 1430 libgit_c_args += '-DINTERNAL_QSORT' 1431endif 1432libgit_sources += 'compat/qsort_s.c' 1433 1434if compiler.has_function('getdelim') 1435 libgit_c_args += '-DHAVE_GETDELIM' 1436endif 1437 1438 1439if compiler.has_function('clock_gettime') 1440 libgit_c_args += '-DHAVE_CLOCK_GETTIME' 1441endif 1442 1443if compiler.compiles(''' 1444 #include <time.h> 1445 1446 void func(void) 1447 { 1448 clockid_t id = CLOCK_MONOTONIC; 1449 } 1450''', name: 'monotonic clock') 1451 libgit_c_args += '-DHAVE_CLOCK_MONOTONIC' 1452endif 1453 1454has_bsd_sysctl = false 1455if compiler.has_header('sys/sysctl.h') 1456 if compiler.compiles(''' 1457 #include <stddef.h> 1458 #include <sys/sysctl.h> 1459 1460 void func(void) 1461 { 1462 int val, mib[2] = { 0 }; 1463 size_t len = sizeof(val); 1464 sysctl(mib, 2, &val, &len, NULL, 0); 1465 } 1466 ''', name: 'BSD sysctl') 1467 libgit_c_args += '-DHAVE_BSD_SYSCTL' 1468 has_bsd_sysctl = true 1469 endif 1470endif 1471 1472if not has_bsd_sysctl 1473 if compiler.has_member('struct sysinfo', 'totalram', prefix: '#include <sys/sysinfo.h>') 1474 libgit_c_args += '-DHAVE_SYSINFO' 1475 endif 1476endif 1477 1478if not meson.is_cross_build() and compiler.run(''' 1479 #include <stdio.h> 1480 1481 int main(int argc, const char **argv) 1482 { 1483 FILE *f = fopen(".", "r"); 1484 return f ? 0 : 1; 1485 } 1486''', name: 'fread reads directories').returncode() == 0 1487 libgit_c_args += '-DFREAD_READS_DIRECTORIES' 1488 libgit_sources += 'compat/fopen.c' 1489endif 1490 1491if not meson.is_cross_build() and fs.exists('/dev/tty') 1492 libgit_c_args += '-DHAVE_DEV_TTY' 1493endif 1494 1495csprng_backend = get_option('csprng_backend') 1496https_backend = get_option('https_backend') 1497sha1_backend = get_option('sha1_backend') 1498sha1_unsafe_backend = get_option('sha1_unsafe_backend') 1499sha256_backend = get_option('sha256_backend') 1500 1501security_framework = dependency('Security', required: 'CommonCrypto' in [https_backend, sha1_backend, sha1_unsafe_backend]) 1502core_foundation_framework = dependency('CoreFoundation', required: security_framework.found()) 1503if https_backend == 'auto' and security_framework.found() 1504 https_backend = 'CommonCrypto' 1505endif 1506 1507openssl_required = 'openssl' in [csprng_backend, https_backend, sha1_backend, sha1_unsafe_backend, sha256_backend] 1508openssl = dependency('openssl', 1509 required: openssl_required, 1510 allow_fallback: openssl_required or https_backend == 'auto', 1511 default_options: ['default_library=static'], 1512) 1513if https_backend == 'auto' and openssl.found() 1514 https_backend = 'openssl' 1515endif 1516 1517if https_backend == 'CommonCrypto' 1518 libgit_dependencies += security_framework 1519 libgit_dependencies += core_foundation_framework 1520 libgit_c_args += '-DAPPLE_COMMON_CRYPTO' 1521elif https_backend == 'openssl' 1522 libgit_dependencies += openssl 1523else 1524 # We either couldn't find any dependencies with 'auto' or the user requested 1525 # 'none'. Both cases are benign. 1526 https_backend = 'none' 1527endif 1528 1529if https_backend != 'openssl' 1530 libgit_c_args += '-DNO_OPENSSL' 1531endif 1532 1533if sha1_backend == 'sha1dc' 1534 libgit_c_args += '-DSHA1_DC' 1535 libgit_c_args += '-DSHA1DC_NO_STANDARD_INCLUDES=1' 1536 libgit_c_args += '-DSHA1DC_INIT_SAFE_HASH_DEFAULT=0' 1537 libgit_c_args += '-DSHA1DC_CUSTOM_INCLUDE_SHA1_C="git-compat-util.h"' 1538 libgit_c_args += '-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C="git-compat-util.h"' 1539 1540 libgit_sources += [ 1541 'sha1dc_git.c', 1542 'sha1dc/sha1.c', 1543 'sha1dc/ubc_check.c', 1544 ] 1545endif 1546if sha1_backend == 'CommonCrypto' or sha1_unsafe_backend == 'CommonCrypto' 1547 if sha1_backend == 'CommonCrypto' 1548 libgit_c_args += '-DSHA1_APPLE' 1549 endif 1550 if sha1_unsafe_backend == 'CommonCrypto' 1551 libgit_c_args += '-DSHA1_APPLE_UNSAFE' 1552 endif 1553 1554 libgit_c_args += '-DCOMMON_DIGEST_FOR_OPENSSL' 1555 # Apple CommonCrypto requires chunking 1556 libgit_c_args += '-DSHA1_MAX_BLOCK_SIZE=1024L*1024L*1024L' 1557endif 1558if sha1_backend == 'openssl' or sha1_unsafe_backend == 'openssl' 1559 if sha1_backend == 'openssl' 1560 libgit_c_args += '-DSHA1_OPENSSL' 1561 endif 1562 if sha1_unsafe_backend == 'openssl' 1563 libgit_c_args += '-DSHA1_OPENSSL_UNSAFE' 1564 endif 1565 1566 libgit_dependencies += openssl 1567endif 1568if sha1_backend == 'block' or sha1_unsafe_backend == 'block' 1569 if sha1_backend == 'block' 1570 libgit_c_args += '-DSHA1_BLK' 1571 endif 1572 if sha1_unsafe_backend == 'block' 1573 libgit_c_args += '-DSHA1_BLK_UNSAFE' 1574 endif 1575 1576 libgit_sources += 'block-sha1/sha1.c' 1577endif 1578 1579if sha256_backend == 'openssl' 1580 libgit_c_args += '-DSHA256_OPENSSL' 1581 libgit_dependencies += openssl 1582elif sha256_backend == 'nettle' 1583 nettle = dependency('nettle') 1584 libgit_dependencies += nettle 1585 libgit_c_args += '-DSHA256_NETTLE' 1586elif sha256_backend == 'gcrypt' 1587 gcrypt = dependency('gcrypt') 1588 libgit_dependencies += gcrypt 1589 libgit_c_args += '-DSHA256_GCRYPT' 1590elif sha256_backend == 'block' 1591 libgit_c_args += '-DSHA256_BLK' 1592 libgit_sources += 'sha256/block/sha256.c' 1593else 1594 error('Unhandled SHA256 backend ' + sha256_backend) 1595endif 1596 1597# Backends are ordered to reflect our preference for more secure and faster 1598# ones over the ones that are less so. 1599if csprng_backend in ['auto', 'arc4random'] and compiler.has_header_symbol('stdlib.h', 'arc4random_buf', required: csprng_backend == 'arc4random') 1600 libgit_c_args += '-DHAVE_ARC4RANDOM' 1601 csprng_backend = 'arc4random' 1602elif csprng_backend in ['auto', 'arc4random_bsd'] and compiler.has_header_symbol('bsd/stdlib.h', 'arc4random_buf', required: csprng_backend == 'arc4random_bsd') 1603 libgit_c_args += '-DHAVE_ARC4RANDOM_BSD' 1604 csprng_backend = 'arc4random_bsd' 1605elif csprng_backend in ['auto', 'getrandom'] and compiler.has_header_symbol('sys/random.h', 'getrandom', required: csprng_backend == 'getrandom') 1606 libgit_c_args += '-DHAVE_GETRANDOM' 1607 csprng_backend = 'getrandom' 1608elif csprng_backend in ['auto', 'getentropy'] and compiler.has_header_symbol('unistd.h', 'getentropy', required: csprng_backend == 'getentropy') 1609 libgit_c_args += '-DHAVE_GETENTROPY' 1610 csprng_backend = 'getentropy' 1611elif csprng_backend in ['auto', 'rtlgenrandom'] and compiler.has_header_symbol('ntsecapi.h', 'RtlGenRandom', prefix: '#include <windows.h>', required: csprng_backend == 'rtlgenrandom') 1612 libgit_c_args += '-DHAVE_RTLGENRANDOM' 1613 csprng_backend = 'rtlgenrandom' 1614elif csprng_backend in ['auto', 'openssl'] and openssl.found() 1615 libgit_c_args += '-DHAVE_OPENSSL_CSPRNG' 1616 csprng_backend = 'openssl' 1617elif csprng_backend in ['auto', 'urandom'] 1618 csprng_backend = 'urandom' 1619else 1620 error('Unsupported CSPRNG backend: ' + csprng_backend) 1621endif 1622 1623git_exec_path = 'libexec/git-core' 1624libexec = get_option('libexecdir') 1625if libexec != 'libexec' and libexec != '.' 1626 git_exec_path = libexec 1627endif 1628 1629if get_option('runtime_prefix') 1630 libgit_c_args += '-DRUNTIME_PREFIX' 1631 build_options_config.set('RUNTIME_PREFIX', 'true') 1632 1633 if git_exec_path.startswith('/') 1634 error('runtime_prefix requires a relative libexecdir not:', libexec) 1635 endif 1636 1637 if compiler.has_header('mach-o/dyld.h') 1638 libgit_c_args += '-DHAVE_NS_GET_EXECUTABLE_PATH' 1639 endif 1640 1641 if has_bsd_sysctl and compiler.compiles(''' 1642 #include <sys/sysctl.h> 1643 1644 void func(void) 1645 { 1646 KERN_PROC_PATHNAME; KERN_PROC; 1647 } 1648 ''', name: 'BSD KERN_PROC_PATHNAME') 1649 libgit_c_args += '-DHAVE_NS_GET_EXECUTABLE_PATH' 1650 endif 1651 1652 if host_machine.system() == 'linux' 1653 libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="/proc/self/exe' + '"' 1654 elif host_machine.system() == 'openbsd' 1655 libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="' + '/proc/curproc/file' + '"' 1656 elif host_machine.system() == 'netbsd' 1657 libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="' + '/proc/curproc/exe' + '"' 1658 endif 1659 1660 if host_machine.system() == 'windows' and compiler.compiles(''' 1661 #include <stdlib.h> 1662 1663 void func(void) 1664 { 1665 _wpgmptr; 1666 } 1667 ''', name: 'Win32 _wpgmptr') 1668 libgit_c_args += '-DHAVE_WPGMPTR' 1669 endif 1670else 1671 build_options_config.set('RUNTIME_PREFIX', 'false') 1672endif 1673libgit_c_args += '-DGIT_EXEC_PATH="' + git_exec_path + '"' 1674 1675git_version_file = custom_target( 1676 command: [ 1677 shell, 1678 meson.current_source_dir() / 'GIT-VERSION-GEN', 1679 meson.current_source_dir(), 1680 '@INPUT@', 1681 '@OUTPUT@', 1682 ], 1683 input: meson.current_source_dir() / 'GIT-VERSION-FILE.in', 1684 output: 'GIT-VERSION-FILE', 1685 env: version_gen_environment, 1686 build_always_stale: true, 1687) 1688 1689version_def_h = custom_target( 1690 command: [ 1691 shell, 1692 meson.current_source_dir() / 'GIT-VERSION-GEN', 1693 meson.current_source_dir(), 1694 '@INPUT@', 1695 '@OUTPUT@', 1696 ], 1697 input: meson.current_source_dir() / 'version-def.h.in', 1698 output: 'version-def.h', 1699 # Depend on GIT-VERSION-FILE so that we don't always try to rebuild this 1700 # target for the same commit. 1701 depends: [git_version_file], 1702 env: version_gen_environment, 1703) 1704libgit_sources += version_def_h 1705 1706cargo = find_program('cargo', dirs: program_path, native: true, required: get_option('rust')) 1707rust_option = get_option('rust').disable_auto_if(not cargo.found()) 1708if rust_option.allowed() 1709 subdir('src') 1710 libgit_c_args += '-DWITH_RUST' 1711 1712 if host_machine.system() == 'windows' 1713 libgit_dependencies += compiler.find_library('userenv') 1714 endif 1715else 1716 libgit_sources += [ 1717 'varint.c', 1718 ] 1719endif 1720 1721libgit = declare_dependency( 1722 link_with: static_library('git', 1723 sources: libgit_sources, 1724 c_args: libgit_c_args + [ 1725 '-DGIT_VERSION_H="' + version_def_h.full_path() + '"', 1726 ], 1727 dependencies: libgit_dependencies, 1728 include_directories: libgit_include_directories, 1729 ), 1730 compile_args: libgit_c_args, 1731 dependencies: libgit_dependencies, 1732 include_directories: libgit_include_directories, 1733) 1734 1735common_main_sources = ['common-main.c'] 1736common_main_link_args = [ ] 1737if host_machine.system() == 'windows' 1738 git_rc = custom_target( 1739 command: [ 1740 shell, 1741 meson.current_source_dir() / 'GIT-VERSION-GEN', 1742 meson.current_source_dir(), 1743 '@INPUT@', 1744 '@OUTPUT@', 1745 ], 1746 input: meson.current_source_dir() / 'git.rc.in', 1747 output: 'git.rc', 1748 depends: [git_version_file], 1749 env: version_gen_environment, 1750 ) 1751 1752 common_main_sources += import('windows').compile_resources(git_rc, 1753 include_directories: [meson.current_source_dir()], 1754 ) 1755 if compiler.get_argument_syntax() == 'gcc' 1756 common_main_link_args += [ 1757 '-municode', 1758 '-Wl,-nxcompat', 1759 '-Wl,-dynamicbase', 1760 '-Wl,-pic-executable,-e,mainCRTStartup', 1761 ] 1762 elif compiler.get_argument_syntax() == 'msvc' 1763 common_main_link_args += [ 1764 '/ENTRY:wmainCRTStartup', 1765 'invalidcontinue.obj', 1766 ] 1767 else 1768 error('Unsupported compiler ' + compiler.get_id()) 1769 endif 1770endif 1771 1772libgit_commonmain = declare_dependency( 1773 link_with: static_library('common-main', 1774 sources: common_main_sources, 1775 dependencies: [ libgit ], 1776 ), 1777 link_args: common_main_link_args, 1778 dependencies: [ libgit ], 1779) 1780 1781bin_wrappers = [ ] 1782test_dependencies = [ ] 1783 1784git_builtin = executable('git', 1785 sources: builtin_sources + 'git.c', 1786 dependencies: [libgit_commonmain], 1787 install: true, 1788 install_dir: git_exec_path, 1789) 1790bin_wrappers += git_builtin 1791 1792test_dependencies += executable('git-daemon', 1793 sources: 'daemon.c', 1794 dependencies: [libgit_commonmain], 1795 install: true, 1796 install_dir: git_exec_path, 1797) 1798 1799test_dependencies += executable('git-sh-i18n--envsubst', 1800 sources: 'sh-i18n--envsubst.c', 1801 dependencies: [libgit_commonmain], 1802 install: true, 1803 install_dir: git_exec_path, 1804) 1805 1806bin_wrappers += executable('git-shell', 1807 sources: 'shell.c', 1808 dependencies: [libgit_commonmain], 1809 install: true, 1810 install_dir: git_exec_path, 1811) 1812 1813test_dependencies += executable('git-http-backend', 1814 sources: 'http-backend.c', 1815 dependencies: [libgit_commonmain], 1816 install: true, 1817 install_dir: git_exec_path, 1818) 1819 1820bin_wrappers += executable('scalar', 1821 sources: 'scalar.c', 1822 dependencies: [libgit_commonmain], 1823 install: true, 1824 install_dir: git_exec_path, 1825) 1826 1827if curl.found() 1828 libgit_curl = declare_dependency( 1829 sources: [ 1830 'http.c', 1831 'http-walker.c', 1832 ], 1833 dependencies: [libgit_commonmain, curl], 1834 ) 1835 1836 test_dependencies += executable('git-remote-http', 1837 sources: 'remote-curl.c', 1838 dependencies: [libgit_curl], 1839 install: true, 1840 install_dir: git_exec_path, 1841 ) 1842 1843 test_dependencies += executable('git-http-fetch', 1844 sources: 'http-fetch.c', 1845 dependencies: [libgit_curl], 1846 install: true, 1847 install_dir: git_exec_path, 1848 ) 1849 1850 if expat.found() 1851 test_dependencies += executable('git-http-push', 1852 sources: 'http-push.c', 1853 dependencies: [libgit_curl], 1854 install: true, 1855 install_dir: git_exec_path, 1856 ) 1857 endif 1858 1859 foreach alias : [ 'git-remote-https', 'git-remote-ftp', 'git-remote-ftps' ] 1860 test_dependencies += executable(alias, 1861 sources: 'remote-curl.c', 1862 dependencies: [libgit_curl], 1863 ) 1864 1865 install_symlink(alias + executable_suffix, 1866 install_dir: git_exec_path, 1867 pointing_to: 'git-remote-http', 1868 ) 1869 endforeach 1870endif 1871 1872test_dependencies += executable('git-imap-send', 1873 sources: 'imap-send.c', 1874 dependencies: [ use_curl_for_imap_send ? libgit_curl : libgit_commonmain ], 1875 install: true, 1876 install_dir: git_exec_path, 1877) 1878 1879foreach alias : [ 'git-receive-pack', 'git-upload-archive', 'git-upload-pack' ] 1880 bin_wrappers += executable(alias, 1881 objects: git_builtin.extract_all_objects(recursive: false), 1882 dependencies: [libgit_commonmain], 1883 ) 1884 1885 install_symlink(alias + executable_suffix, 1886 install_dir: git_exec_path, 1887 pointing_to: 'git', 1888 ) 1889endforeach 1890 1891foreach symlink : [ 1892 'git', 1893 'git-receive-pack', 1894 'git-shell', 1895 'git-upload-archive', 1896 'git-upload-pack', 1897 'scalar', 1898] 1899 if meson.version().version_compare('>=1.3.0') 1900 pointing_to = fs.relative_to(git_exec_path / symlink, get_option('bindir')) 1901 else 1902 pointing_to = '..' / git_exec_path / symlink 1903 endif 1904 1905 install_symlink(symlink, 1906 install_dir: get_option('bindir'), 1907 pointing_to: pointing_to, 1908 ) 1909endforeach 1910 1911scripts_sh = [ 1912 'git-difftool--helper.sh', 1913 'git-filter-branch.sh', 1914 'git-merge-octopus.sh', 1915 'git-merge-one-file.sh', 1916 'git-merge-resolve.sh', 1917 'git-mergetool--lib.sh', 1918 'git-mergetool.sh', 1919 'git-quiltimport.sh', 1920 'git-request-pull.sh', 1921 'git-sh-i18n.sh', 1922 'git-sh-setup.sh', 1923 'git-submodule.sh', 1924 'git-web--browse.sh', 1925] 1926if perl_features_enabled 1927 scripts_sh += 'git-instaweb.sh' 1928endif 1929 1930foreach script : scripts_sh 1931 test_dependencies += custom_target( 1932 input: script, 1933 output: fs.stem(script), 1934 command: [ 1935 shell, 1936 meson.project_source_root() / 'generate-script.sh', 1937 '@INPUT@', 1938 '@OUTPUT@', 1939 meson.project_build_root() / 'GIT-BUILD-OPTIONS', 1940 ], 1941 install: true, 1942 install_dir: git_exec_path, 1943 ) 1944endforeach 1945 1946if perl_features_enabled 1947 scripts_perl = [ 1948 'git-archimport.perl', 1949 'git-cvsexportcommit.perl', 1950 'git-cvsimport.perl', 1951 'git-cvsserver.perl', 1952 'git-send-email.perl', 1953 'git-svn.perl', 1954 ] 1955 1956 pathsep = ':' 1957 if host_machine.system() == 'windows' 1958 pathsep = ';' 1959 endif 1960 1961 perl_header_template = 'perl/header_templates/fixed_prefix.template.pl' 1962 if get_option('runtime_prefix') 1963 perl_header_template = 'perl/header_templates/runtime_prefix.template.pl' 1964 endif 1965 1966 perllibdir = get_option('perllibdir') 1967 if perllibdir == '' 1968 perllibdir = get_option('datadir') / 'perl5' 1969 endif 1970 1971 perl_header = configure_file( 1972 input: perl_header_template, 1973 output: 'GIT-PERL-HEADER', 1974 configuration: { 1975 'GITEXECDIR_REL': git_exec_path, 1976 'PERLLIBDIR_REL': perllibdir, 1977 'LOCALEDIR_REL': get_option('datadir') / 'locale', 1978 'INSTLIBDIR': perllibdir, 1979 'PATHSEP': pathsep, 1980 }, 1981 ) 1982 1983 generate_perl_command = [ 1984 shell, 1985 meson.project_source_root() / 'generate-perl.sh', 1986 meson.project_build_root() / 'GIT-BUILD-OPTIONS', 1987 git_version_file.full_path(), 1988 perl_header, 1989 '@INPUT@', 1990 '@OUTPUT@', 1991 ] 1992 1993 foreach script : scripts_perl 1994 generated_script = custom_target( 1995 input: script, 1996 output: fs.stem(script), 1997 command: generate_perl_command, 1998 install: true, 1999 install_dir: git_exec_path, 2000 depends: [git_version_file], 2001 ) 2002 test_dependencies += generated_script 2003 2004 if script == 'git-cvsserver.perl' 2005 bin_wrappers += generated_script 2006 2007 if meson.version().version_compare('>=1.3.0') 2008 pointing_to = fs.relative_to(git_exec_path / fs.stem(script), get_option('bindir')) 2009 else 2010 pointing_to = '..' / git_exec_path / fs.stem(script) 2011 endif 2012 2013 install_symlink(fs.stem(script), 2014 install_dir: get_option('bindir'), 2015 pointing_to: pointing_to, 2016 ) 2017 endif 2018 endforeach 2019 2020 subdir('perl') 2021endif 2022 2023if target_python.found() 2024 scripts_python = [ 2025 'git-p4.py' 2026 ] 2027 2028 foreach script : scripts_python 2029 generated_python = custom_target( 2030 input: script, 2031 output: fs.stem(script), 2032 command: [ 2033 shell, 2034 meson.project_source_root() / 'generate-python.sh', 2035 meson.project_build_root() / 'GIT-BUILD-OPTIONS', 2036 '@INPUT@', 2037 '@OUTPUT@', 2038 ], 2039 install: true, 2040 install_dir: git_exec_path, 2041 ) 2042 test_dependencies += generated_python 2043 endforeach 2044endif 2045 2046mergetools = [ 2047 'mergetools/araxis', 2048 'mergetools/bc', 2049 'mergetools/codecompare', 2050 'mergetools/deltawalker', 2051 'mergetools/diffmerge', 2052 'mergetools/diffuse', 2053 'mergetools/ecmerge', 2054 'mergetools/emerge', 2055 'mergetools/examdiff', 2056 'mergetools/guiffy', 2057 'mergetools/gvimdiff', 2058 'mergetools/kdiff3', 2059 'mergetools/kompare', 2060 'mergetools/meld', 2061 'mergetools/nvimdiff', 2062 'mergetools/opendiff', 2063 'mergetools/p4merge', 2064 'mergetools/smerge', 2065 'mergetools/tkdiff', 2066 'mergetools/tortoisemerge', 2067 'mergetools/vimdiff', 2068 'mergetools/vscode', 2069 'mergetools/winmerge', 2070 'mergetools/xxdiff', 2071] 2072 2073foreach mergetool : mergetools 2074 install_data(mergetool, install_dir: git_exec_path / 'mergetools') 2075endforeach 2076 2077if intl.found() 2078 subdir('po') 2079endif 2080 2081# Gitweb requires Perl, so we disable the auto-feature if Perl was not found. 2082# We make sure further up that Perl is required in case the gitweb option is 2083# enabled. 2084gitweb_option = get_option('gitweb').disable_auto_if(not perl.found()) 2085if gitweb_option.allowed() 2086 subdir('gitweb') 2087 build_options_config.set('NO_GITWEB', '') 2088else 2089 build_options_config.set('NO_GITWEB', '1') 2090endif 2091 2092subdir('templates') 2093 2094# Everything but the bin-wrappers need to come before this target such that we 2095# can properly set up test dependencies. The bin-wrappers themselves are set up 2096# at configuration time, so these are fine. 2097if get_option('tests') 2098 test_kwargs = { 2099 'timeout': 0, 2100 } 2101 2102 # The TAP protocol was already understood by previous versions of Meson, but 2103 # it was incompatible with the `meson test --interactive` flag. 2104 if meson.version().version_compare('>=1.8.0') 2105 test_kwargs += { 2106 'protocol': 'tap', 2107 } 2108 endif 2109 2110 subdir('t') 2111endif 2112 2113if get_option('fuzzers') 2114 subdir('oss-fuzz') 2115endif 2116 2117subdir('bin-wrappers') 2118if get_option('docs') != [] 2119 doc_targets = [] 2120 subdir('Documentation') 2121else 2122 docs_backend = 'none' 2123endif 2124 2125subdir('contrib') 2126 2127# Note that the target is intentionally configured after including the 2128# 'contrib' directory, as some tool there also have their own manpages. 2129if get_option('docs') != [] 2130 alias_target('docs', doc_targets) 2131endif 2132 2133exclude_from_check_headers = [ 2134 'compat/', 2135 'unicode-width.h', 2136] 2137 2138if sha1_backend != 'openssl' 2139 exclude_from_check_headers += 'sha1/openssl.h' 2140endif 2141if sha256_backend != 'openssl' 2142 exclude_from_check_headers += 'sha256/openssl.h' 2143endif 2144if sha256_backend != 'nettle' 2145 exclude_from_check_headers += 'sha256/nettle.h' 2146endif 2147if sha256_backend != 'gcrypt' 2148 exclude_from_check_headers += 'sha256/gcrypt.h' 2149endif 2150 2151if headers_to_check.length() != 0 and compiler.get_argument_syntax() == 'gcc' 2152 hco_targets = [] 2153 foreach h : headers_to_check 2154 skip_header = false 2155 foreach exclude : exclude_from_check_headers 2156 if h.startswith(exclude) 2157 skip_header = true 2158 break 2159 endif 2160 endforeach 2161 2162 if skip_header 2163 continue 2164 endif 2165 2166 hcc = custom_target( 2167 input: h, 2168 output: h.underscorify() + 'cc', 2169 command: [ 2170 shell, 2171 '-c', 2172 'echo \'#include "git-compat-util.h"\' > @OUTPUT@ && echo \'#include "' + h + '"\' >> @OUTPUT@' 2173 ] 2174 ) 2175 2176 hco = custom_target( 2177 input: hcc, 2178 output: fs.replace_suffix(h.underscorify(), '.hco'), 2179 command: [ 2180 compiler.cmd_array(), 2181 libgit_c_args, 2182 '-I', meson.project_source_root(), 2183 '-I', meson.project_source_root() / 't/unit-tests', 2184 '-o', '/dev/null', 2185 '-c', '-xc', 2186 '@INPUT@' 2187 ] 2188 ) 2189 hco_targets += hco 2190 endforeach 2191 2192 # TODO: deprecate 'hdr-check' in lieu of 'check-headers' in Git 2.51+ 2193 hdr_check = alias_target('hdr-check', hco_targets) 2194 alias_target('check-headers', hdr_check) 2195endif 2196 2197git_clang_format = find_program('git-clang-format', required: false, native: true) 2198if git_clang_format.found() 2199 run_target('style', 2200 command: [ 2201 git_clang_format, 2202 '--style', 'file', 2203 '--diff', 2204 '--extensions', 'c,h' 2205 ] 2206 ) 2207endif 2208 2209foreach key, value : { 2210 'DIFF': diff.full_path(), 2211 'GIT_SOURCE_DIR': meson.project_source_root(), 2212 'GIT_TEST_CMP': diff.full_path() + ' -u', 2213 'GIT_TEST_GITPERLLIB': meson.project_build_root() / 'perl', 2214 'GIT_TEST_TEMPLATE_DIR': meson.project_build_root() / 'templates', 2215 'GIT_TEST_TEXTDOMAINDIR': meson.project_build_root() / 'po', 2216 'PAGER_ENV': get_option('pager_environment'), 2217 'PERL_PATH': target_perl.found() ? target_perl.full_path() : '', 2218 'PYTHON_PATH': target_python.found () ? target_python.full_path() : '', 2219 'SHELL_PATH': target_shell.full_path(), 2220 'TAR': tar.full_path(), 2221 'TEST_OUTPUT_DIRECTORY': test_output_directory, 2222 'TEST_SHELL_PATH': shell.full_path(), 2223} 2224 if value != '' and cygpath.found() 2225 value = run_command(cygpath, value, check: true).stdout().strip() 2226 endif 2227 build_options_config.set_quoted(key, value) 2228endforeach 2229 2230configure_file( 2231 input: 'GIT-BUILD-OPTIONS.in', 2232 output: 'GIT-BUILD-OPTIONS', 2233 configuration: build_options_config, 2234) 2235 2236# Development environments can be used via `meson devenv -C <builddir>`. This 2237# allows you to execute test scripts directly with the built Git version and 2238# puts the built version of Git in your PATH. 2239devenv = environment() 2240devenv.set('GIT_BUILD_DIR', meson.current_build_dir()) 2241devenv.prepend('PATH', meson.current_build_dir() / 'bin-wrappers') 2242meson.add_devenv(devenv) 2243 2244# Generate the 'version' file in the distribution tarball. This is used via 2245# `meson dist -C <builddir>` to populate the source archive with the Git 2246# version that the archive is being generated from. 2247meson.add_dist_script( 2248 shell, 2249 '-c', 2250 '"$1" "$2" "$3" --format="@GIT_VERSION@" "$MESON_DIST_ROOT/version"', 2251 'GIT-VERSION-GEN', 2252 shell, 2253 meson.current_source_dir() / 'GIT-VERSION-GEN', 2254 meson.current_source_dir(), 2255) 2256 2257summary({ 2258 'benchmarks': get_option('tests') and perl.found() and time.found(), 2259 'curl': curl, 2260 'expat': expat, 2261 'gettext': intl, 2262 'gitweb': gitweb_option.allowed(), 2263 'iconv': iconv, 2264 'pcre2': pcre2, 2265 'perl': perl_features_enabled, 2266 'python': target_python.found(), 2267 'rust': rust_option.allowed(), 2268}, section: 'Auto-detected features', bool_yn: true) 2269 2270summary({ 2271 'csprng': csprng_backend, 2272 'docs': docs_backend, 2273 'https': https_backend, 2274 'sha1': sha1_backend, 2275 'sha1_unsafe': sha1_unsafe_backend, 2276 'sha256': sha256_backend, 2277 'zlib': zlib_backend, 2278}, section: 'Backends') 2279 2280summary({ 2281 'perl': target_perl, 2282 'python': target_python, 2283 'shell': target_shell, 2284}, section: 'Runtime executable paths')