Re: Meson build leaks host 'sh' path to target build when cross-compiled
- From
- Peter Seiderer <ps.report@gmx.net>
- Date
- Feb 10, 2025, 11:26 UTC
- Message-ID
- <20250210122603.5130e309@gmx.net>
- In-Reply-To
- <Z6mtnmvKMsIOEVz5@pks.im>
Hello Patrick,
On Mon, 10 Feb 2025 08:41:18 +0100, Patrick Steinhardt <ps@pks.im> wrote:
Show 36 quoted lines
> On Sun, Feb 09, 2025 at 01:30:27PM +0100, Peter Seiderer wrote:
> [snip]
> > The meson build tries to execute the non-existent '/usr/bin/sh' (instead of
> > '/bin/sh' as the autoconf build), 'which sh' on the host returns
> > '/usr/bin/sh'...
> >
> > From meson.build
> >
> > [...]
> > 186 shell = find_program('sh', dirs: program_path)
> > [...]
> > 685 '-DSHELL_PATH="' + fs.as_posix(shell.full_path()) + '"',
> >
> > Do not use the result of 'find_program('sh',...)' for '-DSHELL_PATH='
> > (at least not for cross-compile), use fix '/bin/sh' instead or make it
> > configurable via a meson option?
>
> Hm, very true. We're mixing up concerns here by treating the build
> environment and the target environment the same.
>
> I guess the proper fix is to wire up the "native:" parameter when we
> call `find_program()`, which allows us to tell Meson whether it should
> find an executable for the build or the target host. And then, for those
> binaries where we actually need to know about both the build and target
> host's locations, we'd end up calling `find_program()` twice.
>
> For executables that are supposed to be used on the target host Meson
> would then know to first consult the cross file, which could look like
> this:
>
> [binaries]
> sh = '/target/path/to/sh'
> perl = '/target/path/to/perl'
>
> Meson would then pick up that file via `meson setup --cross-file
> <CROSSFILE_PATH> <BUILDDIR>`.Sorry, I believe this will not work..., the description of the native parameter in find_program ([2]) on the first sight sounds like doing the right thing, but as far as I read the 'Cross compilation' page ([3], [4]) the tools under the '[binaries]' section are the tools used while cross-compiling (running on the build machine) and not the paths/tools on the target (or as meson nomenclature host/target)...
One tiny finding below...
Show 164 quoted lines
>
> The patch should look somewhat like the attached patch, but it conflicts
> with my in-flight patch series at [1]. I'll wait for that series to be
> merged to `next` before sending out the fix.
>
> Thanks for your report!
>
> Patrick
>
> [1]: <20250129-b4-pks-meson-improvements-v1-0-ab709f0be12c@pks.im>
>
> -- >8 --
>
> diff --git a/Documentation/meson.build b/Documentation/meson.build
> index c6117366ff..b033f4a93a 100644
> --- a/Documentation/meson.build
> +++ b/Documentation/meson.build
> @@ -206,9 +206,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.')
> @@ -216,7 +216,7 @@ if docs_backend == 'auto'
> endif
>
> if docs_backend == 'asciidoc'
> - asciidoc = find_program('asciidoc', dirs: program_path)
> + asciidoc = find_program('asciidoc', native: true, dirs: program_path)
> asciidoc_html = 'xhtml11'
> asciidoc_docbook = 'docbook'
> xmlto_extra = [ ]
> @@ -245,7 +245,7 @@ if docs_backend == 'asciidoc'
> asciidoc_conf,
> ]
> elif docs_backend == 'asciidoctor'
> - asciidoctor = find_program('asciidoctor', dirs: program_path)
> + asciidoctor = find_program('asciidoctor', native: true, dirs: program_path)
> asciidoc_html = 'xhtml5'
> asciidoc_docbook = 'docbook5'
> xmlto_extra = [
> @@ -283,7 +283,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.txt',
> @@ -404,7 +404,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 89b403dc9d..88a54b4dc9 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 e153a43918..5a5662bc02 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -173,7 +173,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 +198,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()
> @@ -758,6 +760,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
> @@ -775,7 +778,8 @@ 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 = find_program('perl', version: '>=5.8.1', dirs: program_path, native: true, required: perl_required)
> +target_perl = find_program('perl', version: '>=5.8.1', native: false, required: perl.found())
> perl_features_enabled = perl.found() and get_option('perl').allowed()
> if perl_features_enabled
> build_options_config.set('NO_PERL', '')
> @@ -825,7 +829,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')
> @@ -1954,9 +1958,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 1faf9a44ce..986c2e03be 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', perl.found() ? fs.as_posix(target_perl.full_path()) : '')Above should read (perl.found() vs. target_perl.found()):
+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(Regards, Peter
[2] https://mesonbuild.com/Reference-manual_functions.html#find_program [3] https://mesonbuild.com/Cross-compilation.html [4] https://mesonbuild.com/Machine-files.html