Repository: mesonbuild/meson

Issue:
0.51.0 `native: true`/`native: false` mixing warning doesn't account for safe conditional usage
When building with meson-0.50.1 a lot of warnings are printed like:
```
WARNING:
                        Target eolian_gen is used as a generator, but is built for the host
                        machine. This means most cross builds will fail. You might want to
                        set `native: true` instead to build it for the build machine.
```
However, all of our executables that are used as generators are guarded like this:
```

eolian_gen_bin = executable('eolian_gen',
        eolian_gen_src,
        dependencies: eolian,
        install: true,
        c_args : package_c_args,
)

eolian_gen_path = eolian_gen_bin.full_path()

if meson.is_cross_build()
  _eolian_gen_bin = find_program('eolian_gen', native : true)
  eolian_gen_path = _eolian_gen_bin.path()
else
  _eolian_gen_bin = eolian_gen_bin
  eolian_gen_path = _eolian_gen_bin.full_path()
endif

eolian_gen = [_eolian_gen_bin, '-S']
```

I did a cross compile to a unrunnable arch on my laptop to verify we have no problem there.



Discussion:
The issue is that the warning isn't yet smart enough to see the reference is conditional behind the `meson.is_cross_build()`. Such a smart check is possible but would requires https://en.wikipedia.org/wiki/Abstract_interpretation, which is a big refactor (though perhaps a good one!).

Maybe in the meantime we can simplify your meson project? Is there as reason don't you just do:

```meson
eolian_gen_bin = executable('eolian_gen',
        eolian_gen_src,
        dependencies: eolian,
        install: true,
        c_args : package_c_args,
)

native_eolian_gen_bin = executable('eolian_gen',
        eolian_gen_src,
        dependencies: eolian,
        native: true, # difference here
        c_args : package_c_args,
)

eolian_gen = [native_eolian_gen_bin, '-S']
```

In general, `meson.is_cross_build()` is not something you should ever need.
That is not an option, as this would require us to duplicate the whole library definition structure of the project for native and not native.

Is there a way to turn of this warning somehow in the project settings ?
@marcelhollerbach do you require running meson twice today so the `find_program('eolian_gen', native : true)` works? If the problem is dedup sounds like you need `native: true` subprojects so you can include the "whole library definition structure" twice.

I haven't implemented anything to silence warnings; is there infra for that already? If there isn't I rather just fix the underlying problems.
This has added new warnings in mesa that are leading to wrong bug reports/patches. In mesa we compile a generator for the host architecture (it must be for the host architecture because it checks the sizes of various types). It's only used for x86/x86_64, and we allow it to be built when doing an x86_64 -> x86 cross compile (but for no other cross compile), since it will run fine. We're now getting a warning about it not working (which it does).
@Ericson2314 this is not an option for us, our code is depending on the produced code structure, rendering engines are searching produced shared object files etc... This would all not work with `native: true / false`. 

Also: after testing around a bit, it seems that the warnings are printed independent from the state of conditionals at all. So not using `meson.is_cross_build()` but rather an option or something also does not fix the issue. 
Am I reading this correctly in that you have roughly the following and it complains:

```meson
some_bin = <outcome of find_program>
g = generator(some_bin, ...
```

That should never give warnings because `find_program` only finds things the system thinks are runnable.

Do you perchance have `eolian_gen` in your cross file?
We have rougly:
```
if meson.is_cross() == false
   some_bin = executable(...)
else
   some_bin = find_program(...)
g = generator(some_bin, ...)
```

And it is complaining.
Have you specified the program in the cross file?

And regardless, if you add a `native: true` to the `find_program`, does it still complain?
@jpakkane I added the warning; `native: true` will make it not complain, but it would complain on that executables's own `native: false` dependencies, and evidently it needs to be installed too? I suggested making a subproject and importing it twice with `native: false` and `native: true` once I implement that, to avoid defining everything twice, but I take it @marcelhollerbach said they can't do that because of some introspection similar to what @dcbaker said mesa does for x86_64/x86.
Programm is not specified in the cross file.
@marcelhollerbach to be clear, my proposal does *not* involve looking up `eolian_gen` in the cross file or native file, but rather building it with meson for the build machine and host machine.
Sure I understood that, but that will not work for us.
This is weird, because the part of the code that prints the warning is guarded like this:

```
    def exe_object_to_cmd_array(self, exe):
        if isinstance(exe, build.BuildTarget):
            if exe.for_machine is not MachineChoice.BUILD:
```

That should fail if the exe comes from `find_program`.
And I tested `test cases/common/27 pipeline` with `cross/ubuntu-armhf.txt` and it does _not_ print that warning. As it should not.

Maybe someone is using `override_find_program` sneakily somewhere?
@jpakkane this is a warning that is run in *native* builds. It notices that one is using `eolian_gen_bin` for `native: false` as a code generator and is saying that this looks suspicious as a convience for anyone that hasn't tested native code yet. But that warning doesn't realize that it is *only* using `eolian_gen_bin` in the native case, and not in the cross case, so it's a false alarm.

I don't disagree about the false alarm, but I question whether it is necessary to use the `native: false` `eolian_gen_bin` in the native case. It should be possible to write code without `if meson.is_cross_build()` that works and doesn't trip the warning.
The printing is also guarded by this:

```
                if (self.environment.is_cross_build() and
```

In native builds this should never be printed.
Okay if I change 27 to use `native: false` it does print the text. But it really should not because it does work just fine.
In fact if you just do this:

```meson
e = executable('foo', 'foo.c')
g = generator(e, ..)
```

It will print this warning. That is bad UX. That should work just fine without warnings because that is the common case. Most people and projects don't care about cross compilation and warning about this is confusing.

The warning itself is reasonable but there are just too many false positives.
Yeah it's only foolproof with abstract interpretation, if you care about cross compilation. Is there any way to make warnings configurable on or off? Or is there some sort of linter where I could move this check?
I would just remove this. We have good error messages when the issue _does_ happen so when people eventually encounter this they will know what to do.

Resolving patch:
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -812,11 +812,6 @@ def exe_object_to_cmd_array(self, exe):
                         true. You might want to set `native: true` instead to build it for
                         the build machine.'''.format(exe.name))
                     raise MesonException(s)
-                else:
-                    mlog.warning('''
-                        Target {} is used as a generator, but is built for the host
-                        machine. This means most cross builds will fail. You might want to
-                        set `native: true` instead to build it for the build machine.'''.format(exe.name))
             exe_arr = [os.path.join(self.environment.get_build_dir(), self.get_target_filename(exe))]
         else:
             exe_arr = exe.get_command()


Test patch: