Search notes:

Creating a shared and static library with the Meson build system

This page is an attempt to show how a static and a shared C library can be built with the Meson build system.
It is a sequel to Creating a shared and static library with the gnu compiler (gcc).
The files discussed on this page were contributed by Alberto Fanjul (albfan). I appreciated and benefitted from his work very much and I hope you can, too.

Overview of the source files

This example builds a static and shared version of the tq84-library (whose sources can be viewd here).
The sources are located under ./src/tq84.
After building the libraries, the executables using the libraries are built. There is only one file that uses the library: ./src/main.c.

meson.build files

The Meson build system is mainly configured with meson.build files.
In our example, there are three meson.build files: in the top level directory, in the ./src directory beneath (where main.c and dynamic-library-loader.c are located) and lastly in ./src/tq84 where the files for the shared objects are located (add.* and answer.*).

Top level meson.build file

Our top level meson.build uses the Meson function project() to name the project (sum) and specify the programming language for the project (in this case: C). Also, the project's license and version are stated here.
The subdir() function instructs Meson to enter into the specified directory (src) and execute the meson.build file in that subdirectory
project('sum', 'c',
  version : '1.0.0',
  license : 'GPL')
subdir('src')
Github repository gcc-create-library, path: /meson.build

./src/meson.build

The ./src/meson.build file starts with the subdir() function. So, Meson first descends into ./src/tq84 and executes that meson.file which creates the static and shared object files.
It is necessary to build them first because the executables are dependent on it. More on this later.
After building the shared objects, control is returned to ./src/meson.build. This file now instructs Meson to build three executables, each with the executable() function.
The first argument indicates the name of the executable and the unnamed following (that is: positional) arguments the sources to be compiled. In our case, this is one file: main.c.
The named argument link_with is used to determine with which files the executable is to be linked.
Note that we use a variables here: tq84_lib_static and tq84_lib_shared. The values for these variables were previously set when running ./src/tq84/meson.build.
The executable dynamic-library-loader uses the functions dlsym(), dlopen() and dlerror() which are found in libdl. Using the gnu linker, this library would be linked with the -ldl flag.
In order for Meson to do the same thing, we first get a compiler object (cc) through the meson object's get_compiler('c') function. Then, the compiler object can be queried for the correct ld library with cc.find_library('dl').
With this information, we're ready to create the executable dynamic-library-loader.
subdir('tq84')

executable('statically-linked', 'main.c',
           link_with: tq84_lib_static)

executable('use-shared-library', 'main.c',
           link_with: tq84_lib_shared)


cc = meson.get_compiler('c')
libdl = cc.find_library('dl')
executable('dynamic-library-loader', 'dynamic-library-loader.c',
           dependencies: libdl)
Github repository gcc-create-library, path: /src/meson.build

./src/tq84/meson.build

The ./src/tq84/meson.build file is responsible to create the shared and static shared objects.
The first line assigns the source names to the variable runtime_sources so that they don't need to be repeated.
The static library is built with the static_library() function, the shared library with the shared_library() function.
The install flag set to true causes the target to be installed (probably to /usr/lib.
runtime_sources = ['add.c', 'add.h', 'answer.c', 'answer.h']

tq84_lib_static = static_library('runtime',
                            runtime_sources,
                            install : true)

# We use libtool-version numbers because it's easier to understand.
# Before making a release, the libruntime_so_*
# numbers should be modified. The components are of the form C:R:A.
# a) If binary compatibility has been broken (eg removed or changed interfaces)
#    change to C+1:0:0.
# b) If interfaces have been changed or added, but binary compatibility has
#    been preserved, change to C+1:0:A+1
# c) If the interface is the same as the previous version, change to C:R+1:A
libruntime_lt_c=1
libruntime_lt_r=0
libruntime_lt_a=0

libruntime_so_version = '@0@.@1@.@2@'.format((libruntime_lt_c - libruntime_lt_a),
                                              libruntime_lt_a,
                                              libruntime_lt_r)

tq84_lib_shared = shared_library('runtime',
                            runtime_sources,
                            version : libruntime_so_version,
                            install : true)
Github repository gcc-create-library, path: /src/tq84/meson.build

Index