aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorAlistair Thomas <astavale@yahoo.co.uk>2018-12-15 18:26:35 +0000
committerJussi Pakkanen <jpakkane@gmail.com>2018-12-19 23:16:59 +0200
commitd54daf6e59a8610acfb028ebdb84bd74cc9a84c1 (patch)
treeb9ab15a5956198e46fe53441e6a815d66d1f0048 /docs
parentc1e416ff619e59845c5272475f2e7c1f48f1d8db (diff)
downloadmeson-d54daf6e59a8610acfb028ebdb84bd74cc9a84c1.zip
meson-d54daf6e59a8610acfb028ebdb84bd74cc9a84c1.tar.gz
meson-d54daf6e59a8610acfb028ebdb84bd74cc9a84c1.tar.bz2
docs: make clearer difference between using and building libraries in Vala [skip ci]
Diffstat (limited to 'docs')
-rw-r--r--docs/markdown/Vala.md251
1 files changed, 219 insertions, 32 deletions
diff --git a/docs/markdown/Vala.md b/docs/markdown/Vala.md
index c5d2b79..2184ebc 100644
--- a/docs/markdown/Vala.md
+++ b/docs/markdown/Vala.md
@@ -3,25 +3,147 @@ title: Vala
short-description: Compiling Vala and Genie programs
...
-# Compiling Vala applications
+# Compiling Vala applications and libraries
+Meson supports compiling applications and libraries written in
+[Vala](https://vala-project.org/) and
+[Genie](https://wiki.gnome.org/Projects/Genie) . A skeleton `meson.build` file:
-Meson has support for compiling Vala and Genie programs. A skeleton `meson.build` file for Vala looks like this:
+```meson
+project('vala app', 'vala', 'c')
+
+dependencies = [
+ dependency('glib-2.0'),
+ dependency('gobject-2.0'),
+]
+
+sources = files('app.vala')
+
+executable('app_name', sources, dependencies : dependencies)
+```
+
+You must always specify the `glib-2.0` and `gobject-2.0` libraries as
+dependencies, because all current Vala applications use them.
+[GLib](https://developer.gnome.org/glib/stable/) is used for basic data types
+and [GObject](https://developer.gnome.org/gobject/stable/) is used for the
+runtime type system.
+
+
+## Using libraries
+Meson uses the [`dependency()`](Reference-manual.md#dependency) function to find
+the relevant VAPI, C headers and linker flags when it encounters a Vala source
+file in a build target. Vala needs a VAPI file and a C header or headers to use
+a library. The VAPI file helps map Vala code to the library's C programming
+interface. It is the
+[`pkg-config`](https://www.freedesktop.org/wiki/Software/pkg-config/) tool that
+makes finding these installed files all work seamlessly behind the scenes. When
+a `pkg-config` file doesn't exist for the library then the
+[`find_library()`](Reference-manual.md#find_library) method of the [compiler
+object](Reference-manual.md#compiler-object) needs to be used. Examples are
+given later.
+
+Note Vala uses libraries that follow the C Application Binary Interface (C ABI).
+The library, however, could be written in C, Vala, Rust, Go, C++ or any other
+language that can generate a binary compatible with the C ABI and so provides C
+headers.
+
+
+### The simplest case
+This first example is a simple addition to the `meson.build` file because:
+
+ * the library has a `pkg-config` file, `gtk+-3.0.pc`
+ * the VAPI is distributed with Vala and so installed with the Vala compiler
+ * the VAPI is installed in Vala's standard search path
+ * the VAPI has the same name as the `pkg-config` file, `gtk+-3.0.vapi`
+
+Everything works seamlessly in the background and only a single extra line is
+needed:
```meson
-project('valaprog', 'vala', 'c')
+project('vala app', 'vala', 'c')
-glib_dep = dependency('glib-2.0')
-gobject_dep = dependency('gobject-2.0')
+dependencies = [
+ dependency('glib-2.0'),
+ dependency('gobject-2.0'),
+ dependency('gtk+-3.0'),
+]
-executable('valaprog', 'prog.vala',
- dependencies : [glib_dep, gobject_dep])
+sources = files('app.vala')
+
+executable('app_name', sources, dependencies : dependencies)
```
-You must always specify `glib-2.0` and `gobject-2.0` as dependencies, because all Vala applications use them.
+GTK+ is the graphical toolkit used by GNOME, elementary OS and other desktop
+environments. The binding to the library, the VAPI file, is distributed with
+Vala.
+
+Other libraries may have a VAPI that is distributed with the library itself.
+Such libraries will have their VAPI file installed along with their other
+development files. The VAPI is installed in Vala's standard search path and so
+works just as seamlessly using the `dependency()` function.
+
+
+### Targetting a version of GLib
+Meson's [`dependency()`](Reference-manual.md#dependency) function allows a
+version check of a library. This is often used to check a minimum version is
+installed. When setting a minimum version of GLib, Meson will also pass this to
+the Vala compiler using the `--target-glib` option.
+
+This is needed when using GTK+'s user interface definition files with Vala's
+`[GtkTemplate]`, `[GtkChild]` and `[GtkCallback]` annotations. This requires
+`--target-glib 2.38`, or a newer version, to be passed to Vala. With Meson this
+is simply done with:
+
+```meson
+project('vala app', 'vala', 'c')
+
+dependencies = [
+ dependency('glib-2.0', version: '>=2.38'),
+ dependency('gobject-2.0'),
+ dependency('gtk+-3.0'),
+]
+
+sources = files('app.vala')
-## Using a custom VAPI
+executable('app_name', sources, dependencies : dependencies)
+```
-When dealing with libraries that are not providing Vala bindings, a `--vapidir` flag can be added to extend the search path for the current project.
+Using `[GtkTemplate]` also requires the GTK+ user interface definition files to
+be built in to the binary as GResources. For completeness, the next example
+shows this:
+
+```meson
+project('vala app', 'vala', 'c')
+
+dependencies = [
+ dependency('glib-2.0', version: '>=2.38'),
+ dependency('gobject-2.0'),
+ dependency('gtk+-3.0'),
+]
+
+sources = files('app.vala')
+
+sources += import( 'gnome' ).compile_resources(
+ 'project-resources',
+ 'src/resources/resources.gresource.xml',
+ source_dir: 'src/resources',
+)
+
+executable('app_name', sources, dependencies : dependencies)
+```
+
+
+### Adding to Vala's search path
+So far we have covered the cases where the VAPI file is either distributed with
+Vala or the library. A VAPI can also be included in the source files of your
+project. The convention is to put it in the `vapi` directory of your project.
+
+This is needed when a library does not have a VAPI or your project needs to link
+to another component in the project that uses the C ABI. For example if part of
+the project is written in C.
+
+The Vala compiler's `--vapidir` option is used to add the project directory to
+the VAPI search path. In Meson this is done with the `add_project_arguments()`
+function:
```meson
project('vala app', 'c', 'vala')
@@ -29,53 +151,113 @@ project('vala app', 'c', 'vala')
add_project_arguments(['--vapidir', join_paths(meson.current_source_dir(), 'vapi')],
language: 'vala')
-glib_dep = dependency('glib-2.0')
-gobject_dep = dependency('gobject-2.0')
-foo_dep = dependency('foo') # 'foo.vapi' will be resolved in './vapi/foo.vapi'
+dependencies = [
+ dependency('glib-2.0'),
+ dependency('gobject-2.0'),
+ dependency('foo'), # 'foo.vapi' will be resolved as './vapi/foo.vapi'
+]
-executable('app', 'app.vala', dependencies: [glib_dep, gobject_dep, foo_dep])
+sources = files('app.vala')
+
+executable('app_name', sources, dependencies : dependencies)
```
-In this case, make sure that the VAPI name corresponds to the pkg-config file.
+If the VAPI is for an external library then make sure that the VAPI name
+corresponds to the pkg-config file name.
+
+The [`vala-extra-vapis` repository](https://github.com/nemequ/vala-extra-vapis)
+is a community maintained repository of VAPIs that are not distributed.
+Developers use the repository to share early work on new bindings and
+improvements to existing bindings. So the VAPIs can frequently change. It is
+recommended VAPIs from this repository are copied in to your project's source
+files.
+
+This also works well for starting to write new bindings before they are shared
+with the `vala-extra-vapis` repository.
-If no pkg-config file is provided, you must use `find_library`. Using`declare_dependency` is cleaner because it does not require passing both dependency objects to the target.
+
+### Libraries without pkg-config files
+A library that does not have a corresponding pkg-config file may mean
+`dependency()` is unsuitable for finding the C and Vala interface files. In this
+case it is necessary to use `find_library()`.
+
+The first example uses Vala's POSIX binding. There is no pkg-config file because
+POSIX includes the standard C library on Unix systems. All that is needed is the
+VAPI file, `posix.vapi`. This is included with Vala and installed in Vala's
+standard search path. Meson just needs to be told to only find the library for
+the Vala compiler:
```meson
-foo_lib = meson.get_compiler('c').find_library('foo') # assuming libfoo.so is installed
-foo_vapi = meson.get_compiler('vala').find_library('foo', dirs: join_paths(meson.current_source_dir(), 'vapi'))
-foo_dep = declare_dependency(dependencies: [foo_lib, foo_vapi])
+project('vala app', 'vala', 'c')
-executable('app', 'app.vala', dependencies: [glib_dep, gobject_dep, foo_dep])
-```
+dependencies = [
+ dependency('glib-2.0'),
+ dependency('gobject-2.0'),
+ meson.get_compiler('vala').find_library('posix'),
+]
-## VAPI without pkg-config file
+sources = files('app.vala')
-Some Vala bindings do not need a corresponding pkg-config file and `dependency` is unsuitable for resolving them. It's necessary to use `find_library` in this case.
+executable('app_name', sources, dependencies : dependencies)
+```
+
+The next example shows how to link with a C library where no additional VAPI is
+needed. The standard maths functions are already bound in `glib-2.0.vapi`, but
+the GNU C library requires linking to the maths library separately. In this
+example Meson is told to find the library only for the C compiler:
```meson
-posix_dep = meson.get_compiler('vala').find_library('posix')
+project('vala app', 'vala', 'c')
+
+dependencies = [
+ dependency('glib-2.0'),
+ dependency('gobject-2.0'),
+ meson.get_compiler('c').find_library('m', required: false),
+]
-executable('app', 'app.vala', dependencies: [glib_dep, gobject_dep, posix_dep])
+sources = files('app.vala')
+
+executable('app_name', sources, dependencies : dependencies)
```
-## Custom output names
-If a library target is used, Meson automatically outputs the C header and the VAPI. They can be renamed by setting the `vala_header` and `vala_vapi` arguments respectively. In this case, the second and third elements of the `install_dir` array indicate the destination with `true` to indicate default directories (i.e. `include` and `share/vala/vapi`).
+## Building libraries
+
+
+### Changing C header and VAPI names
+Meson's [`library`](Reference-manual.md#library) target automatically outputs
+the C header and the VAPI. They can be renamed by setting the `vala_header` and
+`vala_vapi` arguments respectively:
```meson
-foo_lib = library('foo', 'foo.vala',
+foo_lib = shared_library('foo', 'foo.vala',
vala_header: 'foo.h',
vala_vapi: 'foo-1.0.vapi',
dependencies: [glib_dep, gobject_dep],
install: true,
install_dir: [true, true, true])
```
+In this example, the second and third elements of the `install_dir` array
+indicate the destination with `true` to use default directories (i.e. `include`
+and `share/vala/vapi`).
+
-## GObject Introspection
+### GObject Introspection and language bindings
+A 'binding' allows another programming language to use a library written in
+Vala. Because Vala uses the GObject type system as its runtime type system it is
+very easy to use introspection to generate a binding. A Meson build of a Vala
+library can generate the GObject introspection metadata. The metadata is then
+used in separate projects with [language specific
+tools](https://wiki.gnome.org/Projects/Vala/LibraryWritingBindings) to generate
+a binding.
-To generate GObject Introspection metadata, the `vala_gir` option has to be set with the desired name.
+The main form of metadata is a GObject Introspection Repository (GIR) XML file.
+GIRs are mostly used by languages that generate bindings at compile time.
+Languages that generate bindings at runtime mostly use a typelib file, which is
+generated from the GIR.
-The fourth element in the `install_dir` array indicate where the GIR file will be installed. The `true` value tells Meson to use the default directory (i.e. `share/gir-1.0`).
+Meson can generate a GIR as part of the build. For a Vala library the
+`vala_gir` option has to be set for the `library`:
```meson
foo_lib = library('foo', 'foo.vala',
@@ -85,7 +267,12 @@ foo_lib = library('foo', 'foo.vala',
install_dir: [true, true, true, true])
```
-For the typelib, use a custom target depending on the library:
+The `true` value in `install_dir` tells Meson to use the default directory (i.e.
+`share/gir-1.0` for GIRs). The fourth element in the `install_dir` array
+indicates where the GIR file will be installed.
+
+To then generate a typelib file use a custom target with the `g-ir-compiler`
+program and a dependency on the library:
```meson
g_ir_compiler = find_program('g-ir-compiler')