We're hiring!

Spotlight on Meson's full-featured developer environment

Xavier Claessens avatar

Xavier Claessens
March 30, 2022

Share this post:

Reading time:

When developing an application or a library, it is very common to want to run it without installing it, or to install it into a custom prefix rather than on the system (i.e. /usr or /usr/local).

Meson has always helped with that by setting rpath in the built executables so they can find their shared libraries within the build directory tree. However, it has two main limitations:

  • Windows does not support rpath, DLLs are searched in PATH.
  • Applications often need to find other resources: plugins, config files, etc.

Many applications solve that with custom shell scripts that set various environment variables, like GST_PLUGIN_PATH, GI_TYPELIB_PATH, etc...

Since Meson 0.58.0, this can be easily done by simply using the meson devenv -C <builddir> command, and adding the needed environment variables directly in your meson.build files using meson.add_devenv().

Collabora - Running gst-launch-1.0 using the meson devenv -C <builddir> command
Running gst-launch-1.0 using the meson devenv -C <builddir> command

Meson's many out-of-the-box features

Doing this directly in Meson instead of relying on custom shell scripts has two big advantages:

  • It's generic, users do not need to know which custom script to use for each project. Many projects might not even have such script at all.
  • Meson already knows most of the needed environment and sets it for you.


As mentioned above, Windows DLLs are searched into the PATH; Meson will automatically set every location within the build directory where a DLL is built.

But that's not all, Meson will also add in PATH every location within the build directory where an executable is built. You can just execute the command to use the built program instead of a program installed on your system.


Let's say you want to test a change you make in a library (e.g. GStreamer) and need to run an application using that library (e.g. Totem) that you have on your system. Since Meson sets LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH on OSX, PATH on Windows), when you run Totem from your system, it will link to GStreamer libraries (and plugins, see below) from your build directory.


Want to test the generated GObject Introspection for your library? Meson sets GI_TYPELIB_PATH automatically for every project that already uses gnome.generate_gir().

gstreamer$ meson devenv -C builddir/ python
>>> import gi
>>> from gi.repository import Gst
>>> Gst.init(None)
>>> Gst.version()
(major=1, minor=21, micro=0, nano=1)


GLib or GTK applications often use gnome.compile_schemas() to define their settings. Meson will set GSETTINGS_SCHEMA_DIR for you, so the application can run and access its settings without having to install their schema on the system.


When using pkg.generate() Meson also writes <name>-uninstalled.pc. In the developer environment, PKG_CONFIG_PATH always includes the directory where Meson wrote those .pc files so you can configure and build applications that use that library. This is especially useful when the application uses another build system such as autotools; if the build system is Meson too, it is often easier to use a subproject instead.

Bash completion

Projects that install executables with a command line interface often also install a bash script for auto-completion. Meson detects such script and sources them directly from your source tree.

Requires Meson 0.62.0.

GDB helper scripts

Some C projects ship GDB scripts to help with debugging (e.g. GLib and GStreamer). Those scripts have a filename in the form of <libname>-gdb.{py,gdb,csm}. When installed in the right location, GDB will load them automatically when libname is linked by the executable being debugged.

Meson detects those files automatically and writes the needed .gdbinit configuration file so GDB will load the helper scripts directly from your source tree.

Requires Meson 0.62.0.

Extend with your own environment variables

Unfortunately, Meson cannot guess everything. Custom environment variables need to be defined manually with the meson.add_devenv() method.

If your application needs to access data files, you typically would add this in data/meson.build:

meson.add_devenv({'MY_APP_DATA_DIR': meson.current_source_dir()})

For projects that build various plugins in many different locations (e.g. GStreamer), you can add each location into the environment variable:

# plugin1/meson.build
meson.add_devenv({'MY_PLUGIN_PATH': meson.current_build_dir()}, method: 'prepend')
# plugin2/meson.build
meson.add_devenv({'MY_PLUGIN_PATH': meson.current_build_dir()}, method: 'prepend')

Even when using subprojects

Meson aggregates the developer environment definitions from every subproject. When your application builds some of its dependencies as a subproject, they will work in your developer environment without having to know which environment variables you have to define for every single one of them.

Convert your projects!

Many projects have their own "uninstalled" script. Replacing them with the proper Meson system benefits everyone, especially when your project can be used by others as a subproject. Please reach out if there is anything else Meson could be doing to help developers!

Most of the features described here are inspired by GStreamer's gst-env.py script. Thanks to the GStreamer community for such a great tool!

Comments (0)

Add a Comment

Allowed tags: <b><i><br>Add a new comment:

Search the newsroom

Latest Blog Posts

Automatic regression handling and reporting for the Linux Kernel


In continuation with our series about Kernel Integration we'll go into more detail about how regression detection, processing, and tracking…

Almost a fully open-source boot chain for Rockchip's RK3588!


Now included in our Debian images & available via our GitLab, you can build a complete, working BL31 (Boot Loader stage 3.1), and replace…

What's the latest with WirePlumber?


Back in 2022, after a series of issues were found in its design, I made the call to rework some of WirePlumber's fundamentals in order to…

DRM-CI: A GitLab-CI pipeline for Linux kernel testing


Continuing our Kernel Integration series, we're excited to introduce DRM-CI, a groundbreaking solution that enables developers to test their…

Persian Rug, Part 4 - The limitations of proxies


This is the fourth and final part in a series on persian-rug, a Rust crate for interconnected objects. We've touched on the two big limitations:…

How to share code between Vulkan and Gallium


One of the key high-level challenges of building Mesa drivers these days is figuring out how to best share code between a Vulkan driver…

Open Since 2005 logo

We use cookies on this website to ensure that you get the best experience. By continuing to use this website you are consenting to the use of these cookies. To find out more please follow this link.

Collabora Ltd © 2005-2024. All rights reserved. Privacy Notice. Sitemap.