diff options
author | Alistair Thomas <astavale@yahoo.co.uk> | 2018-12-15 18:26:35 +0000 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2018-12-19 23:16:59 +0200 |
commit | d54daf6e59a8610acfb028ebdb84bd74cc9a84c1 (patch) | |
tree | b9ab15a5956198e46fe53441e6a815d66d1f0048 /docs | |
parent | c1e416ff619e59845c5272475f2e7c1f48f1d8db (diff) | |
download | meson-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.md | 251 |
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') |