| # Meson build system |
| # ================== |
| # |
| # The Meson build system is an alternative to our Makefile that you can use to |
| # build, test and install Git. Using Meson results in a couple of benefits: |
| # |
| # - Out-of-tree builds. |
| # - Better integration into IDEs. |
| # - Easy-to-use autoconfiguration of available features on your system. |
| # |
| # To use Meson from the command line you need to have both Meson and Ninja |
| # installed. Alternatively, if you do not have Python available on your system, |
| # you can also use Muon instead of Meson and Samurai instead of Ninja, both of |
| # which are drop-ins replacement that only depend on C. |
| # |
| # Basic usage |
| # =========== |
| # |
| # In the most trivial case, you can configure, build and install Git like this: |
| # |
| # 1. Set up the build directory. This only needs to happen once per build |
| # directory you want to have. You can also configure multiple different |
| # build directories with different configurations. |
| # |
| # $ meson setup build/ |
| # |
| # The build directory gets ignored by Git automatically as Meson will write |
| # a ".gitignore" file into it. From hereon, we will assume that you execute |
| # commands inside this build directory. |
| # |
| # 2. Compile Git. You can either use Meson, Ninja or Samurai to do this, so all |
| # of the following invocations are equivalent: |
| # |
| # $ meson compile |
| # $ ninja |
| # $ samu |
| # |
| # The different invocations should ultimately not make much of a difference. |
| # Using Meson also works with other generators though, like when the build |
| # directory has been set up for use with Microsoft Visual Studio. |
| # |
| # Ninja and Samurai use multiple jobs by default, scaling with the number of |
| # processor cores available. You can pass the `-jN` flag to change this. |
| # |
| # Meson automatically picks up ccache and sccache when these are installed |
| # when setting up the build directory. You can override this behaviour when |
| # setting up the build directory by setting the `CC` environment variable to |
| # your desired compiler. |
| # |
| # 3. Execute tests. Again, you can either use Meson, Ninja or Samurai to do this: |
| # |
| # $ meson test |
| # $ ninja test |
| # $ samu test |
| # |
| # It is recommended to use Meson in this case though as it also provides you |
| # additional features that the other build systems don't have available. |
| # You can e.g. pass additional arguments to the test executables or run |
| # individual tests: |
| # |
| # # Execute the t0000-basic integration test and t-reftable-stack unit test. |
| # $ meson test t0000-basic t-reftable-stack |
| # |
| # # Execute all reftable unit tests. |
| # $ meson test t-reftable-* |
| # |
| # # Execute all tests and stop with the first failure. |
| # $ meson test --maxfail 1 |
| # |
| # # Execute single test interactively such that features like `debug ()` work. |
| # $ meson test -i --test-args='-ix' t1400-update-ref |
| # |
| # Test execution is parallelized by default and scales with the number of |
| # processor cores available. You can change the number of processes by passing |
| # the `-jN` flag to `meson test`. |
| # |
| # 4. Install the Git distribution. Again, this can be done via Meson, Ninja or |
| # Samurai: |
| # |
| # $ meson install |
| # $ ninja install |
| # $ samu install |
| # |
| # The prefix into which Git shall be installed is defined when setting up |
| # the build directory. More on that in the "Configuration" section. |
| # |
| # Meson supports multiple backends. The default backend generates Ninja build |
| # instructions, but it also supports the generation of Microsoft Visual |
| # Studio solutions as well as Xcode projects by passing the `--backend` option |
| # to `meson setup`. IDEs like Eclipse and Visual Studio Code provide plugins to |
| # import Meson files directly. |
| # |
| # Configuration |
| # ============= |
| # |
| # The exact configuration of Git is determined when setting up the build |
| # directory via `meson setup`. Unless told otherwise, Meson will automatically |
| # detect the availability of various bits and pieces. There are two different |
| # kinds of options that can be used to further tweak the build: |
| # |
| # - Built-in options provided by Meson. |
| # |
| # - Options defined by the project in the "meson_options.txt" file. |
| # |
| # Both kinds of options can be inspected by running `meson configure` in the |
| # build directory, which will give you a list of the current value for all |
| # options. |
| # |
| # Options can be configured either when setting up the build directory or can |
| # be changed in preexisting build directories: |
| # |
| # # Set up a new build directory with optimized settings that will be |
| # # installed into an alternative prefix. |
| # $ meson setup --buildtype release --optimization 3 --strip --prefix=/home/$USER build |
| # |
| # # Set up a new build directory with a higher warning level. Level 2 is |
| # # mostly equivalent to setting DEVELOPER=1, level 3 and "everything" |
| # # will enable even more warnings. |
| # $ meson setup -Dwarning_level=2 build |
| # |
| # # Set up a new build directory with 'address' and 'undefined' sanitizers |
| # # using Clang. |
| # $ CC=clang meson setup -Db_sanitize=address,undefined build |
| # |
| # # Disable tests in a preexisting build directory. |
| # $ meson configure -Dtests=false |
| # |
| # # Disable features based on Python |
| # $ meson configure -Dpython=disabled |
| # |
| # Options have a type like booleans, choices, strings or features. Features are |
| # somewhat special as they can have one of three values: enabled, disabled or |
| # auto. While the first two values are self-explanatory, "auto" will enable or |
| # disable the feature based on the availability of prerequisites to support it. |
| # Python-based features for example will be enabled automatically when a Python |
| # interpreter could be found. The default value of such features can be changed |
| # via `meson setup --auto-features={enabled,disabled,auto}`, which will set the |
| # value of all features with a value of "auto" to the provided one by default. |
| # |
| # It is also possible to store a set of configuration options in machine files. |
| # This can be useful in case you regularly want to reuse the same set of options: |
| # |
| # [binaries] |
| # c = ['clang'] |
| # ar = ['ar'] |
| # |
| # [project options] |
| # gettext = 'disabled' |
| # default_editor = 'vim' |
| # |
| # [built-in options] |
| # b_lto = true |
| # b_sanitize = 'address,undefined' |
| # |
| # These machine files can be passed to `meson setup` via the `--native-file` |
| # option. |
| # |
| # Subproject wrappers |
| # =================== |
| # |
| # Subproject wrappers are a feature provided by Meson that allows the automatic |
| # fallback to a "wrapped" dependency in case the dependency is not provided by |
| # the system. For example if the system is lacking curl, then Meson will use |
| # "subprojects/curl.wrap" to set up curl as a subproject and compile and link |
| # the dependency into Git itself. This is especially helpful on systems like |
| # Windows, where you typically don't have such dependencies installed. |
| # |
| # The use of subproject wrappers can be disabled by executing `meson setup` |
| # with the `--wrap-mode nofallback` option. |
| |
| project('git', 'c', |
| meson_version: '>=0.61.0', |
| version: 'v2.47.GIT', |
| ) |
| |
| fs = import('fs') |
| |
| program_path = [] |
| # Git for Windows provides all the tools we need to build Git. |
| if host_machine.system() == 'windows' |
| program_path += [ 'C:/Program Files/Git/bin', 'C:/Program Files/Git/usr/bin' ] |
| endif |
| |
| cygpath = find_program('cygpath', dirs: program_path, required: false) |
| diff = find_program('diff', dirs: program_path) |
| shell = find_program('sh', dirs: program_path) |
| tar = find_program('tar', dirs: program_path) |
| |
| script_environment = environment() |
| foreach tool : ['cat', 'cut', 'grep', 'sed', 'sort', 'tr', 'uname'] |
| program = find_program(tool, dirs: program_path) |
| script_environment.prepend('PATH', fs.parent(program.full_path())) |
| endforeach |
| |
| git = find_program('git', dirs: program_path, required: false) |
| if git.found() |
| script_environment.prepend('PATH', fs.parent(git.full_path())) |
| endif |
| |
| if get_option('sane_tool_path') != '' |
| script_environment.prepend('PATH', get_option('sane_tool_path')) |
| endif |
| |
| # The environment used by GIT-VERSION-GEN. Note that we explicitly override |
| # environment variables that might be set by the user. This is by design so |
| # that we always use whatever Meson has configured instead of what is present |
| # in the environment. |
| version_gen_environment = script_environment |
| version_gen_environment.set('GIT_BUILT_FROM_COMMIT', get_option('built_from_commit')) |
| version_gen_environment.set('GIT_DATE', get_option('build_date')) |
| version_gen_environment.set('GIT_USER_AGENT', get_option('user_agent')) |
| version_gen_environment.set('GIT_VERSION', get_option('version')) |
| |
| compiler = meson.get_compiler('c') |
| |
| libgit_sources = [ |
| 'abspath.c', |
| 'add-interactive.c', |
| 'add-patch.c', |
| 'advice.c', |
| 'alias.c', |
| 'alloc.c', |
| 'apply.c', |
| 'archive-tar.c', |
| 'archive-zip.c', |
| 'archive.c', |
| 'attr.c', |
| 'base85.c', |
| 'bisect.c', |
| 'blame.c', |
| 'blob.c', |
| 'bloom.c', |
| 'branch.c', |
| 'bulk-checkin.c', |
| 'bundle-uri.c', |
| 'bundle.c', |
| 'cache-tree.c', |
| 'cbtree.c', |
| 'chdir-notify.c', |
| 'checkout.c', |
| 'chunk-format.c', |
| 'color.c', |
| 'column.c', |
| 'combine-diff.c', |
| 'commit-graph.c', |
| 'commit-reach.c', |
| 'commit.c', |
| 'compat/nonblock.c', |
| 'compat/obstack.c', |
| 'compat/terminal.c', |
| 'compat/zlib-uncompress2.c', |
| 'config.c', |
| 'connect.c', |
| 'connected.c', |
| 'convert.c', |
| 'copy.c', |
| 'credential.c', |
| 'csum-file.c', |
| 'ctype.c', |
| 'date.c', |
| 'decorate.c', |
| 'delta-islands.c', |
| 'diagnose.c', |
| 'diff-delta.c', |
| 'diff-merges.c', |
| 'diff-lib.c', |
| 'diff-no-index.c', |
| 'diff.c', |
| 'diffcore-break.c', |
| 'diffcore-delta.c', |
| 'diffcore-order.c', |
| 'diffcore-pickaxe.c', |
| 'diffcore-rename.c', |
| 'diffcore-rotate.c', |
| 'dir-iterator.c', |
| 'dir.c', |
| 'editor.c', |
| 'entry.c', |
| 'environment.c', |
| 'ewah/bitmap.c', |
| 'ewah/ewah_bitmap.c', |
| 'ewah/ewah_io.c', |
| 'ewah/ewah_rlw.c', |
| 'exec-cmd.c', |
| 'fetch-negotiator.c', |
| 'fetch-pack.c', |
| 'fmt-merge-msg.c', |
| 'fsck.c', |
| 'fsmonitor.c', |
| 'fsmonitor-ipc.c', |
| 'fsmonitor-settings.c', |
| 'gettext.c', |
| 'git-zlib.c', |
| 'gpg-interface.c', |
| 'graph.c', |
| 'grep.c', |
| 'hash-lookup.c', |
| 'hashmap.c', |
| 'help.c', |
| 'hex.c', |
| 'hex-ll.c', |
| 'hook.c', |
| 'ident.c', |
| 'json-writer.c', |
| 'kwset.c', |
| 'levenshtein.c', |
| 'line-log.c', |
| 'line-range.c', |
| 'linear-assignment.c', |
| 'list-objects-filter-options.c', |
| 'list-objects-filter.c', |
| 'list-objects.c', |
| 'lockfile.c', |
| 'log-tree.c', |
| 'loose.c', |
| 'ls-refs.c', |
| 'mailinfo.c', |
| 'mailmap.c', |
| 'match-trees.c', |
| 'mem-pool.c', |
| 'merge-blobs.c', |
| 'merge-ll.c', |
| 'merge-ort.c', |
| 'merge-ort-wrappers.c', |
| 'merge-recursive.c', |
| 'merge.c', |
| 'midx.c', |
| 'midx-write.c', |
| 'name-hash.c', |
| 'negotiator/default.c', |
| 'negotiator/noop.c', |
| 'negotiator/skipping.c', |
| 'notes-cache.c', |
| 'notes-merge.c', |
| 'notes-utils.c', |
| 'notes.c', |
| 'object-file-convert.c', |
| 'object-file.c', |
| 'object-name.c', |
| 'object.c', |
| 'oid-array.c', |
| 'oidmap.c', |
| 'oidset.c', |
| 'oidtree.c', |
| 'pack-bitmap-write.c', |
| 'pack-bitmap.c', |
| 'pack-check.c', |
| 'pack-mtimes.c', |
| 'pack-objects.c', |
| 'pack-revindex.c', |
| 'pack-write.c', |
| 'packfile.c', |
| 'pager.c', |
| 'parallel-checkout.c', |
| 'parse.c', |
| 'parse-options-cb.c', |
| 'parse-options.c', |
| 'patch-delta.c', |
| 'patch-ids.c', |
| 'path.c', |
| 'pathspec.c', |
| 'pkt-line.c', |
| 'preload-index.c', |
| 'pretty.c', |
| 'prio-queue.c', |
| 'progress.c', |
| 'promisor-remote.c', |
| 'prompt.c', |
| 'protocol.c', |
| 'protocol-caps.c', |
| 'prune-packed.c', |
| 'pseudo-merge.c', |
| 'quote.c', |
| 'range-diff.c', |
| 'reachable.c', |
| 'read-cache.c', |
| 'rebase-interactive.c', |
| 'rebase.c', |
| 'ref-filter.c', |
| 'reflog-walk.c', |
| 'reflog.c', |
| 'refs.c', |
| 'refs/debug.c', |
| 'refs/files-backend.c', |
| 'refs/reftable-backend.c', |
| 'refs/iterator.c', |
| 'refs/packed-backend.c', |
| 'refs/ref-cache.c', |
| 'refspec.c', |
| 'reftable/basics.c', |
| 'reftable/error.c', |
| 'reftable/block.c', |
| 'reftable/blocksource.c', |
| 'reftable/iter.c', |
| 'reftable/merged.c', |
| 'reftable/pq.c', |
| 'reftable/reader.c', |
| 'reftable/record.c', |
| 'reftable/stack.c', |
| 'reftable/system.c', |
| 'reftable/tree.c', |
| 'reftable/writer.c', |
| 'remote.c', |
| 'replace-object.c', |
| 'repo-settings.c', |
| 'repository.c', |
| 'rerere.c', |
| 'reset.c', |
| 'resolve-undo.c', |
| 'revision.c', |
| 'run-command.c', |
| 'send-pack.c', |
| 'sequencer.c', |
| 'serve.c', |
| 'server-info.c', |
| 'setup.c', |
| 'shallow.c', |
| 'sideband.c', |
| 'sigchain.c', |
| 'sparse-index.c', |
| 'split-index.c', |
| 'stable-qsort.c', |
| 'statinfo.c', |
| 'strbuf.c', |
| 'streaming.c', |
| 'string-list.c', |
| 'strmap.c', |
| 'strvec.c', |
| 'sub-process.c', |
| 'submodule-config.c', |
| 'submodule.c', |
| 'symlinks.c', |
| 'tag.c', |
| 'tempfile.c', |
| 'thread-utils.c', |
| 'tmp-objdir.c', |
| 'trace.c', |
| 'trace2.c', |
| 'trace2/tr2_cfg.c', |
| 'trace2/tr2_cmd_name.c', |
| 'trace2/tr2_ctr.c', |
| 'trace2/tr2_dst.c', |
| 'trace2/tr2_sid.c', |
| 'trace2/tr2_sysenv.c', |
| 'trace2/tr2_tbuf.c', |
| 'trace2/tr2_tgt_event.c', |
| 'trace2/tr2_tgt_normal.c', |
| 'trace2/tr2_tgt_perf.c', |
| 'trace2/tr2_tls.c', |
| 'trace2/tr2_tmr.c', |
| 'trailer.c', |
| 'transport-helper.c', |
| 'transport.c', |
| 'tree-diff.c', |
| 'tree-walk.c', |
| 'tree.c', |
| 'unpack-trees.c', |
| 'upload-pack.c', |
| 'url.c', |
| 'urlmatch.c', |
| 'usage.c', |
| 'userdiff.c', |
| 'utf8.c', |
| 'varint.c', |
| 'versioncmp.c', |
| 'walker.c', |
| 'wildmatch.c', |
| 'worktree.c', |
| 'wrapper.c', |
| 'write-or-die.c', |
| 'ws.c', |
| 'wt-status.c', |
| 'xdiff-interface.c', |
| 'xdiff/xdiffi.c', |
| 'xdiff/xemit.c', |
| 'xdiff/xhistogram.c', |
| 'xdiff/xmerge.c', |
| 'xdiff/xpatience.c', |
| 'xdiff/xprepare.c', |
| 'xdiff/xutils.c', |
| ] |
| |
| builtin_sources = [ |
| 'builtin/add.c', |
| 'builtin/am.c', |
| 'builtin/annotate.c', |
| 'builtin/apply.c', |
| 'builtin/archive.c', |
| 'builtin/bisect.c', |
| 'builtin/blame.c', |
| 'builtin/branch.c', |
| 'builtin/bugreport.c', |
| 'builtin/bundle.c', |
| 'builtin/cat-file.c', |
| 'builtin/check-attr.c', |
| 'builtin/check-ignore.c', |
| 'builtin/check-mailmap.c', |
| 'builtin/check-ref-format.c', |
| 'builtin/checkout--worker.c', |
| 'builtin/checkout-index.c', |
| 'builtin/checkout.c', |
| 'builtin/clean.c', |
| 'builtin/clone.c', |
| 'builtin/column.c', |
| 'builtin/commit-graph.c', |
| 'builtin/commit-tree.c', |
| 'builtin/commit.c', |
| 'builtin/config.c', |
| 'builtin/count-objects.c', |
| 'builtin/credential-cache--daemon.c', |
| 'builtin/credential-cache.c', |
| 'builtin/credential-store.c', |
| 'builtin/credential.c', |
| 'builtin/describe.c', |
| 'builtin/diagnose.c', |
| 'builtin/diff-files.c', |
| 'builtin/diff-index.c', |
| 'builtin/diff-tree.c', |
| 'builtin/diff.c', |
| 'builtin/difftool.c', |
| 'builtin/fast-export.c', |
| 'builtin/fast-import.c', |
| 'builtin/fetch-pack.c', |
| 'builtin/fetch.c', |
| 'builtin/fmt-merge-msg.c', |
| 'builtin/for-each-ref.c', |
| 'builtin/for-each-repo.c', |
| 'builtin/fsck.c', |
| 'builtin/fsmonitor--daemon.c', |
| 'builtin/gc.c', |
| 'builtin/get-tar-commit-id.c', |
| 'builtin/grep.c', |
| 'builtin/hash-object.c', |
| 'builtin/help.c', |
| 'builtin/hook.c', |
| 'builtin/index-pack.c', |
| 'builtin/init-db.c', |
| 'builtin/interpret-trailers.c', |
| 'builtin/log.c', |
| 'builtin/ls-files.c', |
| 'builtin/ls-remote.c', |
| 'builtin/ls-tree.c', |
| 'builtin/mailinfo.c', |
| 'builtin/mailsplit.c', |
| 'builtin/merge-base.c', |
| 'builtin/merge-file.c', |
| 'builtin/merge-index.c', |
| 'builtin/merge-ours.c', |
| 'builtin/merge-recursive.c', |
| 'builtin/merge-tree.c', |
| 'builtin/merge.c', |
| 'builtin/mktag.c', |
| 'builtin/mktree.c', |
| 'builtin/multi-pack-index.c', |
| 'builtin/mv.c', |
| 'builtin/name-rev.c', |
| 'builtin/notes.c', |
| 'builtin/pack-objects.c', |
| 'builtin/pack-redundant.c', |
| 'builtin/pack-refs.c', |
| 'builtin/patch-id.c', |
| 'builtin/prune-packed.c', |
| 'builtin/prune.c', |
| 'builtin/pull.c', |
| 'builtin/push.c', |
| 'builtin/range-diff.c', |
| 'builtin/read-tree.c', |
| 'builtin/rebase.c', |
| 'builtin/receive-pack.c', |
| 'builtin/reflog.c', |
| 'builtin/refs.c', |
| 'builtin/remote-ext.c', |
| 'builtin/remote-fd.c', |
| 'builtin/remote.c', |
| 'builtin/repack.c', |
| 'builtin/replace.c', |
| 'builtin/replay.c', |
| 'builtin/rerere.c', |
| 'builtin/reset.c', |
| 'builtin/rev-list.c', |
| 'builtin/rev-parse.c', |
| 'builtin/revert.c', |
| 'builtin/rm.c', |
| 'builtin/send-pack.c', |
| 'builtin/shortlog.c', |
| 'builtin/show-branch.c', |
| 'builtin/show-index.c', |
| 'builtin/show-ref.c', |
| 'builtin/sparse-checkout.c', |
| 'builtin/stash.c', |
| 'builtin/stripspace.c', |
| 'builtin/submodule--helper.c', |
| 'builtin/symbolic-ref.c', |
| 'builtin/tag.c', |
| 'builtin/unpack-file.c', |
| 'builtin/unpack-objects.c', |
| 'builtin/update-index.c', |
| 'builtin/update-ref.c', |
| 'builtin/update-server-info.c', |
| 'builtin/upload-archive.c', |
| 'builtin/upload-pack.c', |
| 'builtin/var.c', |
| 'builtin/verify-commit.c', |
| 'builtin/verify-pack.c', |
| 'builtin/verify-tag.c', |
| 'builtin/worktree.c', |
| 'builtin/write-tree.c', |
| ] |
| |
| libgit_sources += custom_target( |
| input: 'command-list.txt', |
| output: 'command-list.h', |
| command: [shell, meson.current_source_dir() + '/generate-cmdlist.sh', meson.current_source_dir(), '@OUTPUT@'], |
| env: script_environment, |
| ) |
| |
| libgit_sources += custom_target( |
| output: 'config-list.h', |
| command: [ |
| shell, |
| meson.current_source_dir() + '/generate-configlist.sh', |
| meson.current_source_dir(), |
| '@OUTPUT@', |
| ], |
| env: script_environment, |
| ) |
| |
| libgit_sources += custom_target( |
| input: 'Documentation/githooks.txt', |
| output: 'hook-list.h', |
| command: [ |
| shell, |
| meson.current_source_dir() + '/generate-hooklist.sh', |
| meson.current_source_dir(), |
| '@OUTPUT@', |
| ], |
| env: script_environment, |
| ) |
| |
| # This contains the variables for GIT-BUILD-OPTIONS, which we use to propagate |
| # build options to our tests. |
| build_options_config = configuration_data() |
| build_options_config.set('GIT_INTEROP_MAKE_OPTS', '') |
| build_options_config.set('GIT_PERF_LARGE_REPO', '') |
| build_options_config.set('GIT_PERF_MAKE_COMMAND', '') |
| build_options_config.set('GIT_PERF_MAKE_OPTS', '') |
| build_options_config.set('GIT_PERF_REPEAT_COUNT', '') |
| build_options_config.set('GIT_PERF_REPO', '') |
| build_options_config.set('GIT_TEST_CMP_USE_COPIED_CONTEXT', '') |
| build_options_config.set('GIT_TEST_INDEX_VERSION', '') |
| build_options_config.set('GIT_TEST_OPTS', '') |
| build_options_config.set('GIT_TEST_PERL_FATAL_WARNINGS', '') |
| build_options_config.set('GIT_TEST_UTF8_LOCALE', '') |
| build_options_config.set_quoted('LOCALEDIR', fs.as_posix(get_option('prefix') / get_option('localedir'))) |
| build_options_config.set('GITWEBDIR', fs.as_posix(get_option('prefix') / get_option('datadir') / 'gitweb')) |
| |
| if get_option('sane_tool_path') != '' |
| build_options_config.set_quoted('BROKEN_PATH_FIX', 's|^\# @BROKEN_PATH_FIX@$|git_broken_path_fix "' + get_option('sane_tool_path') + '"|') |
| else |
| build_options_config.set_quoted('BROKEN_PATH_FIX', '/^\# @BROKEN_PATH_FIX@$/d') |
| endif |
| |
| test_output_directory = get_option('test_output_directory') |
| if test_output_directory == '' |
| test_output_directory = meson.project_build_root() / 'test-output' |
| endif |
| |
| # These variables are used for building libgit.a. |
| libgit_c_args = [ |
| '-DBINDIR="' + get_option('bindir') + '"', |
| '-DDEFAULT_EDITOR="' + get_option('default_editor') + '"', |
| '-DDEFAULT_GIT_TEMPLATE_DIR="' + get_option('datadir') / 'git-core/templates' + '"', |
| '-DDEFAULT_HELP_FORMAT="' + get_option('default_help_format') + '"', |
| '-DDEFAULT_PAGER="' + get_option('default_pager') + '"', |
| '-DETC_GITATTRIBUTES="' + get_option('gitattributes') + '"', |
| '-DETC_GITCONFIG="' + get_option('gitconfig') + '"', |
| '-DFALLBACK_RUNTIME_PREFIX="' + get_option('prefix') + '"', |
| '-DGIT_EXEC_PATH="' + get_option('prefix') / get_option('libexecdir') / 'git-core"', |
| '-DGIT_HOST_CPU="' + host_machine.cpu_family() + '"', |
| '-DGIT_HTML_PATH="' + get_option('datadir') / 'doc/git-doc"', |
| '-DGIT_INFO_PATH="' + get_option('infodir') + '"', |
| '-DGIT_LOCALE_PATH="' + get_option('localedir') + '"', |
| '-DGIT_MAN_PATH="' + get_option('mandir') + '"', |
| '-DPAGER_ENV="' + get_option('pager_environment') + '"', |
| '-DSHELL_PATH="' + fs.as_posix(shell.full_path()) + '"', |
| ] |
| libgit_include_directories = [ '.' ] |
| libgit_dependencies = [ ] |
| |
| # Treat any warning level above 1 the same as we treat DEVELOPER=1 in our |
| # Makefile. |
| if get_option('warning_level') in ['2','3', 'everything'] and compiler.get_argument_syntax() == 'gcc' |
| foreach cflag : [ |
| '-Wdeclaration-after-statement', |
| '-Wformat-security', |
| '-Wold-style-definition', |
| '-Woverflow', |
| '-Wpointer-arith', |
| '-Wstrict-prototypes', |
| '-Wunused', |
| '-Wvla', |
| '-Wwrite-strings', |
| '-fno-common', |
| '-Wtautological-constant-out-of-range-compare', |
| # If a function is public, there should be a prototype and the right |
| # header file should be included. If not, it should be static. |
| '-Wmissing-prototypes', |
| # These are disabled because we have these all over the place. |
| '-Wno-empty-body', |
| '-Wno-missing-field-initializers', |
| '-Wno-sign-compare', |
| ] |
| if compiler.has_argument(cflag) |
| libgit_c_args += cflag |
| endif |
| endforeach |
| endif |
| |
| if get_option('b_sanitize').contains('address') |
| build_options_config.set('SANITIZE_ADDRESS', 'YesCompiledWithIt') |
| else |
| build_options_config.set('SANITIZE_ADDRESS', '') |
| endif |
| if get_option('b_sanitize').contains('leak') |
| build_options_config.set('SANITIZE_LEAK', 'YesCompiledWithIt') |
| else |
| build_options_config.set('SANITIZE_LEAK', '') |
| endif |
| if get_option('b_sanitize').contains('undefined') |
| libgit_c_args += '-DSHA1DC_FORCE_ALIGNED_ACCESS' |
| endif |
| |
| executable_suffix = '' |
| if host_machine.system() == 'cygwin' or host_machine.system() == 'windows' |
| executable_suffix = '.exe' |
| libgit_c_args += '-DSTRIP_EXTENSION="' + executable_suffix + '"' |
| endif |
| build_options_config.set_quoted('X', executable_suffix) |
| |
| python = import('python').find_installation('python3', required: get_option('python')) |
| if python.found() |
| build_options_config.set('NO_PYTHON', '') |
| else |
| libgit_c_args += '-DNO_PYTHON' |
| build_options_config.set('NO_PYTHON', '1') |
| endif |
| |
| # Perl is used for two different things: our test harness and to provide some |
| # features. It is optional if you want to neither execute tests nor use any of |
| # these optional features. |
| perl_required = get_option('perl') |
| if get_option('tests') or get_option('gitweb').enabled() |
| perl_required = true |
| endif |
| |
| # Note that we only set NO_PERL if the Perl features were disabled by the user. |
| # It may not be set when we have found Perl, but only use it to run tests. |
| perl = find_program('perl', version: '>=5.8.1', dirs: program_path, required: perl_required) |
| perl_features_enabled = perl.found() and get_option('perl').allowed() |
| if perl_features_enabled |
| build_options_config.set('NO_PERL', '') |
| |
| if get_option('runtime_prefix') |
| build_options_config.set('PERL_LOCALEDIR', '') |
| else |
| build_options_config.set_quoted('PERL_LOCALEDIR', fs.as_posix(get_option('prefix') / get_option('localedir'))) |
| endif |
| |
| if get_option('perl_cpan_fallback') |
| build_options_config.set('NO_PERL_CPAN_FALLBACKS', '') |
| else |
| build_options_config.set_quoted('NO_PERL_CPAN_FALLBACKS', 'YesPlease') |
| endif |
| else |
| libgit_c_args += '-DNO_PERL' |
| build_options_config.set('NO_PERL', '1') |
| build_options_config.set('PERL_LOCALEDIR', '') |
| build_options_config.set('NO_PERL_CPAN_FALLBACKS', '') |
| endif |
| |
| zlib = dependency('zlib', default_options: ['default_library=static', 'tests=disabled']) |
| if zlib.version().version_compare('<1.2.0') |
| libgit_c_args += '-DNO_DEFLATE_BOUND' |
| endif |
| libgit_dependencies += zlib |
| |
| threads = dependency('threads', required: false) |
| if threads.found() |
| libgit_dependencies += threads |
| build_options_config.set('NO_PTHREADS', '') |
| else |
| libgit_c_args += '-DNO_PTHREADS' |
| build_options_config.set('NO_PTHREADS', '1') |
| endif |
| |
| msgfmt = find_program('msgfmt', dirs: program_path, required: false) |
| gettext_option = get_option('gettext').disable_auto_if(not msgfmt.found()) |
| if not msgfmt.found() and gettext_option.enabled() |
| error('Internationalization via libintl requires msgfmt') |
| endif |
| |
| if gettext_option.allowed() and host_machine.system() == 'darwin' and get_option('macos_use_homebrew_gettext') |
| if host_machine.cpu_family() == 'x86_64' |
| libintl_prefix = '/usr/local' |
| elif host_machine.cpu_family() == 'aarch64' |
| libintl_prefix = '/opt/homebrew' |
| else |
| error('Homebrew workaround not supported on current architecture') |
| endif |
| |
| intl = compiler.find_library('intl', dirs: libintl_prefix / 'lib', required: gettext_option) |
| if intl.found() |
| intl = declare_dependency( |
| dependencies: intl, |
| include_directories: libintl_prefix / 'include', |
| ) |
| endif |
| else |
| intl = dependency('intl', required: gettext_option) |
| endif |
| if intl.found() |
| libgit_dependencies += intl |
| build_options_config.set('NO_GETTEXT', '') |
| build_options_config.set('USE_GETTEXT_SCHEME', '') |
| |
| # POSIX nowadays requires `nl_langinfo()`, but some systems still don't have |
| # the function available. On such systems we instead fall back to libcharset. |
| # On native Windows systems we use our own emulation. |
| if host_machine.system() != 'windows' and not compiler.has_function('nl_langinfo') |
| libcharset = compiler.find_library('charset', required: true) |
| libgit_dependencies += libcharset |
| libgit_c_args += '-DHAVE_LIBCHARSET_H' |
| endif |
| else |
| libgit_c_args += '-DNO_GETTEXT' |
| build_options_config.set('NO_GETTEXT', '1') |
| build_options_config.set('USE_GETTEXT_SCHEME', 'fallthrough') |
| endif |
| |
| iconv = dependency('iconv', required: get_option('iconv')) |
| if iconv.found() |
| libgit_dependencies += iconv |
| build_options_config.set('NO_ICONV', '') |
| |
| have_old_iconv = false |
| if not compiler.compiles(''' |
| #include <iconv.h> |
| |
| extern size_t iconv(iconv_t cd, |
| char **inbuf, size_t *inbytesleft, |
| char **outbuf, size_t *outbytesleft); |
| ''', name: 'old iconv interface', dependencies: [iconv]) |
| libgit_c_args += '-DOLD_ICONV' |
| have_old_iconv = true |
| endif |
| |
| iconv_omits_bom_source = '''# |
| #include <iconv.h> |
| |
| int main(int argc, const char **argv) |
| { |
| ''' |
| if have_old_iconv |
| iconv_omits_bom_source += ''' |
| typedef const char *iconv_ibp; |
| ''' |
| else |
| iconv_omits_bom_source += ''' |
| typedef char *iconv_ibp; |
| ''' |
| endif |
| iconv_omits_bom_source += ''' |
| int v; |
| iconv_t conv; |
| char in[] = "a"; iconv_ibp pin = in; |
| char out[20] = ""; char *pout = out; |
| size_t isz = sizeof in; |
| size_t osz = sizeof out; |
| |
| conv = iconv_open("UTF-16", "UTF-8"); |
| iconv(conv, &pin, &isz, &pout, &osz); |
| iconv_close(conv); |
| v = (unsigned char)(out[0]) + (unsigned char)(out[1]); |
| return v != 0xfe + 0xff; |
| } |
| ''' |
| |
| if compiler.run(iconv_omits_bom_source, |
| dependencies: iconv, |
| name: 'iconv omits BOM', |
| ).returncode() != 0 |
| libgit_c_args += '-DICONV_OMITS_BOM' |
| endif |
| else |
| libgit_c_args += '-DNO_ICONV' |
| build_options_config.set('NO_ICONV', '1') |
| endif |
| |
| pcre2 = dependency('libpcre2-8', required: get_option('pcre2'), default_options: ['default_library=static', 'test=false']) |
| if pcre2.found() |
| libgit_dependencies += pcre2 |
| libgit_c_args += '-DUSE_LIBPCRE2' |
| build_options_config.set('USE_LIBPCRE2', '1') |
| else |
| build_options_config.set('USE_LIBPCRE2', '') |
| endif |
| |
| curl = dependency('libcurl', version: '>=7.21.3', required: get_option('curl'), default_options: ['default_library=static', 'tests=disabled', 'tool=disabled']) |
| use_curl_for_imap_send = false |
| if curl.found() |
| if curl.version().version_compare('>=7.34.0') |
| libgit_c_args += '-DUSE_CURL_FOR_IMAP_SEND' |
| use_curl_for_imap_send = true |
| endif |
| |
| libgit_dependencies += curl |
| libgit_c_args += '-DCURL_DISABLE_TYPECHECK' |
| build_options_config.set('NO_CURL', '') |
| else |
| libgit_c_args += '-DNO_CURL' |
| build_options_config.set('NO_CURL', '1') |
| endif |
| |
| expat = dependency('expat', required: get_option('expat'), default_options: ['default_library=static', 'build_tests=false']) |
| if expat.found() |
| libgit_dependencies += expat |
| |
| if expat.version().version_compare('<=1.2') |
| libgit_c_args += '-DEXPAT_NEEDS_XMLPARSE_H' |
| endif |
| build_options_config.set('NO_EXPAT', '') |
| else |
| libgit_c_args += '-DNO_EXPAT' |
| build_options_config.set('NO_EXPAT', '1') |
| endif |
| |
| if not compiler.has_header('sys/select.h') |
| libgit_c_args += '-DNO_SYS_SELECT_H' |
| endif |
| |
| has_poll_h = compiler.has_header('poll.h') |
| if not has_poll_h |
| libgit_c_args += '-DNO_POLL_H' |
| endif |
| |
| has_sys_poll_h = compiler.has_header('sys/poll.h') |
| if not has_sys_poll_h |
| libgit_c_args += '-DNO_SYS_POLL_H' |
| endif |
| |
| if not has_poll_h and not has_sys_poll_h |
| libgit_c_args += '-DNO_POLL' |
| libgit_sources += 'compat/poll/poll.c' |
| libgit_include_directories += 'compat/poll' |
| endif |
| |
| if not compiler.has_header('inttypes.h') |
| libgit_c_args += '-DNO_INTTYPES_H' |
| endif |
| |
| if compiler.has_header('alloca.h') |
| libgit_c_args += '-DHAVE_ALLOCA_H' |
| endif |
| |
| if compiler.has_header('sys/sysinfo.h') |
| libgit_c_args += '-DHAVE_SYSINFO' |
| endif |
| |
| # Windows has libgen.h and a basename implementation, but we still need our own |
| # implementation to threat things like drive prefixes specially. |
| if host_machine.system() == 'windows' or not compiler.has_header('libgen.h') |
| libgit_c_args += '-DNO_LIBGEN_H' |
| libgit_sources += 'compat/basename.c' |
| endif |
| |
| if compiler.has_header('paths.h') |
| libgit_c_args += '-DHAVE_PATHS_H' |
| endif |
| |
| if compiler.has_header('strings.h') |
| libgit_c_args += '-DHAVE_STRINGS_H' |
| endif |
| |
| networking_dependencies = [ ] |
| if host_machine.system() == 'windows' |
| winsock = compiler.find_library('ws2_32', required: false) |
| if winsock.found() |
| networking_dependencies += winsock |
| endif |
| else |
| libresolv = compiler.find_library('resolv', required: false) |
| if libresolv.found() |
| networking_dependencies += libresolv |
| endif |
| endif |
| libgit_dependencies += networking_dependencies |
| |
| foreach symbol : ['inet_ntop', 'inet_pton', 'strerror'] |
| if not compiler.has_function(symbol, dependencies: networking_dependencies) |
| libgit_c_args += '-DNO_' + symbol.to_upper() |
| endif |
| endforeach |
| |
| has_ipv6 = compiler.has_function('getaddrinfo', dependencies: networking_dependencies) |
| if not has_ipv6 |
| libgit_c_args += '-DNO_IPV6' |
| endif |
| |
| if not compiler.compiles(''' |
| #ifdef _WIN32 |
| # include <winsock2.h> |
| #else |
| # include <sys/types.h> |
| # include <sys/socket.h> |
| #endif |
| |
| void func(void) |
| { |
| struct sockaddr_storage x; |
| } |
| ''', name: 'struct sockaddr_storage') |
| if has_ipv6 |
| libgit_c_args += '-Dsockaddr_storage=sockaddr_in6' |
| else |
| libgit_c_args += '-Dsockaddr_storage=sockaddr_in' |
| endif |
| endif |
| |
| if compiler.has_function('socket', dependencies: networking_dependencies) |
| libgit_sources += [ |
| 'unix-socket.c', |
| 'unix-stream-server.c', |
| ] |
| build_options_config.set('NO_UNIX_SOCKETS', '') |
| else |
| libgit_c_args += '-DNO_UNIX_SOCKETS' |
| build_options_config.set('NO_UNIX_SOCKETS', '1') |
| endif |
| |
| if not compiler.has_function('pread') |
| libgit_c_args += '-DNO_PREAD' |
| libgit_sources += 'compat/pread.c' |
| endif |
| |
| if host_machine.system() == 'darwin' |
| libgit_sources += 'compat/precompose_utf8.c' |
| libgit_c_args += '-DPRECOMPOSE_UNICODE' |
| libgit_c_args += '-DPROTECT_HFS_DEFAULT' |
| endif |
| |
| # Configure general compatibility wrappers. |
| if host_machine.system() == 'cygwin' |
| libgit_sources += [ |
| 'compat/win32/path-utils.c', |
| ] |
| elif host_machine.system() == 'windows' |
| libgit_sources += [ |
| 'compat/mingw.c', |
| 'compat/winansi.c', |
| 'compat/win32/flush.c', |
| 'compat/win32/path-utils.c', |
| 'compat/win32/pthread.c', |
| 'compat/win32/syslog.c', |
| 'compat/win32/dirent.c', |
| 'compat/win32mmap.c', |
| 'compat/nedmalloc/nedmalloc.c', |
| ] |
| |
| libgit_c_args += [ |
| '-DDETECT_MSYS_TTY', |
| '-DENSURE_MSYSTEM_IS_SET', |
| '-DNATIVE_CRLF', |
| '-DNOGDI', |
| '-DNO_POSIX_GOODIES', |
| '-DWIN32', |
| '-D_CONSOLE', |
| '-D_CONSOLE_DETECT_MSYS_TTY', |
| '-D__USE_MINGW_ANSI_STDIO=0', |
| ] |
| |
| libgit_dependencies += compiler.find_library('ntdll') |
| libgit_include_directories += 'compat/win32' |
| if compiler.get_id() == 'msvc' |
| libgit_include_directories += 'compat/vcbuild/include' |
| endif |
| endif |
| |
| if host_machine.system() == 'linux' |
| libgit_sources += 'compat/linux/procinfo.c' |
| elif host_machine.system() == 'windows' |
| libgit_sources += 'compat/win32/trace2_win32_process_info.c' |
| else |
| libgit_sources += 'compat/stub/procinfo.c' |
| endif |
| |
| if host_machine.system() == 'cygwin' or host_machine.system() == 'windows' |
| libgit_c_args += [ |
| '-DUNRELIABLE_FSTAT', |
| '-DMMAP_PREVENTS_DELETE', |
| '-DOBJECT_CREATION_MODE=1', |
| ] |
| endif |
| |
| # Configure the simple-ipc subsystem required fro the fsmonitor. |
| if host_machine.system() == 'windows' |
| libgit_sources += [ |
| 'compat/simple-ipc/ipc-shared.c', |
| 'compat/simple-ipc/ipc-win32.c', |
| ] |
| libgit_c_args += '-DSUPPORTS_SIMPLE_IPC' |
| else |
| libgit_sources += [ |
| 'compat/simple-ipc/ipc-shared.c', |
| 'compat/simple-ipc/ipc-unix-socket.c', |
| ] |
| libgit_c_args += '-DSUPPORTS_SIMPLE_IPC' |
| endif |
| |
| fsmonitor_backend = '' |
| if host_machine.system() == 'windows' |
| fsmonitor_backend = 'win32' |
| elif host_machine.system() == 'darwin' |
| fsmonitor_backend = 'darwin' |
| libgit_dependencies += dependency('CoreServices') |
| endif |
| if fsmonitor_backend != '' |
| libgit_c_args += '-DHAVE_FSMONITOR_DAEMON_BACKEND' |
| libgit_c_args += '-DHAVE_FSMONITOR_OS_SETTINGS' |
| |
| libgit_sources += [ |
| 'compat/fsmonitor/fsm-health-' + fsmonitor_backend + '.c', |
| 'compat/fsmonitor/fsm-ipc-' + fsmonitor_backend + '.c', |
| 'compat/fsmonitor/fsm-listen-' + fsmonitor_backend + '.c', |
| 'compat/fsmonitor/fsm-path-utils-' + fsmonitor_backend + '.c', |
| 'compat/fsmonitor/fsm-settings-' + fsmonitor_backend + '.c', |
| ] |
| endif |
| build_options_config.set_quoted('FSMONITOR_DAEMON_BACKEND', fsmonitor_backend) |
| build_options_config.set_quoted('FSMONITOR_OS_SETTINGS', fsmonitor_backend) |
| |
| 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>') != '' |
| build_options_config.set('NO_REGEX', '') |
| |
| if compiler.get_define('REG_ENHANCED', prefix: '#include <regex.h>') != '' |
| libgit_c_args += '-DUSE_ENHANCED_BASIC_REGULAR_EXPRESSIONS' |
| libgit_sources += 'compat/regcomp_enhanced.c' |
| endif |
| elif not get_option('regex').enabled() |
| libgit_c_args += [ |
| '-DNO_REGEX', |
| '-DGAWK', |
| '-DNO_MBSUPPORT', |
| ] |
| build_options_config.set('NO_REGEX', '1') |
| libgit_sources += 'compat/regex/regex.c' |
| libgit_include_directories += 'compat/regex' |
| else |
| error('Native regex support requested but not found') |
| endif |
| |
| # setitimer and friends are provided by compat/mingw.c. |
| if host_machine.system() != 'windows' |
| if not compiler.compiles(''' |
| #include <sys/time.h> |
| void func(void) |
| { |
| struct itimerval value; |
| } |
| ''', name: 'struct itimerval') |
| libgit_c_args += '-DNO_STRUCT_ITIMERVAL' |
| libgit_c_args += '-DNO_SETITIMER' |
| elif not compiler.has_function('setitimer') |
| libgit_c_args += '-DNO_SETITIMER' |
| endif |
| endif |
| |
| if compiler.has_member('struct stat', 'st_mtimespec.tv_nsec', prefix: '#include <sys/stat.h>') |
| libgit_c_args += '-DUSE_ST_TIMESPEC' |
| elif not compiler.has_member('struct stat', 'st_mtim.tv_nsec', prefix: '#include <sys/stat.h>') |
| libgit_c_args += '-DNO_NSEC' |
| endif |
| |
| if not compiler.has_member('struct stat', 'st_blocks', prefix: '#include <sys/stat.h>') |
| libgit_c_args += '-DNO_ST_BLOCKS_IN_STRUCT_STAT' |
| endif |
| |
| if not compiler.has_member('struct dirent', 'd_type', prefix: '#include <dirent.h>') |
| libgit_c_args += '-DNO_D_TYPE_IN_DIRENT' |
| endif |
| |
| if not compiler.has_member('struct passwd', 'pw_gecos', prefix: '#include <pwd.h>') |
| libgit_c_args += '-DNO_GECOS_IN_PWENT' |
| endif |
| |
| if compiler.has_function('sync_file_range') |
| libgit_c_args += '-DHAVE_SYNC_FILE_RANGE' |
| endif |
| |
| if not compiler.has_function('strcasestr') |
| libgit_c_args += '-DNO_STRCASESTR' |
| libgit_sources += 'compat/strcasestr.c' |
| endif |
| |
| if not compiler.has_function('memmem') |
| libgit_c_args += '-DNO_MEMMEM' |
| libgit_sources += 'compat/memmem.c' |
| endif |
| |
| if not compiler.has_function('strlcpy') |
| libgit_c_args += '-DNO_STRLCPY' |
| libgit_sources += 'compat/strlcpy.c' |
| endif |
| |
| if not compiler.has_function('strdup') |
| libgit_c_args += '-DOVERRIDE_STRDUP' |
| libgit_sources += 'compat/strdup.c' |
| endif |
| |
| if not compiler.has_function('strtoumax') |
| libgit_c_args += '-DNO_STRTOUMAX' |
| libgit_sources += [ |
| 'compat/strtoumax.c', |
| 'compat/strtoimax.c', |
| ] |
| endif |
| |
| if not compiler.has_function('strtoull') |
| libgit_c_args += '-DNO_STRTOULL' |
| endif |
| |
| if not compiler.has_function('setenv') |
| libgit_c_args += '-DNO_SETENV' |
| libgit_sources += 'compat/setenv.c' |
| endif |
| |
| if not compiler.has_function('qsort') |
| libgit_c_args += '-DINTERNAL_QSORT' |
| endif |
| libgit_sources += 'compat/qsort_s.c' |
| |
| # unsetenv is provided by compat/mingw.c. |
| if host_machine.system() != 'windows' and not compiler.has_function('unsetenv') |
| libgit_c_args += '-DNO_UNSETENV' |
| libgit_sources += 'compat/unsetenv.c' |
| endif |
| |
| if not compiler.has_function('mkdtemp') |
| libgit_c_args += '-DNO_MKDTEMP' |
| libgit_sources += 'compat/mkdtemp.c' |
| endif |
| |
| if not compiler.has_function('initgroups') |
| libgit_c_args += '-DNO_INITGROUPS' |
| endif |
| |
| if compiler.has_function('getdelim') |
| libgit_c_args += '-DHAVE_GETDELIM' |
| endif |
| |
| if host_machine.system() == 'windows' |
| libgit_c_args += '-DUSE_WIN32_MMAP' |
| elif not compiler.has_function('mmap') |
| libgit_c_args += '-DNO_MMAP' |
| libgit_sources += 'compat/mmap.c' |
| endif |
| |
| if compiler.has_function('clock_gettime') |
| libgit_c_args += '-DHAVE_CLOCK_GETTIME' |
| endif |
| |
| if compiler.compiles(''' |
| #include <time.h> |
| |
| void func(void) |
| { |
| clockid_t id = CLOCK_MONOTONIC; |
| } |
| ''', name: 'monotonic clock') |
| libgit_c_args += '-DHAVE_CLOCK_MONOTONIC' |
| endif |
| |
| if not compiler.compiles(''' |
| #include <inttypes.h> |
| |
| void func(void) |
| { |
| uintmax_t x = 0; |
| } |
| ''', name: 'uintmax_t') |
| libgit_c_args += '-DNO_UINTMAX_T' |
| endif |
| |
| has_bsd_sysctl = false |
| if compiler.has_header('sys/sysctl.h') |
| if compiler.compiles(''' |
| #include <stddef.h> |
| #include <sys/sysctl.h> |
| |
| void func(void) |
| { |
| int val, mib[2] = { 0 }; |
| size_t len = sizeof(val); |
| sysctl(mib, 2, &val, &len, NULL, 0); |
| } |
| ''', name: 'BSD sysctl') |
| libgit_c_args += '-DHAVE_BSD_SYSCTL' |
| has_bsd_sysctl = true |
| endif |
| endif |
| |
| if not meson.is_cross_build() and compiler.run(''' |
| #include <stdio.h> |
| |
| int main(int argc, const char **argv) |
| { |
| FILE *f = fopen(".", "r"); |
| return f ? 0 : 1; |
| } |
| ''', name: 'fread reads directories').returncode() == 0 |
| libgit_c_args += '-DFREAD_READS_DIRECTORIES' |
| libgit_sources += 'compat/fopen.c' |
| endif |
| |
| if not meson.is_cross_build() and fs.exists('/dev/tty') |
| libgit_c_args += '-DHAVE_DEV_TTY' |
| endif |
| |
| https_backend = get_option('https_backend') |
| |
| security_framework = dependency('Security', required: https_backend == 'CommonCrypto') |
| core_foundation_framework = dependency('CoreFoundation', required: security_framework.found()) |
| if https_backend == 'auto' and security_framework.found() |
| https_backend = 'CommonCrypto' |
| endif |
| |
| openssl_required = https_backend == 'openssl' or get_option('sha1_backend') == 'openssl' or get_option('sha256_backend') == 'openssl' |
| openssl = dependency('openssl', required: openssl_required, default_options: ['default_library=static']) |
| if https_backend == 'auto' and openssl.found() |
| https_backend = 'openssl' |
| endif |
| |
| if https_backend == 'CommonCrypto' |
| libgit_dependencies += security_framework |
| libgit_dependencies += core_foundation_framework |
| libgit_c_args += '-DAPPLE_COMMON_CRYPTO' |
| elif https_backend == 'openssl' |
| libgit_dependencies += openssl |
| else |
| # We either couldn't find any dependencies with 'auto' or the user requested |
| # 'none'. Both cases are benign. |
| endif |
| |
| if https_backend != 'openssl' |
| libgit_c_args += '-DNO_OPENSSL' |
| endif |
| |
| sha1_backend = get_option('sha1_backend') |
| if sha1_backend == 'sha1dc' |
| libgit_c_args += '-DSHA1_DC' |
| libgit_c_args += '-DSHA1DC_NO_STANDARD_INCLUDES=1' |
| libgit_c_args += '-DSHA1DC_INIT_SAFE_HASH_DEFAULT=0' |
| libgit_c_args += '-DSHA1DC_CUSTOM_INCLUDE_SHA1_C="git-compat-util.h"' |
| libgit_c_args += '-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C="git-compat-util.h"' |
| |
| libgit_sources += [ |
| 'sha1dc_git.c', |
| 'sha1dc/sha1.c', |
| 'sha1dc/ubc_check.c', |
| ] |
| elif sha1_backend == 'common-crypto' |
| libgit_c_args += '-DCOMMON_DIGEST_FOR_OPENSSL' |
| libgit_c_args += '-DSHA1_APPLE' |
| # Apple CommonCrypto requires chunking |
| libgit_c_args += '-DSHA1_MAX_BLOCK_SIZE=1024L*1024L*1024L' |
| elif sha1_backend == 'openssl' |
| libgit_c_args += '-DSHA1_OPENSSL' |
| libgit_dependencies += openssl |
| elif sha1_backend == 'block' |
| libgit_c_args += '-DSHA1_BLK' |
| libgit_sources += 'block-sha1/sha1.c' |
| else |
| error('Unhandled SHA1 backend ' + sha1_backend) |
| endif |
| |
| sha256_backend = get_option('sha256_backend') |
| if sha256_backend == 'openssl' |
| libgit_c_args += '-DSHA256_OPENSSL' |
| libgit_dependencies += openssl |
| elif sha256_backend == 'nettle' |
| nettle = dependency('nettle') |
| libgit_dependencies += nettle |
| libgit_c_args += '-DSHA256_NETTLE' |
| elif sha256_backend == 'gcrypt' |
| gcrypt = dependency('gcrypt') |
| libgit_dependencies += gcrypt |
| libgit_c_args += '-DSHA256_GCRYPT' |
| elif sha256_backend == 'block' |
| libgit_c_args += '-DSHA256_BLK' |
| libgit_sources += 'sha256/block/sha256.c' |
| else |
| error('Unhandled SHA256 backend ' + sha256_backend) |
| endif |
| |
| if compiler.has_header_symbol('stdlib.h', 'arc4random_buf') |
| libgit_c_args += '-DHAVE_ARC4RANDOM' |
| elif compiler.has_header_symbol('bsd/stdlib.h', 'arc4random_buf') |
| libgit_c_args += '-DHAVE_ARC4RANDOM_BSD' |
| elif compiler.has_function('getrandom', prefix: '#include <sys/random.h>') |
| libgit_c_args += '-DHAVE_GETRANDOM' |
| elif compiler.has_function('getentropy', prefix: '#include <unistd.h>') |
| libgit_c_args += '-DHAVE_GETENTROPY' |
| elif compiler.has_function('RtlGenRandom', prefix: '#include <windows.h>\n#include <ntsecapi.h>') |
| libgit_c_args += '-DHAVE_RTLGENRANDOM' |
| elif openssl.found() |
| libgit_c_args += '-DHAVE_OPENSSL_CSPRNG' |
| endif |
| |
| if get_option('runtime_prefix') |
| libgit_c_args += '-DRUNTIME_PREFIX' |
| build_options_config.set('RUNTIME_PREFIX', 'true') |
| |
| if compiler.has_header('mach-o/dyld.h') |
| libgit_c_args += '-DHAVE_NS_GET_EXECUTABLE_PATH' |
| endif |
| |
| if has_bsd_sysctl and compiler.compiles(''' |
| #include <sys/sysctl.h> |
| |
| void func(void) |
| { |
| KERN_PROC_PATHNAME; KERN_PROC; |
| } |
| ''', name: 'BSD KERN_PROC_PATHNAME') |
| libgit_c_args += '-DHAVE_NS_GET_EXECUTABLE_PATH' |
| endif |
| |
| if host_machine.system() == 'linux' |
| libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="/proc/self/exe' + '"' |
| elif host_machine.system() == 'openbsd' |
| libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="' + '/proc/curproc/file' + '"' |
| elif host_machine.system() == 'netbsd' |
| libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="' + '/proc/curproc/exe' + '"' |
| endif |
| |
| if host_machine.system() == 'windows' and compiler.compiles(''' |
| #include <stdlib.h> |
| |
| void func(void) |
| { |
| _wpgmptr; |
| } |
| ''', name: 'Win32 _wpgmptr') |
| libgit_c_args += '-DHAVE_WPGMPTR' |
| endif |
| else |
| build_options_config.set('RUNTIME_PREFIX', 'false') |
| endif |
| |
| git_version_file = custom_target( |
| command: [ |
| shell, |
| meson.current_source_dir() / 'GIT-VERSION-GEN', |
| meson.current_source_dir(), |
| '@INPUT@', |
| '@OUTPUT@', |
| ], |
| input: meson.current_source_dir() / 'GIT-VERSION-FILE.in', |
| output: 'GIT-VERSION-FILE', |
| env: version_gen_environment, |
| build_always_stale: true, |
| ) |
| |
| version_def_h = custom_target( |
| command: [ |
| shell, |
| meson.current_source_dir() / 'GIT-VERSION-GEN', |
| meson.current_source_dir(), |
| '@INPUT@', |
| '@OUTPUT@', |
| ], |
| input: meson.current_source_dir() / 'version-def.h.in', |
| output: 'version-def.h', |
| # Depend on GIT-VERSION-FILE so that we don't always try to rebuild this |
| # target for the same commit. |
| depends: [git_version_file], |
| env: version_gen_environment, |
| ) |
| |
| # Build a separate library for "version.c" so that we do not have to rebuild |
| # everything when the current Git commit changes. |
| libgit_version_library = static_library('git-version', |
| sources: [ |
| 'version.c', |
| version_def_h, |
| ], |
| c_args: libgit_c_args, |
| dependencies: libgit_dependencies, |
| include_directories: libgit_include_directories, |
| ) |
| |
| libgit_library = static_library('git', |
| sources: libgit_sources, |
| c_args: libgit_c_args, |
| link_with: libgit_version_library, |
| dependencies: libgit_dependencies, |
| include_directories: libgit_include_directories, |
| ) |
| |
| libgit = declare_dependency( |
| compile_args: libgit_c_args, |
| link_with: libgit_library, |
| dependencies: libgit_dependencies, |
| include_directories: libgit_include_directories, |
| ) |
| |
| common_main_sources = ['common-main.c'] |
| common_main_link_args = [ ] |
| if host_machine.system() == 'windows' |
| git_rc = custom_target( |
| command: [ |
| shell, |
| meson.current_source_dir() / 'GIT-VERSION-GEN', |
| meson.current_source_dir(), |
| '@INPUT@', |
| '@OUTPUT@', |
| ], |
| input: meson.current_source_dir() / 'git.rc.in', |
| output: 'git.rc', |
| depends: [git_version_file], |
| env: version_gen_environment, |
| ) |
| |
| common_main_sources += import('windows').compile_resources(git_rc, |
| include_directories: [meson.current_source_dir()], |
| ) |
| if compiler.get_argument_syntax() == 'gcc' |
| common_main_link_args += [ |
| '-municode', |
| '-Wl,-nxcompat', |
| '-Wl,-dynamicbase', |
| '-Wl,-pic-executable,-e,mainCRTStartup', |
| ] |
| elif compiler.get_argument_syntax() == 'msvc' |
| common_main_link_args += [ |
| '/ENTRY:wmainCRTStartup', |
| 'invalidcontinue.obj', |
| ] |
| else |
| error('Unsupported compiler ' + compiler.get_id()) |
| endif |
| endif |
| common_main_library = static_library('common-main', |
| sources: common_main_sources, |
| c_args: libgit_c_args, |
| dependencies: libgit_dependencies, |
| include_directories: libgit_include_directories, |
| ) |
| common_main = declare_dependency( |
| link_with: common_main_library, |
| link_args: common_main_link_args, |
| ) |
| |
| bin_wrappers = [ ] |
| test_dependencies = [ ] |
| |
| git = executable('git', |
| sources: builtin_sources + 'git.c', |
| dependencies: [libgit, common_main], |
| install: true, |
| install_dir: get_option('libexecdir') / 'git-core', |
| ) |
| bin_wrappers += git |
| |
| test_dependencies += executable('git-daemon', |
| sources: 'daemon.c', |
| dependencies: [libgit, common_main], |
| install: true, |
| install_dir: get_option('libexecdir') / 'git-core', |
| ) |
| |
| test_dependencies += executable('git-sh-i18n--envsubst', |
| sources: 'sh-i18n--envsubst.c', |
| dependencies: [libgit, common_main], |
| install: true, |
| install_dir: get_option('libexecdir') / 'git-core', |
| ) |
| |
| bin_wrappers += executable('git-shell', |
| sources: 'shell.c', |
| dependencies: [libgit, common_main], |
| install: true, |
| install_dir: get_option('libexecdir') / 'git-core', |
| ) |
| |
| test_dependencies += executable('git-http-backend', |
| sources: 'http-backend.c', |
| dependencies: [libgit, common_main], |
| install: true, |
| install_dir: get_option('libexecdir') / 'git-core', |
| ) |
| |
| bin_wrappers += executable('scalar', |
| sources: 'scalar.c', |
| dependencies: [libgit, common_main], |
| install: true, |
| install_dir: get_option('libexecdir') / 'git-core', |
| ) |
| |
| if get_option('curl').enabled() |
| curl_sources = [ |
| 'http.c', |
| 'http-walker.c', |
| ] |
| |
| git_remote_http = executable('git-remote-http', |
| sources: curl_sources + 'remote-curl.c', |
| dependencies: [libgit, common_main], |
| install: true, |
| install_dir: get_option('libexecdir') / 'git-core', |
| ) |
| test_dependencies += git_remote_http |
| |
| test_dependencies += executable('git-http-fetch', |
| sources: curl_sources + 'http-fetch.c', |
| dependencies: [libgit, common_main], |
| install: true, |
| install_dir: get_option('libexecdir') / 'git-core', |
| ) |
| |
| if expat.found() |
| test_dependencies += executable('git-http-push', |
| sources: curl_sources + 'http-push.c', |
| dependencies: [libgit, common_main], |
| install: true, |
| install_dir: get_option('libexecdir') / 'git-core', |
| ) |
| endif |
| |
| foreach alias : [ 'git-remote-https', 'git-remote-ftp', 'git-remote-ftps' ] |
| test_dependencies += executable(alias, |
| objects: git_remote_http.extract_all_objects(recursive: false), |
| dependencies: [libgit, common_main], |
| ) |
| |
| install_symlink(alias + executable_suffix, |
| install_dir: get_option('libexecdir') / 'git-core', |
| pointing_to: 'git-remote-http', |
| ) |
| endforeach |
| endif |
| |
| imap_send_sources = ['imap-send.c'] |
| if use_curl_for_imap_send |
| imap_send_sources += curl_sources |
| endif |
| |
| test_dependencies += executable('git-imap-send', |
| sources: imap_send_sources, |
| dependencies: [libgit, common_main], |
| install: true, |
| install_dir: get_option('libexecdir') / 'git-core', |
| ) |
| |
| foreach alias : [ 'git-receive-pack', 'git-upload-archive', 'git-upload-pack' ] |
| bin_wrappers += executable(alias, |
| objects: git.extract_all_objects(recursive: false), |
| dependencies: [libgit, common_main], |
| ) |
| |
| install_symlink(alias + executable_suffix, |
| install_dir: get_option('libexecdir') / 'git-core', |
| pointing_to: 'git', |
| ) |
| endforeach |
| |
| foreach symlink : [ |
| 'git', |
| 'git-receive-pack', |
| 'git-shell', |
| 'git-upload-archive', |
| 'git-upload-pack', |
| 'scalar', |
| ] |
| if meson.version().version_compare('>=1.3.0') |
| pointing_to = fs.relative_to(get_option('libexecdir') / 'git-core' / symlink, get_option('bindir')) |
| else |
| pointing_to = '../libexec/git-core' / symlink |
| endif |
| |
| install_symlink(symlink, |
| install_dir: get_option('bindir'), |
| pointing_to: pointing_to, |
| ) |
| endforeach |
| |
| scripts_sh = [ |
| 'git-difftool--helper.sh', |
| 'git-filter-branch.sh', |
| 'git-merge-octopus.sh', |
| 'git-merge-one-file.sh', |
| 'git-merge-resolve.sh', |
| 'git-mergetool--lib.sh', |
| 'git-mergetool.sh', |
| 'git-quiltimport.sh', |
| 'git-request-pull.sh', |
| 'git-sh-i18n.sh', |
| 'git-sh-setup.sh', |
| 'git-submodule.sh', |
| 'git-web--browse.sh', |
| ] |
| if perl_features_enabled |
| scripts_sh += 'git-instaweb.sh' |
| endif |
| |
| foreach script : scripts_sh |
| test_dependencies += custom_target( |
| input: script, |
| output: fs.stem(script), |
| command: [ |
| shell, |
| meson.project_source_root() / 'generate-script.sh', |
| '@INPUT@', |
| '@OUTPUT@', |
| meson.project_build_root() / 'GIT-BUILD-OPTIONS', |
| ], |
| install: true, |
| install_dir: get_option('libexecdir') / 'git-core', |
| ) |
| endforeach |
| |
| if perl_features_enabled |
| scripts_perl = [ |
| 'git-archimport.perl', |
| 'git-cvsexportcommit.perl', |
| 'git-cvsimport.perl', |
| 'git-cvsserver.perl', |
| 'git-send-email.perl', |
| 'git-svn.perl', |
| ] |
| |
| pathsep = ':' |
| if host_machine.system() == 'windows' |
| pathsep = ';' |
| endif |
| |
| perl_header_template = 'perl/header_templates/fixed_prefix.template.pl' |
| if get_option('runtime_prefix') |
| perl_header_template = 'perl/header_templates/runtime_prefix.template.pl' |
| endif |
| |
| perl_header = configure_file( |
| input: perl_header_template, |
| output: 'GIT-PERL-HEADER', |
| configuration: { |
| 'GITEXECDIR_REL': get_option('libexecdir') / 'git-core', |
| 'PERLLIBDIR_REL': get_option('datadir') / 'perl5', |
| 'LOCALEDIR_REL': get_option('datadir') / 'locale', |
| 'INSTLIBDIR': get_option('datadir') / 'perl5', |
| 'PATHSEP': pathsep, |
| }, |
| ) |
| |
| generate_perl_command = [ |
| shell, |
| meson.project_source_root() / 'generate-perl.sh', |
| meson.project_build_root() / 'GIT-BUILD-OPTIONS', |
| git_version_file.full_path(), |
| perl_header, |
| '@INPUT@', |
| '@OUTPUT@', |
| ] |
| |
| foreach script : scripts_perl |
| generated_script = custom_target( |
| input: script, |
| output: fs.stem(script), |
| command: generate_perl_command, |
| install: true, |
| install_dir: get_option('libexecdir') / 'git-core', |
| depends: [git_version_file], |
| ) |
| test_dependencies += generated_script |
| |
| if script == 'git-cvsserver.perl' |
| bin_wrappers += generated_script |
| |
| if meson.version().version_compare('>=1.3.0') |
| pointing_to = fs.relative_to(get_option('libexecdir') / 'git-core' / fs.stem(script), get_option('bindir')) |
| else |
| pointing_to = '../libexec/git-core' / fs.stem(script) |
| endif |
| |
| install_symlink(fs.stem(script), |
| install_dir: get_option('bindir'), |
| pointing_to: pointing_to, |
| ) |
| endif |
| endforeach |
| |
| subdir('perl') |
| endif |
| |
| if python.found() |
| scripts_python = [ |
| 'git-p4.py' |
| ] |
| |
| foreach script : scripts_python |
| generated_python = custom_target( |
| input: script, |
| output: fs.stem(script), |
| command: [ |
| shell, |
| meson.project_source_root() / 'generate-python.sh', |
| meson.project_build_root() / 'GIT-BUILD-OPTIONS', |
| '@INPUT@', |
| '@OUTPUT@', |
| ], |
| install: true, |
| install_dir: get_option('libexecdir') / 'git-core', |
| ) |
| test_dependencies += generated_python |
| endforeach |
| endif |
| |
| mergetools = [ |
| 'mergetools/araxis', |
| 'mergetools/bc', |
| 'mergetools/codecompare', |
| 'mergetools/deltawalker', |
| 'mergetools/diffmerge', |
| 'mergetools/diffuse', |
| 'mergetools/ecmerge', |
| 'mergetools/emerge', |
| 'mergetools/examdiff', |
| 'mergetools/guiffy', |
| 'mergetools/gvimdiff', |
| 'mergetools/kdiff3', |
| 'mergetools/kompare', |
| 'mergetools/meld', |
| 'mergetools/nvimdiff', |
| 'mergetools/opendiff', |
| 'mergetools/p4merge', |
| 'mergetools/smerge', |
| 'mergetools/tkdiff', |
| 'mergetools/tortoisemerge', |
| 'mergetools/vimdiff', |
| 'mergetools/vscode', |
| 'mergetools/winmerge', |
| 'mergetools/xxdiff', |
| ] |
| |
| foreach mergetool : mergetools |
| install_data(mergetool, install_dir: get_option('libexecdir') / 'git-core' / 'mergetools') |
| endforeach |
| |
| if intl.found() |
| subdir('po') |
| endif |
| subdir('contrib') |
| |
| # Gitweb requires Perl, so we disable the auto-feature if Perl was not found. |
| # We make sure further up that Perl is required in case the gitweb option is |
| # enabled. |
| gitweb_option = get_option('gitweb').disable_auto_if(not perl.found()) |
| if gitweb_option.allowed() |
| subdir('gitweb') |
| build_options_config.set('NO_GITWEB', '') |
| else |
| build_options_config.set('NO_GITWEB', '1') |
| endif |
| |
| subdir('templates') |
| |
| # Everything but the bin-wrappers need to come before this target such that we |
| # can properly set up test dependencies. The bin-wrappers themselves are set up |
| # at configuration time, so these are fine. |
| if get_option('tests') |
| subdir('t') |
| endif |
| |
| subdir('bin-wrappers') |
| if get_option('docs') != [] |
| subdir('Documentation') |
| endif |
| |
| foreach key, value : { |
| 'DIFF': diff.full_path(), |
| 'GIT_TEST_CMP': diff.full_path() + ' -u', |
| 'GIT_TEST_GITPERLLIB': meson.project_build_root() / 'perl', |
| 'GIT_TEST_MERGE_TOOLS_DIR': meson.project_source_root() / 'mergetools', |
| 'GIT_TEST_POPATH': meson.project_source_root() / 'po', |
| 'GIT_TEST_TEMPLATE_DIR': meson.project_build_root() / 'templates', |
| 'GIT_TEST_TEXTDOMAINDIR': meson.project_build_root() / 'po', |
| 'PAGER_ENV': get_option('pager_environment'), |
| 'PERL_PATH': perl.found() ? perl.full_path() : '', |
| 'PYTHON_PATH': python.found () ? python.full_path() : '', |
| 'SHELL_PATH': shell.full_path(), |
| 'TAR': tar.full_path(), |
| 'TEST_OUTPUT_DIRECTORY': test_output_directory, |
| 'TEST_SHELL_PATH': shell.full_path(), |
| } |
| if value != '' and cygpath.found() |
| value = run_command(cygpath, value, check: true).stdout().strip() |
| endif |
| build_options_config.set_quoted(key, value) |
| endforeach |
| |
| configure_file( |
| input: 'GIT-BUILD-OPTIONS.in', |
| output: 'GIT-BUILD-OPTIONS', |
| configuration: build_options_config, |
| ) |
| |
| summary({ |
| 'curl': curl.found(), |
| 'expat': expat.found(), |
| 'gettext': intl.found(), |
| 'gitweb': gitweb_option.allowed(), |
| 'https': https_backend, |
| 'iconv': iconv.found(), |
| 'pcre2': pcre2.found(), |
| 'perl': perl_features_enabled, |
| 'python': python.found(), |
| }, section: 'Auto-detected features') |