If a tool that is looked up in a .pc file is supposed to be there and
has a pkg-config variable entry, but the value is incorrect, we can't
actually use it.
Since commit ab3d02066c we actually do run
the ExternalProgram search procedure on it though -- which caused it to
go wonky and return a None if it doesn't exist, instead of containing a
path to a program that does not exist and fails at build time. This is
better in the case where searching helps resolve .exe file extensions --
and worse in the case where patches to the dependency means nothing we
do is ever enough to actually find what is expected, since now we crash.
Raise an explicit error in such a case, pointing out that the dependency
itself is broken and needs a distributor-side resolution.
Fixes#12412
ExternalProgram currently assumes that if a command is passed it exists
and can be used as is. In case we extract the path from pkgconfig the
path might not exist, on Windows it might be missing the ".exe" suffix.
By passing the variables as a name ExternalProgram will validate that
the command exists at configure time and will fail if not, and it will
try to fixup the command by appending .exe etc.
Fixes#12271
This detects cases where module A imports a function from B, and C
imports that same function from A instead of B. It's not part of the API
contract of A, and causes innocent refactoring to break things.
This reverts commit a2def550c5.
This results in a 2k line file being unconditionally imported at
startup, and transitively loading two more (for a total cost of 2759
lines of code), and it's not clear it was ever needed to begin with...
We may want to do things like update install scripts as well, which have
to happen before generating the backend. Instead of adding one module
method per thing to do, use a single function that allows for modifying
the Build object directly.
Which adds the `use-set-for-membership` check. It's generally faster in
python to use a set with the `in` keyword, because it's a hash check
instead of a linear walk, this is especially true with strings, where
it's actually O(n^2), one loop over the container, and an inner loop of
the strings (as string comparison works by checking that `a[n] == b[n]`,
in a loop).
Also, I'm tired of complaining about this in reviews, let the tools do
it for me :)
Gettext should search for input files relative to the (sub)project
source root, not the global source root.
This change exposes a root_subdir member in ModuleState.
We're going to do more with this in the next commit, but this just adds
the information for now. This allows the next commit have 100% mv
changes for some of the modules, which makes review easier
Instead of using FeatureNew/FeatureDeprecated in the module.
The goal here is to be able to handle information about modules in a
single place, instead of having to handle it separately. Each module
simply defines some metadata, and then the interpreter handles the rest.
Just like some of glib tools, wayland-scanner can be defined in the
pkgconfig dependency variables. Share code between gnome and wayland
modules into ModuleState.
This moves generally useful logic from GNOME module's
_get_native_binary() into find_program() implementation. We could decide
later to expose it as public API.
Regression in commit 566c2c9a9c.
The interpreter details are a bit of black magic. Functions expect
tuples, but they receive lists and then the type-checking decorators
convert those to tuples.
So, directly manhandling a self._interpreter.func_*() but passing it the
tuple it nominally expected, actually explodes in your face by way of
failing an assert, then dumping 'ERROR: Unhandled python exception'.
Fixes use of gnome.gtkdoc(..., check: true), for example when building
glib.
There is no reason for these inititializers to exist, all they do is
defer to the parent initializer. Worse, since they are not type
annotated thy prevent the parent type annotations from being used
This really is more of a struct than a dict, as the types are disjoint
and they are internally handled, (ie, not from user input). This cleans
some things up, in addition I spotted a bug in the ModuleState where the
dict with the version and license is passed to a field that expects just
the version string.
We have a lot of these. Some of them are harmless, if unidiomatic, such
as `if (condition)`, others are potentially dangerous `assert(...)`, as
`assert(condtion)` works as expected, but `assert(condition, message)`
will result in an assertion that never triggers, as what you're actually
asserting is `bool(tuple[2])`, which will always be true.
This is useful both from the perspective of optional functionality that
requires a module, and also as I continue to progress with Meson++,
which will probably not implement all of the modules that Meson itself
does.
Custom objects returned by modules must be subclass of ModuleObject and
have the state argument in its methods.
Add MutableModuleObject base class for objects that needs to be deep
copied on assignation.
The only advantage they have is they have the interpreter in arguments,
but it's already available as self.interpreter. We should discourage
usage of the interpreter API and rely on ModuleState object instead in
the future.
This also lift the restriction that a module method cannot add build
targets, but that was not enforced for snippet methods anyway (and some
modules were doing it) and it's really loose restriction as it should
check for many other things if we wanted to make it consistent.
install_scripts used to replace @BUILD_ROOT@ and @SOURCE_ROOT@ but it
was not documented and got removed in Meson 0.58.0. gnome.gtkdoc() was
relying on that behaviour, but it has always been broken in the case the
source or build directory contains spaces.
Fix this by changing get_include_args() to substitue paths directly
which will then get escaped correctly.
Add a unit test that builds GObject documentation which is where this
issue has been spotted.
Fixes: #8744
- ModuleState is now a real class that will have methods in the future
for actions modules needs, instead of using interpreter internal API.
- New ModuleObject base class, similar to InterpreterObject, that should
be used by all objects returned by modules. Its methods gets the
ModuleState passed as first argument. It has a `methods` dictionary to
define what is public API that can be called from build definition.
- Method return value is not required to be a ModuleReturnValue any
more, it can be any type that interpreter can holderify, including
ModuleObject.
- Legacy module API is maintained until we port all modules.
In the future modules should be updated:
- Use methods dict.
- Remove snippets.
- Custom objects returned by modules should all be subclass of
ModuleObject to get the state iface in their methods.
- Modules should never call into interpreter directly and instead state
object should have wrapper API.
- Stop using ModuleReturnValue in methods that just return simple
objects like strings. Possibly remove ModuleReturnValue completely
since all objects that needs to be processed by interpreter (e.g.
CustomTarget) should be created through ModuleState API.