Files
git/Documentation/meson.build
Patrick Steinhardt 23633466df meson: distinguish build and target host binaries
Almost all of the tools we discover during the build process need to be
native programs. There are only a handful of exceptions, which typically
are programs whose paths we need to embed into the resulting executable
so that they can be found on the target system when Git executes. While
this distinction typically doesn't matter, it does start to matter when
considering cross-compilation where the build and target machines are
different.

Meson supports cross-compilation via so-called machine files. These
machine files allow the user to override parameters for the build
machine, but also for the target machine when cross-compiling. Part of
the machine file is a section that allows the user to override the
location where binaries are to be found in the target system. The
following machine file would for example override the path of the POSIX
shell:

    [binaries]
    sh = '/usr/xpg4/bin/sh'

It can be handed over to Meson via `meson setup --cross-file`.

We do not handle this correctly right now though because we don't know
to distinguish binaries for the build and target hosts at all. Address
this by explicitly passing the `native:` parameter to `find_program()`:

  - When set to `true`, we get binaries discovered on the build host.

  - When set to `false`, we get either the path specified in the
    machine file. Or, if no machine file exists or it doesn't specify
    the binary path, then we fall back to the binary discovered on the
    build host.

As mentioned, only a handful of binaries are not native: only the system
shell, Python and Perl need to be treated specially here.

Reported-by: Peter Seiderer <ps.report@gmx.net>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-04-01 02:20:44 -07:00

509 lines
13 KiB
Meson

