While adding link args for external deps, sometimes different
libraries come from different prefixes, and an older version of the
same library might be present in other prefixes and we don't want to
accidentally pick that up.
For example:
/usr/local/lib/libglib-2.0.so
/usr/local/lib/pkgconfig/glib-2.0.pc
/usr/local/lib/libz.so
/usr/local/lib/pkgconfig/zlib.pc
/home/mesonuser/.local/lib/libglib-2.0.so
/home/mesonuser/.local/lib/pkgconfig/glib-2.0.pc
PKG_CONFIG_PATH="/home/mesonuser/.local/lib/pkgconfig/:/usr/local/lib/pkgconfig/"
If a target uses `dependencies : [glib_dep, zlib_dep]`, it will end up
using /usr/local/lib/libglib-2.0.so instead of
/home/mesonuser/.local/lib/libglib-2.0.so despite using the pkg-config
file in /home/mesonuser/.local/lib/pkgconfig because we reorder the -L
flag and separate it from the -l flag.
With this change, external link arguments will be added to the
compiler list without de-dup or reordering.
Closes https://github.com/mesonbuild/meson/issues/1718
- Adds a `crate_type` kwarg to library targets, allowing the different
types of Rust [linkage][1].
- Shared libraries use the `dylib` crate type by default, but can also
be `cdylib`
- Static libraries use the `rlib` crate type by default, but can also
be `staticlib`
- If any Rust target has shared library dependencies, add the
appropriate linker arguments, including rpath for the sysroot of the
Rust compiler
[1]: https://doc.rust-lang.org/reference/linkage.html
When the CCompiler.links method call in CCompiler.find_library fails,
find_library resorts to finding the library file itself. In this second
case, the return value is not a list, whereas if links suceeds, the
return value is a list. Make it so that find_library returns a list
in either case.
Now we aggressively de-dup the list of libraries used while linking,
and when linking with GNU ld we have to enclose all static libraries
with -Wl,--start-group and -Wl,--end-group to force the linker to
resolve all symbols recursively. This is needed when static libraries
have circular deps on each other (see included test).
The --start/end-group change is also needed for circular dependencies
between static libraries because we no longer recursively list out all
library dependencies.
The size of build.ninja for GStreamer is now down to 6.1M from 20M,
and yields a net reduction in configuration time of 10%
Note that gui_app: is currently ignored when using the ninja backend with VS
compilers, so I guess you get the default linker behaviour, which the
documentation says is guessing the subsystem depending on if a main or
WinMain symbol exists...
Module definition files may be useful when building with gcc on Windows also
(e.g. if the existing build uses them, if exports are aliased, if we were
retro enough to export by ordinal, etc.)
Add the .def file to the link command line when using gcc on Windows
Run the appropriate windows tests irrespective of compiler.
Move '-C' option into 'get_always_args' as we always generate C sources.
Add a branch in the dependency management to perform Vala-specific work
of adding '--pkg' and '--target-glib'.
We never use preprocessed output anywhere except compiler checks,
so we don't care about the debugging information that it adds.
Just always disable it.
Closes https://github.com/mesonbuild/meson/issues/1726
Meson has a common pattern of using 'if len(foo) == 0:' or
'if len(foo) != 0:', however, this is a common anti-pattern in python.
Instead tests for emptiness/non-emptiness should be done with a simple
'if foo:' or 'if not foo:'
Consider the following:
>>> import timeit
>>> timeit.timeit('if len([]) == 0: pass')
0.10730923599840025
>>> timeit.timeit('if not []: pass')
0.030033907998586074
>>> timeit.timeit('if len(['a', 'b', 'c', 'd']) == 0: pass')
0.1154778649979562
>>> timeit.timeit("if not ['a', 'b', 'c', 'd']: pass")
0.08259823200205574
>>> timeit.timeit('if len("") == 0: pass')
0.089759664999292
>>> timeit.timeit('if not "": pass')
0.02340641999762738
>>> timeit.timeit('if len("foo") == 0: pass')
0.08848102600313723
>>> timeit.timeit('if not "foo": pass')
0.04032287199879647
And for the one additional case of 'if len(foo.strip()) == 0', which can
be replaced with 'if not foo.isspace()'
>>> timeit.timeit('if len(" ".strip()) == 0: pass')
0.15294511600222904
>>> timeit.timeit('if " ".isspace(): pass')
0.09413968399894657
>>> timeit.timeit('if len(" abc".strip()) == 0: pass')
0.2023209120015963
>>> timeit.timeit('if " abc".isspace(): pass')
0.09571301700270851
In other words, it's always a win to not use len(), when you don't
actually want to check the length.
The MSVC static library tool, lib.exe, does not understand the same set
of arguments as the linker. Avoid a warning by not adding /DEBUG or /PDB
to the command line when invoking lib.exe
Now as long as you have a C compiler available in the project, it will
be used to compile assembly even if the target contains a C++ compiler
and even if the target contains only assembly and C++ sources.
Earlier, the order in which sources appeared in a target would decide
which compiler would be used.
However, if the project only provides a C++ compiler, that will be
used for compiling assembly sources.
If this breaks your use-case, please tell us.
Includes a test that ensures that all of the above is adhered to.