mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.52k stars 1.6k forks source link

Alternative find_runtime_program() #8073

Open Jehan opened 3 years ago

Jehan commented 3 years ago

Describe the bug

Say you want to check for a program run as runtime dependency. It needs to be meant for the target architecture/OS. Yet if find_program() has a native=false value (the default), the doc says:

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.

It means that if the same program exists on the build machine (while not available for the target), the test will pass and we will not realize we are missing a runtime dependency (until a problem occurs).

Now maybe changing the meaning of native is not the best idea because of retro-compatibility, nor is changing its type (for a 3-value type for instance: yes, no, and both (meaning cross-binary first, native second). Especially as I'm sure the current false case is useful for other use-cases, in particular I think it is mostly useful for build-time programs where native=false often does not actually mean we want a non-native program (the option name is misleading), it means we want a program targetted at the target machine (i.e. a native binary but made to create files for the target machine).

So maybe rather than doing this, an alternative find_runtime_program() would be very useful. The goal is mostly to detect availability of runtime dependencies and warn for their absence. I would also suggest a configure option to actually disable the errors generated as runtime dependencies are not build-breaking by definition (you just don't want to forget to package them, yet adding them in the finale package is also a perfectly feasible approach).

To Reproduce

Say you want to produce something at runtime with the program dot so you want to make the packagers aware of it and clearly list this as a runtime dependency in your meson.build. Right now, you could add this test:

find_program('dot', native=false)

The worst case is if dot is available on the native system, so the test will pass. Then later, when the program tries to call this program on the actual target machine (which doesn't have dot), it fails (or worse, it crashes if expecting this to work without proper checks).

Expected behavior

A proposed new function could therefore be:

find_runtime_program('dot')

It would only look for a target program. Actually if it could be a bit clever when possible, for instance if the target happens to be Windows, it would actually look for dot.exe.

By default, the absence of the dependency program would trigger a configuration error. There could be a configure option to disable the runtime checks errors (meson configure -Druntime-checks=false for instance?). It may actually still do the runtime checks yet only display them as warnings in the end. Therefore someone could just ignore these (it won't prevent the build) but still be warned that it has to be added in the finale installer/package (or dependency list if doing a RPM/deb package, etc.).

Also the find_runtime_program() would produce an object producing either full paths, relative paths or basenames:

dot = find_runtime_program('dot')
dot.full_path() # Full path /usr/bin/dot
dot.relative_path() # Relative path
dot.basename() # 'dot' or 'dot.exe' for instance

Finally there would be a function producing different strings depending on the platform:

# produces '/usr/bin/dot' on native Linux/BSD/UNIX (but just 'dot' on cross-builds for these), but 'dot.exe' on Windows or 'dot' on macOS
dot.path()

This last one is based on target platform common practices:

The usefulness of this value will be to feed your program with a macro for instance, like a DOT_EXE which will contain the appropriate value depending on your target platform.

tristan957 commented 1 year ago

@eli-schwartz I feel like there was a similar issue not too long ago (maybe in xdg-desktop-portal-gnome) and the consensus was that Meson would not add support for this because the machine you are building on might be different than the machine the artifacts will run on.

I think this should be closed.

Jehan commented 1 year ago

the machine you are building on might be different than the machine the artifacts will run on.

Well that's exactly the point of the report.

Anyway I could understand the point if meson was totally Linux/UNIX targetted, because in there, we mostly rely on others doing packaging with their own runtime dependency rules (though even this becomes less and less true, with flatpak and whatnot: detecting the missing runtime dependency at build time will save us a lot of trouble later on!).

For Windows and macOS builds for instance, which are mostly self-contained, even when we cross-compile and the run machine will be very different, the package will be pretty much the contents of what we have in some temp prefix on the build machine. So detecting these missing runtime dependencies early on is a very important feature in order not to end up with broken builds because of human error.