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.
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.
Cache the absolute dir that the script is searched in and the name of
the script. These are the only two things that change.
Update the test to test for both #1235 and the case when a script of the
same name is in a different directory (which also covers the subproject
case).
Closes#1235
Also don't use `dependencies` as a module name since it is commonly used
as a variable name too. Instead, directly import the classes that we use
from that module.
This avoids printing several 'Found:' messages during configure, and
also avoids doing several searches for the same binary. This is already
done by the interpreter for `find_program` calls from build files.
Also move it to the module-wide __init__.py file so it can be used by
other modules as-needed.
Also use it for g-ir-scanner where it was missed in one place, also fix
exception name in the same place.
It is often useful to be able to check if a specific object is of a type
defined in a module. To that end, define all such targets in
modules/__init__.py so that everyone can refer to them without poking
into module-specific code.
Without this, the user has to both compile the resource with
gnome.compile_resources, pass that to the target sources, and also
pass --gresources=/path/to/gres.xml to vala_args in the target.
With this, we will do that automatically.
Everywhere we use this object, we end up iterating over it and comparing
compiler.get_language() with something. Using a dict is the obvious
choice and simplifies a lot of code.
Instead of adding it everywhere manually, create a wrapper called
mesonlib.Popen_safe and use that everywhere that we call an executable
and extract its output.
This will also allow us to tweak it to do more/different things if
needed for some locales and/or systems.
Closes#1079
When generating the .gir file we need g-ir-scanner to link the
introspector binary against the right dependencies, for that
we used to use the --library option but this has a special meaning
and the libs passed in there end up being the ones in the .gir file
itself, which is not what we want.
A new --extra-library option is beeing added in goject-introspection
(https://bugzilla.gnome.org/show_bug.cgi?id=774625) to handle our use case
(ie. not using libtool which allows g-ir-scanner to know about those)
and we should make use of it.
Closes#981
This defaults to not exporting resources as that is generally what
you want but that does make this a breaking change. Along with that
if you export your resources you would want to install the header.
The install argument is allowed for CustomTargets, but we use
install_header as the setting now. Also, setting a generic template when
specifying the more specific source or header template shouldn't be
allowed.
Earlier, we were never adding dependencies on other GirTargets that we
need. The dependency would only be added indirectly through other
BuildTargets such as SharedLibrary. Now we add all GirTargets specified
in the `dependencies :` kwarg to the list of dependencies of the
GirTarget that we generate.
Also, we weren't adding include directories for the typelib generation
command recursively. We were only adding it for the GirTargets listed
under the `dependencies :` kwarg to gnome.generate_gir. Now we search
all link targets, find GirTargets, extract the include dir, and use it.
In summation, dependencies were completely broken.
- Use depfile support on recent glib-compile-resources
- Don't pass dep files to header ever
- Pass depends for generated deps
- Avoid duplicate --sourcedir args
- Include correct subdir of generated deps
If building in a prefix with a version of the library that's already
installed with other dependencies already installed in that prefix,
then the installed library was being picked up to link with
for gir generation instead of the newly built library.
Not all headers are public, or contain public types. GTK-Doc allows
adding headers to be ignored during the "scan" phase, by passing the
`--ignore-headers` command line argument to gtkdoc-scan.
Currently, you can do something like:
ignored_headers = [ 'foo-private.h', 'bar-private.h', ]
gnome.gtkdoc(...
scan_args: [
'--ignore-headers=' + ' '.join(ignored_headers),
],
...)
But it does not guarantee escaping rules and it's definitely not nice.
We can add a simpler version of that mechanism through a new positional
argument, `ignore_headers`, which behaves like `content_files` or
`html_assets`, and takes an array of header files to ignore:
gnome.gtkdoc(...
ignore_headers: ignored_headers,
...)
This commit adds a 'dependencies' keyword to the
gnome.compile_resources() function, which allows your resource blob
to depend on files generated at build-time from custom_target() or
configure_file() targets.
My current use case for this is source data that gets processed with Gettext
translation tools before being compiled into the resource blob.
This feature only works with GLib version 2.48.2 and above. So the
compile_resources() function now detects GLib version and raises an
error if the version of GLib being used is too old.
The compile_resources() test case is now split into two, so that the
existing one can continue to run on systems with old GLib versions (such
as Ubuntu Xenial, which the automated tests on travisci.org use), but
where new enough GLib is available we also test generating gresource
content.
The existing warning about glib-compile-resources is now only printed
if GLib version is older than 2.50.0 because
<https://bugzilla.gnome.org/show_bug.cgi?id=745754> is fixed in the
2.50.0 release.
Allowing the object tree to be generated.
We need to add options to allow copying the ncesseary sources and
assets so the HTML generator can work with them (everything is
relative so we need to copy them in the build directory).
Until now the documentation was not generated from the user provided
main sgml file but it was using a generated one, which lead to a broken
documentation. Starting using it revealed the other bugs fixed in that
commit.
These paths are now generated similar to
NinjaBackend.generate_single_compile where IncludeDirs create includes
of both the build directory path and the source directory path.
This also fixes a bug with include_directories, where the path string
supplied to the IncludeDirs initializer was used for the search path,
instead of the actual location to which it referred. Often, this was a
'.', and not a really useful path.
The extra arguments are typically used to specified the location of
installed API references that gtk-doc can use to create cross links
for symbols.
Fixes#555
There are use case where one may want to specify --sourcedir option
multiple times to glib-compile-resources, which will look for
resources in every specified directory.
By doing this, we also need to get rid of the manual GResource XML
parsing and we opted to use the glib-compile-resources command with
the --generate-dependencies option. This command will solve the
multiple source_dir case for us.