Re: Meson build leaks host 'sh' path to target build when cross-compiled

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2/18/25 6:47 AM, Patrick Steinhardt wrote:
> On Mon, Feb 10, 2025 at 12:26:03PM +0100, Peter Seiderer wrote:
>> On Mon, 10 Feb 2025 08:41:18 +0100, Patrick Steinhardt <ps@xxxxxx> wrote:
>>> 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)...
> 
> Quoting the documentation of `find_program()`'s `native` parameter [1]:
> 
>     Defines how this executable should be searched. By default it is set to
>     false, which causes Meson to first look for the executable in the cross
>     file (when cross building) and if it is not defined there, then from the
>     system. If set to true, the cross file is ignored and the program is
>     only searched from the system.
> 
> So I think this should work as expected when passing the file via
> `--cross-file`, shouldn't it? If we are cross-compiling we'd find the
> target binaries via the cross file when `native: false`, which is
> exactly what we want.
> 
> But I see what you're saying. The _intent_ is to specify the environment
> of the cross-compiling environment, and not to describe the target
> environment.
> 
> I can think of two alternatives:
> 
>   - We can introduce build options for this. If unset, we continue to
>     use the result of `find_program()`. Otherwise, we use the value
>     specified by the user.
> 
>   - We can introduce properties into the cross file that allow the user
>     to specify those parameters. We can then retrieve them by calling
>     `meson.get_external_property()`, but only when cross-compiling.
> 
> Let me also Cc Eli, he might have an opinion on how to do this.


For the specific case of detecting sh, the portable "API filename" is
exactly /bin/sh and nothing else. It should always exist on pretty much
any unix system ever... except for the ones where it exists but is a
pre-POSIX shell and the actual POSIX one isn't always on PATH at all. Hi
there, Solaris /usr/xpg4/bin/sh ! :)

Overriding it via the cross file would be fine -- if your goal is to
only ever find_program(..., native: false) in order to detect a path and
embed it, then it doesn't matter whether cross files are for running
cross tools on the build machine or for looking up cross tools to detect
a path and embed it, since the two goals would never *come into
conflict*. And that's what actually matters -- if you are concerned that
cross files will be wrong as they specify the cross-compile environment
not the install environment, then you shouldn't be using find_program()
either, you should be exclusively using build options.



But again -- that's the general case, and for the specific case you
should be defaulting to /bin/sh

This does have a highly practical application to it. Gentoo supports
split-usr systems, and binary package support needs to consistently use
paths that are present on both merged- and split-usr systems. There is
no /usr/bin/sh on a split-usr system, but on a merged-usr system they
are the same directory, so it will exist "anyway".

Note that this is NOT a cross compile environment. I'm compiling for the
current x86-64 environment, but also tarring it up for installation on
other x86-64 environments that happen to use a different filesystem
partition scheme.


Cc Sam as we will need to fix this in our Gentoo packaging one way or
another:

$ ebuild git-2.48.1.ebuild clean install
[...]
$ ag usr/bin /var/tmp/portage/dev-vcs/git-2.48.1/image

It is finding and embedding various hits for /usr/bin/sh because I
happened to build on a merged-usr profile.



-- 
Eli Schwartz

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux