All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Seiderer <ps.report@gmx.net>
To: Patrick Steinhardt <ps@pks.im>
Cc: git@vger.kernel.org, Eli Schwartz <eschwartz@gentoo.org>,
	Junio C Hamano <gitster@pobox.com>
Subject: Re: [PATCH] meson: distinguish build and target host binaries
Date: Mon, 3 Mar 2025 15:09:56 +0100	[thread overview]
Message-ID: <20250303150956.24a1815e@gmx.net> (raw)
In-Reply-To: <20250303-pks-meson-cross-compiling-v1-1-73002ef6432e@pks.im>

Hello Patrick,

On Mon, 03 Mar 2025 13:10:59 +0100, Patrick Steinhardt <ps@pks.im> wrote:

> 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.
>
> Signed-off-by: Patrick Steinhardt <ps@pks.im>
> ---
> Hi,
>
> this patch addresses the issue reported at [1], where it is impossible
> to specify the shell, Python and Perl paths during cross-compilation
> when using Meson.

I still believe that is is a 'misuse' of the cross-file (as stated already
here [1]) the given programs in cross-file are to be meant to run while
cross-compiling (at compile time) and not on the target (e.g. it would be
impossible to find a program (as the name find_program indicates) at
compile/configure where the target layout is yet unknown....

I believe the correct solution is an extra configure option for cross-compile
and a sane default (or find_program) in case of native build...

Regards,
Peter

[1] https://public-inbox.org/git/20250210122603.5130e309@gmx.net/

>
> The series is built on top of master at cb0ae672aea (A bit more post
> -rc0, 2025-02-27) with junio/ps/build-meson-fixes-0130 at 9350423982a
> (gitlab-ci: restrict maximum number of link jobs on Windows, 2025-02-26)
> merged into it.
>
> Thanks!
>
> Patrick
>
> [1]: <20250209133027.64a865aa@gmx.net>
> ---
>  Documentation/meson.build | 12 ++++-----
>  gitweb/meson.build        |  2 +-
>  meson.build               | 66 ++++++++++++++++++++++++++++++++++++-----------
>  templates/meson.build     |  4 +--
>  4 files changed, 60 insertions(+), 24 deletions(-)
>
> diff --git a/Documentation/meson.build b/Documentation/meson.build
> index 0a0f2bfa14a..63891fb4455 100644
> --- a/Documentation/meson.build
> +++ b/Documentation/meson.build
> @@ -207,9 +207,9 @@ manpages = {
>
>  docs_backend = get_option('docs_backend')
>  if docs_backend == 'auto'
> -  if find_program('asciidoc', dirs: program_path, required: false).found()
> +  if find_program('asciidoc', dirs: program_path, native: true, required: false).found()
>      docs_backend = 'asciidoc'
> -  elif find_program('asciidoctor', dirs: program_path, required: false).found()
> +  elif find_program('asciidoctor', dirs: program_path, native: true, required: false).found()
>      docs_backend = 'asciidoctor'
>    else
>      error('Neither asciidoc nor asciidoctor were found.')
> @@ -217,7 +217,7 @@ if docs_backend == 'auto'
>  endif
>
>  if docs_backend == 'asciidoc'
> -  asciidoc = find_program('asciidoc', dirs: program_path)
> +  asciidoc = find_program('asciidoc', dirs: program_path, native: true)
>    asciidoc_html = 'xhtml11'
>    asciidoc_docbook = 'docbook'
>    xmlto_extra = [ ]
> @@ -246,7 +246,7 @@ if docs_backend == 'asciidoc'
>      asciidoc_conf,
>    ]
>  elif docs_backend == 'asciidoctor'
> -  asciidoctor = find_program('asciidoctor', dirs: program_path)
> +  asciidoctor = find_program('asciidoctor', dirs: program_path, native: true)
>    asciidoc_html = 'xhtml5'
>    asciidoc_docbook = 'docbook5'
>    xmlto_extra = [
> @@ -284,7 +284,7 @@ elif docs_backend == 'asciidoctor'
>    ]
>  endif
>
> -xmlto = find_program('xmlto', dirs: program_path)
> +xmlto = find_program('xmlto', dirs: program_path, native: true)
>
>  cmd_lists = [
>    'cmds-ancillaryinterrogators.adoc',
> @@ -405,7 +405,7 @@ if get_option('docs').contains('html')
>      pointing_to: 'git.html',
>    )
>
> -  xsltproc = find_program('xsltproc', dirs: program_path)
> +  xsltproc = find_program('xsltproc', dirs: program_path, native: true)
>
>    user_manual_xml = custom_target(
>      command: asciidoc_common_options + [
> diff --git a/gitweb/meson.build b/gitweb/meson.build
> index 89b403dc9de..88a54b4dc99 100644
> --- a/gitweb/meson.build
> +++ b/gitweb/meson.build
> @@ -1,5 +1,5 @@
>  gitweb_config = configuration_data()
> -gitweb_config.set_quoted('PERL_PATH', perl.full_path())
> +gitweb_config.set_quoted('PERL_PATH', target_perl.full_path())
>  gitweb_config.set_quoted('CSSMIN', '')
>  gitweb_config.set_quoted('JSMIN', '')
>  gitweb_config.set_quoted('GIT_BINDIR', get_option('prefix') / get_option('bindir'))
> diff --git a/meson.build b/meson.build
> index 516207f9cfe..0a229f44199 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -155,6 +155,37 @@
>  # These machine files can be passed to `meson setup` via the `--native-file`
>  # option.
>  #
> +# Cross compilation
> +# =================
> +#
> +# Machine files can also be used in the context of cross-compilation to
> +# describe the target machine as well as the cross-compiler toolchain that
> +# shall be used. An example machine file could look like the following:
> +#
> +#   [binaries]
> +#   c = 'x86_64-w64-mingw32-gcc'
> +#   cpp = 'x86_64-w64-mingw32-g++'
> +#   ar = 'x86_64-w64-mingw32-ar'
> +#   windres = 'x86_64-w64-mingw32-windres'
> +#   strip = 'x86_64-w64-mingw32-strip'
> +#   exe_wrapper = 'wine64'
> +#   sh = 'C:/Program Files/Git for Windows/usr/bin/sh.exe'
> +#
> +#   [host_machine]
> +#   system = 'windows'
> +#   cpu_family = 'x86_64'
> +#   cpu = 'x86_64'
> +#   endian = 'little'
> +#
> +# These machine files can be passed to `meson setup` via the `--cross-file`
> +# option.
> +#
> +# Note that next to the cross-compiler toolchain, the `[binaries]` section is
> +# also used to locate a couple of binaries that will be built into Git. This
> +# includes `sh`, `python` and `perl`, so when cross-compiling Git you likely
> +# want to set these binary paths in addition to the cross-compiler toolchain
> +# binaries.
> +#
>  # Subproject wrappers
>  # ===================
>  #
> @@ -173,7 +204,7 @@ project('git', 'c',
>    # The version is only of cosmetic nature, so if we cannot find a shell yet we
>    # simply don't set up a version at all. This may be the case for example on
>    # Windows systems, where we first have to bootstrap the host environment.
> -  version: find_program('sh', required: false).found() ? run_command(
> +  version: find_program('sh', native: true, required: false).found() ? run_command(
>      'GIT-VERSION-GEN', meson.current_source_dir(), '--format=@GIT_VERSION@',
>      capture: true,
>      check: true,
> @@ -198,16 +229,18 @@ elif 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)
> -git = find_program('git', dirs: program_path, required: false)
> -sed = find_program('sed', dirs: program_path)
> -shell = find_program('sh', dirs: program_path)
> -tar = find_program('tar', dirs: program_path)
> +cygpath = find_program('cygpath', dirs: program_path, native: true, required: false)
> +diff = find_program('diff', dirs: program_path, native: true)
> +git = find_program('git', dirs: program_path, native: true, required: false)
> +sed = find_program('sed', dirs: program_path, native: true)
> +shell = find_program('sh', dirs: program_path, native: true)
> +tar = find_program('tar', dirs: program_path, native: true)
> +
> +target_shell = find_program('sh', dirs: program_path, native: false)
>
>  # Sanity-check that programs required for the build exist.
>  foreach tool : ['cat', 'cut', 'grep', 'sort', 'tr', 'uname']
> -  find_program(tool, dirs: program_path)
> +  find_program(tool, dirs: program_path, native: true)
>  endforeach
>
>  script_environment = environment()
> @@ -706,7 +739,7 @@ libgit_c_args = [
>    '-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()) + '"',
> +  '-DSHELL_PATH="' + fs.as_posix(target_shell.full_path()) + '"',
>  ]
>  libgit_include_directories = [ '.' ]
>  libgit_dependencies = [ ]
> @@ -761,6 +794,7 @@ endif
>  build_options_config.set_quoted('X', executable_suffix)
>
>  python = import('python').find_installation('python3', required: get_option('python'))
> +target_python = find_program('python3', native: false, required: python.found())
>  if python.found()
>    build_options_config.set('NO_PYTHON', '')
>  else
> @@ -790,9 +824,11 @@ endif
>  # which we can do starting with Meson 1.5.0 and newer, or we have to
>  # match against the minor version.
>  if meson.version().version_compare('>=1.5.0')
> -  perl = find_program('perl', dirs: program_path, required: perl_required, version: '>=5.26.0', version_argument: '-V:version')
> +  perl = find_program('perl', dirs: program_path, native: true, required: perl_required, version: '>=5.26.0', version_argument: '-V:version')
> +  target_perl = find_program('perl', dirs: program_path, native: false, required: perl.found(), version: '>=5.26.0', version_argument: '-V:version')
>  else
> -  perl = find_program('perl', dirs: program_path, required: perl_required, version: '>=26')
> +  perl = find_program('perl', dirs: program_path, native: true, required: perl_required, version: '>=26')
> +  target_perl = find_program('perl', dirs: program_path, native: false, required: perl.found(), version: '>=26')
>  endif
>  perl_features_enabled = perl.found() and get_option('perl').allowed()
>  if perl_features_enabled
> @@ -843,7 +879,7 @@ else
>    build_options_config.set('NO_PTHREADS', '1')
>  endif
>
> -msgfmt = find_program('msgfmt', dirs: program_path, required: false)
> +msgfmt = find_program('msgfmt', dirs: program_path, native: true, 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')
> @@ -1975,9 +2011,9 @@ foreach key, value : {
>    '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(),
> +  'PERL_PATH': target_perl.found() ? target_perl.full_path() : '',
> +  'PYTHON_PATH': target_python.found () ? target_python.full_path() : '',
> +  'SHELL_PATH': target_shell.full_path(),
>    'TAR': tar.full_path(),
>    'TEST_OUTPUT_DIRECTORY': test_output_directory,
>    'TEST_SHELL_PATH': shell.full_path(),
> diff --git a/templates/meson.build b/templates/meson.build
> index 1faf9a44cea..02e6eebe80b 100644
> --- a/templates/meson.build
> +++ b/templates/meson.build
> @@ -1,6 +1,6 @@
>  template_config = configuration_data()
> -template_config.set('PERL_PATH', perl.found() ? fs.as_posix(perl.full_path()) : '')
> -template_config.set('SHELL_PATH', fs.as_posix(shell.full_path()))
> +template_config.set('PERL_PATH', target_perl.found() ? fs.as_posix(target_perl.full_path()) : '')
> +template_config.set('SHELL_PATH', fs.as_posix(target_shell.full_path()))
>  template_config.set('GITWEBDIR', fs.as_posix(get_option('prefix') / get_option('datadir') / 'gitweb'))
>
>  configure_file(
>
> ---
> base-commit: af208620eecbe9b4655e06a28d5146a40738150e
> change-id: 20250303-pks-meson-cross-compiling-7bad3078b9e8
>


  reply	other threads:[~2025-03-03 14:10 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-03 12:10 [PATCH] meson: distinguish build and target host binaries Patrick Steinhardt
2025-03-03 14:09 ` Peter Seiderer [this message]
2025-03-04  9:07   ` Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250303150956.24a1815e@gmx.net \
    --to=ps.report@gmx.net \
    --cc=eschwartz@gentoo.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=ps@pks.im \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.