gnome.compile_resources() was not parsing custom target sources
properly. It was using the custom target name as the output of the
custom target instead of looking at the list of outputs.
Also modify the GNOME framework test to expose this.
We prefer to use the --extra-library parameter for passing -l arguments
to g-ir-scanner, however we need to be careful to only replace the first
'-l' occurrence to not translate
'-lfoo-lib'
to
'--extra-library=foo--extra-library=ib'
The glib-genmarshal tool was rewritten in GLib 2.53.3, and now supports
more command line arguments, such as:
"--pragma-once": emits a "#pragma once" instead of the old header
guards when generating the header file
"--prototypes": emits the marshallers prototype when generating the
source file
"-D,-U": defines and undefines pre-processor symbols
"--include-header": emits an "#include" directive when generating the
source file for the specified header file
Meson should take advantage of these new options, as they can be used to
replace most of the ad hoc build rules that projects are currently using
to implement the same thing.
Instead of mapping each option to a named argument, I used the same
approach as the compile_resources() and generate_gir() methods; the
genmarshal() method now has an 'extra_args' argument that can be used to
pass extra arguments to the glib-genmarshal tool.
When dealing with the SharedLibrary or StaticLibrary include
directories, we where not taking into acount that path are relative to
the source tree. With proper helper, this works now. This fixues issue
where the gir may be generated bug from headers found in the prefix.
While g-ir-scanner's compatible -I and -D flags cover what most dependencies
use, there's no guarantee that a dependency's cflags don't include more
exotic flags that conflict with the tool's own options.
For a real world example, mozjs-38 has '-include some-header-file.h', which
translates to '--include nclude another-file-to-scan.h' for the scanner;
unless for some reason there's an 'nclude' GIR available on the system,
the target will thus fail.
For this purpose, g-ir-scanner allows explicitly marking some flags as
preprocessor/compiler flags by guarding them with --cflags-begin and
--cflags-end. Make sure it is used this for all cflags, not only for
global and project flags.
This class now consolidates a lot of the logic that each external
dependency was duplicating in its class definition.
All external dependencies now set:
* self.version
* self.compile_args and self.link_args
* self.is_found (if found)
* self.sources
* etc
And the abstract ExternalDependency class defines the methods that
will fetch those properties. Some classes still override that for
various reasons, but those should also be migrated to properties as
far as possible.
Next step is to consolidate and standardize the way in which we call
'configuration binaries' such as sdl2-config, llvm-config, pkg-config,
etc. Currently each class has to duplicate code involved with that
even though the format is very similar.
Currently only pkg-config supports multiple version requirements, and
some classes don't even properly check the version requirement. That
will also become easier now.
While g-ir-scanner's compatible -I and -D flags cover what most pkg-config
files use, there's no guarantee that files don't set anything more exotic
that conflicts with the tool's own options.
For a real world example, mozjs-38 has '-include some-header-file.h', which
translates to '--include nclude another-file-to-scan.h' for the scanner;
unless for some reason there's an 'nclude' GIR available on the system,
the target will thus fail.
Avoid this case by pointing g-ir-scanner to the correct pkg-config file
instead of passing any cflags directly.
There are cases where we need to specify arguments to gtkdoc-mkdb, like
telling it to scan extensions that are not '.h' and '.c'. Let's add a
new named argument to gnome.gtkdoc(), as well as the plumbing needed for
the gtk-doc helper script.
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.
You can now pass a list of strings to the install_dir: kwarg to
build_target and custom_target.
Custom Targets:
===============
Allows you to specify the installation directory for each
corresponding output. For example:
custom_target('different-install-dirs',
output : ['first.file', 'second.file'],
...
install : true,
install_dir : ['somedir', 'otherdir])
This would install first.file to somedir and second.file to otherdir.
If only one install_dir is provided, all outputs are installed there
(same behaviour as before).
To only install some outputs, pass `false` for the outputs that you
don't want installed. For example:
custom_target('only-install-second',
output : ['first.file', 'second.file'],
...
install : true,
install_dir : [false, 'otherdir])
This would install second.file to otherdir and not install first.file.
Build Targets:
==============
With build_target() (which includes executable(), library(), etc),
usually there is only one primary output. However some types of
targets have multiple outputs.
For example, while generating Vala libraries, valac also generates
a header and a .vapi file both of which often need to be installed.
This allows you to specify installation directories for those too.
# This will only install the library (same as before)
shared_library('somevalalib', 'somesource.vala',
...
install : true)
# This will install the library, the header, and the vapi into the
# respective directories
shared_library('somevalalib', 'somesource.vala',
...
install : true,
install_dir : ['libdir', 'incdir', 'vapidir'])
# This will install the library into the default libdir and
# everything else into the specified directories
shared_library('somevalalib', 'somesource.vala',
...
install : true,
install_dir : [true, 'incdir', 'vapidir'])
# This will NOT install the library, and will install everything
# else into the specified directories
shared_library('somevalalib', 'somesource.vala',
...
install : true,
install_dir : [false, 'incdir', 'vapidir'])
true/false can also be used for secondary outputs in the same way.
Valac can also generate a GIR file for libraries when the `vala_gir:`
keyword argument is passed to library(). In that case, `install_dir:`
must be given a list with four elements, one for each output.
Includes tests for all these.
Closes https://github.com/mesonbuild/meson/issues/705
Closes https://github.com/mesonbuild/meson/issues/891
Closes https://github.com/mesonbuild/meson/issues/892
Closes https://github.com/mesonbuild/meson/issues/1178
Closes https://github.com/mesonbuild/meson/issues/1193
This avoids unnecessary rebuilds occuring when Meson regenerates the
build.ninja file. Previously, if the ordering of the commandline
arguments changed then Ninja would consider the outputs dirty and
rebuild them.
There is no need to do obj.get_command() and in fact it's wrong
because the VS backends need to resolve each object to absolute paths
and get_command() does not do that.
This should fix invocation of GNOME module helpers with the VS backends
For the record, absolute paths for programs are needed because the
same PATH environment won't necessarily be available to Visual Studio
when it builds the generated solution.
Related to https://github.com/mesonbuild/meson/issues/1419
This used to produce a warning, but then would crash anyway. It's
simpler if we just error out and have the user disable gir generation or
install gobject-introspection.
We can't support generated XML files with custom_target() because the
dependency scanning happens at configure time, but we *can* support
generating them with configure_file().
Closes https://github.com/mesonbuild/meson/issues/1380
We don't need dependencies to work correctly to use the output of
configure_file in the dependencies: kwarg.
This allows GNOME Recipes to built without the latest glib git.