This time we have a case where people are passing non-objects by using
them as str | File, which we never warned about and silently accepted.
If it was passed via custom_target outputs we *would* error out,
interestingly enough. At the backend layer, we just pass them directly
to the linker... which is valid, if we misdetected what's a valid linker
input or people just used funny names. In particular, the mingw
toolchain allows passing a *.def file directly, and some people are
doing that.
If we do want to allow this, we should do it consistently. For now, just
follow the current theme of what's expected, but do so by warning
instead of fatally erroring, for cases where users were able to do it in
the past.
Pass link arguments directly down to linker by using `-C link-args=`
instead of letting rustc/linker resolve `-l` arguments. This solves
problems with e.g. +verbatim not being portable. Note that we also pass
`-l` args as `-Clink-args=-l` because rustc would otherwise reorder
arguments and put `-lstdc++` before `-Clink-args=libfoo++.a`.
However, when building a rlib/staticlib we should still use `-l`
arguments because that allows rustc to bundle static libraries we
link-whole. In that case, since there is no platform specific dynamic
linker, +verbatim works.
This also fix installed staticlib that now bundle uninstalled static
libraries it links to (recursively). This is done by putting them all
into self.link_whole_targets instead of putting their objects into
self.objects, and let rustc do the bundling. This has the extra
advantage that rustc can bundle static libries built with CustomTarget.
Disable bundling in all other cases, otherwise we could end up with
duplicated objects in static libraries, in diamond dependency graph
case.
Fixes: #12484
CustomTarget and CustomTargetIndex often have to be special cased
because they are not subclass of BuildTarget. It's easier to introduce a
dummy base class.
This fix recursive functions over link targets that might encouters
libraries built as CustomTarget.
Previously, AIX support was updated to archive shared libraries per AIX
platform conventions, which expect .a files that contain .so files. This
is usually correct, but an edge case occurs for loadable plugins, e.g.
what meson creates for `shared_module()`. A notable example is python
extensions (SciPy, for example).
These should *not* be archived, because the .so file itself needs to be
loaded as a plugin. For example, SciPy fails to import in the python
interpreter.
Handle this by differentiating between plugins and regular libraries,
and only archiving when safe to do so.
Fixes#12219
adb1a360b9 added the feature and also the
usual meson-style warning to users that might be using the feature but
were not targeting a new enough meson version. Well unfortunately the
warning both doesn't actually work (it didn't take different directories
into account) and is also really slow because it creates an O(N^2) loop
for checking this.
Instead, rework this by adding an additional set that stores a tuple
containing the target name and its subdirectory. We only add this tuple
if the target is an executable since it is the only time it will be
relevant. After that, simply check if the name + subdir combination
already exists in the set along with the target being executable. If so,
then we execute FeatureNew which may possibly warn. This is a simply
O(1) lookup which is way faster. Fixes#12404.
This also moves the repacking into the interpreter, making the build
implementation simpler and removing a layering violation. This also
makes use a defaultdict to remove the need to call `.get()`
Way back in Meson 0.25, support was added to `vala_args` for Files.
Strangely, this was never added to any other language, though it's been
discussed before. For type safety, it makes more sense to handle this in
the interpreter level, and pass only strings into the build IR.
This is accomplished by adding a `depend_files` field to the
`BuildTarget` class (which is not exposed to the user), and adding the
depend files into that field, while converting the arguments to relative
string paths. This ensures both the proper build dependencies happen, as
well as that the arguments are always strings.
When checking target names, meson explictly forbids having multiple
targets with the same name. This is good, but it is strict and it is
impossible to have targets with the same basename and differing suffixes
(e.g. foo and foo.bin) in the same directory. Allow this for executables
by including the suffix (if it exists) in the interal target id. So foo
would be foo@exe and foo.bin would be foo.bin@exe.
The MSVC code is extremely confusing, and it turns out it actually
constructs debug (pdb) files names/path independently in separate
places. This is really hard to parse. Instead, refactor it so that the
source of the debug filename is within the target itself
(get_debug_filename). Add a couple of generic methods to retrieve the
full path of the debug filename name in the backend and use that when
needed.
This differentiates export_dynamic being explicitly set to False from it
being unset. This allows us to deprecate explicitly setting
export_dynamic to false, but setting implib. This is already the case in
the other direction, if implib is False but export_dynamic is enabled
then we get a hard error.
This also moves the validation up to the Interpreter and out of the
build level.
Installing python sources causes the python module to call
create_install_data() before Ninja backends adds extra outputs to Vala
targets.
Target objects are supposed to be immutable, adding outputs that late is
totally wrong. Add extra vala outputs immediately, but be careful
because the main output is only added later in post_init(). Luckily
the base class already puts a placeholder item in self.outputs for the
main filename so we can just replace self.outputs[0] instead of
replacing the whole list which would contain vala outputs at that stage.
This is surprisingly what SharedLibrary was already doing.
Coredata is where all option handling is done so it makes sense there.
It is a view on a list of options for a given subproject and with
optional overrides. This change prepare for using that view in a more
generic way in the future.
Performed using https://github.com/ilevkivskyi/com2ann
This has no actual effect on the codebase as type checkers (still)
support both and negligible effect on runtime performance since
__future__ annotations ameliorates that. Technically, the bytecode would
be bigger for non function-local annotations, of which we have many
either way.
So if it doesn't really matter, why do a large-scale refactor? Simple:
because people keep wanting to, but it's getting nickle-and-dimed. If
we're going to do this we might as well do it consistently in one shot,
using tooling that guarantees repeatability and correctness.
Repeat with:
```
com2ann mesonbuild/
```
When an installed static library A links to an internal static library B
built using a custom_target(), raise an error instead of a warning. This
is because to be usable, A needs to contain B which would require to
extract the archive to get its objects files.
This used to work, but was printing a warning and was installing a
broken static library, because we used to overlink in many cases, and
that got fixed in Meson 1.2.0. It now fails at link time with symbols
from the custom target not being defined. It's better to turn the
warning into a hard error at configure time.
While at it, noticed this situation can happen for any internal custom
or rust target we link to, recursively.
get_internal_static_libraries_recurse() could be called on CustomTarget
objects which do not implement it, and even if we did not call that
method, it would still fail when trying to call extract_all_objects() on
it.
Fixes: #12006
Improve the error message when a build target is assigned as dependency
of another build target, which allows to better pinpoint where the issue
lies on.
In the example that follow, modules/meson.build:294 is in a for loop
creating library targets from an array of dictionary, and doesn't point
to the location where interop_sw_plugin is assigned with vlc_opengl:
Before:
modules/meson.build:294:17: ERROR: Tried to use a build target as a dependency.
You probably should put it in link_with instead.
After:
modules/meson.build:294:17: ERROR: Tried to use a build target vlc_opengl as a dependency of target interop_sw_plugin.
You probably should put it in link_with instead.
It would probably be best to directly pinpoint where the assignment was
made but it's probably harder so start simple by saying what is
concerned by the error.
We allow custom_target() but check for it based on hasattr, ever since
the initial implementation way back in the day, in commit
66a6ea984b. This is a bit broken because
various objects might support that but still aren't supposed to work. We
can actually just use isintance checks like we do immediately above,
which are more accurate and avoid crashes on things that aren't even
targets at all, like run_target(). Although custom_target indexes are
actually targets those didn't work either.
Fixes#9648
Since it's deprecated anyway, we don't really want to plumb it all the
way down into the build and backend layers. Instead, we can just turn
it into a `win_subsystem` value in the interpreter if `win_subsystem`
isn't already set.
This would be either the value `kwargs['install']`, or `False`. There
isn't any case that `BuildTarget.need_install` handles that
`BuildTarget.install` doesn't handle, if we just initialized it
correctly. So, just set Target.install correctly in the super
initializer, and do away with need_install.
Also move it into the Jar class. This is an exclusive Jar keyword
argument, and is only used inside java paths, so there's no reason to
have this in all build targets.
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 fixes regression caused by
3162b901ca
that changes the order in which libraries are put on the link command.
In addition, that commit was wrong because libraries from dependencies
were processed before process_compiler() is called, which that commit
wanted to avoid.