manpages = {
# Category 1.
'git-add.adoc' : 1,
'git-am.adoc' : 1,
'git-annotate.adoc' : 1,
'git-apply.adoc' : 1,
'git-archimport.adoc' : 1,
'git-archive.adoc' : 1,
'git-backfill.adoc' : 1,
'git-bisect.adoc' : 1,
'git-blame.adoc' : 1,
'git-branch.adoc' : 1,
'git-bugreport.adoc' : 1,
'git-bundle.adoc' : 1,
'git-cat-file.adoc' : 1,
'git-check-attr.adoc' : 1,
'git-check-ignore.adoc' : 1,
'git-check-mailmap.adoc' : 1,
'git-checkout-index.adoc' : 1,
'git-checkout.adoc' : 1,
'git-check-ref-format.adoc' : 1,
'git-cherry-pick.adoc' : 1,
'git-cherry.adoc' : 1,
'git-citool.adoc' : 1,
'git-clean.adoc' : 1,
'git-clone.adoc' : 1,
'git-column.adoc' : 1,
'git-commit-graph.adoc' : 1,
'git-commit-tree.adoc' : 1,
'git-commit.adoc' : 1,
'git-config.adoc' : 1,
'git-count-objects.adoc' : 1,
'git-credential-cache--daemon.adoc' : 1,
'git-credential-cache.adoc' : 1,
'git-credential-store.adoc' : 1,
'git-credential.adoc' : 1,
'git-cvsexportcommit.adoc' : 1,
'git-cvsimport.adoc' : 1,
'git-cvsserver.adoc' : 1,
'git-daemon.adoc' : 1,
'git-describe.adoc' : 1,
'git-diagnose.adoc' : 1,
'git-diff-files.adoc' : 1,
'git-diff-index.adoc' : 1,
'git-difftool.adoc' : 1,
'git-diff-tree.adoc' : 1,
'git-diff.adoc' : 1,
'git-fast-export.adoc' : 1,
'git-fast-import.adoc' : 1,
'git-fetch-pack.adoc' : 1,
'git-fetch.adoc' : 1,
'git-filter-branch.adoc' : 1,
'git-fmt-merge-msg.adoc' : 1,
'git-for-each-ref.adoc' : 1,
'git-for-each-repo.adoc' : 1,
'git-format-patch.adoc' : 1,
'git-fsck-objects.adoc' : 1,
'git-fsck.adoc' : 1,
'git-fsmonitor--daemon.adoc' : 1,
'git-gc.adoc' : 1,
'git-get-tar-commit-id.adoc' : 1,
'git-grep.adoc' : 1,
'git-gui.adoc' : 1,
'git-hash-object.adoc' : 1,
'git-help.adoc' : 1,
'git-hook.adoc' : 1,
'git-http-backend.adoc' : 1,
'git-http-fetch.adoc' : 1,
'git-http-push.adoc' : 1,
'git-imap-send.adoc' : 1,
'git-index-pack.adoc' : 1,
'git-init-db.adoc' : 1,
'git-init.adoc' : 1,
'git-instaweb.adoc' : 1,
'git-interpret-trailers.adoc' : 1,
'git-log.adoc' : 1,
'git-ls-files.adoc' : 1,
'git-ls-remote.adoc' : 1,
'git-ls-tree.adoc' : 1,
'git-mailinfo.adoc' : 1,
'git-mailsplit.adoc' : 1,
'git-maintenance.adoc' : 1,
'git-merge-base.adoc' : 1,
'git-merge-file.adoc' : 1,
'git-merge-index.adoc' : 1,
'git-merge-one-file.adoc' : 1,
'git-mergetool--lib.adoc' : 1,
'git-mergetool.adoc' : 1,
'git-merge-tree.adoc' : 1,
'git-merge.adoc' : 1,
'git-mktag.adoc' : 1,
'git-mktree.adoc' : 1,
'git-multi-pack-index.adoc' : 1,
'git-mv.adoc' : 1,
'git-name-rev.adoc' : 1,
'git-notes.adoc' : 1,
'git-p4.adoc' : 1,
'git-pack-objects.adoc' : 1,
'git-pack-redundant.adoc' : 1,
'git-pack-refs.adoc' : 1,
'git-patch-id.adoc' : 1,
'git-prune-packed.adoc' : 1,
'git-prune.adoc' : 1,
'git-pull.adoc' : 1,
'git-push.adoc' : 1,
'git-quiltimport.adoc' : 1,
'git-range-diff.adoc' : 1,
'git-read-tree.adoc' : 1,
'git-rebase.adoc' : 1,
'git-receive-pack.adoc' : 1,
'git-reflog.adoc' : 1,
'git-refs.adoc' : 1,
'git-remote-ext.adoc' : 1,
'git-remote-fd.adoc' : 1,
'git-remote.adoc' : 1,
'git-repack.adoc' : 1,
'git-replace.adoc' : 1,
'git-replay.adoc' : 1,
'git-request-pull.adoc' : 1,
'git-rerere.adoc' : 1,
'git-reset.adoc' : 1,
'git-restore.adoc' : 1,
'git-revert.adoc' : 1,
'git-rev-list.adoc' : 1,
'git-rev-parse.adoc' : 1,
'git-rm.adoc' : 1,
'git-send-email.adoc' : 1,
'git-send-pack.adoc' : 1,
'git-shell.adoc' : 1,
'git-sh-i18n--envsubst.adoc' : 1,
'git-sh-i18n.adoc' : 1,
'git-shortlog.adoc' : 1,
'git-show-branch.adoc' : 1,
'git-show-index.adoc' : 1,
'git-show-ref.adoc' : 1,
'git-show.adoc' : 1,
'git-sh-setup.adoc' : 1,
'git-sparse-checkout.adoc' : 1,
'git-stage.adoc' : 1,
'git-stash.adoc' : 1,
'git-status.adoc' : 1,
'git-stripspace.adoc' : 1,
'git-submodule.adoc' : 1,
'git-svn.adoc' : 1,
'git-switch.adoc' : 1,
'git-symbolic-ref.adoc' : 1,
'git-tag.adoc' : 1,
'git-unpack-file.adoc' : 1,
'git-unpack-objects.adoc' : 1,
'git-update-index.adoc' : 1,
'git-update-ref.adoc' : 1,
'git-update-server-info.adoc' : 1,
'git-upload-archive.adoc' : 1,
'git-upload-pack.adoc' : 1,
'git-var.adoc' : 1,
'git-verify-commit.adoc' : 1,
'git-verify-pack.adoc' : 1,
'git-verify-tag.adoc' : 1,
'git-version.adoc' : 1,
'git-web--browse.adoc' : 1,
'git-whatchanged.adoc' : 1,
'git-worktree.adoc' : 1,
'git-write-tree.adoc' : 1,
'git.adoc' : 1,
'gitk.adoc' : 1,
'gitweb.adoc' : 1,
'scalar.adoc' : 1,
# Category 5.
'gitattributes.adoc' : 5,
'gitformat-bundle.adoc' : 5,
'gitformat-chunk.adoc' : 5,
'gitformat-commit-graph.adoc' : 5,
'gitformat-index.adoc' : 5,
'gitformat-pack.adoc' : 5,
'gitformat-signature.adoc' : 5,
'githooks.adoc' : 5,
'gitignore.adoc' : 5,
'gitmailmap.adoc' : 5,
'gitmodules.adoc' : 5,
'gitprotocol-capabilities.adoc' : 5,
'gitprotocol-common.adoc' : 5,
'gitprotocol-http.adoc' : 5,
'gitprotocol-pack.adoc' : 5,
'gitprotocol-v2.adoc' : 5,
'gitrepository-layout.adoc' : 5,
'gitweb.conf.adoc' : 5,
# Category 7.
'gitcli.adoc' : 7,
'gitcore-tutorial.adoc' : 7,
'gitcredentials.adoc' : 7,
'gitcvs-migration.adoc' : 7,
'gitdiffcore.adoc' : 7,
'giteveryday.adoc' : 7,
'gitfaq.adoc' : 7,
'gitglossary.adoc' : 7,
'gitpacking.adoc' : 7,
'gitnamespaces.adoc' : 7,
'gitremote-helpers.adoc' : 7,
'gitrevisions.adoc' : 7,
'gitsubmodules.adoc' : 7,
'gittutorial-2.adoc' : 7,
'gittutorial.adoc' : 7,
'gitworkflows.adoc' : 7,
}
docs_backend = get_option('docs_backend')
if docs_backend == 'auto'
if find_program('asciidoc', dirs: program_path, native: true, required: false).found()
docs_backend = 'asciidoc'
elif find_program('asciidoctor', dirs: program_path, native: true, required: false).found()
docs_backend = 'asciidoctor'
else
error('Neither asciidoc nor asciidoctor were found.')
endif
endif
if docs_backend == 'asciidoc'
asciidoc = find_program('asciidoc', dirs: program_path, native: true)
asciidoc_html = 'xhtml11'
asciidoc_docbook = 'docbook'
xmlto_extra = [ ]
asciidoc_conf = custom_target(
command: [
shell,
meson.project_source_root() / 'GIT-VERSION-GEN',
meson.project_source_root(),
'@INPUT@',
'@OUTPUT@',
],
input: 'asciidoc.conf.in',
output: 'asciidoc.conf',
depends: [git_version_file],
env: version_gen_environment,
)
asciidoc_common_options = [
asciidoc,
'--conf-file=' + asciidoc_conf.full_path(),
'--attribute=build_dir=' + meson.current_build_dir(),
]
documentation_deps = [
asciidoc_conf,
]
elif docs_backend == 'asciidoctor'
asciidoctor = find_program('asciidoctor', dirs: program_path, native: true)
asciidoc_html = 'xhtml5'
asciidoc_docbook = 'docbook5'
xmlto_extra = [
'--skip-validation',
'-x', meson.current_source_dir() / 'manpage.xsl',
]
asciidoctor_extensions = custom_target(
command: [
shell,
meson.project_source_root() / 'GIT-VERSION-GEN',
meson.project_source_root(),
'@INPUT@',
'@OUTPUT@',
],
input: 'asciidoctor-extensions.rb.in',
output: 'asciidoctor-extensions.rb',
depends: [git_version_file],
env: version_gen_environment,
)
asciidoc_common_options = [
asciidoctor,
'--attribute', 'compat-mode',
'--attribute', 'tabsize=8',
'--attribute', 'litdd=&#x2d;&#x2d;',
'--attribute', 'docinfo=shared',
'--attribute', 'build_dir=' + meson.current_build_dir(),
'--load-path', meson.current_build_dir(),
'--require', 'asciidoctor-extensions',
]
documentation_deps = [
asciidoctor_extensions,
]
endif
if get_option('breaking_changes')
asciidoc_common_options += ['--attribute', 'with-breaking-changes']
endif
xmlto = find_program('xmlto', dirs: program_path, native: true)
cmd_lists = [
'cmds-ancillaryinterrogators.adoc',
'cmds-ancillarymanipulators.adoc',
'cmds-mainporcelain.adoc',
'cmds-plumbinginterrogators.adoc',
'cmds-plumbingmanipulators.adoc',
'cmds-synchingrepositories.adoc',
'cmds-synchelpers.adoc',
'cmds-guide.adoc',
'cmds-developerinterfaces.adoc',
'cmds-userinterfaces.adoc',
'cmds-purehelpers.adoc',
'cmds-foreignscminterface.adoc',
]
documentation_deps += custom_target(
command: [
perl,
'@INPUT@',
meson.project_source_root(),
meson.current_build_dir(),
] + cmd_lists,
input: 'cmd-list.perl',
output: cmd_lists
)
foreach mode : [ 'diff', 'merge' ]
documentation_deps += custom_target(
command: [
shell,
'@INPUT@',
'..',
mode,
'@OUTPUT@'
],
env: [
'MERGE_TOOLS_DIR=' + meson.project_source_root() / 'mergetools',
],
input: 'generate-mergetool-list.sh',
output: 'mergetools-' + mode + '.adoc',
)
endforeach
foreach manpage, category : manpages
if get_option('docs').contains('man')
manpage_xml_target = custom_target(
command: asciidoc_common_options + [
'--backend=' + asciidoc_docbook,
'--doctype=manpage',
'--out-file=@OUTPUT@',
'@INPUT@',
],
depends: documentation_deps,
input: manpage,
output: fs.stem(manpage) + '.xml',
)
manpage_path = fs.stem(manpage) + '.' + category.to_string()
manpage_target = custom_target(
command: [
xmlto,
'-m', '@INPUT0@',
'-m', '@INPUT1@',
'--stringparam',
'man.base.url.for.relative.links=' + get_option('prefix') / get_option('mandir'),
'man',
manpage_xml_target,
'-o',
meson.current_build_dir(),
] + xmlto_extra,
input: [
'manpage-normal.xsl',
'manpage-bold-literal.xsl',
],
output: manpage_path,
install: true,
install_dir: get_option('mandir') / 'man' + category.to_string(),
)
endif
if get_option('docs').contains('html')
custom_target(
command: asciidoc_common_options + [
'--backend=' + asciidoc_html,
'--doctype=manpage',
'--out-file=@OUTPUT@',
'@INPUT@',
],
depends: documentation_deps,
input: manpage,
output: fs.stem(manpage) + '.html',
install: true,
install_dir: get_option('datadir') / 'doc/git-doc',
)
endif
endforeach
if get_option('docs').contains('html')
configure_file(
input: 'docinfo-html.in',
output: 'docinfo.html',
copy: true,
install: true,
install_dir: get_option('datadir') / 'doc/git-doc',
)
configure_file(
input: 'docbook-xsl.css',
output: 'docbook-xsl.css',
copy: true,
install: true,
install_dir: get_option('datadir') / 'doc/git-doc',
)
install_symlink('index.html',
install_dir: get_option('datadir') / 'doc/git-doc',
pointing_to: 'git.html',
)
xsltproc = find_program('xsltproc', dirs: program_path, native: true)
user_manual_xml = custom_target(
command: asciidoc_common_options + [
'--backend=' + asciidoc_docbook,
'--doctype=book',
'--out-file=@OUTPUT@',
'@INPUT@',
],
input: 'user-manual.adoc',
output: 'user-manual.xml',
depends: documentation_deps,
)
custom_target(
command: [
xsltproc,
'--xinclude',
'--stringparam', 'html.stylesheet', 'docbook-xsl.css',
'--param', 'generate.consistent.ids', '1',
'--output', '@OUTPUT@',
'@INPUT@',
user_manual_xml,
],
input: 'docbook.xsl',
output: 'user-manual.html',
install: true,
install_dir: get_option('datadir') / 'doc/git-doc',
)
articles = [
'DecisionMaking.adoc',
'MyFirstContribution.adoc',
'MyFirstObjectWalk.adoc',
'ReviewingGuidelines.adoc',
'SubmittingPatches',
'ToolsForGit.adoc',
'git-bisect-lk2009.adoc',
'git-tools.adoc',
]
foreach article : articles
custom_target(
command: asciidoc_common_options + [
'--backend=' + asciidoc_html,
'--out-file=@OUTPUT@',
'@INPUT@',
],
input: article,
output: fs.stem(article) + '.html',
depends: documentation_deps,
install: true,
install_dir: get_option('datadir') / 'doc/git-doc',
)
endforeach
asciidoc_html_options = asciidoc_common_options + [
'--backend=' + asciidoc_html,
'--out-file=@OUTPUT@',
'--attribute', 'git-relative-html-prefix=../',
'@INPUT@',
]
subdir('howto')
subdir('technical')
endif
# Sanity check that we are not missing any tests present in 't/'. This check
# only runs once at configure time and is thus best-effort, only. Furthermore,
# it only verifies man pages for the sake of simplicity.
configured_manpages = manpages.keys() + [ 'git-bisect-lk2009.adoc', 'git-tools.adoc' ]
actual_manpages = run_command(shell, '-c', 'ls git*.adoc scalar.adoc',
check: true,
env: script_environment,
).stdout().strip().split('\n')
if configured_manpages != actual_manpages
missing_manpage = [ ]
foreach actual_manpage : actual_manpages
if actual_manpage not in configured_manpages
missing_manpage += actual_manpage
endif
endforeach
if missing_manpage.length() > 0
error('Man page found, but not configured:\n\n - ' + '\n - '.join(missing_manpage))
endif
superfluous_manpage = [ ]
foreach configured_manpage : configured_manpages
if configured_manpage not in actual_manpages
superfluous_manpage += configured_manpage
endif
endforeach
if superfluous_manpage.length() > 0
error('Man page configured, but not found:\n\n - ' + '\n - '.join(superfluous_manpage))
endif
endif