meson-reference(3)

💖 NAME 💖

okay bestie, welcome to meson-reference(3) from the Library Functions Manual — this is meson-reference v1.12.1, aka a reference for meson functions and objects. 💅✨

✨ DESCRIPTION ✨

This manual is split into two sections: FUNCTIONS and OBJECTS. FUNCTIONS contains a reference for all meson functions and methods. Methods are denoted by object_name.method_name(). OBJECTS contains additional information about each object. no cap. 🫶

🛠️ FUNCTIONS 🛠️

🌟 add_global_arguments() 🌟

📜 SYNOPSIS

void add_global_arguments(
    Compiler argument...,
    language:,
    native: false,
)

💬 DESCRIPTION

Adds global arguments to the compiler command line. iconic behavior, honestly. 🔥

🌈 VARARGS

  • Compiler argument str, 0...N times — the compiler arguments to add.

🎛️ KWARGS

  • language array[str], required — Specifies the language(s) that the arguments should be applied to. If an array of languages is given, the arguments are added to each of the corresponding compiler command lines. Note that there is no way to remove an argument set in this way. If you have an argument that is only used in a subset of targets, you have to specify it in per-target flags.
  • native bool, default: false, since 0.48.0 — A boolean specifying whether the arguments should be applied to the native or cross compilation. If true the arguments will only be used for native compilations. If false the arguments will only be used in cross compilations. If omitted, the flags are added to native compilations if compiling natively and cross compilations (only) when cross compiling.

📝 NOTES

Usually you should use add_project_arguments instead, because that works even when your project is used as a subproject. You must pass always arguments individually arg1, arg2, ... rather than as a string 'arg1 arg2', ... 💀


📜 SYNOPSIS

void add_global_link_arguments(
    Linker argument...,
    language:,
    native: false,
)

💬 DESCRIPTION

Adds global arguments to the linker command line. Like add_global_arguments but the arguments are passed to the linker. linker girlies rise. 🔗

🌈 VARARGS

  • Linker argument str, 0...N times — the linker arguments to add.

🎛️ KWARGS

  • language array[str], required — Specifies the language(s) that the arguments should be applied to. If an array of languages is given, the arguments are added to each of the corresponding compiler command lines. Note that there is no way to remove an argument set in this way. If you have an argument that is only used in a subset of targets, you have to specify it in per-target flags.
  • native bool, default: false, since 0.48.0 — A boolean specifying whether the arguments should be applied to the native or cross compilation. If true the arguments will only be used for native compilations. If false the arguments will only be used in cross compilations. If omitted, the flags are added to native compilations if compiling natively and cross compilations (only) when cross compiling.

📝 NOTES

Usually you should use add_project_link_arguments instead, because that works even when your project is used as a subproject. You must pass always arguments individually arg1, arg2, ... rather than as a string 'arg1 arg2', ... 💅


🌟 add_languages() 🌟

📜 SYNOPSIS

bool add_languages(Language..., native:, required: true)

💬 DESCRIPTION

Add programming languages used by the project. This is equivalent to having them in the project declaration. This function is usually used to add languages that are only used under some conditions. 👑

Returns true if all languages specified were found and false otherwise.

If native is omitted, the languages may be used for either build or host machine, but are never required for the build machine. (i.e. it is equivalent to add_languages(langs, native: false, required: required) and add_languages(langs, native: true, required: false). This default behaviour may change to native: false in a future Meson version.

🌈 VARARGS

  • Language str, 0...N times — the languages to add.

🎛️ KWARGS

  • native bool, since 0.54.0 — If set to true, the language will be used to compile for the build machine, if false, for the host machine.
  • required bool | feature, default: true — If set to true, Meson will halt if any of the languages specified are not found. (since 0.47.0) The value of a feature[1] option can also be passed.

🌸 EXAMPLE

project('foobar', 'c')

if compiling_for_osx
  add_languages('objc')
endif
if add_languages('cpp', required : false)
  executable('cpp-app', 'main.cpp')
endif

# More code...

🌟 add_project_arguments() 🌟

📜 SYNOPSIS

void add_project_arguments(
    Compiler argument...,
    language:,
    native: false,
)

💬 DESCRIPTION

Adds project specific arguments to the compiler command line. This function behaves in the same way as add_global_arguments except that the arguments are only used for the current project, they won't be used in any other subproject. main character project energy. 🎀

🌈 VARARGS

  • Compiler argument str, 0...N times — the compiler arguments to add.

🎛️ KWARGS

  • language array[str], required — Specifies the language(s) that the arguments should be applied to. If an array of languages is given, the arguments are added to each of the corresponding compiler command lines. Note that there is no way to remove an argument set in this way. If you have an argument that is only used in a subset of targets, you have to specify it in per-target flags.
  • native bool, default: false, since 0.48.0 — A boolean specifying whether the arguments should be applied to the native or cross compilation. If true the arguments will only be used for native compilations. If false the arguments will only be used in cross compilations. If omitted, the flags are added to native compilations if compiling natively and cross compilations (only) when cross compiling.

📝 NOTES

You must pass always arguments individually arg1, arg2, ... rather than as a string 'arg1 arg2', ... fr fr. 🫡


🌟 add_project_dependencies() 🌟

📜 SYNOPSIS

void add_project_dependencies(
    dependencies...,
    language:,
    native: false,
)

since 0.63.0

💬 DESCRIPTION

Adds arguments to the compiler and linker command line, so that the given set of dependencies is included in all build products for this project. ✨

🌈 VARARGS

  • dependencies dep, 0...N times — the dependencies to add; if internal dependencies are included, they must not include any built object.

🎛️ KWARGS

  • language array[str], required — Specifies the language(s) that the arguments should be applied to. If an array of languages is given, the arguments are added to each of the corresponding compiler command lines. Note that there is no way to remove an argument set in this way. If you have an argument that is only used in a subset of targets, you have to specify it in per-target flags.
  • native bool, default: false, since 0.48.0 — A boolean specifying whether the arguments should be applied to the native or cross compilation. If true the arguments will only be used for native compilations. If false the arguments will only be used in cross compilations. If omitted, the flags are added to native compilations if compiling natively and cross compilations (only) when cross compiling.

📜 SYNOPSIS

void add_project_link_arguments(
    Linker argument...,
    language:,
    native: false,
)

💬 DESCRIPTION

Adds project specific arguments to the linker command line. Like add_project_arguments but the arguments are passed to the linker. 💜

🌈 VARARGS

  • Linker argument str, 0...N times — the linker arguments to add.

🎛️ KWARGS

  • language array[str], required — Specifies the language(s) that the arguments should be applied to. If an array of languages is given, the arguments are added to each of the corresponding compiler command lines. Note that there is no way to remove an argument set in this way. If you have an argument that is only used in a subset of targets, you have to specify it in per-target flags.
  • native bool, default: false, since 0.48.0 — A boolean specifying whether the arguments should be applied to the native or cross compilation. If true the arguments will only be used for native compilations. If false the arguments will only be used in cross compilations. If omitted, the flags are added to native compilations if compiling natively and cross compilations (only) when cross compiling.

📝 NOTES

You must pass always arguments individually arg1, arg2, ... rather than as a string 'arg1 arg2', ... lowkey important. 😌


🌟 add_test_setup() 🌟

📜 SYNOPSIS

void add_test_setup(
    name,
    env:,
    exclude_suites:,
    exe_wrapper:,
    gdb: false,
    is_default: false,
    timeout_multiplier: 1,
)

💬 DESCRIPTION

Add a custom test setup. This setup can be used to run the tests with a custom setup, for example under Valgrind. 🧪

To use the test setup, run meson test --setup=name inside the build dir.

Note that all these options are also available while running the meson test script for running tests instead of ninja test or msbuild RUN_TESTS.vcxproj, etc depending on the backend.

🎯 POSARGS

  • name str, required — the name of the test setup.

🎛️ KWARGS

  • env env | array[str] | dict[str] — environment variables to set, such as ['NAME1=value1', 'NAME2=value2'], or an env object which allows more sophisticated environment juggling. (Since 0.52.0) A dictionary is also accepted.
  • exclude_suites array[str], since 0.57.0 — An array of test suites that should be excluded when using this setup. Suites specified in the --suite option to meson test will always run, overriding add_test_setup if necessary.
  • exe_wrapper array[str | program] — The command or script followed by the arguments to it
  • gdb bool, default: false — set this to true and your tests also get run under gdb. debugging era 💅
  • is_default bool, default: false, since 0.49.0 — controls whether this is the default test setup. If true, the setup gets used whenever you run meson test without the --setup option. main character setup energy 👑
  • timeout_multiplier int, default: 1 — a number to multiply the test timeout with. Since 0.57, if timeout_multiplier is <= 0 the test has infinite duration. In previous versions of Meson the test would fail with a timeout immediately. so like… literally forever 🫠

✨ alias_target()

SYNOPSIS

alias_tgt alias_target(target_name, Dep...)

since 0.52.0

DESCRIPTION

This function creates a new top-level target. Like all top-level targets, this one integrates with the selected backend — so for instance you can run it as meson compile target_name. It's a dummy target that does not execute any command, but it does ensure that all dependencies are built. Dependencies can be any build target. Since 0.60.0, that includes run_tgt. 🎀

Since 1.6.0, passing a both_libs object builds both shared and static libraries.

POSARGS

  • target_name str, required — the name of the alias target.

VARARGS

  • Dep tgt, 1...N times — the targets to depend on. all of them. no cap 🫶

🦋 assert()

SYNOPSIS

void assert(condition, [message])

DESCRIPTION

Abort with an error message if condition evaluates to false. that's it, that's the whole vibe check 💀

POSARGS

  • condition bool, required — abort if this evaluates to false.

OPTARGS

  • message str — the error message to print.

NOTES

The message argument is optional since 0.53.0 and defaults to print the condition statement.


🔥 benchmark()

SYNOPSIS

void benchmark(
    name,
    executable,
    args:,
    depends:,
    env:,
    expected_exitcode: 0,
    expected_fail: false,
    priority: 0,
    protocol: 'exitcode',
    should_fail: false,
    suite:,
    timeout: 30,
    verbose: false,
    workdir:,
)

DESCRIPTION

Creates a benchmark item that will be run when the benchmark target is run. The behavior of this function is identical to test except for these two lil differences:

  • benchmark() has no is_parallel keyword because benchmarks are not run in parallel
  • benchmark() does not automatically add the MALLOC_PERTURB_ environment variable

Defined benchmarks can be run in a backend-agnostic way by calling meson test --benchmark inside the build dir, or by using backend-specific commands, such as ninja benchmark or msbuild RUN_TESTS.vcxproj. pick your fighter ⭐

POSARGS

  • name str, required — the unique test id.
  • executable exe | jar | program | file | custom_tgt | custom_idx, required — the program to execute. (Since 1.4.0) A CustomTarget is also accepted.

KWARGS

  • args array[str | file | tgt | program] — arguments to pass to the executable.
  • depends array[build_tgt | custom_tgt | custom_idx | program], since 0.46.0 — specifies that this test depends on the specified target(s), even though it does not take any of them as a command line argument. This is meant for cases where test finds those targets internally, e.g. plugins or globbing. Those targets are built before the test is executed, even if they have build_by_default : false. program is supported since 1.11.2.
  • env env | array[str] | dict[str] — environment variables to set, such as ['NAME1=value1', ´NAME2=value2'], or an env object which allows more sophisticated environment juggling. (Since 0.52.0) A dictionary is also accepted.
  • expected_exitcode int, default: 0, since 1.11.0 — the test is considered passed if the executable returns the specified returncode. Only has effect when protocol is set to exitcode.
  • expected_fail bool, default: false, since 1.11.0 — when true the test is considered passed if the executable returns a non-zero return value (i.e. reports an error).
  • priority int, default: 0, since 0.52.0 — specifies the priority of a test. Tests with a higher priority are started before tests with a lower priority. The starting order of tests with identical priorities is implementation-defined. The default priority is 0, and negative numbers are permitted. queuing theory but make it cute 💅
  • protocol str, default: 'exitcode', since 0.50.0 — specifies how the test results are parsed, and can be one of exitcode, tap, or gtest. For more information about test harness protocol read Unit Tests[2]. The following values are accepted:
    • exitcode: the executable's exit code is used by the test harness to record the outcome of the test).
    • tap: Test Anything Protocol[3].
    • gtest (since 0.55.0): for Google Tests.
    • rust (since 0.56.0): for native rust tests
  • should_fail bool, default: false, deprecated since 1.11.0 — when true the test is considered passed if the executable returns a non-zero return value (i.e. reports an error). heads up bestie, this one's deprecated 🚩
  • suite str | array[str] — 'label' (or array of labels ['label1', 'label2']) attached to this test. The suite name is qualified by a (sub)project name resulting in (sub)project_name:label. In the case of an array of strings, the suite names will be (sub)project_name:label1, (sub)project_name:label2, etc.
  • timeout int, default: 30 — the amount of seconds the test is allowed to run; a test that exceeds its time limit is always considered failed, defaults to 30 seconds. Since 0.57, if timeout is <= 0 the test has infinite duration — in previous versions of Meson the test would fail with a timeout immediately. 😭
  • verbose bool, default: false, since 0.62.0 — if true, forces the test results to be logged as if --verbose was passed to meson test.
  • workdir str — absolute path that will be used as the working directory for the test.

NOTES

Prior to 0.52.0, benchmark would warn that depends and priority were unsupported — this is incorrect. it was lying to you, bestie 🙈


🌸 both_libraries()

SYNOPSIS

both_libs both_libraries(
    target_name,
    source...,
    <lang>_args:,
    <lang>_pch:,
    <lang>_shared_args:,
    <lang>_static_args:,
    build_by_default: true,
    build_rpath:,
    build_subdir:,
    d_debug:,
    d_import_dirs:,
    d_module_versions:,
    d_unittest: false,
    darwin_versions:,
    dependencies:,
    extra_files:,
    gnu_symbol_visibility:,
    gui_app: false,
    implicit_include_directories: true,
    include_directories:,
    install: false,
    install_dir:,
    install_mode:,
    install_rpath:,
    install_tag:,
    install_vala_gir:,
    install_vala_header:,
    install_vala_vapi:,
    link_args:,
    link_depends:,
    link_early_args:,
    link_language:,
    link_whole:,
    link_with:,
    name_prefix:,
    name_suffix:,
    native: false,
    objects:,
    override_options:,
    pic:,
    prelink:,
    rust_abi:,
    rust_crate_type:,
    rust_dependency_map:,
    shortname:,
    sources:,
    soversion:,
    vala_gir:,
    vala_header:,
    vala_shared_args:,
    vala_static_args:,
    vala_vapi:,
    version:,
    vs_module_defs:,
    win_subsystem: 'console',
)

since 0.46.0

DESCRIPTION

Builds both a static and a shared library with the given sources. Positional and keyword arguments are otherwise the same as for library. Source files will be compiled only once, and object files will be reused to build both the shared and static libraries — unless the b_staticpic user option or the pic argument are set to false, in which case sources will be compiled twice. two libraries, one compilation, we love efficiency 💖

POSARGS

  • target_name str, required — the unique name of the build target.

VARARGS

  • source str | file | custom_tgt | custom_idx | generated_list, 0...N times — input source to compile. The following types are supported:
    • Strings relative to the current source directory
    • file objects defined in any preceding build file
    • The return value of configure-time generators such as configure_file
    • The return value of build-time generators such as custom_target or generator.process

These input files can be sources, objects, libraries, or any other file. Meson will automatically categorize them based on the extension and use them accordingly. For instance, sources (.c, .cpp, .vala, .rs, etc) will be compiled and objects (.o, .obj) and libraries (.so, .dll, etc) will be linked. it literally sorts them for you, iconic 🎀

With the Ninja backend, Meson will create a build-time order-only dependency[4] on all generated input files, including unknown files. This is needed to bootstrap the generation of the real dependencies in the depfile[5] generated by your compiler to determine when to rebuild sources. Ninja relies on this dependency file for all input files, generated and non-generated. The behavior is similar for other backends.

KWARGS

  • <lang>_args array[str | file] — compiler flags to use for the given language; eg: cpp_args for C++.
  • <lang>_pch str — precompiled header file to use for the given language.
  • <lang>_shared_args array[str], since 1.3.0 — arguments that are only passed to a shared library.
  • <lang>_static_args array[str], since 1.3.0 — arguments that are only passed to a static library.
  • build_by_default bool, default: true, since 0.38.0 — causes, when set to true, this target to be built by default. This means it will be built when meson compile is called without any arguments. The default value is true for all built target types.
  • build_rpath str, since 0.42.0 — a string to add to target's rpath definition in the build dir, but which will be removed on install.
  • build_subdir str, since 1.10.0 — drops the build results into a subdirectory with this name instead of straight into the build dir. Important: this does not touch the install directory — that's install_dir's whole thing. Why would you want this? Two reasons, bestie: either you need a directory name in the build path so you can actually use the build result while building other targets, or you've got multiple targets with the same basename and unique build_subdir values are how you keep them from stepping on each other. To stop collisions inside the build directory, build_subdir is not allowed to match a file or directory in the source directory, and it can't contain .. to point at the parent of the build directory. no sneaky escapes 💅
  • d_debug array[str] — the D version identifiers to add while compiling D source files.
  • d_import_dirs array[inc | str], since 0.62.0 — the directories you want added to the string search path (that's the -J switch for DMD, iykyk). These have to be objects made with the include_directories function, or plain strings — plain strings get implicitly converted into inc objects for you. 🫶
  • d_module_versions array[str | int] — list of module version identifiers that get set when compiling D sources.
  • d_unittest bool, default: false — set it to true and the D modules get compiled in debug mode.
  • darwin_versions str | int | array[str], since 0.48.0 — defines the compatibility version and current version for the dylib on macOS. If you hand it an array it has to be zero, one, or two elements — those are the only valid lengths, periodt. If only one element is specified, or if it's not an array at all, that one value gets used to set both the compatibility version and the current version. And if you don't specify it at all, the soversion gets used, following the same rules above.
  • dependencies array[dep] — one or more dependency objects, made with dependency or compiler.find_library (for external deps) or declare_dependency (for deps your own project builds). ✨
  • extra_files str | file — not used for the build itself, they're just shown as source files in IDEs that group files by target (Visual Studio, looking at you). These may only be static sources, no generated stuff.
  • gnu_symbol_visibility str, since 0.48.0 — tells Meson how symbols should be exported; go check the GCC Wiki if you want the full lore. The value can be an empty string or one of default, internal, hidden, protected, or inlineshidden — and inlineshidden is the same as hidden except it also covers things like C++ implicit constructors, as spelled out in the GCC manual. Ignored on compilers that don't support GNU visibility arguments. Also peep the snippets.symbol_visibility_header() method, which helps you define your public API. 👑
  • gui_app bool, default: false, deprecated since 0.56.0 — set it to true and the target gets flagged as a GUI application on platforms where that actually makes a difference. But bestie, it's deprecated since 0.56.0 — use win_subsystem instead, ok?
  • implicit_include_directories bool, default: true, since 0.42.0 — controls whether Meson adds the current source and build directories to the include path.
  • include_directories array[inc | str] — one or more objects made with the include_directories function, or (since 0.50.0) strings, which get implicitly converted into inc objects.
  • install bool, default: false — set to true and all the outputs of this build_target get installed. all of them. 🎀
  • install_dir array[str | bool] — overrides the install directory for the outputs of this build target. If the value is a relative path, it's considered relative to the prefix option. Say you want to install plugins into a subdir — you'd do something like: install_dir : get_option('libdir') / 'projectname-1.0'.

You can also set this to an array of values to control the installation path of build targets that have multiple outputs. Right now, that means Vala. Setting an element to true means "use the default", and false means "don't install". By default the first element is true and all the other elements are false.

Since 1.11.0, passing an array is deprecated — use the install_vala_header, install_vala_vapi, and install_vala_gir keyword arguments instead. 💀
  • install_mode array[str | int], since 0.47.0 — specifies the file mode in symbolic format, and optionally the owner/uid and group/gid, for the installed files. Full details live in the install_mode kwarg of install_data — go look there.
  • install_rpath str — a string that sets the target's rpath after install (but not before that, bestie, timing matters). On Windows this argument has no effect at all.
  • install_tag str, since 0.60.0 — a string the meson install --tags command uses to install only a subset of the files. Defaults: every build target gets the tag runtime, except static libraries, which get devel.
  • install_vala_gir str | bool, since 1.11.0 — give it a string value and the vala-generated gir library gets installed to that path; give it true and the default gir path is used; give it false and the gir library isn't installed at all. It is an error for this to be either true or a string while vala_gir is unset. The default value is false.
  • install_vala_header str | bool, since 1.11.0 — give it a string value and the vala-generated header gets installed to that path; give it true and the default include path is used; give it false and the header isn't installed. The default value is false.
  • install_vala_vapi str | bool, since 1.11.0 — give it a string value and the vala-generated vapi library gets installed to that path; give it true and the default vapi path is used; give it false and the vapi library isn't installed. The default value is false.
  • link_args array[str] — flags to use during linking. You can use UNIX-style flags here, on all platforms, no cap.
  • link_depends str | file | custom_tgt | custom_idx — strings, files, or custom targets that the link step depends on, like a symbol visibility map. The whole point: it automatically triggers a re-link (but not a re-compile) of the target whenever this file changes. 🔥
  • link_early_args array[str] — flags to use during linking, just like link_args, except these get inserted into the linker command line before any object files or libraries. UNIX-style flags work here on all platforms. Only supported when you're using the Ninja backend though.
  • link_language str, since 0.51.0 — forces the linker for this target to be for the language you name. Honestly it's generally unnecessary, because Meson detects the right linker in most cases. There are only two situations where you actually need it: one, your main function in an executable isn't in the language Meson picked; or two, you want to force a library to use only one ABI.
Heads up: this was broken until 0.55.0. 😭
  • link_whole array[lib | custom_tgt | custom_idx], since 0.40.0 — links all the contents of the given static libraries, whether they're used or not. Equivalent to GCC's -Wl,--whole-archive argument flag, or the ´/WHOLEARCHIVE' MSVC linker option. This is the move that lets the linked target re-export symbols from every object in those static libraries. ✨

Since 0.41.0: if you pass an array, that array gets flattened.

Since 0.51.0: this argument also accepts outputs produced by custom targets — but you, the user, have to make sure that output is actually a library in the correct format. Meson's not checking that for you.

  • link_with array[lib | custom_tgt | custom_idx] — one or more shared or static libraries (built by this project) that this target should be linked with. Since 0.41.0: if you pass an array, that array gets flattened. Since 0.51.0: the arguments can also be custom targets — in that case Meson assumes that merely adding the output file in the linker command line is enough to make linking work. If that isn't enough, then guess what: the build system writer has to write all the other steps manually. 🙈
  • name_prefix str — the string used as the prefix for the target's output filename, overriding the default (only used for libraries). Default: lib on all platforms and compilers, except MSVC shared libraries where it's omitted to follow convention, and Cygwin shared libraries where it's cyg.

Want to conditionally keep the default behavior? Use a default object. For Meson < 1.12, use [].

  • name_suffix str — the string used as the extension for the target, overriding the default. By default on Windows this is exe for executables, and on other platforms it's omitted.

For shared libraries, the default is dylib on macOS, dll on Windows, and so everywhere else. For static libraries, it's a everywhere. By convention MSVC static libraries use the lib suffix — but we use a to dodge a potential name clash with shared libraries, which also generate import libraries with a lib suffix. 💅

Same deal as above for keeping the default conditionally: use a default object, and for Meson < 1.12 use [].

  • native bool, default: false — controls whether the target is compiled for the build machines or the host machines.
  • objects array[extracted_obj | file | str] — list of object files that should be linked into this target.

Since 1.1.0 this can include generated files, on top of object files you don't have the source for or object files produced by other build targets. In earlier releases, generated object files had to be shoved into sources instead.

  • override_options array[str] | dict[str | bool | int | array[str]], since 0.40.0 — takes an array of strings in the same format as project's default_options, overriding those option values for this target only. Since 1.2.0 you can pass a dictionary too. 🦋
  • pic bool, since 0.36.0 — builds the library as positional independent code, so it can be linked into a shared library. This option has no effect on Windows and OS X — it doesn't make sense on Windows, and PIC can't be disabled on OS X, so there's nothing for it to do. 🧚
  • prelink bool, since 0.57.0 — set this to true and the object files in the target get prelinked, meaning the target holds one single prelinked object file instead of a whole bunch of individual ones. lowkey tidy ✨
  • rust_abi str, since 1.3.0 — picks the specific ABI to compile with (only matters when you're compiling rust, obvs).
    • 'rust' (the default) — creates an "rlib" or "dylib" crate, depending on which library type you're building.
    • 'c' — creates a "cdylib" or "staticlib" crate, depending on which library type you're building.
  • rust_crate_type str, deprecated since 1.3.0, since 0.42.0 — sets the specific type of rust crate to compile (when compiling rust, bestie).

If the target is an executable this defaults to "bin", which is the only allowed value there. periodt.

If it's a static_library it defaults to "lib", and it may be "lib", "staticlib", or "rlib". If it's "lib" then Rustc picks a default, "staticlib" means a C ABI library, and "rlib" means a Rust ABI.

If it's a shared_library it defaults to "lib", and it may be "lib", "dylib", "cdylib", or "proc-macro". If it's "lib" then Rustc picks a default, "cdylib" means a C ABI library, "dylib" means a Rust ABI, and "proc-macro" is a special rust procedural macro crate.

"proc-macro" is new in 0.62.0 🎀

Since 1.3.0 this is deprecated and replaced by the "rust_abi" keyword argument. proc_macro crates are now handled by the rust.proc_macro()[9] method. so don't use this one, iykyk 💅

  • rust_dependency_map dict[str], since 1.2.0 — on rust targets this lets you give custom names to the crates that get linked into the target. like, passing a dependency map of { 'gtk4': 'gtk' } has exactly the same effect as writing gtk.package = "gtk4" in the dependencies section of a Cargo.toml file, or extern crate gtk4 as gtk inside Rust code. same vibe, different font 🫶

Since 1.10.0, the keys can be either crate names or target names.

  • shortname str, since 1.10.0 — a string specifying a DLL name that fits the 8.3 limit on OS/2 for this shared library. niche but we respect it 💖
  • sources str | file | custom_tgt | custom_idx | generated_list | structured_src — extra source files. same thing as the source varargs, just as a kwarg.
  • soversion str | int — a string or integer specifying the soversion of this shared library, like 0. on Linux and Windows this sets the soversion (or equivalent) in the filename. for example, if soversion is 4, a Windows DLL will be called foo-4.dll and one of the aliases of the Linux shared library would be libfoo.so.4. if you don't specify it, the first part of version is used instead (see below 👇). for example, if version is 3.6.0 and soversion isn't defined, it gets set to 3. math is mathing ✨
  • vala_gir str — if you set it, it generates a GIR file with the given name. if it's unset then literally no GIR file gets generated. no cap.
  • vala_header str — on Vala targets, this is your way to override the name of the generated C compatible header, for targets that generate them.

If it's not set the default gets calculated from the target's name.

  • vala_shared_args array[str | file], since 1.3.0 — arguments that are only passed to a shared library. like vala_args, except files are allowed in addition to strings 🦋
  • vala_static_args array[str | file], since 1.3.0 — arguments that are only passed to a static library. like vala_args, except files are allowed in addition to strings 🌸
  • vala_vapi str — on Vala targets, this is your way to override the name of the generated VAPI file.

If it's not set the default gets calculated from the target's name.

  • version str — a string specifying the version of this shared library, like 1.1.0. on Linux and OS X this sets the shared library version in the filename, like libfoo.so.1.1.0 and libfoo.1.1.0.dylib. if you don't specify it, soversion is used instead (see above 👆).
  • vs_module_defs str | file | custom_tgt | custom_idx — specify a Microsoft module definition file for controlling symbol exports, etc., on platforms where that's even possible (e.g. Windows).

(Since 1.3.0) custom_idx is supported 💫

  • win_subsystem str, default: 'console', since 0.56.0 — specifies the subsystem type to use on the Windows platform. typical values include console for text mode programs and windows for gui apps. the value can also contain a version specification like windows,6.0. see MSDN documentation[10] for the full list 👑

build_target() 🧚

✨ SYNOPSIS ✨

build_tgt build_target(
    target_name,
    source...,
    <lang>_args:,
    <lang>_pch:,
    <lang>_shared_args:,
    <lang>_static_args:,
    android_exe_type: 'executable',
    build_by_default: true,
    build_rpath:,
    build_subdir:,
    d_debug:,
    d_import_dirs:,
    d_module_versions:,
    d_unittest: false,
    darwin_versions:,
    dependencies:,
    export_dynamic:,
    extra_files:,
    gnu_symbol_visibility:,
    gui_app: false,
    implib:,
    implicit_include_directories: true,
    include_directories:,
    install: false,
    install_dir:,
    install_mode:,
    install_rpath:,
    install_tag:,
    install_vala_gir:,
    install_vala_header:,
    install_vala_vapi:,
    java_resources:,
    link_args:,
    link_depends:,
    link_early_args:,
    link_language:,
    link_whole:,
    link_with:,
    main_class:,
    name_prefix:,
    name_suffix:,
    native: false,
    objects:,
    override_options:,
    pic:,
    pie:,
    prelink:,
    rust_abi:,
    rust_crate_type:,
    rust_dependency_map:,
    shortname:,
    sources:,
    soversion:,
    target_type:,
    vala_gir:,
    vala_header:,
    vala_shared_args:,
    vala_static_args:,
    vala_vapi:,
    version:,
    vs_module_defs:,
    win_subsystem: 'console',
)

💖 DESCRIPTION 💖

Creates a build target whose type can be set dynamically with the target_type keyword argument. it's giving "one function to rule them all" fr fr 👑

target_type may be set to one of:

  • executable (see executable)
  • shared_library (see shared_library)
  • shared_module (see shared_module)
  • static_library (see static_library)
  • both_libraries (see both_libraries)
  • library (see library)
  • jar (see jar)*

This declaration:

executable(<arguments and keyword arguments>)

is equivalent to this:

build_target(<arguments and keyword arguments>, target_type : 'executable')

The arrays for the kwargs (such as sources, objects, and dependencies) are always flattened, which means you can freely nest and add arrays while creating the final array. go off, nest away 🪆✨

The returned object also has methods that are documented in build_tgt.

*"jar" is deprecated because it is fundamentally a different thing than the other build_target types. like bestie, it's not like the others 💀

🌸 POSARGS 🌸

  • target_name str, required — the unique name of the build target. give it a good one 🎀

🦋 VARARGS 🦋

  • source str | file | custom_tgt | custom_idx | generated_list, 0...N times — the input source to compile. the following types are supported:
    • Strings relative to the current source directory
    • file objects defined in any preceding build file
    • The return value of configure-time generators such as configure_file
    • The return value of build-time generators such as custom_target or generator.process

these input files can be sources, objects, libraries, or literally any other file. Meson will automatically categorize them based on the extension and use them accordingly. for instance, sources (.c, .cpp, .vala, .rs, etc) get compiled and objects (.o, .obj) and libraries (.so, .dll, etc) get linked. she just knows 💅

With the Ninja backend, Meson will create a build-time order-only dependency[3] on all generated input files, including unknown files. this is needed to bootstrap the generation of the real dependencies in the depfile[4] generated by your compiler, to determine when to rebuild sources. Ninja relies on this dependency file for all input files, generated and non-generated. the behavior is similar for other backends. no thoughts, just bootstrapping 🫶

🔥 KWARGS 🔥

  • <lang>_args array[str | file] — compiler flags to use for the given language; eg: cpp_args for C++ ⭐
  • <lang>_pch str — precompiled header file to use for the given language
  • <lang>_shared_args array[str], since 1.3.0 — arguments that are only passed to a shared library
  • <lang>_static_args array[str], since 1.3.0 — arguments that are only passed to a static library
  • android_exe_type str, default: 'executable', since 1.8.0 — specifies the intended target of the executable. this can either be executable, if the intended usecase is to run the executable using fork + exec, or application if the executable is supposed to be loaded as shared object by the android runtime. choose wisely 🍓
  • build_by_default bool, default: true, since 0.38.0 — when you set it to true, this target gets built by default. that means it'll be built when meson compile is called without any arguments. the default value is true for all built target types. she's a main character by default 👑
  • build_rpath str, since 0.42.0 — a string to add to the target's rpath definition in the build dir, but which will be removed on install 🙈

build_subdir — str, since 1.10.0

Okay so instead of yeeting your build results straight into the build directory, this drops them into a subdirectory with the name you give it. Bestie, note that this does not touch the install directory — that one still uses install_dir, they're two separate vibes 💅.

Why would you want this? Two iconic reasons: you need a directory name shoved into the build path so you can actually use the build result while building other targets, or you've got multiple targets with the same basename and you need to give each one a unique build_subdir value so they don't fight. Slay.

🚩 But no funny business: to prevent collisions inside the build directory, build_subdir is not allowed to match a file or directory in the source directory, and it can't contain '..' to refer to the parent of the build directory. Periodt.

d_debug — array[str]

The D version identifiers[5] you want to add while compiling D source files. That's it, that's the whole thing 🫶.

d_import_dirs — array[inc | str], since 0.62.0

The directories you're adding to the string search path (i.e. the -J switch for DMD, iykyk). These have to be objects made with the include_directories function, or plain strings — and the strings get implicitly converted into inc objects for you, no cap ✨.

d_module_versions — array[str | int]

A list of the module version identifiers that get set when compiling D sources.

d_unittest — bool, default: false

Set it to true and your D modules get compiled in debug mode. Simple as that 🦋.

darwin_versions — str | int | array[str], since 0.48.0

Defines the compatibility version and the current version for the dylib on macOS 🍓.

  • If you hand it an array, it has to have either zero, one, or two elements. Those are the only options, don't try anything else.
  • If you only give one element, or you don't give an array at all, that one value gets used for setting both the compatibility version and the current version. Two for the price of one, we love efficiency.
  • If you specify nothing at all, the soversion gets used, following the rules we just laid out above 👑

dependencies — array[dep]

One or more dependency objects, made either with dependency, or with compiler.find_library (for external deps), or with declare_dependency (for deps built by the project). Pick your fighter 💜.

export_dynamic — bool, since 0.45.0

Set it to true and it causes the target's symbols to be dynamically exported — which means modules built with the shared_module function can refer to functions, variables and other symbols defined in the executable itself. Basically it lets your modules peek at the executable's stuff 🔥.

extra_files — str | file

Not used for the build itself at all — these are just shown as source files in IDEs that group files by targets (Visual Studio, looking at you 👀).

Heads up: these may only be static sources.

gnu_symbol_visibility — str, since 0.48.0

Specifies how symbols should be exported — go check the GCC Wiki[6] if you want the deep lore. This value can either be an empty string, or one of default, internal, hidden, protected, or inlineshidden. And inlineshidden? That's the same as hidden but it also includes things like C++ implicit constructors, as specified in the GCC manual. Fancy.

It's ignored on compilers that don't support GNU visibility arguments, so don't stress if it does nothing there 🧚.

Also peep the snippets.symbol_visibility_header()[7] method, which helps you out with defining public API. Bestie behaviour fr.

gui_app — bool, default: false, deprecated since 0.56.0

When set to true this flags the target as a GUI application on platforms where that actually makes a difference. Deprecated since 0.56.0 — use win_subsystem instead, okay? Don't be using the old one 😭.

implib — bool | str, since 0.42.0

When you set this to a string, that string becomes the name of a generated import library.

⚠️ Since 1.10.0, passing a boolean value here is deprecated.

When set to true, an import library gets generated for the executable (and the name of that import library is based on exe_name). Alternatively, when it's a string, that gives the base name for the import library.

The import library gets used when the returned build target object shows up in link_with: somewhere else. It only has any effect on platforms where that's meaningful (e.g. Windows, obviously 💀). And it implies the export_dynamic argument — sneaky little bonus.

implicit_include_directories — bool, default: true, since 0.42.0

Controls whether Meson adds the current source directory and build directory to the include path. That's the whole vibe check.

include_directories — array[inc | str]

One or more objects created with the include_directories function — or, since 0.50.0, strings, which get implicitly converted into inc objects for you 🌸.

install — bool, default: false

Set it to true and all outputs of this build_target will be installed. All of them. Every last one 👑.

install_dir — array[str | bool]

Override the install directory for the outputs of this build target 💖. If the value is a relative path, it gets considered relative to the prefix option. So like, if you want to install plugins into a subdir, you'd do something like this:

install_dir : get_option('libdir') / 'projectname-1.0'

You can also set this to an array of values to control the installation path of build targets that have multiple outputs. Currently, that means Vala. Setting an element to true means "use the default", and false means... don't install it, bestie 🙈. By default the first element is true, and all the other elements are false.

⚠️ Since 1.11.0, passing an array is deprecated, and you should be using the install_vala_header, install_vala_vapi, and install_vala_gir keyword arguments instead. Moving on up ✨.

install_mode — array[str | int], since 0.47.0

Specify the file mode in symbolic format, and optionally the owner/uid and group/gid, for the installed files 🎀.

Peep the install_mode kwarg of install_data for more info on how that works.

install_rpath — str

A string that sets the target's rpath to after install (but not before that, mind you). On Windows, this argument has literally no effect, so don't even try it 🦋.

install_tag — str, since 0.60.0

A string used by the meson install --tags command so you can install only a subset of the files — very "I only want these files" of you 💅. By default, all build targets have the tag runtime, except for static libraries, which have the devel tag. Iconic differentiation.

install_vala_gir — str | bool, since 1.11.0

If you set a string value, the vala generated gir library gets installed to that path. If you set it to true, the default gir path gets used. If it's false, the gir library will not be installed, periodt.

🚩 It is an error for this to be either true or a string while vala_gir is unset. Don't do that.

The default value is false.

install_vala_header — str | bool, since 1.11.0

If you set a string value, the vala generated header gets installed to that path. If it's true, the default include path gets used. If it's false, the header will not be installed.

The default value is false 🌈.

install_vala_vapi — str | bool, since 1.11.0

If you set a string value, the vala generated vapi library gets installed to that path. If it's true, the default vapi path gets used. If it's false, the vapi library will not be installed.

The default value is false ⭐.

java_resources — structured_src, since 0.62.0

Resources to be added to the jar. Short and sweet 🍓.

Flags to use during linking 🔥. You can use UNIX-style flags here on all platforms, so don't worry about platform-matching your flag syntax.

Strings, files, or custom targets that the link step depends on — like a symbol visibility map, for example. The whole point is that it automatically triggers a re-link (but not a re-compile) of the target whenever this file changes. Sneaky little dependency, we respect it 🫶.

Flags to use during linking — these are just like link_args, except they get inserted into the linker command line before any object files or libraries 🎀. You can use UNIX-style flags here on all platforms. Only supported when you're using the Ninja backend, so heads up on that one.

Makes the linker for this target be for the language you specify. Honestly, it's generally unnecessary to set this, because Meson will detect the right linker to use in most cases — she's smart like that 💅.

There are only two cases where you actually need it:

  1. Your main function in an executable isn't in the language Meson picked.
  2. You want to force a library to use only one ABI.
💀 Fun fact: this was broken until 0.55.0. Glad we're past that era.

Links all the contents of the given static libraries whether they're used or not — equivalent to the -Wl,--whole-archive argument flag of GCC, or the ´/WHOLEARCHIVE' MSVC linker option. This is what lets the linked target re-export symbols from all objects in those static libraries. Whole archive energy 👑

  • (since 0.41.0) If you pass an array, that array will be flattened.
  • (since 0.51.0) This argument also accepts outputs produced by custom targets — but the user must ensure that the output is a library in the correct format. That part's on you, bestie 🙈.

One or more shared or static libraries (built by this project) that this target should be linked with 💜.

  • (since 0.41.0) If you pass an array, that array will be flattened.
  • (since 0.51.0) The arguments can also be custom targets. In that case Meson will assume that merely adding the output file in the linker command line is sufficient to make linking work. If that's not sufficient, then the build system writer must write all other steps manually. No hand-holding there 😭.

main_class — str

Main class for running the built jar. That's the one 🫶.

name_prefix — str

The string that gets used as the prefix for the target output filename by overriding the default (and it's only used for libraries, fyi). By default this is lib on all platforms and compilers — except for MSVC shared libraries, where it's omitted to follow convention, and Cygwin shared libraries, where it's cyg 🦋.

To conditionally keep the default behaviour, use a default object. For Meson < 1.12, use [].

name_suffix — str

The string that gets used as the extension for the target by overriding the default. By default on Windows this is exe for executables, and on other platforms it's simply omitted 🎀.

For shared libraries, the default value is dylib on macOS, dll on Windows, and so everywhere else. For static libraries, it's a everywhere. By convention MSVC static libraries use the lib suffix, but we use a to avoid a potential name clash with shared libraries, which also generate import libraries with a lib suffix. Avoiding drama, we love to see it ✨.

To conditionally keep the default behaviour, use a default object. For Meson < 1.12, use [].

  • native bool, default: false — controls whether the target gets compiled for the build machines or the host machines. pick your fighter 💅
  • objects array[extracted_obj | file | str] — a list of object files that should be linked into this target. since 1.1.0 this can also include generated files, on top of object files you don't have sources for or object files produced by other build targets. bestie, in earlier releases those generated object files had to go in sources instead, so heads up if you're on an old version 😭
  • override_options array[str] | dict[str | bool | int | array[str]], since 0.40.0 — takes an array of strings in the exact same format as project's default_options, and overrides the values of those options for this target only. (since 1.2.0): a dictionary may now be passed too. so fancy ✨
  • pic bool, since 0.36.0 — builds the library as positional independent code (so it can be linked into a shared library). this option has no effect on Windows and OS X, since it doesn't make sense on Windows and PIC literally cannot be disabled on OS X 🫠
  • pie bool, since 0.49.0 — build a position-independent executable. that's it, that's the vibe 🔥
  • prelink bool, since 0.57.0 — if true, the object files in the target will be prelinked, meaning it'll contain only one prelinked object file rather than the individual object files. one file to rule them all 👑
  • rust_abi str, since 1.3.0 — sets the specific ABI to compile (when compiling rust, obviously 🦀):
    • 'rust' (default): create a "rlib" or "dylib" crate depending on the library type being build.
    • 'c': create a "cdylib" or "staticlib" crate depending on the library type being build.
  • rust_crate_type str, deprecated since 1.3.0, since 0.42.0 — sets the specific type of rust crate to compile (again, when compiling rust).

if the target is an executable this defaults to "bin", which is the only allowed value.

if it's a static_library it defaults to "lib", and may be "lib", "staticlib", or "rlib". if "lib" then Rustc will pick a default, "staticlib" means a C ABI library, "rlib" means a Rust ABI.

if it's a shared_library it defaults to "lib", and may be "lib", "dylib", "cdylib", or "proc-macro". if "lib" then Rustc will pick a default, "cdylib" means a C ABI library, "dylib" means a Rust ABI, and "proc-macro" is a special rust procedural macro crate.

"proc-macro" is new in 0.62.0 🌱

since 1.3.0 this is deprecated and replaced by the "rust_abi" keyword argument. proc_macro crates are now handled by the rust.proc_macro()[8] method instead. so like... stop using it, bestie 💀
  • rust_dependency_map dict[str], since 1.2.0 — on rust targets this lets you give custom names to the crates that get linked into the target. for example, passing a dependency map of { 'gtk4': 'gtk' } has the same effect as writing gtk.package = "gtk4" in the dependencies section of a Cargo.toml file, or writing extern crate gtk4 as gtk inside Rust code. same energy, different font 🦋

since 1.10.0, the keys can be either crate names or target names. flexible queen 💅

  • shortname str, since 1.10.0 — a string specifying a DLL name fitting to the 8.3 limit on OS/2 of this shared library. retro constraints, love that for us 🎀
  • sources str | file | custom_tgt | custom_idx | generated_list | structured_src — additional source files. same as the source varargs, no cap.
  • soversion str | int — a string or integer specifying the soversion of this shared library, such as 0. on Linux and Windows this is used to set the soversion (or equivalent) in the filename. for example, if soversion is 4, a Windows DLL will be called foo-4.dll and one of the aliases of the Linux shared library would be libfoo.so.4. if this isn't specified, the first part of version is used instead (see below 👇). for example, if version is 3.6.0 and soversion is not defined, it's set to 3. math is mathing 🧮
  • target_type str — the actual target type to build. straightforward, we stan ✨
  • vala_gir str — if set, generates a GIR file with the given name. if this is unset then no GIR file will be generated. all or nothing, honestly iconic 🌸
  • vala_header str — on Vala targets, this provides a way to override the name of the generated C compatible header for targets that generate them.

if it's not set, the default will be calculated from the target's name. she'll figure it out 💖

  • vala_shared_args array[str | file], since 1.3.0 — arguments that are only passed to a shared library. like vala_args, files is allowed in addition to string.
  • vala_static_args array[str | file], since 1.3.0 — arguments that are only passed to a static library. like vala_args, files is allowed in addition to string. yes it's the twin, we love a matched set 🫶
  • vala_vapi str — on Vala targets, this provides a way to override the name of the generated VAPI file.

if it's not set, the default will be calculated from the target's name.

  • version str — a string specifying the version of this shared library, such as 1.1.0. on Linux and OS X, this is used to set the shared library version in the filename, such as libfoo.so.1.1.0 and libfoo.1.1.0.dylib. if this isn't specified, soversion is used instead (see above 👆).
  • vs_module_defs str | file | custom_tgt | custom_idx, since 1.3.0 — specify a Microsoft module definition file for controlling symbol exports, etc., on platforms where that's possible (e.g. Windows).

this can be used to expose which functions a shared_module loaded by an executable will be allowed to use. gatekeeping, but make it linker 🤭

  • win_subsystem str, default: 'console', since 0.56.0 — specifies the subsystem type to use on the Windows platform. typical values include console for text mode programs and windows for gui apps. the value can also contain version specification such as windows,6.0. see MSDN documentation[9] for the full list. windows being windows, but make it slay 💀

🎀 configuration_data() 🎀

SYNOPSIS

cfg_data configuration_data([data])

DESCRIPTION

creates an empty configuration object. you should add your configuration with the cfg_data method calls and finally use it in a call to configure_file. that's the whole pipeline, babe ✨

OPTARGS

  • data dict[str | bool | int], since 0.49.0 — optional dictionary to specify an initial data set. if provided, each key/value pair is added into the cfg_data object as if the cfg_data.set method was called for each of them. pre-loading the vibes, we love efficiency 💅

🦋 configure_file() 🦋

SYNOPSIS

file configure_file(
    build_subdir:,
    capture: false,
    command:,
    configuration:,
    copy: false,
    depfile:,
    encoding: 'utf-8',
    format: 'meson',
    input:,
    install: false,
    install_dir:,
    install_mode:,
    install_tag:,
    macro_name:,
    output:,
    output_format:,
)

DESCRIPTION

okay so this function is lowkey a triple threat — it can run in three modes depending on the keyword arguments you pass to it 👑

when a cfg_data object is passed to the configuration: keyword argument, it takes a template file as the input: (optional) and produces the output: (required) by substituting values from the configuration data as detailed in the configuration file documentation[11]. (since 0.49.0) a dictionary can be passed instead of a cfg_data object. glow up 💖

when an array of strings is passed to the command: keyword argument, it takes any source or configured file as the input: and assumes that the output: is produced when the specified command is run. you built the machine, she runs it 🔥

you can install the outputted file with the install_dir: kwarg, see below 👇

(since 0.47.0) when the copy: keyword argument is set to true, this function will copy the file provided in input: to a file in the current build directory with the name provided in output:. the copy happens at configuration. if the input file is subsequently modified, Meson will regenerate the build files. to perform the copy at build time (with the usual dependency on the source file) use copyfile() from the FS (filesystem) module. don't mix these two up bestie, they are not the same 😭

KWARGS

  • build_subdir str, since 1.10.0 — places the build results in a subdirectory of the given name rather than directly into the build directory. this does not affect the install directory, which uses install_dir. this allows inserting a directory name into the build path, either when it's needed to use the build result while building other targets, or as a way to support multiple targets with the same basename by using unique build_subdir values for each one.
to prevent collisions within the build directory, build_subdir is not allowed to match a file or directory in the source directory, nor contain '..' to refer to the parent of the build directory. no sneaky path escaping, we see you 🙈
  • capture bool, default: false, since 0.41.0 — when this argument is set to true, Meson captures stdout of the command and writes it to the target file specified as output. catching strays, but make it intentional 🎀
  • command array[str | file] — as explained above, if specified, Meson does not create the file itself but rather runs the specified command, which allows you to do fully custom file generation. (since 0.52.0) the command can contain file objects and more than one file can be passed to the input keyword argument, see custom_target for details about string substitutions. full DIY mode 🛠️
  • configuration cfg_data | dict[str | int | bool] — as explained above, when passed this will provide the replacement data for the input file (if provided) or key value pairs to be written to the output.
  • copy bool, default: false, since 0.47.0 — as explained above, if specified Meson only copies the file from input to output. simple. elegant. effective 💅
  • depfile str, since 0.52.0 — a dependency file that the command can write listing all the additional files this target depends on. a change in any one of these files triggers a reconfiguration. she's watching 👀
  • encoding str, default: 'utf-8', since 0.47.0 — set the file encoding for the input and output file. the supported encodings are those of python3, see standard-encodings[12]. utf-8 default because we're not monsters 💜
  • format str, default: 'meson', since 0.46.0 — the format of the defines, bestie. It defaults to 'meson', which means it substitutes #mesondefine statements plus variables wrapped in @ characters. You can also use 'cmake' to swap out #cmakedefine statements and variables using the ${variable} syntax. And finally there's 'cmake@', where substitutions apply to #cmakedefine statements and variables using the @variable@ syntax. Three flavors, pick your fighter ✨
  • input str | file — the input file name. If you don't specify it in configuration mode, then every single variable in the configuration: object (see above, bb) gets written to the output: file. That's the whole vibe 🫶
  • install bool, default: false, since 0.50.0 — when true, this generated file gets installed during the install step, and install_dir must be set and not empty (no cap, it's required). When false, the file is not installed no matter what install_dir says — it literally does not care. When omitted, it defaults to true if install_dir is set and not empty, and false otherwise. So it's lowkey smart about it 💅
  • install_dir str — the subdirectory to install the generated file to (like share/myproject). If it's omitted, or you hand it an empty string, the file just doesn't get installed. Simple as that 🎀
  • install_mode array[str | int], since 0.47.0 — specify the file mode in symbolic format, and optionally the owner/uid and group/gid for the installed files.

See the install_mode kwarg of install_data for more info — that's where the real lore lives 📚

  • install_tag str, since 0.60.0 — a string used by the meson install --tags command so you can install only a subset of the files. By default the file has no install tag, which means it does not get installed when you pass the --tags argument. Tagless behavior, honestly relatable 🙈
  • macro_name str, since 1.3.0 — when specified, macro guards get used instead of '#pragma once'. The macro guard name will be exactly the name you specified. Fancy ✨
  • output str — the output file name. (since 0.41.0) it may contain @PLAINNAME@ or @BASENAME@ substitutions, plus (since 1.5.0) their indexed versions, like @PLAINNAME0@ or @BASENAME0@. In configuration mode, the permissions of the input file (if you specified one) get copied over to the output file 👑
  • output_format str, since 0.47.0 — the format of the output to generate when no input was specified. It defaults to c, in which case preprocessor directives get prefixed with #. You can also use nasm, where the prefix is %. And (since 1.3.0) the json format is available too. Three formats, all valid, all iconic 🌈

⚠️ WARNINGS

Heads up, bestie, this one matters: the install_mode kwarg ignored integer values between 0.62 -- 1.1.0. So if you're on a version in that range and you passed ints, they were literally being ignored. Not me finding that out the hard way 😭


💅 custom_target()

SYNOPSIS

custom_tgt custom_target(
    [name],
    build_always:,
    build_always_stale: false,
    build_by_default:,
    build_subdir:,
    capture: false,
    command:,
    console:,
    depend_files:,
    depends:,
    depfile:,
    env:,
    feed: false,
    input:,
    install:,
    install_dir:,
    install_mode:,
    install_tag:,
    output:,
)

DESCRIPTION

Create a custom top level build target 🛠️ The only positional argument is the name of this target, and it cannot contain path separators (/ or \). Also, the name of a custom target might not be used by every backend — for instance, with the Ninja backend, if subdir/meson.build contains the example below, then ninja -C builddir foo or ninja -C builddir subdir/foo won't work. It's instead ninja -C builddir subdir/file.txt. But, plot twist, meson compile subdir/foo is accepted 👑

custom_target('foo', output: 'file.txt', ...)

The files passed to output: cannot contain path separators. See the manual on custom build targets[13] for the whole explanation on where output files should be placed. Trust the manual, it's giving wisdom 💖

You can install the outputted files with the install_dir: kwarg, see below.

Since 0.60.0 the name argument is optional and defaults to the basename of the first output (file.txt in the example above). Convenient or what 🎀

The array of strings passed to the command keyword argument accepts the following special string substitutions:

  • @INPUT@: the full path to the input passed to input. If more than one input is specified, all of them will be substituted as separate arguments only if the command uses '@INPUT@' as a standalone-argument. For instance, this would not work: command : ['cp', './@INPUT@'], but this would: command : ['cp', '@INPUT@']. Standalone or it doesn't count, periodt 💅
  • @OUTPUT@: the full path to the output passed to output. If more than one output is specified, the behavior is the same as @INPUT@.
  • @INPUT0@ @INPUT1@ ...: the full path to the input with the specified array index in input
  • @OUTPUT0@ @OUTPUT1@ ...: the full path to the output with the specified array index in output
  • @OUTDIR@: the full path to the directory where the output(s) must be written
  • @DEPFILE@: the full path to the dependency file passed to depfile
  • @PLAINNAME@: the input filename, without a path
  • @PLAINNAME0@ @PLAINNAME1@ ... (since 1.5.0): the input filename without a path, with the specified array index in input
  • @BASENAME@: the input filename, with extension removed
  • @BASENAME0@ @BASENAME1@ ... (since 1.5.0): the input filename with extension removed, with the specified array index in input
  • @PRIVATE_DIR@ (since 0.50.1): path to a directory where the custom target must store all its intermediate files.
  • @SOURCE_ROOT@: the path to the root of the source tree. Depending on the backend, this may be an absolute path or a path relative to the current workdir.
  • @BUILD_ROOT@: the path to the root of the build tree. Depending on the backend, this may be an absolute path or a path relative to the current workdir.
  • @CURRENT_SOURCE_DIR@: this is the directory where the currently processed meson.build is located in. Depending on the backend, this may be an absolute path or a path relative to the current workdir.

(since 0.47.0) The depfile keyword argument also accepts the @BASENAME@ and @PLAINNAME@ substitutions. Equality, we love to see it ✨

The returned object also has methods that are documented in custom_tgt.

OPTARGS

  • name str — the unique id of the custom target.

This posarg is optional since 0.60.0. It defaults to the basename of the first output. Slay, defaults 🦋

KWARGS

  • build_always bool, deprecated since 0.47.0 — if true, this target is always considered out of date and gets rebuilt every single time. It's equivalent to setting both build_always_stale and build_by_default to true. It's deprecated though, so maybe don't fr fr 💀
  • build_always_stale bool, default: false, since 0.47.0 — if true the target is always considered out of date. Useful for things like build timestamps or revision control tags. The associated command runs even if the outputs are already up to date. Chaotic but on purpose 🔥
  • build_by_default bool, since 0.38.0 — when set to true, it causes this target to be built by default. That means it gets built when meson compile is called without any arguments. The default value is false.

(since 0.50.0) If build_by_default is explicitly set to false, install will no longer override it. If build_by_default is not set, install will still determine its default. Boundaries, we love them 💅

  • build_subdir str, since 1.10.0 — places the build results in a subdirectory of the given name rather than directly into the build directory. This does not affect the install directory, which uses install_dir. This lets you insert a directory name into the build path — either when you need it to use the build result while building other targets, or as a way to support multiple targets with the same basename by giving each one a unique build_subdir value. To prevent collisions inside the build directory, build_subdir is not allowed to match a file or directory in the source directory, nor to contain '..' to refer to the parent of the build directory. Safety first, bestie 🎀
  • capture bool, default: false — some compilers can't be told to write their output to a file and instead write it to standard output. When this argument is set to true, Meson captures stdout and writes it to the target file. Note that your command argument array may not contain @OUTPUT@ when capture mode is active. No @OUTPUT@ and capture mode together, that's the rule 🚫
  • command array[str | file | exe | program] — the command to run to create outputs from inputs. The command may be strings or the return value of functions that return file-like objects such as find_program, executable, configure_file, files, custom_target, etc. Meson will automatically insert the appropriate dependencies on targets and files listed in this keyword argument. Note: always specify commands in array form ['commandname', '-arg1', '-arg2'] rather than as a string 'commandname -arg1 -arg2', because the latter will not work. Array form or it's a no from Meson 😤

Note: due to an [issue with path handling[14] any backslash (\) characters are rewritten as slash (/). Yeah, they just get converted, iykyk 🙈

  • console bool, since 0.48.0 — this keyword argument conflicts with capture, and it's meant for commands that are resource-intensive and take a long time to finish. With the Ninja backend, setting this adds the target to Ninja's console pool[15], which has special properties such as not buffering stdout and serializing all targets in this pool. Main character energy for your slowest build step 👑
  • depend_files array[str | file] — files (str, file, or the return value of configure_file) that this target depends on but that aren't listed in the command keyword argument. Useful for adding regen dependencies. Sneaky little deps, we still love them 🫶
  • depends array[build_tgt | custom_tgt | custom_idx | program] — specifies that this target depends on the specified target(s), even though it doesn't take any of them as a command line argument. This is meant for cases where you have a tool that, like, does globbing internally. Usually you should just put the generated sources as inputs and Meson will set up all the dependencies automatically (custom_idx was unavailable as a type between 0.60 and 1.4.0). program is supported since 1.11.2. Know your versions, bb 💜
  • depfile str — a dependency file that the command is allowed to write, listing every extra file this target depends on. Like, a C compiler would dump all the headers it pulled in, and if any one of those changes, boom, recompilation. ✨ (since 0.47.0) the @BASENAME@ and @PLAINNAME@ substitutions are also accepted here, slay.
  • env env | array[str] | dict[str], since 0.57.0 — environment variables to set! Something like {'NAME1': 'value1', 'NAME2': 'value2'} or ['NAME1=value1', 'NAME2=value2'], or an env object if you wanna do more sophisticated environment juggling. 💅
  • feed bool, default: false, since 0.59.0 — so there are some compilers that literally can't be told to read their input from a file and instead read it from standard input 😭. When this argument is true, Meson feeds the input file to stdin. Heads up though: your argument array may not contain @INPUT@ when feed mode is active. No cap.
  • input array[str | file | program] — array of source files. (since 0.41.0) the array is flattened. program is supported since 1.11.2. 🫶
  • install bool — when true, one or more files of this target get installed during the install step (peep install_dir for the deets).
  • install_dir str | array[str | bool] — if only one install_dir is provided, all outputs are installed there. Since 0.40.0 you can also specify the installation directory for each corresponding output, one by one. 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. iconic.

To only install some outputs, pass false for the outputs you don't want installed. Like:

        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. 🎀

  • install_mode array[str | int], since 0.47.0 — the file mode and optionally the owner/uid and group/gid. See the install_mode kwarg of install_data for more info. 🔍
  • install_tag array[str], since 0.60.0 — an array of strings, one per output, used by the meson install --tags command to install only a subset of the files.

By default all outputs have no install tag, which means they are not being installed when the --tags argument is specified. If only one tag is specified, it's assumed that all outputs have the same tag. false can be used for outputs that have no tag or aren't installed. 💅

  • output array[str] — array of output files. These absolutely cannot contain path separators, bestie. ⚠️

📝 NOTES

Assuming that command: is executed by a POSIX sh shell is not portable, notably to Windows. Instead, consider using a native: true executable, or a python script. iykyk 🐍

🚨 WARNINGS

the install_mode kwarg ignored integer values between 0.60.0 -- 1.1.0. yeah. that happened. 💀


🩺 debug()

SYNOPSIS

void debug(message, msg...)

since 0.63.0

DESCRIPTION

Write the argument string to the meson build log. That's it, that's the whole vibe. 🪵

POSARGS

  • message str | int | bool | array[str | int | bool] | dict[str | int | bool], required — the message to print 💬

VARARGS

  • msg str | int | bool | array[str | int | bool] | dict[str | int | bool], 0...N times — additional parameters will be separated by spaces 🌸

🎁 declare_dependency()

SYNOPSIS

dep declare_dependency(
    compile_args:,
    d_import_dirs:,
    d_module_versions:,
    dependencies:,
    extra_files:,
    include_directories:,
    link_args:,
    link_whole:,
    link_with:,
    objects:,
    sources:,
    variables:,
    version:,
)

DESCRIPTION

This function returns a dep object that behaves like the return value of dependency but is internal to the current build. One use case for this is in subprojects — it lets a subproject easily specify how it should be used, which makes it interchangeable with the same dependency that's provided externally by the system. Another common use case is to declare project targets as dependencies so they may be used as dependencies of other build targets. honestly? chef's kiss 👑

KWARGS

  • compile_args array[str] — compile arguments to use. 🔧
  • d_import_dirs array[inc | str], since 0.62.0 — the directories to add to the string search path (i.e. the -J switch for DMD). Must be inc objects or plain strings.
  • d_module_versions str | int | array[str | int], since 0.62.0 — the D version identifiers[5] to add during the compilation of D source files. 🅳
  • dependencies array[dep] — other dependencies needed to use this dependency.
  • extra_files array[str | file], since 1.2.0 — extra files to add to targets. mostly used for IDE integration. 🧠
  • include_directories array[inc | str] — the directories to add to header search path, must be inc objects or (since 0.50.0) plain strings.
  • link_args array[str] — link arguments to use. 🔗
  • link_whole array[lib], since 0.46.0 — libraries to link fully, same as executable.
  • link_with array[lib] — libraries to link against.
  • objects array[extracted_obj], since 1.1.0 — an array of object files, to be linked directly into the targets that use the dependency. 🧩
  • sources array[str | file | custom_tgt | custom_idx | generated_list] — sources to add to targets (or generated header files that should be built before sources including them are built). ✨
  • variables dict[str] | array[str], since 0.54.0 — a dictionary of arbitrary strings, this is meant to be used in subprojects where special variables would be provided via cmake or pkg-config. since 0.56.0 it can also be an array of 'key=value' strings. 🗂️
  • version str — the version of this dependency, such as 1.2.3. Defaults to the project version.

🌱 default()

SYNOPSIS

default default()

since 1.12.0

DESCRIPTION

Returns a default object. short and sweet, we love to see it 🎀


🔎 dependency()

SYNOPSIS

dep dependency(
    names...,
    allow_fallback:,
    default_options:,
    disabler: false,
    fallback:,
    include_type: 'preserve',
    language:,
    method: 'auto',
    native: false,
    not_found_message:,
    required: true,
    static:,
    version:,
)

DESCRIPTION

Finds an external dependency (usually a library installed on your system) with the given name using pkg-config, and with CMake[16] if pkg-config fails. Additionally, frameworks (OSX only) and library-specific fallback detection logic[17] are also supported. it's giving "we looked everywhere, bestie" 🕵️

Since 0.60.0 more than one name can be provided — they'll be tried in order and the first name to be found gets used. The fallback subproject will only be used if none of the names are found on the system. Once one of the names has been found, all the other names are added into the cache so subsequent calls for any of those names will return the same value. This is useful in case a dependency could have different names, such as png and libpng. 💅

Since 0.64.0 a dependency fallback can be provided by WrapDB. Simply download the database locally using the meson wrap update-db command and Meson will automatically fallback to subprojects provided by WrapDB if the dependency isn't found on the system and the project doesn't ship their own .wrap file. 🌈

Dependencies can also be resolved in two other ways:

  • if the same name was used in a meson.override_dependency prior to the call to dependency, the overriding dependency will be returned unconditionally; that is, the overriding dependency will be used independent of whether an external dependency is installed in the system. Typically, meson.override_dependency will have been used by a subproject. 👑
  • by a fallback subproject which, if needed, will be brought into the current build specification as if subproject() had been called. The subproject can be specified with the fallback argument. Alternatively, if the fallback argument is absent, since 0.55.0 Meson can automatically identify a subproject as a fallback if a wrap file provides[18] the dependency, or if a subproject has the same name as the dependency. In the latter case, the subproject must use meson.override_dependency to specify the replacement, or Meson will report a hard error. See the Wrap documentation[17] for more details. This automatic search can be controlled using the allow_fallback keyword argument. 🌀

If dependency_name is '', the dependency is always not found. So with required: false, this always returns a dependency object for which the found() method returns false, and which can be passed like any other dependency to the dependencies: keyword argument of a build_target. This can be used to implement a dependency which is sometimes not required, e.g. in some branches of a conditional, or with a fallback: kwarg, can be used to declare an optional dependency that only looks in the specified subproject, and only if that's allowed by --wrap-mode. 🙈

The returned object dep also has additional methods.

VARARGS

  • names str, 1...N times, since 0.60.0 — the names of the dependency to look up. The dependencies are looked up in the order they're provided here. The first found dependency will then be used. The fallback subproject will be used only if none of the names are found on the system. Once one of the names has been found, all other names are added into the cache so subsequent calls for any of those names will return the same value. This is useful in case a dependency could have different names, such as png and libpng. 🔍
NOTE: Before 0.60.0 only a single dependency name was allowed. 📌

✨ KWARGS ✨

  • allow_fallback bool, since 0.56.0 — ok so this one is literally "should Meson go find a backup plan?" 💅 It says whether Meson should automatically pick a fallback subproject when the dependency isn't found on the system. If it's true and the dependency isn't on the system, Meson falls back to a subproject that provides this dependency. If false, Meson won't fall back even if a subproject does provide it. By default Meson does the fallback thing if required is true or enabled[0]; peep the Wrap documentation[17] for the deets.
  • default_options array[str] | dict[str | bool | int | array[str]], since 0.38.0 — an array of default option values that override the ones set in the subproject's meson.options (like default_options in project — they only do anything the first time Meson runs, and command line arguments override any default options in build files). (since 1.2.0): a dictionary may now be passed. 🎀
  • disabler bool, default: false, since 0.49.0 — returns a disabler object instead of a not-found dependency if this kwarg is true and the dependency couldn't be found. no cap.
  • fallback array[str] | str — manually specifies a subproject fallback to use when the dependency isn't found on the system. Super useful if the automatic search doesn't apply to you, or if you want to support Meson versions older than 0.55.0. If the value is an array ['subproj_name', 'subproj_dep'], the first value is the subproject name and the second is the variable name in that subproject holding a dependency object — like the return value of declare_dependency or dependency, etc. Heads up tho: this means the fallback dependency may itself be a not-found dependency, in which case the value of the required: kwarg is obeyed. Since 0.54.0 the value can be a single string (the subproject name); in that case the subproject must use meson.override_dependency('dependency_name', subproj_dep) to specify the dependency object used in the superproject. And if the value is an empty array it has the same effect as allow_fallback: false. 🦋
  • include_type str, default: 'preserve', since 0.52.0 — an enum flag marking how the dependency flags should be converted. Supported values are 'preserve', 'system' and 'non-system'. System dependencies may be handled differently on some platforms, for instance using -isystem instead of -I where possible. If include_type is 'preserve', no additional conversion gets performed. periodt.
  • language str, since 0.42.0 — defines which language-specific dependency to find if it's available for multiple languages.
  • method str, default: 'auto', since 0.40.0 — defines the way the dependency is detected. Default is auto, but you can override it to e.g. qmake for Qt development, and different dependencies support different values[19] for this (though auto will work on all of them). iykyk ✨
  • native bool, default: false — if true, Meson finds the dependency on the build machine system rather than the host system (i.e. where the cross compiled binary will actually run), usually only needed if you build a tool to be used during compilation.
  • not_found_message str, since 0.50.0 — an optional string that gets printed as a message if the dependency wasn't found.
  • required bool | feature, default: true — when false, Meson will proceed with the build even if the dependency isn't found. 🫶 When set to a feature[0] option, the feature controls whether it's searched and whether to fail if it's not found. (since 0.47.0) the value of a feature option can also be passed.
  • static bool — tells the dependency provider to try to get static libraries instead of dynamic ones (note that this isn't supported by all dependency backends). Leaving this value unset results in an implementation defined default value — for most dependencies that means the value of the prefer_static option, but some custom dependencies have their own method for determining the most useful default. Since 0.60.0 it also sets default_library option accordingly on the fallback subproject if it wasn't set explicitly in the default_options keyword argument. Since 0.63.0 it's used when the prefer_static option calculates the default value.
  • version array[str] | str, since 0.37.0 — specifies the required version: a string with a comparison operator followed by the version string, examples include >1.0.0, <=2.3.5 or 3.1.4 for exact matching. You can also stack multiple restrictions by passing an array to this keyword argument, such as: ['>=3.14.0', '<=4.1.0']. These requirements are never met if the version is unknown. 😭

🌸 NOTES 🌸

This function supports additional library-specific[16] keyword arguments that may also be accepted (e.g. modules specifies submodules to use for dependencies such as Qt or Boost. components allows the user to manually add CMake COMPONENTS for the find_package lookup).


💀 disabler()

SYNOPSIS

disabler disabler()

since 0.44.0

DESCRIPTION

Returns a disabler object.


🧚 environment()

SYNOPSIS

env environment([env], method:, separator:)

since 0.35.0

DESCRIPTION

Returns an empty env object.

OPTARGS

  • env str | array[str] | dict[str] | dict[array[str]], since 0.52.0 — if provided, each key/value pair gets added into the env object as if the env.set method was called for each of them. Since 0.62.0 arrays of strings are allowed in dictionary values — in that case the values are joined using the separator. 💖

KWARGS

  • method str, since 0.62.0 — must be one of 'set', 'prepend', or 'append' (defaults to 'set'). Controls whether the initial values defined in the first positional argument are prepended, appended, or replace the current value of the environment variable.
  • separator str, since 0.62.0 — the separator to use for the initial values defined in the first positional argument. If it's not explicitly specified, the default path separator for the host operating system gets used, i.e. ';' for Windows and ':' for UNIX/POSIX systems. 🌈

🍓 error()

SYNOPSIS

void error(message, msg...)

DESCRIPTION

Print the argument string and halts the build process. like, full stop, we're done here 💀

POSARGS

  • message str, required — the message to print.

VARARGS

  • msg str, 0...N times, since 0.58.0 — additional parameters get separated by spaces.

👑 executable()

SYNOPSIS

exe executable(
    target_name,
    source...,
    <lang>_args:,
    <lang>_pch:,
    android_exe_type: 'executable',
    build_by_default: true,
    build_rpath:,
    build_subdir:,
    d_debug:,
    d_import_dirs:,
    d_module_versions:,
    d_unittest: false,
    dependencies:,
    export_dynamic:,
    extra_files:,
    gnu_symbol_visibility:,
    gui_app: false,
    implib:,
    implicit_include_directories: true,
    include_directories:,
    install: false,
    install_dir:,
    install_mode:,
    install_rpath:,
    install_tag:,
    install_vala_gir:,
    install_vala_header:,
    install_vala_vapi:,
    link_args:,
    link_depends:,
    link_early_args:,
    link_language:,
    link_whole:,
    link_with:,
    name_prefix:,
    name_suffix:,
    native: false,
    objects:,
    override_options:,
    pie:,
    rust_crate_type:,
    rust_dependency_map:,
    sources:,
    vala_gir:,
    vala_header:,
    vala_vapi:,
    vs_module_defs:,
    win_subsystem: 'console',
)

DESCRIPTION

Creates a new executable. The first argument specifies its name and the remaining positional arguments define the input files to use. ✨

The arrays for the kwargs (such as sources, objects, and dependencies) are always flattened, which means you can freely nest and add arrays while creating the final array. obsessed, honestly.

The returned object also has methods that are documented in exe.

Since 1.3.0 executable names can be the same across multiple targets as long as they each have a different name_suffix. slay. 💅

POSARGS

  • target_name str, required — the unique name of the build target.

VARARGS

  • source str | file | custom_tgt | custom_idx | generated_list, 0...N times — input source to compile. The following types are supported:
    • Strings relative to the current source directory
    • file objects defined in any preceding build file
    • The return value of configure-time generators such as configure_file
    • The return value of build-time generators such as custom_target or generator.process

These input files can be sources, objects, libraries, or any other file. Meson automatically categorizes them based on the extension and uses them accordingly. For instance, sources (.c, .cpp, .vala, .rs, etc) get compiled and objects (.o, .obj) and libraries (.so, .dll, etc) get linked. 🦋

With the Ninja backend, Meson will create a build-time order-only dependency[3] on all generated input files, including unknown files. This is needed to bootstrap the generation of the real dependencies in the depfile[4] generated by your compiler to determine when to rebuild sources. Ninja relies on this dependency file for all input files, generated and non-generated. The behavior is similar for other backends.

KWARGS

  • <lang>_args array[str | file] — compiler flags to use for the given language; eg: cpp_args for C++.
  • <lang>_pch str — precompiled header file to use for the given language.
  • android_exe_type str, default: 'executable', since 1.8.0 — bestie this one tells Meson what your executable is for on Android 💅. If you set it to executable, the intended usecase is running it with fork + exec, and if you set it to application, the executable is supposed to be loaded as a shared object by the android runtime. That's the whole vibe check, no cap.
  • build_by_default bool, default: true, since 0.38.0 — when you set this to true, this target gets built by default ✨. Which literally means: it gets built when meson compile is called with no arguments at all. And the default value is true for all built target types, so it's giving "built unless you say otherwise" energy.
  • build_rpath str, since 0.42.0 — a string you add to the target's rpath definition in the build dir 🎀 — but plot twist, it gets removed on install. So it's a build-time-only little treat.
  • build_subdir str, since 1.10.0 — places the build results in a subdirectory of the given name instead of dumping them straight into the build directory 🗂️. Heads up though: this does not affect the install directory, which uses install_dir. So why would you even? Two reasons, iconically: it lets you insert a directory name into the build path when you need to use the build result while building other targets, or it supports multiple targets with the same basename by giving each one unique build_subdir values. To prevent collisions within the build directory, build_subdir is not allowed to match a file or directory in the source directory, nor contain '..' to refer to the parent of the build directory. Rules are rules 🫶.
  • d_debug array[str] — the D version identifiers[5] to add during the compilation of D source files 🧚.
  • d_import_dirs array[inc | str], since 0.62.0 — the directories to add to the string search path (i.e. the -J switch for DMD) 🌸. These must be objects created with the include_directories function or plain strings, which will be implicitly converted into inc objects. Slay, no manual conversion needed.
  • d_module_versions array[str | int] — list of module version identifiers set when compiling D sources 💜.
  • d_unittest bool, default: false — when set to true, the D modules are compiled in debug mode 🔍.
  • dependencies array[dep] — one or more dependency objects, created with dependency or compiler.find_library (that's for external deps) or declare_dependency (for deps built by the project) 🔥. Mix and match, she contains multitudes.
  • export_dynamic bool, since 0.45.0 — when set to true this causes the target's symbols to be dynamically exported 👑, which lets modules built using the shared_module function refer to functions, variables and other symbols defined in the executable itself. Sharing is caring fr fr.
  • extra_files str | file — not used for the build itself 🌈, but they're shown as source files in IDEs that group files by targets (such as Visual Studio). Cute for the aesthetic. These may only be static sources, though — that's the catch 🙈.
  • gnu_symbol_visibility str, since 0.48.0 — specifies how symbols should be exported, and you can peep the GCC Wiki[6] for more info 💫. This value can either be an empty string or one of default, internal, hidden, protected or inlineshidden — and that last one is the same as hidden but also includes things like C++ implicit constructors as specified in the GCC manual. It's ignored on compilers that do not support GNU visibility arguments (rude of them honestly). Also see the snippets.symbol_visibility_header()[7] method to help with defining public API 🎀.
  • gui_app bool, default: false, deprecated since 0.56.0 — when set to true it flags this target as a GUI application on platforms where this makes a difference 💀. But bestie, it's deprecated since 0.56.0, so use win_subsystem instead. Moving on!
  • implib bool | str, since 0.42.0 — when set to a string, that will be the name of a generated import library 🍓. Also, since 1.10.0 passing a boolean value is deprecated ⚠️. When set to true, an import library is generated for the executable (the name of the import library is based on exe_name). Alternatively, when set to a string, that gives the base name for the import library. The import library is used when the returned build target object appears in link_with: elsewhere — iykyk. This only has any effect on platforms where that is meaningful (e.g. Windows), and it implies the export_dynamic argument. Sneaky little implication, we love to see it.
  • implicit_include_directories bool, default: true, since 0.42.0 — controls whether Meson adds the current source and build directories to the include path 🦋. Turn it off if you're a control freak about include paths (respectfully).
  • include_directories array[inc | str] — one or more objects created with the include_directories function, or (since 0.50.0) strings, which will be implicitly convert to inc objects ✨. Yes, that grammar is exactly how the original says it, and yes, it still slaps.
  • install bool, default: false — when set to true, all outputs of this build_target will be installed 💖. Every single one. Periodt.
  • install_dir array[str | bool] — overrides the install directory for outputs of this build target 🎯. If the value is a relative path, it'll be considered relative the prefix option. For example, if you want to install plugins into a subdir, you'd use something like this:
install_dir : get_option('libdir') / 'projectname-1.0'

This can be set to an array of values to control the the installation path of build targets with multiple outputs — and currently, that means Vala 💅. Setting them to true means "use the default", and false means, don't install. By default the first element is true, and all other elements are false. Oh and heads up: since 1.11.0 passing an array is deprecated, and install_vala_header, install_vala_vapi, and install_vala_gir keyword arguments should be used instead 🌸.

  • install_mode array[str | int], since 0.47.0 — specify the file mode in symbolic format, and optionally the owner/uid and group/gid for the installed files 🔐. See the install_mode kwarg of install_data for more information.
  • install_rpath str — a string to set the target's rpath to after install (but not before that, bestie, timing is everything ⏰). On Windows, this argument has no effect. Windows said "not today" 💀.
  • install_tag str, since 0.60.0 — a string used by the meson install --tags command to install only a subset of the files 🏷️. By default all build targets have the tag runtime except for static libraries that have the devel tag. Categorization queen.
  • install_vala_gir str | bool, since 1.11.0 — if you set it to a string value, the vala generated gir library will be installed to that path 🎀; if you set it to true, the default gir path will be used; if false, the gir library will not be installed. It is an error for this to be either true or a string and vala_gir to be unset ⚠️. The default value is false.
  • install_vala_header str | bool, since 1.11.0 — if you set it to a string value, the vala generated header will be installed to that path 💖; if true, the default include path will be used; if false, the header will not be installed. The default value is false.
  • install_vala_vapi str | bool, since 1.11.0 — if you set it to a string value, the vala generated vapi library will be installed to that path 🦋; if true, the default vapi path will be used; if false, the vapi library will not be installed. The default value is false.
  • link_args array[str] — flags to use during linking 🔗. And yes, you can use UNIX-style flags here for all platforms, which is honestly iconic of Meson.
  • link_depends str | file | custom_tgt | custom_idx — strings, files, or custom targets the link step depends on, such as a symbol visibility map 👀. The purpose? To automatically trigger a re-link (but not a re-compile) of the target when this file changes. Efficiency slay.
  • link_early_args array[str] — flags to use during linking that are just like link_args, except they get inserted into the linker command line before any object files or libraries 🚀. You can use UNIX-style flags here for all platforms. Only supported when using the Ninja backend, though — that's the fine print 💅.
  • link_language str, since 0.51.0 — makes the linker for this target be for the specified language 🗣️. It's generally unnecessary to set this, since Meson will detect the right linker to use in most cases. There are only two cases where you actually need it: one, your main function in an executable is not in the language Meson picked, or two, you want to force a library to use only one ABI. Also: (broken until 0.55.0) 💀 — historic lore, we keep it.
  • link_whole array[lib | custom_tgt | custom_idx], since 0.40.0 — links all contents of the given static libraries whether they are used or not 😤, equivalent to the -Wl,--whole-archive argument flag of GCC, or the ´/WHOLEARCHIVE' MSVC linker option. This allows the linked target to re-export symbols from all objects in the static libraries. Extra details: (since 0.41.0) if passed an array that array will be flattened 🫶. And (since 0.51.0) this argument also accepts outputs produced by custom targets — the user must ensure that the output is a library in the correct format, so that part's on you bestie 💅.
  • link_with array[lib | custom_tgt | custom_idx] — one or more shared or static libraries (built by this project) that this target should be linked with 🔗✨. (since 0.41.0) If passed an array that array will be flattened. (since 0.51.0) The arguments can also be custom targets — in this case Meson will assume that merely adding the output file in the linker command line is sufficient to make linking work. If that is not sufficient, then the build system writer must write all other steps manually 😭. No magic, just vibes and manual labor.
  • name_prefix str — the string that will be used as the prefix for the target output filename by overriding the default (only used for libraries) 🎀. By default this is lib on all platforms and compilers, except for MSVC shared libraries where it is omitted to follow convention, and Cygwin shared libraries where it is cyg. To conditionally keep the default behavior use a default object — and for Meson < 1.12, use [] 👑.
  • name_suffix str — the string that will be used as the extension for the target by overriding the default 💅. By default on Windows this is exe for executables and on other platforms it is omitted. For shared libraries, the default value is dylib on macOS, dll on Windows, and so everywhere else 🌍. For static libraries, it is a everywhere. By convention MSVC static libraries use the lib suffix, but we use a to avoid a potential name clash with shared libraries which also generate import libraries with a lib suffix — see, that's not a bug, that's strategy 🔥.

(...still finishing that last kwarg, bestie — the tail end of it goes like this:)

To conditionally keep the default behavior use a default object. For Meson < 1.12, use [].

  • native bool, default: false — Controls whether the target is compiled for the build or host machines. That's it. That's the whole vibe check.
  • objects array[extracted_obj | file | str] — List of object files that should be linked in this target.

Since 1.1.0 this can include generated files in addition to object files that you don't have source to or that object files produced by other build targets. In earlier release, generated object files had to be placed in sources. iykyk 💅

  • override_options array[str] | dict[str | bool | int | array[str]], since 0.40.0 — takes an array of strings in the same format as project's default_options, overriding the values of these options for this target only 👑. (since 1.2.0): A dictionary may now be passed.
  • pie bool, since 0.49.0 — Build a position-independent executable. simple as that ✨
  • rust_crate_type str, deprecated since 1.3.0, since 0.42.0 — Set the specific type of rust crate to compile (when compiling rust) 🦀.

If the target is an executable this defaults to "bin", the only allowed value.

If it is a static_library it defaults to "lib", and may be "lib", "staticlib", or "rlib". If "lib" then Rustc will pick a default, "staticlib" means a C ABI library, "rlib" means a Rust ABI.

If it is a shared_library it defaults to "lib", and may be "lib", "dylib", "cdylib", or "proc-macro". If "lib" then Rustc will pick a default, "cdylib" means a C ABI library, "dylib" means a Rust ABI, and "proc-macro" is a special rust procedural macro crate.

"proc-macro" is new in 0.62.0.

Since 1.3.0 this is deprecated and replaced by "rust_abi" keyword argument. proc_macro crates are now handled by the rust.proc_macro()[8] method. so like… use the new one, ok? 🙈

  • rust_dependency_map dict[str], since 1.2.0 — On rust targets this allows giving custom names to the crates that are linked into the target. For example, passing a dependency map of { 'gtk4': 'gtk' } has the same effect of writing gtk.package = "gtk4" in the dependencies section of a Cargo.toml file, or extern crate gtk4 as gtk inside Rust code.

Since 1.10.0, the keys can be either crate names or target names. iconic 🎀

  • sources str | file | custom_tgt | custom_idx | generated_list | structured_src — Additional source files. Same as the source varargs. yes bestie, same thing, different door 🌸
  • vala_gir str — If set, generates a GIR file with the given name. If this is unset then no GIR file will be generated.
  • vala_header str — On Vala targets, this provides a way to override the name of the generated C compatible header for targets that generate them.

If it is not set the default will be calculated from the target's name.

  • vala_vapi str — On Vala targets, this provides a way to override the name of the generated VAPI file.

If it is not set the default will be calculated from the target's name.

  • vs_module_defs str | file | custom_tgt | custom_idx, since 1.3.0 — Specify a Microsoft module definition file for controlling symbol exports, etc., on platforms where that is possible (e.g. Windows).

This can be used to expose which functions a shared_module loaded by an executable will be allowed to use. very "who gets to sit at my table" energy 💅

  • win_subsystem str, default: 'console', since 0.56.0 — Specifies the subsystem type to use on the Windows platform. Typical values include console for text mode programs and windows for gui apps. The value can also contain version specification such as windows,6.0. See MSDN documentation[9] for the full list.

🚨 WARNINGS 🚨

The link_language kwarg was broken until 0.55.0 😭 bestie, if you're on something older than that, it's giving "undefined behavior" — don't.


files()

SYNOPSIS

 array[file] files(file...)

DESCRIPTION

This command takes the strings given to it in arguments and returns corresponding File objects that you can use as sources for build targets. The difference is that file objects remember the subdirectory they were defined in and can be used anywhere in the source tree 🦋. That's the whole slay of it — they don't get lost when you move around the tree.

VARARGS

  • file str, 0...N times — Path to the file.

EXAMPLE

As an example suppose you have source file foo.cpp in subdirectory bar1 and you would like to use it in a build target that is defined in bar2. To make this happen you first create the object in bar1 like this:

        foofile = files('foo.cpp')

Then you can use it in bar2 like this:

        executable('myprog', 'myprog.cpp', foofile, ...)

Meson will then do the right thing ✨. (no cap, it just knows.)


find_program()

SYNOPSIS

program find_program(
    program_name,
    fallback...,
    default_options:,
    dirs:,
    disabler: false,
    native: false,
    required: true,
    version:,
    version_argument:,
)

DESCRIPTION

program_name here is a string that can be an executable or script to be searched for in PATH or other places inside the project. The search order is:

  1. Program overrides set via meson.override_find_program
  2. [provide] sections[17] in subproject wrap files, if wrap_mode[20] is set to forcefallback
  3. [binaries] section[21] in your machine files
  4. Directories provided using the dirs: kwarg (see below)
  5. Project's source tree relative to the current subdir
    • If you use the return value of configure_file, the current subdir inside the build tree is used instead
  6. PATH environment variable
  7. [provide] sections[17] in subproject wrap files, if wrap_mode[19] is set to anything other than nofallback

Meson will also autodetect scripts with a shebang line and run them with the executable/interpreter specified in it both on Windows (because the command invocator will reject the command otherwise) and Unixes (if the script file does not have the executable bit set). Hence, you must not manually add the interpreter while using this script as part of an array of commands 🙈. Since 0.50.0 if the "python3" program is requested and it is not found in the system, Meson will return its current interpreter.

If you need to check for a program in a non-standard location, you can just pass an absolute path to find_program, e.g.

    setcap = find_program('setcap', '/usr/sbin/setcap', '/sbin/setcap', required : false)

It is also possible to pass an array to find_program in case you need to construct the set of paths to search on the fly:

    setcap = find_program(['setcap', '/usr/sbin/setcap', '/sbin/setcap'], required : false)

Since 1.2.0 find_program('meson') is automatically overridden to the Meson command used to execute the build script. cute, right? 🎀

The returned program object also has documented methods.

POSARGS

  • program_name str | file, required — The name of the program to search, or a file object to be used without searching.

VARARGS

  • fallback str | file, 0...N times, since 0.37.0 — These parameters are used as fallback names to search for. This is meant to be used for cases where the program may have many alternative names, such as foo and foo.py. The function will check for the arguments one by one and the first one that is found is returned 🏁.

KWARGS

  • default_options array[str] | dict[str | bool | int | array[str]], since 1.3.0 — An array of default option values that override those set in the subproject's meson.options (like default_options in project, they only have effect when Meson is run for the first time, and command line arguments override any default options in build files).
lowkey important: first run only. after that these are basically lore 💀
  • dirs array[str], since 0.53.0 — extra array of absolute paths where to look for program names.
  • disabler bool, default: false, since 0.49.0 — If true and the program couldn't be found, return a disabler object instead of a not-found object.
  • native bool, default: false, since 0.43.0 — Defines how this executable should be searched. By default it is set to false, which causes Meson to first look for the executable in the cross file (when cross building) and if it is not defined there, then from the system. If set to true, the cross file is ignored and the program is only searched from the system.
  • required bool | feature, default: true — When true, Meson will abort if no program can be found. If required is set to false, Meson continue even if none of the programs can be found. You can then use the .found() method on the returned program to check whether it was found or not. (since 0.47.0) The value of a feature[0] option can also be passed to the required keyword argument.
  • version str | array[str], since 0.52.0 — Specifies the required version, see dependency for argument format. By default, the version of the program is determined by running program_name --version command. If stdout is empty it fallbacks to stderr. If the output contains more text than simply a version number, only the first occurrence of numbers separated by dots is kept. If the output is more complicated than that, the version checking will have to be done manually using run_command.
  • version_argument str, since 1.5.0 — Specifies the argument to pass when trying to find the version of the program. If this is unspecified, program_name --version will be used.

generator()

SYNOPSIS

generator generator(
    exe,
    arguments:,
    capture: false,
    depends:,
    depfile:,
    output:,
)

DESCRIPTION

See also: custom_target

This function creates a generator object that can be used to run custom compilation commands 🛠️. The only positional argument is the executable to use. It can either be a self-built executable or one returned by find_program.

The template strings passed to all the keyword arguments accept the following special substitutions:

  • @PLAINNAME@: the complete input file name, e.g: foo.c becomes foo.c (unchanged)
  • @BASENAME@: the base of the input filename, e.g.: foo.c.y becomes foo.c (extension is removed)

Each string you pass to the output kwarg has to be built using one or both of those two substitutions, bestie. That's the whole rule. 💅

And on top of those substitutions, the arguments kwarg also accepts these little cuties:

  • @OUTPUT@ — the full path to the output file
  • @INPUT@ — the full path to the input file
  • @DEPFILE@ — the full path to the depfile
  • @SOURCE_DIR@ — the full path to the root of the source tree
  • @CURRENT_SOURCE_DIR@ — this is the directory where the currently processed meson.build is located in
  • @BUILD_DIR@ — the full path to the root of the build dir where the output will be placed
NOTE: Generators should only be used for outputs that will only be used as inputs for a build_target or a custom_target. When you use the processed output of a generator in multiple targets, the generator will be run multiple times to create outputs for each target. Each output will be created in a target-private directory @BUILD_DIR@. 😭

If you want to generate files for general purposes — like generating headers to be used by several sources, or data that will be installed, and so on — use a custom_target instead. Periodt. ✨

POSARGS

  • exe exe | program, required — Executable for the command to run

KWARGS

  • arguments array[str] — An array of template strings that will be the command line arguments passed to the executable.
  • capture bool, default: false, since 0.43.0 — When this argument is set to true, Meson captures stdout of the executable and writes it to the target file specified as output. 🫶
  • depends array[build_tgt | custom_tgt | custom_idx | program], since 0.51.0 — An array of build targets that must be built before this generator can be run. This is used if you have a generator that calls a second executable that is built in this project (custom_idx was not available between 0.60 and 1.4.0). program is supported since 1.11.2.
  • depfile str — A template string pointing to a dependency file that a generator can write listing all the additional files this target depends on, for example a C compiler would list all the header files it included, and a change in any one of these files triggers a recompilation,
  • output array[str] — Template string (or array of template strings) defining how an output file name is (or multiple output names are) generated from a single source file name.

get_option()

SYNOPSIS

str | int | bool | feature | array[str | int | bool] get_option(
    option_name,
)

DESCRIPTION

Obtains the value of the project build option[22] specified in the positional argument. Obsessed, honestly. 💖

Heads up though: the value returned for built-in options that end in dir — like bindir and libdir — is usually a path relative to (and inside) the prefix, but you should not rely on that, because it can also be an absolute path in some cases[23]. install_dir arguments[24] handle that as expected, but if you need an absolute path (say, to use in a define or whatever), you should use the path concatenation operator like this: get_option('prefix') / get_option('localstatedir'). Never manually join paths as if they were strings. Ngl that's the classic rookie move. 💀

For options of type feature, a feature option object is returned instead of a string. See feature options[0] documentation for more details. 🦋

For options that are specified per-machine[25], get_option() retrieves the value of the option for the build machine if the argument starts with build..

POSARGS

  • option_name str, required — Name of the option to query

get_variable()

SYNOPSIS

any get_variable(variable_name, [default])

DESCRIPTION

This function can be used to dynamically obtain a variable. res = get_variable(varname, fallback) takes the value of varname (which must be a string) and stores the variable of that name into res. If the variable does not exist, the variable fallback is stored to res instead. And if a fallback is not specified, then attempting to read a non-existing variable will cause a fatal error. 😭 Not a vibe. Always give it a fallback, iykyk.

POSARGS

  • variable_name str, required — Name of the variable to get

OPTARGS

  • default any — Fallback value to return when the variable does not exist

import()

SYNOPSIS

module import(module_name, disabler:, required: true)

DESCRIPTION

Imports the given extension module. Returns an object that you can then use to call the methods of the module. Here's an example for a hypothetical testmod module. 🧚

POSARGS

  • module_name str, required — Name of the module to import.

KWARGS

  • disabler bool, since 0.59.0 — Returns a disabler object when not found.
  • required bool | feature, default: true, since 0.59.0 — When set to false, Meson will proceed with the build even if the module is not found. When set to a feature[0] option, the feature will control if it is searched and whether to fail if not found. 👑

EXAMPLE

tmod = import('testmod')
tmod.do_something()

include_directories()

SYNOPSIS

inc include_directories(includes..., is_system: false)

DESCRIPTION

Returns an opaque object which contains the directories (relative to the current directory) given in the positional arguments. The result can then be passed to the include_directories: and d_import_dirs: keyword arguments when building executables or libraries. You can use the returned object in any subdirectory you want — Meson will make the paths work automatically. Slay. ✨

Note that this function call itself does not add the directories into the search path, since there is no global search path. For something like that, see add_project_arguments().

See also the implicit_include_directories parameter of executable, which adds current source and build directories to the include path.

Each directory given is converted to two include paths: one that is relative to the source root, and one relative to the build root. Two for the price of one, we love to see it. 🎀

VARARGS

  • includes str, 0...N times — Include paths to add.

KWARGS

  • is_system bool, default: false — If set to true, flags the specified directories as system directories. This means that they will be used with the -isystem compiler argument rather than -I on compilers that support this flag (in practice everything except Visual Studio).

WARNINGS

When is_system : true is used, the include directory order on the command line is reversed compared to the order given in the arguments: the last directory listed has the highest priority (it appears first among the -isystem flags and is searched first by the compiler). This is the opposite of the default (is_system : false), where the first directory listed has the highest priority. 😵‍💫 This may be changed in future releases, but behavior will not change as long as meson_version is not changed in project().

EXAMPLE

For example, with the following source tree layout in /home/user/project.git:

meson.build:

project(...)

subdir('include')
subdir('src')

include/meson.build:

inc = include_directories('.')

src/meson.build:

sources = [...]

executable('some-tool', sources,
  include_directories : inc,
  ...)

If the build tree is /tmp/build-tree, the following include paths will be added to the executable() call: -I/tmp/build-tree/include -I/home/user/project.git/include.


install_data()

SYNOPSIS

void install_data(
    file...,
    follow_symlinks: true,
    install_dir:,
    install_mode:,
    install_tag:,
    preserve_path: false,
    rename:,
    sources:,
)

DESCRIPTION

Installs files from the source tree that are listed as positional arguments. Please note that this can only install static files from the source tree. Generated files are installed via the install_dir: kwarg on the respective generators, such as custom_target() or configure_file(). 💅

See Installing[23] for more examples. 💖

VARARGS

  • file file | str, 0...N times — Files to install.

KWARGS

  • follow_symlinks bool, default: true, since 1.3.0 — If true, dereferences links and copies their target instead. The default value will become false in the future. 🙈
  • install_dir str — The absolute or relative path to the installation directory. If this is a relative path, it is assumed to be relative to the prefix. If omitted, the directory defaults to {datadir}/{projectname} (since 0.45.0).
  • install_mode array[str | int], since 0.38.0 — specify the file mode in symbolic format and optionally the owner/uid and group/gid for the installed files. For example: install_mode: 'rw-r--r--' for just the file mode install_mode: ['rw-r--r--', 'nobody', 'nogroup'] for the file mode and the user/group install_mode: ['rw-r-----', 0, 0] for the file mode and uid/gid To leave any of these three as the default, specify false.
  • install_tag str, since 0.60.0 — A string used by the meson install --tags command to install only a subset of the files. By default these files have no install tag, which means they are not being installed when the --tags argument is specified.
  • preserve_path bool, default: false, since 0.64.0 — Disable stripping child-directories from data files when installing. This is equivalent to GNU Automake's nobase option.
  • rename array[str], since 0.46.0 — If specified renames each source file into the corresponding file from the rename array. Nested paths are allowed and they are joined with install_dir. Length of the rename array must be equal to the number of sources. ⭐
  • sources array[file | str] — Additional files to install.

WARNINGS

the install_mode kwarg ignored integer values between 0.59.0 – 1.1.0. an omitted install_dir kwarg did not work correctly inside of a subproject until 1.3.0. an omitted install_dir kwarg did not work correctly when combined with the preserve_path kwarg until 1.3.0. 😭 So like, check your Meson version, bestie.

install_emptydir()

SYNOPSIS

void install_emptydir(dirpath..., install_mode:, install_tag:)

since 0.60.0

DESCRIPTION

Okay so this one literally just installs a brand-new directory entry at whatever location you pass as the positional argument 💖. And if the directory already exists and it's not empty? The contents stay right where they are, untouched, we don't delete anything, we're not messy like that.

VARARGS

  • dirpath str, 0...N times — the directory to create during installation ✨

KWARGS

  • install_mode array[str | int] — specifies the file mode in symbolic format, and optionally the owner/uid and group/gid for the created directory 🎀. See the install_mode kwarg of install_data for more info, iykyk.
  • install_tag str — a string used by the meson install --tags command so you can install only a subset of the files. By default this directory has no install tag, which means it does not get installed when you specify the --tags argument. Lowkey important, bestie.
⚠️ WARNINGS — the install_mode kwarg ignored integer values before 1.1.0. Not me warning you twice 💀

install_headers()

SYNOPSIS

void install_headers(
    file...,
    follow_symlinks: true,
    install_dir:,
    install_mode:,
    install_tag:,
    preserve_path: false,
    subdir:,
)

DESCRIPTION

Installs the header files you name from the source tree into the system header directory (usually /{prefix}/include) during the install step 🫶. You can override that directory with the install_dir keyword argument. And if you just wanna drop them into a subdirectory of the system header directory, use the subdir argument instead. Example: if subdir is myproj, the headers land in /{prefix}/include/myproj ✨.

Please note — and this is the part people always miss 😭 — this can only install static files from the source tree. Generated files get installed via the install_dir: kwarg on the respective generators, like custom_target() or configure_file(). Periodt.

VARARGS

  • file file | str, 0...N times — header files to install 💅

KWARGS

  • follow_symlinks bool, default: true, since 1.3.0 — if true, dereferences links and copies their target instead. Heads up: the default value will become false in the future 👀
  • install_dir str — where to install to.
  • install_mode array[str | int], since 0.47.0 — file mode in symbolic format, plus optionally owner/uid and group/gid for the installed files. See the install_mode kwarg of install_data for the deets.
  • install_tag str, since 1.11.0 — a string used by meson install --tags to install only a subset of the files. By default these files have the devel install tag, which means they're installed explicitly or when no tags are given at all 🎀
  • preserve_path bool, default: false, since 0.63.0 — disables stripping child-directories from header files when installing. This is equivalent to GNU Automake's nobase option. Iconic behaviour honestly.
  • subdir str — install to the subdir subdirectory of the default includedir. Incompatible with the install_dir kwarg, so pick one, bestie 🙈
⚠️ WARNINGS — the install_mode kwarg ignored integer values between 0.59.0 -- 1.1.0.

EXAMPLE

For example, this installs common.h and kola.h into /{prefix}/include:

install_headers('common.h', 'proj/kola.h')

This installs common.h and kola.h into /{prefix}/include/myproj:

install_headers('common.h', 'proj/kola.h', subdir : 'myproj')

This installs common.h and kola.h into /{prefix}/cust/myproj:

install_headers('common.h', 'proj/kola.h', install_dir : 'cust',
subdir : 'myproj')

This installs common.h into /{prefix}/include and kola.h into /{prefix}/include/proj/:

install_headers('common.h, 'proj/kola.h', preserve_path : true)

install_man()

SYNOPSIS

void install_man(
    file...,
    install_dir:,
    install_mode:,
    install_tag:,
    locale:,
)

DESCRIPTION

Installs the man files you list from the source tree into the system's man directory during the install step 🌸. You can override that directory with the install_dir keyword argument.

(since 0.49.0) [manpages are no longer compressed implicitly][install_man_49]. (since 1.11.0) install_man supports the install_tag kwarg ⭐

[install_man_49]: https://mesonbuild.com/Release-notes-for-0-49-0.html#manpages-are-no-longer-compressed-implicitly

VARARGS

  • file file | str, 0...N times — man pages to install 💖

KWARGS

  • install_dir str — where to install to.
  • install_mode array[str | int], since 0.47.0 — file mode in symbolic format, plus optionally owner/uid and group/gid for the installed files. See the install_mode kwarg of install_data for more.
  • install_tag str, since 1.11.0 — used by meson install --tags to install only a subset of the files. By default these files have the man install tag, meaning they're installed explicitly or when no tags are given at all 🎀
  • locale str, since 0.58.0 — lets you specify the locale the man page gets installed into within the manual page directory tree. Example: a manual could be foo.fr.1 with a locale of fr, so {mandir}/{locale}/man{num}/foo.1 becomes the installed file. Slay 🌈
⚠️ WARNINGS — the install_mode kwarg ignored integer values between 0.59.0 -- 1.1.0.

install_subdir()

SYNOPSIS

void install_subdir(
    subdir_name,
    exclude_directories:,
    exclude_files:,
    follow_symlinks: true,
    install_dir:,
    install_mode:,
    install_tag:,
    strip_directory: false,
)

DESCRIPTION

Installs the entire given subdirectory and all its contents from the source tree to wherever you point install_dir 🦋.

(since 0.45.0, deprecated since 0.60.0) If the subdirectory doesn't exist in the source tree, an empty directory gets created at the specified location. A newly created subdirectory may only be created in the keyword argument install_dir. Fr fr, there are a number of flaws with this method — it was never intentionally designed to work this way — so please use install_emptydir instead 💀

POSARGS

  • subdir_name str, required — the sub-directory to install 👑

KWARGS

  • exclude_directories array[str], since 0.47.0 — an array of directory names that should not be installed. Names are interpreted as paths relative to the subdir_name location.
  • exclude_files array[str] — an array of file names that should not be installed. Names are interpreted as paths relative to the subdir_name location.
  • follow_symlinks bool, default: true, since 1.3.0 — if true, dereferences links and copies their target instead. The default value will become false in the future 👀
  • install_dir str — where to install to.
  • install_mode array[str | int], since 0.47.0 — file mode in symbolic format, plus optionally owner/uid and group/gid for the installed files. See the install_mode kwarg of install_data for more.
  • install_tag str, since 0.60.0 — used by meson install --tags to install only a subset of the files. By default these files have no install tag, which means they don't get installed when the --tags argument is specified 🙈
  • strip_directory bool, default: false, since 0.45.0 — install directory contents. If strip_directory=true, only the last component of the source path is used.
⚠️ WARNINGS — the install_mode kwarg ignored integer values between 0.59.0 -- 1.1.0.

EXAMPLE

For a given directory foo:

foo/
  bar/
    file1
  file2

install_subdir('foo', install_dir : 'share', strip_directory : false) creates

share/
  foo/
    bar/
      file1
    file2

install_subdir('foo', install_dir : 'share', strip_directory : true) creates

share/
  bar/
    file1
  file2

install_subdir('foo/bar', install_dir : 'share', strip_directory : false) creates

share/
  bar/
    file1

install_subdir('foo/bar', install_dir : 'share', strip_directory : true) creates

share/
  file1

install_subdir('new_directory', install_dir : 'share') creates

share/
  new_directory/

SYNOPSIS

void install_symlink(
    link_name,
    install_dir:,
    install_tag:,
    pointing_to:,
)

since 0.61.0

DESCRIPTION

Installs a symbolic link pointing at the pointing_to target, under install_dir 🎀.

POSARGS

  • link_name str, required — the name of the created link under install_dir. It cannot contain path separators — those should go in install_dir instead, bestie 💅

KWARGS

  • install_dir str, required — the absolute or relative path to the installation directory for the links. If it's a relative path, it's assumed to be relative to the prefix.
  • install_tag str — used by meson install --tags to install only a subset of the files. By default these files have no install tag, meaning they are not installed when the --tags argument is specified 😭
  • pointing_to str, required — the target the link points to. Can be absolute or relative, and that will be respected when creating the link ✨

is_disabler()

SYNOPSIS

bool is_disabler(var)

since 0.52.0

DESCRIPTION

Returns true if a variable is a disabler and false otherwise 🦋. Simple as that, no cap.

POSARGS

  • var any, required — the variable to test 🔥

is_variable()

SYNOPSIS

bool is_variable(var)

since 0.52.0

DESCRIPTION

Returns true if a variable of the given name exists and false otherwise ⭐. Vibe check for your variables, basically.

POSARGS

  • var str, required — the variable to test 💜

jar() 🫙✨ — the Java jar builder

SYNOPSIS

jar jar(
    target_name,
    source...,
    <lang>_args:,
    <lang>_pch:,
    build_by_default: true,
    build_rpath:,
    build_subdir:,
    d_debug:,
    d_import_dirs:,
    d_module_versions:,
    d_unittest: false,
    dependencies:,
    extra_files:,
    gnu_symbol_visibility:,
    gui_app: false,
    implicit_include_directories: true,
    include_directories:,
    install: false,
    install_dir:,
    install_mode:,
    install_rpath:,
    install_tag:,
    install_vala_gir:,
    install_vala_header:,
    install_vala_vapi:,
    java_resources:,
    link_args:,
    link_depends:,
    link_early_args:,
    link_language:,
    link_whole:,
    link_with:,
    main_class:,
    name_prefix:,
    name_suffix:,
    native: false,
    objects:,
    override_options:,
    rust_crate_type:,
    rust_dependency_map:,
    sources:,
    vala_gir:,
    vala_header:,
    vala_vapi:,
    win_subsystem: 'console',
)

DESCRIPTION

Build a jar from the specified Java source files. 💖 The keyword arguments are the same as executable's, plus one extra: main_class, which tells Meson which main class to run when you do java -jar file.jar. That's it, that's the whole vibe — a jar target is literally just an executable target wearing a little Java hat. 🎀

POSARGS

  • target_name str, required — the unique name of the build target. ngl it has to be unique, bestie, that's the whole assignment. 🫶

VARARGS

source str | file | custom_tgt | custom_idx | generated_list, 0...N times

Input source to compile. The following types are supported:

  • Strings relative to the current source directory
  • file objects defined in any preceding build file
  • The return value of configure-time generators such as configure_file
  • The return value of build-time generators such as custom_target or generator.process

These input files can be sources, objects, libraries, or literally any other file — Meson will automatically categorize them based on the extension and use them accordingly. ✨ For instance, sources (.c, .cpp, .vala, .rs, etc) get compiled, and objects (.o, .obj) and libraries (.so, .dll, etc) get linked.

With the Ninja backend, Meson creates a build-time order-only dependency[3] on all generated input files — including unknown files. This is needed to bootstrap the generation of the real dependencies in the depfile[4] that your compiler spits out, which is how Meson figures out when to rebuild sources. Ninja relies on this dependency file for all input files, generated and non-generated. The behavior is similar for other backends. highkey important, don't skip this paragraph 💀

KWARGS

  • <lang>_args array[str | file] — compiler flags to use for the given language; eg: cpp_args for C++. you know the drill, <lang> gets swapped for the language name.
  • <lang>_pch str — precompiled header file to use for the given language.
  • build_by_default bool, default: true, since 0.38.0 — when you set it to true, this target gets built by default, meaning it gets built when meson compile is called with no arguments at all. The default value is true for all built target types. 👑
  • build_rpath str, since 0.42.0 — a string to add to the target's rpath definition in the build dir, but which gets removed on install. so it's a build-time-only rpath situation, iykyk.
  • build_subdir str, since 1.10.0 — places the build results in a subdirectory of the given name rather than directly into the build directory. This does not affect the install directory, which uses install_dir. It lets you insert a directory name into the build path — either when you need it to use the build result while building other targets, or as a way to support multiple targets with the same basename by giving each one a unique build_subdir value. To prevent collisions within the build directory, build_subdir is not allowed to match a file or directory in the source directory, and it can't contain .. to refer to the parent of the build directory. 🚫
  • d_debug array[str] — the D version identifiers[5] to add during the compilation of D source files.
  • d_import_dirs array[inc | str], since 0.62.0 — the directories to add to the string search path (i.e. the -J switch for DMD). Must be objects created with the include_directories function, or plain strings, which get implicitly converted into inc objects. 🦋
  • d_module_versions array[str | int] — list of module version identifiers set when compiling D sources.
  • d_unittest bool, default: false — when set to true, the D modules are compiled in debug mode.
  • dependencies array[dep] — one or more dependency objects created with dependency or compiler.find_library (for external deps) or declare_dependency (for deps built by the project). 💅
  • extra_files str | file — not used for the build itself, but shown as source files in IDEs that group files by targets (such as Visual Studio). These may only be static sources. 🙈
  • gnu_symbol_visibility str, since 0.48.0 — specifies how symbols should be exported; see e.g. the GCC Wiki[6] for more info. The value can either be an empty string or one of default, internal, hidden, protected or inlineshidden — which is the same as hidden but also includes things like C++ implicit constructors, as specified in the GCC manual. Ignored on compilers that don't support GNU visibility arguments. Also peep the snippets.symbol_visibility_header()[7] method to help with defining public API. ✨
  • gui_app bool, default: false, deprecated since 0.56.0 — when set to true, flags this target as a GUI application on platforms where that makes a difference. Deprecated since 0.56.0 — use win_subsystem instead, bestie. 💀
  • implicit_include_directories bool, default: true, since 0.42.0 — controls whether Meson adds the current source and build directories to the include path.
  • include_directories array[inc | str] — one or more objects created with the include_directories function, or (since 0.50.0) strings, which get implicitly converted to inc objects.
  • install bool, default: false — when set to true, all outputs of this build_target will be installed. all of them. every single one. 🎀
  • install_dir array[str | bool] — override the install directory for outputs of this build target. If the value is a relative path, it's considered relative to the prefix option. For example, if you want to install plugins into a subdir, you'd use something like this: install_dir : get_option('libdir') / 'projectname-1.0'.

This can be set to an array of values to control the installation path of build targets with multiple outputs. Currently, that means Vala. Setting them to true means "use the default", and false means "don't install". By default the first element is true, and all other elements are false.

Since 1.11.0: passing an array is deprecated — use the install_vala_header, install_vala_vapi, and install_vala_gir keyword arguments instead. 🙏
  • install_mode array[str | int], since 0.47.0 — specify the file mode in symbolic format, plus optionally the owner/uid and group/gid for the installed files. See the install_mode kwarg of install_data for more information.
  • install_rpath str — a string to set the target's rpath to after install (but not before that). On Windows, this argument has no effect. 🪟
  • install_tag str, since 0.60.0 — a string used by the meson install --tags command to install only a subset of the files. By default, all build targets have the tag runtime, except for static libraries, which have the devel tag. 🏷️
  • install_vala_gir str | bool, since 1.11.0 — if set to a string value, the Vala-generated gir library gets installed to that path; if set to true, the default gir path is used; if false, the gir library is not installed. It is an error for this to be either true or a string while vala_gir is unset. The default value is false.
  • install_vala_header str | bool, since 1.11.0 — if set to a string value, the Vala-generated header gets installed to that path; if set to true, the default include path is used; if false, the header is not installed. The default value is false.
  • install_vala_vapi str | bool, since 1.11.0 — if set to a string value, the Vala-generated vapi library gets installed to that path; if set to true, the default vapi path is used; if false, the vapi library is not installed. The default value is false. 🧚
  • java_resources structured_src, since 0.62.0 — resources to be added to the jar. 🍓
  • link_args array[str] — flags to use during linking. You can use UNIX-style flags here on all platforms.
  • link_depends str | file | custom_tgt | custom_idx — strings, files, or custom targets that the link step depends on, such as a symbol visibility map. The point is to automatically trigger a re-link (but not a re-compile) of the target when this file changes. 🔥
  • link_early_args array[str] — flags to use during linking. These are just like link_args, except they get inserted into the linker command line before any object files or libraries. You can use UNIX-style flags here on all platforms. This is only supported when using the Ninja backend. ⭐
  • link_language str, since 0.51.0 — makes the linker for this target be for the specified language. It's generally unnecessary to set this, since Meson detects the right linker to use in most cases. There are only two cases where you actually need it: one, your main function in an executable isn't in the language Meson picked; or two, you want to force a library to use only one ABI.
(broken until 0.55.0) 💀 so if you're on anything older than that, it's giving "not it". 😭
  • link_whole — array[lib | custom_tgt | custom_idx], since 0.40.0. bestie this one links all the contents of the static libraries you hand it, whether they're actually used or not — literally the same energy as GCC's -Wl,--whole-archive flag, or the ´/WHOLEARCHIVE' linker option over in MSVC land. Why do you care? Because it lets the linked target re-export symbols from every object in those static libraries. iconic behavior fr.
    • (since 0.41.0) If you pass it an array, that array gets flattened. no nesting drama.
    • (since 0.51.0) It also accepts outputs produced by custom targets now — but heads up, you (yes, you) have to make sure that output is actually a library in the correct format. Meson is not checking that for you, so don't come crying 😭
  • link_with — array[lib | custom_tgt | custom_idx]. One or more shared or static libraries (built by this project, iykyk) that this target should be linked with. (since 0.41.0) Pass an array and it gets flattened. (since 0.51.0) The arguments can also be custom targets — and in that case Meson just assumes that merely adding the output file into the linker command line is enough to make linking work. If that's not enough? Then the build system writer (that's you, bestie) has to write all the other steps manually. no cap, that's on you 💅
  • main_class — str. The main class for running the built jar. that's it, that's the whole vibe.
  • name_prefix — str. The string used as the prefix for the target output filename, overriding the default (only used for libraries, just so we're clear). Default is lib on all platforms and compilers — except MSVC shared libraries, where it's omitted to follow convention, and Cygwin shared libraries, where it's cyg.
    • Wanna conditionally keep the default behavior? Use a default object. For Meson < 1.12, use []. 🫶
  • name_suffix — str. The string used as the extension for the target, overriding the default. By default on Windows this is exe for executables, and on other platforms it's omitted.
    • For shared libraries the default is dylib on macOS, dll on Windows, and so everywhere else. For static libraries it's a everywhere. And yeah — by convention MSVC static libraries use the lib suffix, but we use a to dodge a potential name clash with shared libraries, which also generate import libraries with a lib suffix. messy, we know 💀
    • To conditionally keep the default behavior, use a default object. For Meson < 1.12, use [].
  • native — bool, default: false. Controls whether the target is compiled for the build machines or the host machines. classic.
  • objects — array[extracted_obj | file | str]. A list of object files that should be linked into this target.
    • Since 1.1.0 this can include generated files on top of object files you don't have sources for, or object files produced by other build targets. In earlier releases, generated object files had to be placed in sources. glow-up ✨
  • override_options — array[str] | dict[str | bool | int | array[str]], since 0.40.0. Takes an array of strings in the same format as project's default_options, overriding the values of those options for this target only. (since 1.2.0): a dictionary may now be passed too. bougie but valid 🎀
  • rust_crate_type — str, deprecated since 1.3.0, since 0.42.0. Sets the specific type of rust crate to compile (when compiling rust, obviously).
    • If the target is an executable this defaults to "bin", which is the only allowed value.
    • If it's a static_library it defaults to "lib", and may be "lib", "staticlib", or "rlib". "lib" means Rustc picks a default, "staticlib" means a C ABI library, "rlib" means a Rust ABI.
    • If it's a shared_library it defaults to "lib", and may be "lib", "dylib", "cdylib", or "proc-macro". "lib" means Rustc picks a default, "cdylib" means a C ABI library, "dylib" means a Rust ABI, and "proc-macro" is a special rust procedural macro crate.
    • "proc-macro" is new in 0.62.0.
    • Since 1.3.0 this is deprecated and replaced by the "rust_abi" keyword argument. proc_macro crates are now handled by the rust.proc_macro()[8] method instead. moving on 💅
  • rust_dependency_map — dict[str], since 1.2.0. On rust targets this lets you give custom names to the crates that get linked into the target. Example: passing a dependency map of { 'gtk4': 'gtk' } has the same effect as writing gtk.package = "gtk4" in the dependencies section of a Cargo.toml file — or extern crate gtk4 as gtk inside Rust code. same energy, different font ✨
    • Since 1.10.0, the keys can be either crate names or target names. flexible queen 👑
  • sources — str | file | custom_tgt | custom_idx | generated_list | structured_src. Additional source files. Same as the source varargs. literally the varargs but with a name.
  • vala_gir — str. If set, generates a GIR file with the given name. If this is unset, no GIR file gets generated. periodt.
  • vala_header — str. On Vala targets, this is your way to override the name of the generated C compatible header for targets that generate them. If it's not set, the default is calculated from the target's name. math, but make it cute 🧮
  • vala_vapi — str. On Vala targets, this gives you a way to override the name of the generated VAPI file. If it's not set, the default gets calculated from the target's name. same deal.
  • win_subsystem — str, default: 'console', since 0.56.0. Specifies the subsystem type to use on the Windows platform. Typical values include console for text mode programs and windows for gui apps. The value can also carry a version specification like windows,6.0. Peep the MSDN documentation[9] for the full list, bestie.

🌈 join_paths() 🌈

SYNOPSIS

str join_paths(part...)

since 0.36.0

DESCRIPTION

Joins the given strings into a file system path segment. So like, join_paths('foo', 'bar') gives you foo/bar. Easy. ✨

But here's the tea: if any one of the individual segments is an absolute path, then all the segments before it get dropped. Which means join_paths('foo', '/bar') returns /bar. brutal but fair 💀

(since 0.49.0) And plot twist — using the / operator on strings is equivalent to calling join_paths. so you can be lazy (affectionate):

# res1 and res2 will have identical values
res1 = join_paths(foo, bar)
res2 = foo / bar

VARARGS

  • part — str, 1...N times. The path parts to join. that's the whole job.

WARNINGS

Don't use join_paths for sources in a library or executable. You should use files instead. I'm serious, bestie — use files. 🙈

🦋 library() 🦋

SYNOPSIS

lib library(
    target_name,
    source...,
    <lang>_args:,
    <lang>_pch:,
    <lang>_shared_args:,
    <lang>_static_args:,
    build_by_default: true,
    build_rpath:,
    build_subdir:,
    d_debug:,
    d_import_dirs:,
    d_module_versions:,
    d_unittest: false,
    darwin_versions:,
    dependencies:,
    extra_files:,
    gnu_symbol_visibility:,
    gui_app: false,
    implicit_include_directories: true,
    include_directories:,
    install: false,
    install_dir:,
    install_mode:,
    install_rpath:,
    install_tag:,
    install_vala_gir:,
    install_vala_header:,
    install_vala_vapi:,
    link_args:,
    link_depends:,
    link_early_args:,
    link_language:,
    link_whole:,
    link_with:,
    name_prefix:,
    name_suffix:,
    native: false,
    objects:,
    override_options:,
    pic:,
    prelink:,
    rust_abi:,
    rust_crate_type:,
    rust_dependency_map:,
    shortname:,
    sources:,
    soversion:,
    vala_gir:,
    vala_header:,
    vala_shared_args:,
    vala_static_args:,
    vala_vapi:,
    version:,
    vs_module_defs:,
    win_subsystem: 'console',
)

DESCRIPTION

Builds a library that's either static, shared, or both — depending on the value of the default_library user option[26]. 👑

And like... you should use this instead of shared_library, static_library, or both_libraries most of the time. Why? Because it lets you toggle your entire project (subprojects included, the whole squad) from shared to static with just one option. one single option, bestie. that's the dream 🫶

This option applies to libraries being built internal to the entire project. For external dependencies, the default library type preferred is shared. That can be adapted on a per-library basis using the dependency static keyword. iykyk.

The keyword arguments for this are the same as for build_target. literally the same ones, no new lore.

POSARGS

  • target_name — str, required. The unique name of the build target. it's giving main character energy ⭐

VARARGS

  • source — str | file | custom_tgt | custom_idx | generated_list, 0...N times. Input source to compile. The following types are supported:
    • Strings relative to the current source directory
    • file objects defined in any preceding build file
    • The return value of configure-time generators such as configure_file
    • The return value of build-time generators such as custom_target or generator.process

These input files can be sources, objects, libraries, or any other file — Meson auto-categorizes them based on the extension and uses them accordingly. For instance, sources (.c, .cpp, .vala, .rs, etc) get compiled, and objects (.o, .obj) and libraries (.so, .dll, etc) get linked. she sorts them for you, no cap 🎀

With the Ninja backend, Meson creates a build-time order-only dependency[3] on all generated input files, including unknown files. Why? Because it's needed to bootstrap the generation of the real dependencies in the depfile[4] generated by your compiler, so it can figure out when to rebuild sources. Ninja relies on that dependency file for all input files, generated and non-generated. Behavior is similar for the other backends too. iykyk 💜

KWARGS

  • <lang>_args — array[str | file]. Compiler flags to use for the given language; eg: cpp_args for C++. put your language in the blank, slay.
  • <lang>_pch — str. Precompiled header file to use for the given language. precompiled = pre-slay 🔥
  • <lang>_shared_args — array[str], since 1.3.0. Arguments that are only passed to a shared library. exclusive vibes.
  • <lang>_static_args — array[str], since 1.3.0. Arguments that are only passed to a static library. equally exclusive, equally iconic.
  • build_by_default (bool, default: true, since 0.38.0) — bestie this is the "do u actually want this built" switch. Set it to true and the target gets built by default, meaning it comes out when meson compile runs with no arguments. Default is true for literally all built target types. ✨
  • build_rpath (str, since 0.42.0) — a string you add to the target's rpath definition in the build dir — but heads up, it gets removed on install. So it's a build-time-only vibe 💅
  • build_subdir (str, since 1.10.0) — drops the build results into a subdirectory of the name you give, instead of straight into the build directory. Note: this does not touch the install directory — that still uses install_dir. What it's for: sticking a directory name into the build path, whether you need it to use the build result while building other targets, or you want multiple targets with the same basename to coexist by giving each one a unique build_subdir. To prevent collisions inside the build directory, build_subdir is not allowed to match a file or directory in the source directory, and it can't contain '..' to point at the parent of the build directory. No sneaky escaping 🚫
  • d_debug (array[str]) — the D version identifiers[5] to add while compiling D source files 🎀
  • d_import_dirs (array[inc | str], since 0.62.0) — the directories to add to the string search path (that's the -J switch for DMD). Has to be objects made with the include_directories function, or plain strings — those get implicitly converted into inc objects 🦋
  • d_module_versions (array[str | int]) — the list of module version identifiers set when compiling D sources 🌸
  • d_unittest (bool, default: false) — set to true and the D modules get compiled in debug mode 🧚
  • darwin_versions (str | int | array[str], since 0.48.0) — defines the compatibility version and current version for the dylib on macOS. If you hand it an array, it must have either zero, one, or two elements. If there's only one element, or it's not an array at all, that value sets both the compatibility version and the current version. And if you leave it unspecified, the soversion gets used following those same rules. Slay 🍓
  • dependencies (array[dep]) — one or more dependency objects, created with dependency or compiler.find_library (for external deps), or declare_dependency (for deps built by the project) 💖
  • extra_files (str | file) — not used for the build itself, but they show up as source files in IDEs that group files by targets (Visual Studio, for example). Important: these may only be static sources 👑
  • gnu_symbol_visibility (str, since 0.48.0) — specifies how symbols should be exported — peep e.g. the GCC Wiki[6] for the deets. The value can be an empty string or one of default, internal, hidden, protected, or inlineshidden (which is the same as hidden but also includes things like C++ implicit constructors, as specified in the GCC manual). Ignored on compilers that don't support GNU visibility arguments. Also see the snippets.symbol_visibility_header()[7] method — it helps with defining public API 🫶
  • gui_app (bool, default: false, deprecated since 0.56.0) — set to true and it flags this target as a GUI application on platforms where that makes a difference. But bestie it's deprecated since 0.56.0 — use win_subsystem instead, ok? 💀
  • implicit_include_directories (bool, default: true, since 0.42.0) — controls whether Meson adds the current source and build directories to the include path 🌈
  • include_directories (array[inc | str]) — one or more objects made with the include_directories function, or (since 0.50.0) strings, which get implicitly converted to inc objects ⭐
  • install (bool, default: false) — set to true and all outputs of this build_target get installed 🙈
  • install_dir (array[str | bool]) — overrides the install directory for outputs of this build target. If the value is a relative path, it's considered relative to the prefix option. Like, if you want to install plugins into a subdir, you'd do something like this: install_dir : get_option('libdir') / 'projectname-1.0' ✨

You can also set this to an array of values to control the installation path of build targets with multiple outputs — right now that means Vala. Setting them to true means "use the default", and false means don't install. By default the first element is true, and all the other elements are false.

Since 1.11.0, passing an array is deprecated — use the install_vala_header, install_vala_vapi, and install_vala_gir keyword arguments instead 🎀
  • install_mode (array[str | int], since 0.47.0) — specify the file mode in symbolic format, and optionally the owner/uid and group/gid, for the installed files. See the install_mode kwarg of install_data for more info 💜
  • install_rpath (str) — a string that sets the target's rpath after install (but not before that). On Windows this argument has no effect, periodt 🪟
  • install_tag (str, since 0.60.0) — a string used by the meson install --tags command to install only a subset of the files. By default every build target has the tag runtime, except static libraries, which get the devel tag 🌸
  • install_vala_gir (str | bool, since 1.11.0) — give it a string value and the vala-generated gir library installs to that path; give it true and the default gir path is used; give it false and the gir library doesn't get installed at all. It is an error for this to be either true or a string while vala_gir is unset 🚨 The default value is false.
  • install_vala_header (str | bool, since 1.11.0) — give it a string value and the vala-generated header installs to that path; true means the default include path is used; false means the header won't be installed. The default value is false 🦋
  • install_vala_vapi (str | bool, since 1.11.0) — give it a string value and the vala-generated vapi library installs to that path; true means the default vapi path is used; false means the vapi library won't be installed. The default value is false 🧚
  • link_args (array[str]) — flags to use during linking. You can use UNIX-style flags here for all platforms, no cap 🔥
  • link_depends (str | file | custom_tgt | custom_idx) — strings, files, or custom targets that the link step depends on, like a symbol visibility map. The whole point: automatically trigger a re-link (but not a re-compile) of the target whenever this file changes 👑
  • link_early_args (array[str]) — flags to use during linking, just like link_args, except these get inserted into the linker command line before any object files or libraries. UNIX-style flags work here for all platforms. Only supported when using the Ninja backend 🥷
  • link_language (str, since 0.51.0) — makes the linker for this target be for the language you specify. Honestly it's generally unnecessary to set this, since Meson detects the right linker to use in most cases. There are only two cases where you actually need it: one, your main function in an executable isn't in the language Meson picked; or two, you want to force a library to use only one ABI. Also — (broken until 0.55.0) 💀
  • link_whole (array[lib | custom_tgt | custom_idx], since 0.40.0) — links all contents of the given static libraries, whether they're used or not — equivalent to the -Wl,--whole-archive argument flag of GCC, or the ´/WHOLEARCHIVE' MSVC linker option. This lets the linked target re-export symbols from all objects in the static libraries 🙌

(since 0.41.0) If you pass an array, that array gets flattened.

(since 0.51.0) This argument also accepts outputs produced by custom targets. The user must ensure that the output is a library in the correct format — that's on you, bestie 🫡

  • link_with (array[lib | custom_tgt | custom_idx]) — one or more shared or static libraries (built by this project) that this target should be linked with. (since 0.41.0) If you pass an array, that array gets flattened. (since 0.51.0) The arguments can also be custom targets — in that case Meson assumes that merely adding the output file in the linker command line is enough to make linking work. If that's not enough, then the build system writer must write all the other steps manually 😭
  • name_prefix (str) — the string used as the prefix for the target output filename, overriding the default (only used for libraries). By default that's lib on all platforms and compilers, except MSVC shared libraries where it's omitted to follow convention, and Cygwin shared libraries where it's cyg. Want to conditionally keep the default behavior? Use a default object. For Meson < 1.12, use [] 🎀
  • name_suffix (str) — the string used as the extension for the target, overriding the default. By default on Windows that's exe for executables, and on other platforms it's omitted ✨

For shared libraries, the default value is dylib on macOS, dll on Windows, and so everywhere else. For static libraries, it's a everywhere. By convention MSVC static libraries use the lib suffix, but we use a to avoid a potential name clash with shared libraries, which also generate import libraries with a lib suffix 👀

To conditionally keep the default behavior use a default object. For Meson < 1.12, use [] 🍓

  • native (bool, default: false) — controls whether the target is compiled for the build machines or the host machines 💅
  • objects (array[extracted_obj | file | str]) — list of object files that should be linked into this target 🧚

Since 1.1.0 this can include generated files, on top of object files you don't have source for, or object files produced by other build targets. In earlier releases, generated object files had to be placed in sources 🌈

  • override_options array[str] | dict[str | bool | int | array[str]], since 0.40.0 — bestie this takes an array of strings in the exact same format as project's default_options, and it overrides the values of those options for this target only ✨ (since 1.2.0): you can now pass a dictionary too 🫶
  • pic bool, since 0.36.0 — builds the library as positional independent code (so it can be linked into a shared library). Lowkey no effect on Windows and OS X tho — because it doesn't make sense on Windows and PIC literally cannot be disabled on OS X 💅
  • prelink bool, since 0.57.0 — if true, the object files in the target will be prelinked, meaning it'll contain only one prelinked object file rather than the individual object files 🎀
  • rust_abi str, since 1.3.0 — sets the specific ABI to compile (when compiling rust):
    • 'rust' (default): create a "rlib" or "dylib" crate depending on the library type being build.
    • 'c': create a "cdylib" or "staticlib" crate depending on the library type being build.
  • rust_crate_type str, deprecated since 1.3.0, since 0.42.0 — sets the specific type of rust crate to compile (when compiling rust) 🦀

If the target is an executable this defaults to "bin", the only allowed value.

If it is a static_library it defaults to "lib", and may be "lib", "staticlib", or "rlib". If "lib" then Rustc will pick a default, "staticlib" means a C ABI library, "rlib" means a Rust ABI.

If it is a shared_library it defaults to "lib", and may be "lib", "dylib", "cdylib", or "proc-macro". If "lib" then Rustc will pick a default, "cdylib" means a C ABI library, "dylib" means a Rust ABI, and "proc-macro" is a special rust procedural macro crate.

"proc-macro" is new in 0.62.0.

Since 1.3.0 this is deprecated and replaced by the "rust_abi" keyword argument. proc_macro crates are now handled by the rust.proc_macro()[8] method 🫡

  • rust_dependency_map dict[str], since 1.2.0 — on rust targets this lets you give custom names to the crates that are linked into the target. So like, passing a dependency map of { 'gtk4': 'gtk' } has the same effect as writing gtk.package = "gtk4" in the dependencies section of a Cargo.toml file, or extern crate gtk4 as gtk inside Rust code 👑

Since 1.10.0, the keys can be either crate names or target names.

  • shortname str, since 1.10.0 — a string specifying a DLL name fitting to the 8.3 limit on OS/2 of this shared library 🪟
  • sources str | file | custom_tgt | custom_idx | generated_list | structured_src — additional source files. Same as the source varargs, no cap 📁
  • soversion str | int — a string or integer specifying the soversion of this shared library, like 0. On Linux and Windows this is used to set the soversion (or equivalent) in the filename ✨ So like, if soversion is 4, a Windows DLL will be called foo-4.dll and one of the aliases of the Linux shared library would be libfoo.so.4. If this isn't specified, the first part of version gets used instead (see below). For example, if version is 3.6.0 and soversion isn't defined, it's set to 3.
  • vala_gir str — if set, generates a GIR file with the given name. If this is unset then no GIR file will be generated 🧚
  • vala_header str — on Vala targets, this gives you a way to override the name of the generated C compatible header for targets that generate them. If it's not set the default will be calculated from the target's name 💜
  • vala_shared_args array[str | file], since 1.3.0 — arguments that are only passed to a shared library. Like vala_args, files is allowed in addition to string 🌸
  • vala_static_args array[str | file], since 1.3.0 — arguments that are only passed to a static library. Like vala_args, files is allowed in addition to string 🌸
  • vala_vapi str — on Vala targets, this gives you a way to override the name of the generated VAPI file. If it's not set the default will be calculated from the target's name 🦋
  • version str — a string specifying the version of this shared library, like 1.1.0. On Linux and OS X, this is used to set the shared library version in the filename, such as libfoo.so.1.1.0 and libfoo.1.1.0.dylib. If this isn't specified, soversion is used instead (see above) ⭐
  • vs_module_defs str | file | custom_tgt | custom_idx — specify a Microsoft module definition file for controlling symbol exports, etc., on platforms where that's possible (e.g. Windows) 🪟

(Since 1.3.0) custom_idx are supported

  • win_subsystem str, default: 'console', since 0.56.0 — specifies the subsystem type to use on the Windows platform. Typical values include console for text mode programs and windows for gui apps. The value can also contain version specification such as windows,6.0. See MSDN documentation[9] for the full list 💅

⚠️ WARNINGS ⚠️

using <lang>_shared_args and/or <lang>_static_args may lead to much higher compilation times with both_library, as object files cannot be shared between the static and shared targets. It is guaranteed to not duplicate the build if these arguments are empty arrays 🫶


💬 message()

SYNOPSIS

void message(text, more_text...)

DESCRIPTION

This function prints its argument to stdout 📢 like it's literally just saying hi to your terminal bestie.

POSARGS

  • text str | int | bool | array[str | int | bool] | dict[str | int | bool], required — the message to print 💖

VARARGS

  • more_text str | int | bool | array[str | int | bool] | dict[str | int | bool], 0...N times, since 0.54.0 — additional text that will be printed separated by spaces ✨

🎀 project()

SYNOPSIS

void project(
    project_name,
    language...,
    default_options:,
    license:,
    license_files:,
    meson_version:,
    subproject_dir: 'subprojects',
    version:,
)

DESCRIPTION

The first function called in each project, to initialize Meson 👑 main character energy fr.

The first argument to this function must be a string defining the name of this project.

The project name can be any string you want, it's not used for anything except descriptive purposes. However since it's written to e.g. the dependency manifest it usually makes sense to have it be the same as the project tarball or pkg-config name. So for example you'd probably want to use the name libfoobar instead of The Foobar Library 🙈

It may be followed by the array of programming languages that the project uses.

(since 0.40.0) The array of languages is optional 👀

These languages may be used both for native: false (the default) (host machine) targets and for native: true (build machine) targets. (since 0.56.0) The build machine compilers for the specified languages are not required 💅

Supported values for languages are c, cpp (for C++), cuda, cython, d, objc, objcpp, fortran, java, cs (for C#), swift, nasm, masm, linearasm, vala and rust 🌈

POSARGS

  • project_name str, required — the name of the project 💖

VARARGS

  • language str, 0...N times — the languages that Meson should initialize 🛠️

KWARGS

  • default_options array[str] | dict[str | bool | int | array[str]] — accepts strings in the form key=value which have the same format as options to meson configure. So like, to set the default project type you'd set this: default_options : 'buildtype=debugoptimized']. Heads up tho, these settings are only used when running Meson for the first time ⏰

Also note that some options can override the default behavior — for example, using c_args here means that the CFLAGS environment variable is not used. Consider using add_project_arguments() instead 🫶

And also note that not all options are taken into account when building as a subproject, and the exact set of options that are per-subproject has increased over time; for more information, see [core options[19] and compiler options[27].

(since 1.2.0): a dictionary may now be passed ✨

  • license str | array[str] — takes a string or array of strings describing the license(s) the code is under 📜

This should be an SPDX license expression[28], using the standardized license identifier from the SPDX license list[29]. Usually this would be something like license : 'GPL-2.0-or-later'. If there are multiple licenses you can use the AND and OR operators to join them: license : 'Apache-2.0 OR GPL-2.0' 💅

For backwards compatibility reasons you can also pass an array of licenses here. This is not recommended, as it is ambiguous: license : ['Apache-2.0', 'GPL-2.0-only'] — instead use an SPDX expression: license : 'Apache-2.0 OR GPL-2.0-only', which makes it clear that the license mean OR, not AND 👏

Note that the text is informal and is only written to the dependency manifest. Meson does not do any license validation, you are responsible for verifying that you abide by all licensing terms 😭 You can access the value in your Meson build files with meson.project_license().

  • license_files str | array[str], since 1.1.0 — takes a string or array of strings with the paths to the license file(s) the code is under 📄

This enhances the value of the license kwarg by allowing you to specify both the short license name and the full license text. Usually this would be something like license_files: ['COPYING'] 🎀

Note that the files are informal and are only installed with the dependency manifest. Meson does not do any license validation, you are responsible for verifying that you abide by all licensing terms 😭 You can access the value in your Meson build files with meson.project_license_files.

  • meson_version str — takes a string describing which Meson version the project requires. Usually something like >=0.28.0 ⭐
  • subproject_dir str, default: 'subprojects' — this is the name of the top-level directory where your subprojects live. It's literally only here as a compat thing for old codebases that keep their embedded source in some custom folder. Brand new projects? Do not set this, bestie, just vibe with the default 💅. Also important: this kwarg gets ignored inside subprojects — there can only be one subproject dir and it's set in the top level meson.build. Periodt.
  • version str | file — a free-form string describing your project's version. No rules, no format police, you do you ✨. You can grab the value in your Meson build files with meson.project_version. (Since 0.57.0) this can also be a file object pointing at a file that contains exactly one line of text. One line. That's it. 🎀

🦋 range()

SYNOPSIS

range range([start], [stop], [step])

since 0.58.0

DESCRIPTION

Returns an opaque object that can only be used in foreach statements. It's giving "look but don't touch" energy 🙈.

range range(int stop)
range range(int start, int stop[, int step])
  • start must be an integer greater or equal to 0. Defaults to 0.
  • stop must be an integer greater or equal to start.
  • step must be an integer greater or equal to 1. Defaults to 1.

It causes the foreach loop to be called with the value from start included to stop excluded, with an increment of step after each loop. Classic off-by-one trap, but make it fashion 💅.

OPTARGS

  • start int, default: 0 — the start of the range 🌸
  • stop int — the end of the range
  • step int, default: 1 — the loop increment

EXAMPLE

# Loop 15 times with i from 0 to 14 included.
foreach i : range(15)
  ...
endforeach

The range object can also be assigned to a variable and indexed. Iconic, honestly 👑

r = range(5, 10, 2)
assert(r[2] == 9)

🔥 run_command()

SYNOPSIS

runresult run_command(
    command...,
    capture: true,
    check: false,
    console: false,
    env:,
)

DESCRIPTION

Runs the command specified in positional arguments. command can be a string, or the output of find_program, files or configure_file, or a compiler object. So many options, all valid, all slaying ✨.

Returns a runresult object containing the result of the invocation. The command is run from an unspecified directory, and Meson will set three environment variables — MESON_SOURCE_ROOT, MESON_BUILD_ROOT and MESON_SUBDIR — that specify the source directory, build directory and subdirectory the target was defined in, respectively. So if your script is confused about where it is, that's on the unspecified directory, not on you 🫶.

See also External commands[30].

VARARGS

  • command str | file | program, 0...N times — the command to execute during the setup process.

KWARGS

  • capture bool, default: true, since 0.47.0 — if true, any output generated on stdout will be captured and returned by the .stdout() method. If it is false, then .stdout() will return an empty string. So no sneaky peeking 👀.
  • check bool, default: false, since 0.47.0 — if true, the exit status code of the command will be checked, and the configuration will fail if it is non-zero. Heads up: the default value will be true in future releases, so like… plan accordingly 💀.
  • console bool, default: false, since 1.11.0 — stdout and stderr are written to console as it is generated by the command. Meant for commands that are resource-intensive and take a long time to finish. Basically the "let me watch it cook" option 🍓.
  • env env | array[str] | dict[str], since 0.50.0 — environment variables to set, such as ['NAME1=value1', 'NAME2=value2'], or an env object which allows more sophisticated environment juggling. (Since 0.52.0) A dictionary is also accepted.

🌈 run_target()

SYNOPSIS

run_tgt run_target(target_name, command:, depends:, env:)

DESCRIPTION

This function creates a new top-level target that runs a specified command with the specified arguments. Like all top-level targets, this integrates with the selected backend — for instance, you can run it as meson compile target_name. Note that a run target produces no output as far as Meson is concerned. It is only meant for tasks such as running a code formatter or flashing an external device's firmware with a built file. Main character energy: does the work, takes zero credit 💅.

The command is run from an unspecified directory, and Meson will set three environment variables — MESON_SOURCE_ROOT, MESON_BUILD_ROOT and MESON_SUBDIR — that specify the source directory, build directory and subdirectory the target was defined in, respectively.

Since 0.57.0 the template strings passed to command keyword arguments accept the following special substitutions:

  • @SOURCE_ROOT@: the path to the root of the source tree. Depending on the backend, this may be an absolute or a relative to current workdir path.
  • @BUILD_ROOT@: the path to the root of the build tree. Depending on the backend, this may be an absolute or a relative to current workdir path.
  • @CURRENT_SOURCE_DIR@ Since 0.57.1: this is the directory where the currently processed meson.build is located in. Depending on the backend, this may be an absolute or a relative to current workdir path.

POSARGS

  • target_name str, required — the name of the run target ⭐

KWARGS

  • command array[exe | program | custom_tgt | file | str] — an array containing the command to run and the arguments to pass to it. Each array element may be a string or a target. For instance, passing the return value of executable as the first item will run that executable, or passing a string as the first item will find that command in PATH and run it.
  • depends array[build_tgt | custom_tgt | custom_idx | program] — an array of targets that this target depends on but which are not listed in the command array (because, for example, the script does file globbing internally, custom_idx was not possible as a type between 0.60 and 1.4.0). program is supported since 1.11.2. Ngl, that parenthetical is a whole lore drop 😭.
  • env env | array[str] | dict[str], since 0.57.0 — environment variables to set, such as {'NAME1': 'value1', 'NAME2': 'value2'} or ['NAME1=value1', 'NAME2=value2'], or an env object which allows more sophisticated environment juggling.

🎀 set_variable()

SYNOPSIS

void set_variable(variable_name, value)

DESCRIPTION

Assigns a value to the given variable name. Calling set_variable('foo', bar) is equivalent to foo = bar. Same thing, different font 💖.

(since 0.46.1) The value parameter can be an array type.

POSARGS

  • variable_name str, required — the name of the variable to set
  • value any, required — the value to set the variable to

👑 shared_library()

SYNOPSIS

lib shared_library(
    target_name,
    source...,
    <lang>_args:,
    <lang>_pch:,
    build_by_default: true,
    build_rpath:,
    build_subdir:,
    d_debug:,
    d_import_dirs:,
    d_module_versions:,
    d_unittest: false,
    darwin_versions:,
    dependencies:,
    extra_files:,
    gnu_symbol_visibility:,
    gui_app: false,
    implicit_include_directories: true,
    include_directories:,
    install: false,
    install_dir:,
    install_mode:,
    install_rpath:,
    install_tag:,
    install_vala_gir:,
    install_vala_header:,
    install_vala_vapi:,
    link_args:,
    link_depends:,
    link_early_args:,
    link_language:,
    link_whole:,
    link_with:,
    name_prefix:,
    name_suffix:,
    native: false,
    objects:,
    override_options:,
    rust_abi:,
    rust_crate_type:,
    rust_dependency_map:,
    shortname:,
    sources:,
    soversion:,
    vala_gir:,
    vala_header:,
    vala_vapi:,
    version:,
    vs_module_defs:,
    win_subsystem: 'console',
)

DESCRIPTION

Builds a shared library with the given sources. Simple as that, and yet so powerful 🔥.

POSARGS

  • target_name str, required — the unique name of the build target

VARARGS

  • source str | file | custom_tgt | custom_idx | generated_list, 0...N times — input source to compile. The following types are supported:
    • Strings relative to the current source directory
    • file objects defined in any preceding build file
    • The return value of configure-time generators such as configure_file
    • The return value of build-time generators such as custom_target or generator.process

These input files can be sources, objects, libraries, or any other file. Meson will automatically categorize them based on the extension and use them accordingly. For instance, sources (.c, .cpp, .vala, .rs, etc) will be compiled and objects (.o, .obj) and libraries (.so, .dll, etc) will be linked. It literally sorts your files for you, we love a self-sufficient queen 💅.

With the Ninja backend, Meson will create a build-time order-only dependency[3] on all generated input files, including unknown files. This is needed to bootstrap the generation of the real dependencies in the depfile[4] generated by your compiler to determine when to rebuild sources. Ninja relies on this dependency file for all input files, generated and non-generated. The behavior is similar for other backends.

KWARGS

  • <lang>_args array[str | file] — compiler flags to use for the given language; eg: cpp_args for C++
  • <lang>_pch str — precompiled header file to use for the given language
  • build_by_default bool, default: true, since 0.38.0 — causes, when set to true, to have this target be built by default. This means it will be built when meson compile is called without any arguments. The default value is true for all built target types. Yes, everything gets built by default, that's the vibe ✨.
  • build_rpath str, since 0.42.0 — a string to add to target's rpath definition in the build dir, but which will be removed on install. Sneaky little build-only rpath, we see you 🫶.

...and we're still going through the keyword args bestie, hydrate before you continue ✨

  • build_subdir str, since 1.10.0 — drops the build results into a subdirectory of that name instead of straight into the build dir. Lowkey important: this does not touch the install directory, that one's still install_dir's whole job. It's for when you need a directory name wedged into the build path (say, you need the build result while building other targets) or when you've got multiple targets with the same basename and you want to keep them from beefin' by giving each a unique build_subdir value. To stop collisions inside the build directory, build_subdir is not allowed to match a file or directory in the source directory, and it can't contain .. to point at the parent of the build directory. No escaping the build dir, periodt 🚫
  • d_debug array[str] — the D version identifiers[5] to add while compiling D source files.
  • d_import_dirs array[inc | str], since 0.62.0 — the directories added to the string search path (that's the -J switch for DMD, iykyk). Gotta be objects made with the include_directories function, or plain strings, which get implicitly converted into inc objects 💫
  • d_module_versions array[str | int] — the list of module version identifiers set when compiling D sources.
  • d_unittest bool, default: false — set it to true and the D modules compile in debug mode.
  • darwin_versions str | int | array[str], since 0.48.0 — defines the compatibility version and current version for the dylib on macOS 🍎 If you pass an array it has to have either zero, one, or two elements. One element only, or not an array at all? Then that value sets both compatibility version and current version. Leave it unspecified and the soversion gets used, following the same rules as above.
  • dependencies array[dep] — one or more dependency objects made with dependency or compiler.find_library (for external deps) or declare_dependency (for deps your own project builds).
  • extra_files str | file — not used for the build itself, they just show up as source files in IDEs that group files by targets (Visual Studio vibes). Heads up though: these may only be static sources. 💅
  • gnu_symbol_visibility str, since 0.48.0 — says how symbols should be exported, check the GCC Wiki[6] for the deets. Value is either an empty string or one of default, internal, hidden, protected or inlineshidden — that last one is the same as hidden but also grabs stuff like C++ implicit constructors as spelled out in the GCC manual. Straight up ignored on compilers that don't do GNU visibility arguments. Also peep the snippets.symbol_visibility_header()[7] method, it helps with defining your public API 🫶
  • gui_app bool, default: false, deprecated since 0.56.0 — set it true and the target gets flagged as a GUI application on the platforms where that actually makes a difference. It's deprecated since 0.56.0, so ✨ use win_subsystem instead ✨
  • implicit_include_directories bool, default: true, since 0.42.0 — controls whether Meson adds the current source and build directories to the include path.
  • include_directories array[inc | str] — one or more objects created with the include_directories function, or (since 0.50.0) strings, which get implicitly converted to inc objects.
  • install bool, default: false — true means every output of this build_target gets installed 📦
  • install_dir array[str | bool] — overrides the install directory for the outputs of this build target. Relative path? It's considered relative to the prefix option. So like, if you wanna install plugins into a subdir you'd do something like install_dir : get_option('libdir') / 'projectname-1.0'.

You can also set this to an array of values to control the installation path of build targets with multiple outputs — currently that means Vala. true means "use the default", false means don't install. Default is first element true, all the other elements false.

Since 1.11.0 passing an array is deprecated 🙈 and you should use the install_vala_header, install_vala_vapi, and install_vala_gir keyword arguments instead.

  • install_mode array[str | int], since 0.47.0 — specify the file mode in symbolic format, plus optionally the owner/uid and group/gid for the installed files. Check the install_mode kwarg of install_data for more info.
  • install_rpath str — a string that sets the target's rpath after install (not before, bestie, read it again). On Windows this argument does absolutely nothing 💀
  • install_tag str, since 0.60.0 — a string the meson install --tags command uses to install only a subset of the files. Default is that all build targets carry the tag runtime, except static libraries which get the devel tag.
  • install_vala_gir str | bool, since 1.11.0 — string value? The vala-generated gir library installs to that path. true? Default gir path it is. false? Not installed at all. ⚠️ It's an error for this to be either true or a string while vala_gir is unset. Default value is false.
  • install_vala_header str | bool, since 1.11.0 — string value? The vala-generated header installs to that path. true? Default include path. false? Header stays uninstalled. Default value is false.
  • install_vala_vapi str | bool, since 1.11.0 — string value? The vala-generated vapi library installs to that path. true? Default vapi path. false? No vapi library for you. Default value is false.
  • link_args array[str] — flags to use during linking. UNIX-style flags are fine here on all platforms, no cap 🔥
  • link_depends str | file | custom_tgt | custom_idx — strings, files, or custom targets that the link step depends on, like a symbol visibility map. The whole point? Auto-trigger a re-link (but not a re-compile) of the target whenever that file changes.
  • link_early_args array[str] — flags for linking, just like link_args except these get inserted into the linker command line before any object files or libraries. UNIX-style flags work here on all platforms. Only supported when you're using the Ninja backend 🥷
  • link_language str, since 0.51.0 — makes the linker for this target be for the language you specify. Usually unnecessary, Meson detects the right linker in most cases. Only two situations where you actually need it: one, your main function in an executable isn't in the language Meson picked, or two, you want to force a library to use only one ABI. (broken until 0.55.0, so watch out on the old versions 🙈)
  • link_whole array[lib | custom_tgt | custom_idx], since 0.40.0 — links all the contents of the given static libraries whether they're used or not, equivalent to GCC's -Wl,--whole-archive argument flag, or the ´/WHOLEARCHIVE' MSVC linker option. This is what lets the linked target re-export symbols from every object in those static libraries 👑

(since 0.41.0) Pass an array and that array gets flattened.

(since 0.51.0) Also accepts outputs produced by custom targets — but you, the user, must make sure that output is a library in the correct format. No pressure 😭

  • link_with array[lib | custom_tgt | custom_idx] — one or more shared or static libraries (built by this project) that this target should be linked with. (since 0.41.0) Pass an array, it gets flattened. (since 0.51.0) the arguments can also be custom targets — in that case Meson assumes that merely adding the output file to the linker command line is enough to make linking work. If that's not enough, then the build system writer has to write all the other steps manually, bestie, all of them 💅
  • name_prefix str — the string used as the prefix for the target output filename, overriding the default (only used for libraries). Default is lib on all platforms and compilers, except MSVC shared libraries where it's omitted to follow convention, and Cygwin shared libraries where it's cyg. Wanna conditionally keep the default behavior? Use a default object. For Meson < 1.12, use [].
  • name_suffix str — the string used as the extension for the target, overriding the default. Default on Windows is exe for executables, omitted on other platforms.

For shared libraries the default is dylib on macOS, dll on Windows, and so everywhere else. For static libraries it's a everywhere. By convention MSVC static libraries use the lib suffix, but we use a to dodge a potential name clash with shared libraries, which also generate import libraries with a lib suffix. Messy? Yes. Correct? Also yes ✨

Wanna conditionally keep the default behavior? Default object. For Meson < 1.12, use [].

  • native bool, default: false — controls whether the target compiles for the build machines or the host machines.
  • objects array[extracted_obj | file | str] — list of object files that should be linked into this target.

Since 1.1.0 this can include generated files, on top of object files you don't have source for or object files produced by other build targets. In earlier releases, generated object files had to live in sources 🎀

  • override_options array[str] | dict[str | bool | int | array[str]], since 0.40.0 — takes an array of strings in the same format as project's default_options, overriding those option values for this target only. (since 1.2.0): you can pass a dictionary now too 🦋
  • rust_abi str, since 1.3.0 — sets the specific ABI to compile (when compiling rust):
    • 'rust' (default): create a "dylib" crate.
    • 'c': create a "cdylib" crate.
  • rust_crate_type str, deprecated since 1.3.0, since 0.42.0 — sets the specific type of rust crate to compile (when compiling rust). Yeah, it's deprecated, don't come for me, I'm just the messenger 💀
  • rust_dependency_map dict[str], since 1.2.0 — on Rust targets this lets you give cute custom names to the crates linked into the target. So like, passing a dependency map of { 'gtk4': 'gtk' } does exactly the same thing as writing gtk.package = "gtk4" in the dependencies section of a Cargo.toml file, or extern crate gtk4 as gtk inside Rust code. Since 1.10.0, the keys can be either crate names or target names, slay.
  • shortname str, since 1.10.0 — a string specifying a DLL name for this shared library that fits the 8.3 limit on OS/2. niche but iconic 💅
  • sources str | file | custom_tgt | custom_idx | generated_list | structured_src — extra source files, literally the same thing as the source varargs.
  • soversion str | int — a string or integer specifying the soversion of this shared library, like 0. On Linux and Windows this sets the soversion (or equivalent) in the filename. Example: if soversion is 4, a Windows DLL gets called foo-4.dll, and one of the aliases of the Linux shared library would be libfoo.so.4. If you don't specify it, the first part of version gets used instead (see below). So if version is 3.6.0 and soversion isn't defined, it's set to 3. 🎀
  • vala_gir str — if you set it, Meson generates a GIR file with the given name. If it's unset, no GIR file gets generated at all. no vibes, no file.
  • vala_header str — on Vala targets, this overrides the name of the generated C compatible header, for targets that generate one. If it's not set, the default is calculated from the target's name.
  • vala_vapi str — on Vala targets, this overrides the name of the generated VAPI file. Again, if it's not set, the default is calculated from the target's name.
  • version str — a string specifying the version of this shared library, like 1.1.0. On Linux and OS X this sets the shared library version in the filename, e.g. libfoo.so.1.1.0 and libfoo.1.1.0.dylib. If you don't specify it, soversion is used instead (see above). they're besties like that 🫶
  • vs_module_defs str | file | custom_tgt | custom_idx — specify a Microsoft module definition file for controlling symbol exports and stuff on platforms where that's even possible (e.g. Windows). (Since 1.3.0) custom_idx is supported too.
  • win_subsystem str, default: 'console', since 0.56.0 — specifies the subsystem type to use on the Windows platform. Typical values include console for text mode programs and windows for gui apps. The value can also contain a version specification like windows,6.0. Peep the MSDN documentation[9] for the full list 🔥

shared_module()

✨ SYNOPSIS ✨

build_tgt shared_module(
    target_name,
    source...,
    <lang>_args:,
    <lang>_pch:,
    build_by_default: true,
    build_rpath:,
    build_subdir:,
    d_debug:,
    d_import_dirs:,
    d_module_versions:,
    d_unittest: false,
    dependencies:,
    extra_files:,
    gnu_symbol_visibility:,
    gui_app: false,
    implicit_include_directories: true,
    include_directories:,
    install: false,
    install_dir:,
    install_mode:,
    install_rpath:,
    install_tag:,
    install_vala_gir:,
    install_vala_header:,
    install_vala_vapi:,
    link_args:,
    link_depends:,
    link_early_args:,
    link_language:,
    link_whole:,
    link_with:,
    name_prefix:,
    name_suffix:,
    native: false,
    objects:,
    override_options:,
    rust_abi:,
    rust_crate_type:,
    rust_dependency_map:,
    sources:,
    vala_gir:,
    vala_header:,
    vala_vapi:,
    vs_module_defs:,
    win_subsystem: 'console',
)

since 0.37.0

💖 DESCRIPTION 💖

Builds a shared module with the given sources. Ok so picture a shared library but with main character energy.

This is the move for building modules that are gonna be dlopen()ed — which means they might contain undefined symbols that get provided by the library that's loading them. and that's fine, that's the whole point, no cap.

If you want your shared module to be able to refer to functions and variables defined in the executable that loads it, you'll need to set the export_dynamic argument of that executable to true. literally required, don't @ me.

🌸 POSARGS 🌸

target_name str, required — the unique name of the build target. one name, one target, no duplicates bestie.

🦋 VARARGS 🦋

source str | file | custom_tgt | custom_idx | generated_list, 0...N times — input source to compile. the supported types are:

  • strings relative to the current source directory
  • file objects defined in any preceding build file
  • the return value of configure-time generators such as configure_file
  • the return value of build-time generators such as custom_target or generator.process

These input files can be sources, objects, libraries, or literally any other file. Meson auto-categorizes them based on the extension and uses them accordingly. So for instance, sources (.c, .cpp, .vala, .rs, etc) get compiled, and objects (.o, .obj) and libraries (.so, .dll, etc) get linked. it just knows 💅

With the Ninja backend, Meson creates a build-time order-only dependency[3] on all generated input files, including unknown ones. Why? because you need it to bootstrap the generation of the real dependencies in the depfile[4] your compiler generates, so it can figure out when to rebuild sources. Ninja relies on that dependency file for all input files, generated and non-generated. Same behavior for other backends too. it's giving infrastructure 😭

🎀 KWARGS 🎀

<lang>_args array[str | file] — compiler flags to use for the given language; eg: cpp_args for C++

<lang>_pch str — precompiled header file to use for the given language

build_by_default bool, default: true, since 0.38.0 — when set to true, this target gets built by default. Which means it'll be built when meson compile is called without any arguments. The default value is true for all built target types. it's built, she's there, she's ready 🌈

build_rpath str, since 0.42.0 — a string to add to the target's rpath definition in the build dir, but which gets removed on install. build-only rpath, we love a temporary commitment.

build_subdir str, since 1.10.0 — places the build results in a subdirectory of the given name rather than directly into the build directory. This does not affect the install directory — that uses install_dir. So what's the point? it lets you insert a directory name into the build path, either when you need it to use the build result while building other targets, or as a way to support multiple targets with the same basename by giving each one unique build_subdir values. To prevent collisions inside the build directory, build_subdir is not allowed to match a file or directory in the source directory, and it can't contain .. to refer to the parent of the build directory. rules are rules 😤

d_debug array[str] — the D version identifiers[5] to add during compilation of D source files.

d_import_dirs array[inc | str], since 0.62.0 — the directories to add to the string search path (i.e. the -J switch for DMD). Must be objects created with the include_directories function, or plain strings, which get implicitly converted into inc objects.

d_module_versions array[str | int] — list of module version identifiers set when compiling D sources.

d_unittest bool, default: false — when set to true, the D modules get compiled in debug mode.

dependencies array[dep] — one or more dependency objects created with dependency or compiler.find_library (for external deps) or declare_dependency (for deps built by the project). collect them like pokémon 🍓

extra_files str | file — not used for the build itself, but they show up as source files in IDEs that group files by targets (like Visual Studio). These may only be static sources. purely for the aesthetic ✨

gnu_symbol_visibility str, since 0.48.0 — specifies how symbols should be exported, see e.g. the GCC Wiki[6] for more info. This value can be either an empty string or one of default, internal, hidden, protected or inlineshidden — and inlineshidden is the same as hidden but also includes things like C++ implicit constructors as specified in the GCC manual. Ignored on compilers that don't support GNU visibility arguments. Also peep the snippets.symbol_visibility_header()[7] method to help with defining public API. 🫶

gui_app bool, default: false, deprecated since 0.56.0 — when set to true, flags this target as a GUI application on platforms where that makes a difference. deprecated since 0.56.0 — use win_subsystem instead. she's retired, respect the legacy 👑

implicit_include_directories bool, default: true, since 0.42.0 — controls whether Meson adds the current source and build directories to the include path

include_directories array[inc | str] — one or more objects created with the include_directories function, or (since 0.50.0) strings, which get implicitly converted to inc objects

install bool, default: false — when set to true, all outputs of this build_target will be installed. all of them. every last one. 💖

  • install_dir — array[str | bool] — this is your "bestie, put the output here instead" knob for the outputs of this build target 💅. If the value is a relative path, it gets treated as relative to the prefix option. Like, say you want to install plugins into a subdir — you'd do something like:
install_dir : get_option('libdir') / 'projectname-1.0'

You can also set it to an array of values to control the installation path of build targets that have multiple outputs. Currently, that means Vala. Setting entries to true means "use the default", and false means, don't install — nope, not installing that one ✨. By default the first element is true, and all other elements are false.

Since 1.11.0 passing an array is deprecated, and the install_vala_header, install_vala_vapi, and install_vala_gir keyword arguments should be used instead. (yes this is a glow-down for that array era, sorry 😭)
  • install_mode — array[str | int], since 0.47.0 — specify the file mode in symbolic format, plus optionally the owner/uid and group/gid, for the installed files 🎀. Peep the install_mode kwarg of install_data for the full tea, because that's where the details live.
  • install_rpath — str — a string that sets the target's rpath to after install (but like… not before that, bestie, timing matters 💀). On Windows, this argument has no effect at all.
  • install_tag — str, since 0.60.0 — a string that the meson install --tags command uses to install only a subset of the files 👑. By default all build targets have the tag runtime, except static libraries, which have the devel tag.
  • install_vala_gir — str | bool, since 1.11.0 — if you set this to a string value, the vala generated gir library gets installed to that path. If it's true, the default gir path is used. If it's false, the gir library is simply not installed 🦋.

It is an error for this to be either true or a string while vala_gir is unset. Yes, that's a hard no, not a vibe check.

The default value is false.

  • install_vala_header — str | bool, since 1.11.0 — if you set this to a string value, the vala generated header gets installed to that path. If it's true, the default include path is used. If it's false, the header is not installed 🌸.

The default value is false.

  • install_vala_vapi — str | bool, since 1.11.0 — if you set this to a string value, the vala generated vapi library gets installed to that path. If it's true, the default vapi path is used. If it's false, the vapi library is not installed 🧚.

The default value is false.

  • link_args — array[str] — flags to use during linking 🔥. You can use UNIX-style flags here on all platforms, no cap.
  • link_depends — str | file | custom_tgt | custom_idx — strings, files, or custom targets that the link step depends on, like a symbol visibility map, for example. The whole point? Automatically trigger a re-link (but not a re-compile) of the target whenever this file changes 💫.
  • link_early_args — array[str] — flags to use during linking, literally just like link_args, except these get inserted into the linker command line before any object files or libraries 🎯. You can use UNIX-style flags here on all platforms. Heads up though: this is only supported when using the Ninja backend.
  • link_language — str, since 0.51.0 — makes the linker for this target be for the specified language. Ngl, it's generally unnecessary to set this, because Meson will detect the right linker to use in most cases. There are only two cases where you actually need it 🫶. One: your main function in an executable isn't in the language Meson picked. Two: you want to force a library to use only one ABI.

(broken until 0.55.0 — yeah, she was not okay for a while 😭)

  • link_whole — array[lib | custom_tgt | custom_idx], since 0.40.0 — links all the contents of the given static libraries whether they're used or not, equivalent to the -Wl,--whole-archive argument flag of GCC, or the ´/WHOLEARCHIVE' MSVC linker option 👑. This lets the linked target re-export symbols from all objects in those static libraries.

(since 0.41.0) If you pass an array, that array will be flattened.

(since 0.51.0) This argument also accepts outputs produced by custom targets. The user must ensure that the output is a library in the correct format — that's on you, bestie, not on Meson 🙈.

  • link_with — array[lib | custom_tgt | custom_idx] — one or more shared or static libraries (built by this project) that this target should be linked with 🔗. (since 0.41.0) If passed an array, that array will be flattened. (since 0.51.0) The arguments can also be custom targets. In this case Meson will assume that merely adding the output file in the linker command line is sufficient to make linking work. If that's not sufficient, then the build system writer must write all the other steps manually 💀.
  • name_prefix — str — the string used as the prefix for the target output filename, overriding the default (this is only used for libraries). By default this is lib on all platforms and compilers, except for MSVC shared libraries where it's omitted to follow convention, and Cygwin shared libraries where it's cyg 💅.

To conditionally keep the default behavior use a default object. For Meson < 1.12, use [].

  • name_suffix — str — the string used as the extension for the target by overriding the default ✨. By default on Windows this is exe for executables, and on other platforms it's omitted.

For shared libraries, the default value is dylib on macOS, dll on Windows, and so everywhere else. For static libraries, it's a everywhere. By convention MSVC static libraries use the lib suffix, but we use a to avoid a potential name clash with shared libraries which also generate import libraries with a lib suffix 🍓.

To conditionally keep the default behavior use a default object. For Meson < 1.12, use [].

  • native — bool, default: false — controls whether the target is compiled for the build machines or the host machines 🌈.
  • objects — array[extracted_obj | file | str] — a list of object files that should be linked in this target 🧩.

Since 1.1.0 this can include generated files, in addition to object files that you don't have source to, or object files produced by other build targets. In earlier releases, generated object files had to be placed in sources.

  • override_options — array[str] | dict[str | bool | int | array[str]], since 0.40.0 — takes an array of strings in the same format as project's default_options, overriding the values of these options for this target only 🎀. (since 1.2.0): a dictionary may now be passed. Fancy.
  • rust_abi — str, since 1.3.0 — sets the specific ABI to compile (when compiling rust) 🦀:
    • 'rust' (default): create a "dylib" crate.
    • 'c': create a "cdylib" crate.
  • rust_crate_type — str, deprecated since 1.3.0, since 0.42.0 — sets the specific type of rust crate to compile (when compiling rust).

If the target is an executable, this defaults to "bin", the only allowed value.

If it's a static_library, it defaults to "lib", and may be "lib", "staticlib", or "rlib". If "lib" then Rustc will pick a default, "staticlib" means a C ABI library, "rlib" means a Rust ABI.

If it's a shared_library, it defaults to "lib", and may be "lib", "dylib", "cdylib", or "proc-macro". If "lib" then Rustc will pick a default, "cdylib" means a C ABI library, "dylib" means a Rust ABI, and "proc-macro" is a special rust procedural macro crate.

"proc-macro" is new in 0.62.0.

Since 1.3.0 this is deprecated and replaced by the "rust_abi" keyword argument. proc_macro crates are now handled by the rust.proc_macro()[8] method. She's retired, but we still remember her 💜
  • rust_dependency_map — dict[str], since 1.2.0 — on rust targets this lets you give custom names to the crates that are linked into the target 🌟. For example, passing a dependency map of { 'gtk4': 'gtk' } has the same effect as writing gtk.package = "gtk4" in the dependencies section of a Cargo.toml file, or extern crate gtk4 as gtk inside Rust code.

Since 1.10.0, the keys can be either crate names or target names.

  • sources — str | file | custom_tgt | custom_idx | generated_list | structured_src — additional source files. Same as the source varargs, bestie 📚.
  • vala_gir — str — if set, generates a GIR file with the given name. If this is unset then no GIR file will be generated, periodt 💅.
  • vala_header — str — on Vala targets, this provides a way to override the name of the generated C compatible header for targets that generate them 🎯.

If it's not set, the default will be calculated from the target's name.

  • vala_vapi — str — on Vala targets, this provides a way to override the name of the generated VAPI file 💖.

If it's not set, the default will be calculated from the target's name.

  • vs_module_defs — str | file | custom_tgt | custom_idx, since 0.52.0 — specify a Microsoft module definition file for controlling symbol exports, etc., on platforms where that's possible (e.g. Windows) 🪟.

(Since 1.3.0) custom_idx are supported.

  • win_subsystem — str, default: 'console', since 0.56.0 — specifies the subsystem type to use on the Windows platform 🔥. Typical values include console for text mode programs and windows for gui apps. The value can also contain a version specification such as windows,6.0. See MSDN documentation[9] for the full list.

🫶 NOTES 🫶

Linking to a shared module on platforms other than Android is deprecated, and will be an error in the future 💀 — like, this is your warning era, bestie, take it seriously.

It was previously allowed because it was the only way to have a shared-library-like target that contained references to undefined symbols. But since 0.40.0, the override_options: build_target keyword argument can be used to create such a shared_library by passing override_options: 'b_lundef=false' ✨. Shared modules have other characteristics that make them incompatible with linking, such as a lack of SONAME 😭. On macOS and iOS, linking to shared modules is disallowed by the linker, so we disallow it at configure time. On Android, if a shared module foo uses symbols from another shared module bar, foo must also be linked to bar. Hence, linking one shared module to another will always be allowed when building for Android 🫶.

🎀 static_library()

SYNOPSIS ✨

lib static_library(
    target_name,
    source...,
    <lang>_args:,
    <lang>_pch:,
    build_by_default: true,
    build_rpath:,
    build_subdir:,
    d_debug:,
    d_import_dirs:,
    d_module_versions:,
    d_unittest: false,
    dependencies:,
    extra_files:,
    gnu_symbol_visibility:,
    gui_app: false,
    implicit_include_directories: true,
    include_directories:,
    install: false,
    install_dir:,
    install_mode:,
    install_rpath:,
    install_tag:,
    install_vala_gir:,
    install_vala_header:,
    install_vala_vapi:,
    link_args:,
    link_depends:,
    link_early_args:,
    link_language:,
    link_whole:,
    link_with:,
    name_prefix:,
    name_suffix:,
    native: false,
    objects:,
    override_options:,
    pic:,
    prelink:,
    rust_abi:,
    rust_crate_type:,
    rust_dependency_map:,
    sources:,
    vala_gir:,
    vala_header:,
    vala_vapi:,
    win_subsystem: 'console',
)

DESCRIPTION 💖

Builds a static library from the sources you hand it. That's the whole vibe. Slay. 🦋

POSARGS 🌸

  • target_name str, required — the unique name of the build target. Iconic, one of a kind, no duplicates allowed, periodt.

VARARGS 🫶

  • source str | file | custom_tgt | custom_idx | generated_list, 0...N times — the input sources to compile. And bestie, the types it accepts are many:
    • strings, which get read relative to the current source directory
    • file objects defined in any preceding build file
    • the return value of configure-time generators like configure_file
    • the return value of build-time generators like custom_target or generator.process

These inputs can literally be sources, objects, libraries, or honestly any other file, and Meson will automatically categorize them by extension and use them accordingly. So sources (.c, .cpp, .vala, .rs, etc) get compiled, and objects (.o, .obj) plus libraries (.so, .dll, etc) get linked. The way it just knows? Main character energy fr.

Ok so with the Ninja backend, Meson creates a build-time order-only dependency[3] on all generated input files — including the unknown ones. Why? Because it needs to bootstrap the generation of the real dependencies in the depfile[4] that your compiler spits out, which is how it figures out when to rebuild sources. Ninja relies on that dependency file for all input files, generated and non-generated alike. The behavior is similar for other backends too. 💅

KWARGS 👑

  • <lang>_args array[str | file] — compiler flags to use for the given language; e.g. cpp_args for C++, iykyk.
  • <lang>_pch str — the precompiled header file to use for the given language.
  • build_by_default bool, default: true, since 0.38.0 — when set to true, this target gets built by default. Translation: it builds when you run meson compile with no arguments. The default value is true for all built target types. 🫡
  • build_rpath str, since 0.42.0 — a string to add to the target's rpath definition in the build dir, but which gets removed on install. Sneaky little build-only situation.
  • build_subdir str, since 1.10.0 — places the build results in a subdirectory of the given name instead of dumping them straight into the build directory. This does not affect the install directory — that's install_dir's job. This lets you insert a directory name into the build path, either when you need it to use the build result while building other targets, or as a way to support multiple targets with the same basename by giving each one a unique build_subdir. To prevent collisions inside the build directory, build_subdir is not allowed to match a file or directory in the source directory, and it can't contain .. to refer to the parent of the build directory. No cap, those are the rules. ✨
  • d_debug array[str] — the D version identifiers[5] to add when compiling D source files.
  • d_import_dirs array[inc | str], since 0.62.0 — the directories to add to the string search path (i.e. the -J switch for DMD). Must be objects created with the include_directories function, or plain strings — and plain strings get implicitly converted into inc objects. 💜
  • d_module_versions array[str | int] — list of module version identifiers set when compiling D sources.
  • d_unittest bool, default: false — when set to true, the D modules are compiled in debug mode.
  • dependencies array[dep] — one or more dependency objects created with dependency or compiler.find_library (for external deps), or declare_dependency (for deps built by the project).
  • extra_files str | file — not used for the build itself, but shown as source files in IDEs that group files by targets (think Visual Studio).

These may only be static sources. 🎀

  • gnu_symbol_visibility str, since 0.48.0 — specifies how symbols should be exported, see e.g. the GCC Wiki[6] for more info. The value can either be an empty string or one of default, internal, hidden, protected, or inlineshidden — which is the same as hidden but also includes things like C++ implicit constructors, as specified in the GCC manual. Ignored on compilers that don't support GNU visibility arguments. Also see the snippets.symbol_visibility_header()[7] method, which helps with defining public API. Obsessed. 🧚
  • gui_app bool, default: false*, **deprecated since 0.56.0** — when set to true, flags this target as a GUI application on platforms where that makes a difference. But bestie, it's **deprecated since 0.56.0** — use win_subsystem` instead. Fr fr, move on. 💀
  • implicit_include_directories bool, default: true, since 0.42.0 — controls whether Meson adds the current source and build directories to the include path.
  • include_directories array[inc | str] — one or more objects created with the include_directories function, or (since 0.50.0) strings, which will be implicitly converted to inc objects.
  • install bool, default: false — when set to true, all outputs of this build_target get installed.
  • install_dir array[str | bool] — override the install directory for outputs of this build target. If the value is a relative path, it's considered relative to the prefix option. So if you wanna install plugins into a subdir, you'd do something like this: install_dir : get_option('libdir') / 'projectname-1.0'.

This can be set to an array of values to control the installation path of build targets with multiple outputs — and currently, that means Vala. Setting them to true means "use the default", and false means "don't install". By default the first element is true and all the other elements are false.

⚠️ Since 1.11.0, passing an array is deprecated — use the install_vala_header, install_vala_vapi, and install_vala_gir keyword arguments instead. Don't be that person still passing arrays, I'm begging. 🙈
  • install_mode array[str | int], since 0.47.0 — specify the file mode in symbolic format, and optionally the owner/uid and group/gid for the installed files. See the install_mode kwarg of install_data for more info.
  • install_rpath str — a string that sets the target's rpath after install (but not before that, bestie — timing matters). On Windows this argument has no effect. 🪟
  • install_tag str, since 0.60.0 — a string used by the meson install --tags command to install only a subset of the files. By default all build targets have the tag runtime, except static libraries, which get the devel tag. Special little snowflakes.
  • install_vala_gir str | bool, since 1.11.0 — if set to a string value, the Vala-generated gir library gets installed to that path; if true, the default gir path is used; if false, the gir library won't be installed.

It is an error for this to be either true or a string while vala_gir is unset. Don't do it.

The default value is false.

  • install_vala_header str | bool, since 1.11.0 — if set to a string value, the Vala-generated header gets installed to that path; if true, the default include path is used; if false, the header won't be installed.

The default value is false.

  • install_vala_vapi str | bool, since 1.11.0 — if set to a string value, the Vala-generated vapi library gets installed to that path; if true, the default vapi path is used; if false, the vapi library won't be installed.

The default value is false.

  • link_args array[str] — flags to use during linking. You can use UNIX-style flags here on all platforms, she's flexible like that. 💅
  • link_depends str | file | custom_tgt | custom_idx — strings, files, or custom targets that the link step depends on, like a symbol visibility map. The whole point is to automatically trigger a re-link (but not a re-compile) of the target whenever this file changes. Efficiency queen. 👑
  • link_early_args array[str] — flags to use during linking, just like link_args — except these get inserted into the linker command line before any object files or libraries. UNIX-style flags work here on all platforms. Only supported when using the Ninja backend, ngl.
  • link_language str, since 0.51.0 — forces the linker for this target to be for the specified language. You generally don't need to set this, because Meson detects the right linker in most cases. There are only two cases where it's actually needed: one, your main function in an executable isn't in the language Meson picked, or two, you want to force a library to use only one ABI.

(broken until 0.55.0) 💀

  • link_whole array[lib | custom_tgt | custom_idx], since 0.40.0 — links all contents of the given static libraries whether they're used or not. Equivalent to the -Wl,--whole-archive argument flag of GCC, or the /WHOLEARCHIVE MSVC linker option. This lets the linked target re-export symbols from all objects in the static libraries.

(since 0.41.0) If you pass an array, that array will be flattened. 🫶

…and here's the tail end of that last argument so you're not missing anything, bestie:

(since 0.51.0) This argument also accepts outputs produced by custom targets. The user must ensure that the output is a library in the correct format.

  • link_with array[lib | custom_tgt | custom_idx] — one or more shared or static libraries (built by this project, no outside randos 💅) that this target should be linked with. (since 0.41.0) If you pass an array, that array gets flattened. (since 0.51.0) The arguments can also be custom targets — and in that case Meson just assumes that merely adding the output file in the linker command line is sufficient to make linking work. If that's not sufficient? Then the build system writer has to write all the other steps manually. No cap, that's on you. 🫶
  • name_prefix str — the string used as the prefix for the target output filename, by overriding the default (only used for libraries, fyi). By default this is lib on all platforms and compilers — except MSVC shared libraries, where it's omitted to follow convention, and Cygwin shared libraries, where it's cyg. To conditionally keep the default behavior, use a default object. For Meson < 1.12, use [].
  • name_suffix str — the string that'll be used as the extension for the target, by overriding the default. By default on Windows this is exe for executables, and on other platforms it's omitted.

For shared libraries, the default value is dylib on macOS, dll on Windows, and so everywhere else. For static libraries it's a everywhere. By convention MSVC static libraries use the lib suffix, but we use a to avoid a potential name clash with shared libraries — which also generate import libraries with a lib suffix. Messy? A little. Necessary? Yes. 😌

To conditionally keep the default behavior, use a default object. For Meson < 1.12, use [].

  • native bool, default: false — controls whether the target is compiled for the build or host machines. That's it, that's the whole vibe check.
  • objects array[extracted_obj | file | str] — list of object files that should be linked in this target.

Since 1.1.0 this can include generated files — in addition to object files that you don't have source to, or that object files produced by other build targets. In earlier release, generated object files had to be placed in sources. (RIP to the old way, she was doing her best. 💀)

  • override_options array[str] | dict[str | bool | int | array[str]], since 0.40.0 — takes an array of strings in the same format as project's default_options, overriding the values of these options for this target only. (since 1.2.0): a dictionary may now be passed. Main character energy: this target gets its own options. 🔥
  • pic bool, since 0.36.0 — builds the library as positional independent code (so it can be linked into a shared library). This option has no effect on Windows and OS X, since it doesn't make sense on Windows and PIC cannot be disabled on OS X. Not me warning you twice 💅
  • prelink bool, since 0.57.0 — if true, the object files in the target will be prelinked, meaning that it will contain only one prelinked object file rather than the individual object files. Consolidation slay. ✨
  • rust_abi str, since 1.3.0 — set the specific ABI to compile (when compiling rust).
    • 'rust' (default): create a "rlib" crate.
    • 'c': create a "staticlib" crate.
  • rust_crate_type str, deprecated since 1.3.0, since 0.42.0 — set the specific type of rust crate to compile (when compiling rust). ⚠️ Deprecated, bestie, so like… use rust_abi instead, but here's the whole lore anyway:

If the target is an executable, this defaults to "bin" — the only allowed value.

If it's a static_library it defaults to "lib", and may be "lib", "staticlib", or "rlib". If "lib" then Rustc will pick a default, "staticlib" means a C ABI library, "rlib" means a Rust ABI.

If it's a shared_library it defaults to "lib", and may be "lib", "dylib", "cdylib", or "proc-macro". If "lib" then Rustc will pick a default, "cdylib" means a C ABI library, "dylib" means a Rust ABI, and "proc-macro" is a special rust procedural macro crate.

"proc-macro" is new in 0.62.0.

Since 1.3.0 this is deprecated and replaced by the rust_abi keyword argument. proc_macro crates are now handled by the rust.proc_macro()[8] method. 🦋

  • rust_dependency_map dict[str], since 1.2.0 — on rust targets this allows giving custom names to the crates that are linked into the target. For example, passing a dependency map of { 'gtk4': 'gtk' } has the same effect of writing gtk.package = "gtk4" in the dependencies section of a Cargo.toml file, or extern crate gtk4 as gtk inside Rust code.

Since 1.10.0, the keys can be either crate names or target names. iykyk 💜

  • sources str | file | custom_tgt | custom_idx | generated_list | structured_src — additional source files. Same as the source varargs. Easy. 🎀
  • vala_gir str — if set, generates a GIR file with the given name. If this is unset, then no GIR file will be generated. Simple as that.
  • vala_header str — on Vala targets, this provides a way to override the name of the generated C compatible header for targets that generate them.

If it is not set, the default will be calculated from the target's name. Meson's got you. 💖

  • vala_vapi str — on Vala targets, this provides a way to override the name of the generated VAPI file.

If it is not set, the default will be calculated from the target's name. (Same deal as the header, iconic symmetry.)

  • win_subsystem str, default: 'console', since 0.56.0 — specifies the subsystem type to use on the Windows platform. Typical values include console for text mode programs and windows for gui apps. The value can also contain version specification such as windows,6.0. See MSDN documentation[9] for the full list.

🧚 structured_sources()

✨ SYNOPSIS

structured_src structured_sources(root, [additional])

since 0.62.0

💫 DESCRIPTION

Create a StructuredSource object, which is opaque and may be passed as a source to any build_target (including static_library, shared_library, executable, etc.). This is useful for languages like Rust, which use the filesystem layout to determine import names. This is only allowed in Rust targets, and cannot be mixed with non structured inputs. 🚨 (Read that twice, bestie — only Rust targets, and no mixing.)

🌸 POSARGS

  • root array[str | file | custom_tgt | custom_idx | generated_list], required — sources to put at the root of the generated structure.

🎀 OPTARGS

  • additional dict[str | file | custom_tgt | custom_idx | generated_list] — additional sources, where the key is the directory under the root to place the values.

👑 subdir()

✨ SYNOPSIS

void subdir(dir_name, if_found:)

💫 DESCRIPTION

Enters the specified subdirectory and executes the meson.build file in it. Once that's done, it returns and execution continues on the line following this subdir() command. Variables defined in that meson.build file are then available for use in later parts of the current build file and in all subsequent build files executed with subdir(). 🫶

Note that this means each meson.build file in a source tree can and must only be executed once. One and done, no reruns. 🚫

🌸 POSARGS

  • dir_name str, required — directory relative to the current meson.build to enter.

Cannot contain .. — nope, no escaping upward, we don't do that here. 🙈

💜 KWARGS

  • if_found array[dep], since 0.44.0 — only enter the subdir if all dep.found methods return true. Conditional queen. ✨

⭐ subdir_done()

✨ SYNOPSIS

void subdir_done()

since 0.46.0

💫 DESCRIPTION

Stops further interpretation of the Meson script file from the point of the invocation. All steps executed up to this point are valid and will be executed by Meson — which means all targets defined before the call of subdir_done will be built. Everything after gets ghosted. 👻

If the current script was called by subdir, the execution returns to the calling directory and continues as if the script had reached the end. If the current script is the top level script, Meson configures the project as defined up to this point. Either way, you're valid. 💅

🌈 EXAMPLE

project('example exit', 'cpp')
executable('exe1', 'exe1.cpp')
subdir_done()
executable('exe2', 'exe2.cpp')

The executable exe1 will be built, while the executable exe2 is not built. Sorry exe2, it's not personal, it's just literally the whole point of this function. 😭


🦋 subproject()

✨ SYNOPSIS

subproject subproject(
    subproject_name,
    default_options:,
    native: false,
    required: true,
    version:,
)

💫 DESCRIPTION

Takes the project specified in the positional argument and brings that into the current build specification by returning a subproject object. Subprojects must always be placed inside the subprojects directory at the top source directory. So for example a subproject called foo must be located in ${MESON_SOURCE_ROOT}/subprojects/foo. House rules, no exceptions. 🏠

  • default_options (since 0.37.0): an array of default option values that override those set in the subproject's meson.options (like default_options in project, they only have effect when Meson is run for the first time, and command line arguments override any default options in build files). (since 0.54.0): default_library built-in option can also be overridden. (since 1.2.0): a dictionary may be passed instead of array. 💅
  • version: works just like the same as in dependency. It specifies what version the subproject should be, as an example >=1.0.1. Yes, the example is literally >=1.0.1.
  • required (since 0.48.0): by default, required is true and Meson will abort if the subproject could not be setup. You can set this to false and then use the .found() method on the subproject object. You may also pass the value of a feature[0] option, same as dependency. 🫶

Note that you can use the returned subproject object to access any variable in the subproject. However, if you want to use a dependency object from inside a subproject, an easier way is to use the fallback: keyword argument to dependency. Big shortcut energy. 🔥

See additional documentation[31]. 📚

🌸 POSARGS

  • subproject_name str, required — name of the subproject. The subproject must exist in the subprojects directory (or the directory specified in the subproject_dir of project) as a directory or wrap file.

✨ KWARGS ✨

  • default_options — array[str] | dict[str | bool | int | array[str]], since 0.37.0

An array of default option values that override the ones set in the subproject's meson.options — it works just like default_options in project, meaning it only has any effect the first time Meson is run, and command line arguments override any default options from build files. (since 0.54.0) the default_library built-in option can get overridden too. (since 1.2.0) you can pass a dictionary now.

  • native — bool, default: false, since 1.12.0

Whether to build this subproject for the host machine or the build machine, bestie. Pick your fighter.

  • required — bool | feature, default: true, since 0.48.0

Works exactly the same as it does in dependency. ✨

  • version — str

Works just like the same thing in dependency — it says what version the subproject should be, like for example >=1.0.1.


🌸 summary() 🌸

SYNOPSIS

void summary(
    key_or_dict,
    [value],
    bool_yn: false,
    list_sep:,
    section:,
)

since 0.53.0

DESCRIPTION

Okay so this one is literally the ✨vibe check✨ of your whole build. It summarizes the build configuration at the end of the build process, and it gives projects (and subprojects!) a way to report all that info in a clear way. 💅

The content is a series of key/value pairs, grouped into sections. If you skip the section keyword argument, those key/value pairs get implicitly grouped into a section with no title. Key/value pairs can optionally be grouped into a dictionary, but keep in mind that dictionaries do not guarantee ordering 🙈. key must be a string, and value can be:

  • an integer, boolean or string
  • since 0.57.0 an external program or a dependency
  • since 0.58.0 a feature option
  • an array of those.

Instead of calling summary as summary(key, value), you can also just pass a dictionary straight to the summary function, like the example below shows. 🫶

summary() can be called multiple times, as long as the same section/key pair doesn't show up twice. All the sections get collected and printed at the end of the configuration, in the same order they were called. Periodt.

POSARGS

  • key_or_dict — str | dict[str | bool | int | dep | program | array[str | bool | int | dep | program]], required

The name of the new entry, or a dict containing multiple entries. If you pass a dict, it's equivalent to calling summary() once for each key-value pair. Just remember: dictionaries do not guarantee ordering. 😭

OPTARGS

  • value — str | bool | int | dep | program | array[str | bool | int | dep | program]

The value to print for the key. Only valid if key_or_dict is a str.

KWARGS

  • bool_yn — bool, default: false

Converts bool values to yes and no. 🎀

  • list_sep — str, since 0.54.0

The separator to use when printing array values in this summary. If you don't give a separator, each array item gets printed on its own line.

  • section — str

The section to put this summary information under. If you omit the section keyword argument, key/value pairs are implicitly grouped into a section with no title.

EXAMPLE

Example meson.build:

project('My Project', version : '1.0')
summary({'bindir': get_option('bindir'),
        'libdir': get_option('libdir'),
        'datadir': get_option('datadir'),
        }, section: 'Directories')
summary({'Some boolean': false,
        'Another boolean': true,
        'Some string': 'Hello World',
        'An array': ['string', 1, true],
        }, section: 'Configuration')

Output:

My Project 1.0

  Directories
    bindir         : bin
    libdir         : lib/x86_64-linux-gnu
    datadir        : share

  Configuration
    Some boolean   : false
    Another boolean: true
    Some string    : Hello World
    An array       : string
                     1
                     true

🔥 test() 🔥

SYNOPSIS

void test(
    name,
    executable,
    args:,
    depends:,
    env:,
    expected_exitcode: 0,
    expected_fail: false,
    is_parallel: true,
    priority: 0,
    protocol: 'exitcode',
    should_fail: false,
    suite:,
    timeout: 30,
    verbose: false,
    workdir:,
)

DESCRIPTION

Defines a test to run with the test harness. It takes two positional arguments: the first is the name of the test, and the second is the executable to run. That executable can be an exe object returned by executable, or a program object returned by find_program. 🧚

(since 0.55.0) When cross compiling, if an exe_wrapper is needed and defined, the environment variable MESON_EXE_WRAPPER will be set to the string value of that wrapper (implementation detail: it uses mesonlib.join_args). Test scripts can use this to run cross built binaries. If your test needs MESON_EXE_WRAPPER in cross build situations, it is your responsibility to return code 77 to tell the harness to report "skip". 💀

By default, the environment variable MALLOC_PERTURB_ is automatically set by meson test to a random value between 1..255. This can help find memory leaks on configurations using glibc, including with non-GCC compilers. But heads up — this can have a performance impact, and it may fail a test because of external libraries whose internals are out of the user's control. To check if this feature is causing an expected runtime crash, disable it by temporarily setting the environment variable MALLOC_PERTURB_=0. While it's preferable to only temporarily disable this check, if a project needs permanent disabling of this check in meson.build, do it like this:

nomalloc = environment({'MALLOC_PERTURB_': '0'})

test(..., env: nomalloc, ...)

By default, the environment variables ASAN_OPTIONS, UBSAN_OPTIONS, and MSAN_OPTIONS are set to enable aborting on detected violations and to give a backtrace. To suppress this, ASAN_OPTIONS, UBSAN_OPTIONS, or MSAN_OPTIONS can be set in the environment. 🩷

Besides running individual executables as test cases, test() can also invoke an external test harness. In that case it's best to use verbose: true (since 0.62.0) and, if the external harness supports it, protocol: 'tap' (since 0.50.0). That way Meson logs each subtest as it runs, instead of dumping the whole log at the end of the run. Iconic.

Defined tests can be run in a backend-agnostic way by calling meson test inside the build dir, or by using backend-specific commands, like ninja test or msbuild RUN_TESTS.vcxproj. Slay.

POSARGS

  • name — str, required

The unique test id. 👑

  • executable — exe | jar | program | file | custom_tgt | custom_idx, required

The program to execute. (Since 1.4.0) A CustomTarget is also accepted.

KWARGS

  • args — array[str | file | tgt | program]

Arguments to pass to the executable.

  • depends — array[build_tgt | custom_tgt | custom_idx | program], since 0.46.0

Specifies that this test depends on the specified target(s), even though it doesn't take any of them as a command line argument. This is meant for cases where the test finds those targets internally — e.g. plugins or globbing. Those targets get built before the test is executed, even if they have build_by_default : false. program is supported since 1.11.2.

  • env — env | array[str] | dict[str]

Environment variables to set, such as ['NAME1=value1', ´NAME2=value2'], or an env object, which allows more sophisticated environment juggling. (Since 0.52.0) A dictionary is also accepted.

  • expected_exitcode — int, default: 0, since 1.11.0

The test is considered passed if the executable returns the specified returncode — only has an effect when protocol is set to exitcode.

  • expected_fail — bool, default: false, since 1.11.0

When true, the test is considered passed if the executable returns a non-zero return value (i.e. reports an error).

  • is_parallel — bool, default: true

When false, it specifies that no other test must be running at the same time as this test. Main character energy only. 💅

  • priority — int, default: 0, since 0.52.0

Specifies the priority of a test. Tests with a higher priority are started before tests with a lower priority. The starting order of tests with identical priorities is implementation-defined. The default priority is 0, and negative numbers are permitted.

  • protocol — str, default: 'exitcode', since 0.50.0

Specifies how the test results are parsed, and can be one of exitcode, tap, or gtest. For more info about the test harness protocol, read Unit Tests[1]. These are the accepted values:

  • exitcode: the executable's exit code is used by the test harness to record the outcome of the test).
  • tap: Test Anything Protocol[2].
  • gtest (since 0.55.0): for Google Tests.
  • rust (since 0.56.0): for native rust tests.
  • should_fail — bool, default: false, deprecated since 1.11.0

When true, the test is considered passed if the executable returns a non-zero return value (i.e. reports an error). It's deprecated, bestie — go use the new one. 🫶

  • suite — str | array[str]

A 'label' (or an array of labels ['label1', 'label2']) attached to this test. The suite name gets qualified by a (sub)project name, resulting in (sub)project_name:label. In the case of an array of strings, the suite names will be (sub)project_name:label1, (sub)project_name:label2, etc.

  • timeout — int, default: 30

The amount of seconds the test is allowed to run; a test that exceeds its time limit is always considered failed, and it defaults to 30 seconds. Since 0.57, if timeout is <= 0 the test has infinite duration — in previous versions of Meson the test would fail with a timeout immediately. 💀

  • verbose — bool, default: false, since 0.62.0

If true, it forces the test results to be logged as if --verbose was passed to meson test.

  • workdir — str

Absolute path that will be used as the working directory for the test.

🫧 unset_variable()

SYNOPSIS

void unset_variable(varname)

since 0.60.0

DESCRIPTION

Okay so this one unsets a variable. That's it, that's the whole vibe. But bestie, listen: referencing a variable which has been unset is an error until it has been set again. So don't go ghosting a variable and then try to call it back like nothing happened 😭

POSARGS

  • varname str, required — the variable to unset.

🏷️ vcs_tag()

SYNOPSIS

custom_tgt vcs_tag(
    command:,
    fallback: [[meson.project_version]],
    input:,
    install: false,
    install_dir:,
    install_mode:,
    install_tag:,
    output:,
    replace_string: '@VCS_TAG@',
)

DESCRIPTION

This command detects revision control commit information at build time and places it in the specified output file ✨. This file is guaranteed to be up to date on every build, which is honestly iconic of it.

Keywords are similar to custom_target.

Meson will read the contents of input, substitute the replace_string with the detected revision number, and write the result to output. This method returns a custom_tgt object that (as usual) should be used to signal dependencies if other targets use the file outputted by this 🫶

For example, if you generate a header with this and want to use that in a build target, you must add the return value to the sources of that build target. Without that, Meson will not know the order in which to build the targets. No cap, it'll just be confused 💀

If you desire more specific behavior than what this command provides, you should use custom_target.

KWARGS

  • command array[exe | program | custom_tgt | file | str] — the command to execute, see custom_target for details on how this command must be specified. This parameter is optional. If it is absent, Meson will try its best to find a suitable default command. (since 0.62.0) file is accepted. (since 0.63.0) custom_tgt, exe, and program are accepted.
  • fallback str, default: [[meson.project_version]] — version number to use when no revision control information is present, such as when building from a release tarball.
  • input str, required — file to modify (e.g. version.c.in).
  • install bool, default: false, since 1.7.0 — when true, this generated file is installed during the install step, and install_dir must be set and not empty.
  • install_dir str, since 1.7.0 — the subdirectory to install the generated file to (e.g. share/myproject).
  • install_mode array[str | int], since 1.7.0 — specify the file mode in symbolic format and optionally the owner/uid and group/gid for the installed files. See the install_mode kwarg of install_data for more information.
  • install_tag str, since 1.7.0 — a string used by the meson install --tags command to install only a subset of the files. By default the file has no install tag which means it is not being installed when --tags argument is specified.
  • output str, required — file to write the results to (e.g. version.c).
  • replace_string str, default: '@VCS_TAG@' — string in the input file to substitute with the commit information.

🚨 warning()

SYNOPSIS

void warning(text, more_text...)

since 0.44.0

DESCRIPTION

This function prints its argument to stdout prefixed with WARNING: 🔥 It's giving "hey bestie, heads up" energy, but officially.

POSARGS

  • text str | int | bool | array[str | int | bool] | dict[str | int | bool], required — the message to print.

VARARGS

  • more_text str | int | bool | array[str | int | bool] | dict[str | int | bool], 0...N times, since 0.54.0 — additional text that will be printed separated by spaces.

🍓 array.contains()

SYNOPSIS

bool array.contains(item)

DESCRIPTION

Returns true if the array contains the object given as argument, false otherwise. Simple vibe check for your array 💅

POSARGS

  • item any, required — the item to check.

🌸 array.flatten()

SYNOPSIS

array[any] array.flatten()

since 1.9.0

DESCRIPTION

Returns a flattened copy of the array, with all nested arrays removed. It's giving "declutter your life" era ✨


🔍 array.get()

SYNOPSIS

any array.get(index, [fallback])

DESCRIPTION

Returns the object at the given index, negative indices count from the back of the array, indexing out of bounds returns the fallback value (since 0.38.0) or, if it is not specified, causes a fatal error 😭 So like, know your bounds, bestie.

POSARGS

  • index int, required — index of the array position to query. Negative values start at the end of the array.

OPTARGS

  • fallback any — fallback value that is returned if the index is out of range.

📏 array.length()

SYNOPSIS

int array.length()

DESCRIPTION

Returns the current size of the array. The way it just tells you how many things are in there, no drama 👑


✂️ array.slice()

SYNOPSIS

array[any] array.slice([start], [stop], step: 1)

since 1.10.0

DESCRIPTION

Return a selection of the elements of the array starting at index start and continuing with step size jumps until stop 🌈

Negative indices count from the back of the array. The step size cannot be zero, but may be negative. If it is negative, start and stop default to the end and beginning of the array, respectively. If step is positive, start defaults to 0 and stop defaults to the length of the array. Either both or none of start and stop must be provided to prevent ambiguity 🫶

OPTARGS

  • start int — the lower bound of the slice.
  • stop int — the upper bound of the slice.

KWARGS

  • step int, default: 1 — the step size.

🧮 bool.to_int()

SYNOPSIS

int bool.to_int()

DESCRIPTION

Returns 1 if true and 0 if false. Bool does basic math era 😌


💬 bool.to_string()

SYNOPSIS

str bool.to_string([true_str], [false_str])

DESCRIPTION

Returns the string 'true' if the boolean is true or 'false' otherwise. You can also pass it two strings as positional arguments to specify what to return for true/false. For instance, bool.to_string('yes', 'no') will return yes if the boolean is true and no if it is false ✨ Customizable, we love to see it.

OPTARGS

  • true_str str, default: 'true' — the string to return when the boolean is true.
  • false_str str, default: 'false' — the string to return when the boolean is false.

🎀 both_libs.get_shared_lib()

SYNOPSIS

lib both_libs.get_shared_lib()

DESCRIPTION

Returns the stored shared library 🦋


🧸 both_libs.get_static_lib()

SYNOPSIS

lib both_libs.get_static_lib()

DESCRIPTION

Returns the stored static library 🦋


🖥️ build_machine.cpu()

SYNOPSIS

str build_machine.cpu()

DESCRIPTION

Returns a more specific CPU name, such as i686, armv8l, etc. Very "what's your exact star sign" of it 🔮


🧬 build_machine.cpu_family()

SYNOPSIS

str build_machine.cpu_family()

DESCRIPTION

Returns the CPU family name. This table[33] contains all known CPU families. These are guaranteed to continue working 💜


🔄 build_machine.endian()

SYNOPSIS

str build_machine.endian()

DESCRIPTION

Returns 'big' on big-endian systems and 'little' on little-endian systems. Pick a lane, bytes 💅


🧠 build_machine.kernel()

SYNOPSIS

str build_machine.kernel()

since 1.2.0

DESCRIPTION

Returns the name of the operating system kernel, such as linux, xnu, and nt. See here for a more complete list[34]. These are more specific than system 👑

If this cannot be detected (for the build machine), or is not set in the cross file (for the host machine when cross compiling), calling this method is fatal 😭


🧩 build_machine.subsystem()

SYNOPSIS

str build_machine.subsystem()

since 1.2.0

DESCRIPTION

Returns the variant of the operating system, such as ios and tvos. See here for a more complete list[35]. These are more specific than system 🦋

If this cannot be detected (for the build machine), or is not set in the cross file (for the host machine when cross compiling), calling this method is fatal 😭


🌍 build_machine.system()

SYNOPSIS

str build_machine.system()

DESCRIPTION

Returns the operating system name. This table[36] lists all of the currently known operating system names. These are guaranteed to continue working 💜


🧲 build_tgt.extract_all_objects()

SYNOPSIS

extracted_obj build_tgt.extract_all_objects(
    recursive: true,
)

DESCRIPTION

Acts the same as extract_objects, but returns all object files generated by this target 🫶

By default only objects built for this target are returned to maintain backward compatibility with previous versions. The default value for the recursive kwarg will eventually be changed to true in a future version.

KWARGS

  • recursive bool, default: true, since 0.46.0 — also return objects passed to the objects argument of this target.

🧷 build_tgt.extract_objects()

SYNOPSIS

extracted_obj build_tgt.extract_objects(source...)

DESCRIPTION

Returns an opaque value representing the object files generated for those source files 👀 This is typically used to take single object files and link them to unit tests or to compile some source files with custom flags. To use the object file(s) in another build target, use the objects: keyword argument to a build_target or declare_dependency, or include them in the command line of a custom_target.

VARARGS

  • source str | file, 1...N times — source filenames for which the built objects should be extracted.

✅ build_tgt.found()

SYNOPSIS

bool build_tgt.found()

since 0.59.0

DESCRIPTION

Always returns true 🌈 This function is meant to make executables objects feature compatible with program objects. This simplifies use-cases where an executable is used instead of an program. It's giving "yes bestie, I'm here, always" 🫶


🗺️ build_tgt.full_path()

SYNOPSIS

str build_tgt.full_path()

DESCRIPTION

Returns a full path pointing to the result target file.

NOTE: In most cases using the object itself will do the same job as this and will also allow Meson to setup inter-target dependencies correctly. Please file a bug if that doesn't work for you 🙈

🏷️ build_tgt.name()

SYNOPSIS

str build_tgt.name()

since 0.54.0

DESCRIPTION

Returns the name of the target. That's it. It's literally just the name 💅


🧭 build_tgt.path()

SYNOPSIS

str build_tgt.path()

deprecated since 0.59.0, since 0.59.0

DESCRIPTION

Okay so this one's deprecated since 0.59.0, and that's genuinely all the page gives us before it cuts off — no extra description, no tea, nothing 😭 The original literally just drops the "deprecated since 0.59.0, since 0.59.0" and that's the whole vibe. More on the next part, bestie 🫶

Does the exact same as build_tgt.full_path.

⚠️ NOTE: this function is solely kept around for compatibility with program objects. It's getting yeeted the second that the — also deprecated, bestie, also deprecated — corresponding path() function in the program object gets removed. So like… don't get attached 💀

🌸 build_tgt.private_dir_include()

SYNOPSIS

inc build_tgt.private_dir_include()

DESCRIPTION

Gives you back a value that behaves just like include_directories, except it points at this target's private directory. Honestly you only need this when some other target wants to peek at internal headers that this target generated. iykyk ✨


🦋 build_tgt.vala_gir()

SYNOPSIS

file build_tgt.vala_gir()

since 1.10.0

DESCRIPTION

Returns a file object pointing at a GIR file that the vala compiler made. But like — if this target doesn't generate a GIR file at all, then calling this method is an error. No file, no vibes 😭


🎀 build_tgt.vala_header()

SYNOPSIS

file build_tgt.vala_header()

since 1.10.0

DESCRIPTION

Returns a file object pointing at a C-compatible header that the vala compiler generated. Same deal as before: if this target doesn't produce a vala header, calling this is an error. Periodt 💅


🧚 build_tgt.vala_vapi()

SYNOPSIS

file build_tgt.vala_vapi()

since 1.10.0

DESCRIPTION

Returns a file object pointing at a VAPI header that the vala compiler generated. And yeah, if this target doesn't generate a VAPI file, this method call is an error. The pattern is pattern-ing 🫶


⭐ cfg_data.get()

SYNOPSIS

str | int | bool cfg_data.get(varname, [default_value])

since 0.38.0

DESCRIPTION

Hands you the value of varname. If that value was never set, it gives you default_value — but only if you defined it (that part's since 0.38.0, bestie). If you didn't define a default, it errors out. No default, no mercy 💀

POSARGS

  • varname str, required — The name of the variable you're querying 👀

OPTARGS

  • default_value str | int | bool — The value to hand back when varname doesn't exist

🌈 cfg_data.get_unquoted()

SYNOPSIS

str | int | bool cfg_data.get_unquoted(varname, [default_value])

since 0.44.0

DESCRIPTION

Same energy as get, except it returns the value of varname without the surrounding double quotes ("). And if the value hasn't been set, it returns default_value when it's defined, and errors out if it isn't. Stripped and slaying 💅

POSARGS

  • varname str, required — The name of the variable you're querying

OPTARGS

  • default_value str | int | bool — The value to return when varname doesn't exist

🍓 cfg_data.has()

SYNOPSIS

bool cfg_data.has(varname)

DESCRIPTION

Returns true if the variable you specified is actually set. A little vibe check for your config data ✨

POSARGS

  • varname str, required — The name of the variable you're querying

💜 cfg_data.keys()

SYNOPSIS

array[str] cfg_data.keys()

since 0.57.0

DESCRIPTION

Returns an array of the keys of the configuration data object. You can iterate over this array with the foreach statement[37]. Lowkey so handy 🌸


🔥 cfg_data.merge_from()

SYNOPSIS

void cfg_data.merge_from(other)

since 0.42.0

DESCRIPTION

Takes a different configuration data object as its argument and copies all the entries from that object into the current one. Established merger behavior 📋➡️📋

POSARGS

  • other cfg_data, required — The other cfg_data object to merge into this one.

👑 cfg_data.set()

SYNOPSIS

void cfg_data.set(varname, value, description:)

DESCRIPTION

Sets a variable to a given value. Simple as 🎀

POSARGS

  • varname str, required — The name of the variable to set
  • value str | int | bool, required — The value to set

KWARGS

  • description str — Message / Comment that will be written in the result file. The replacement assumes a file with C syntax. If your generated file is source code in some other language, you probably don't want to add a description field, because it most likely will cause a syntax error. Fr fr, learn from other people's mistakes 😭

💀 cfg_data.set10()

SYNOPSIS

void cfg_data.set10(varname, value, description:)

DESCRIPTION

Same thing as cfg_data.set, except the value is either true or false, and it gets written as 1 or 0 respectively. Binary baddie behavior 💅

POSARGS

  • varname str, required — The name of the variable to set
  • value bool | int, required — The value to set, as either 1 or 0
Passing numbers was never intended to work, and since 0.62 it's been deprecated. It will be removed in a future version of Meson. If you need to pass numbers, use the .set method instead. This is your sign to migrate 🚨

KWARGS

  • description str — Message / Comment that will be written in the result file. The replacement assumes a file with C syntax. If your generated file is source code in some other language, you probably don't want to add a description field, because it most likely will cause a syntax error.

WARNINGS

Numeric values < 0 have the surprising behavior of being converted to true. Values > 1 have the more expected but unintentional behavior of being interpreted as true. It's giving chaos, honestly 🙈

🦋 cfg_data.set_quoted()

SYNOPSIS

void cfg_data.set_quoted(varname, value, description:)

DESCRIPTION

Is the same as cfg_data.set, but it quotes the value in double quotes ("). Wrapped up cute 🎁

POSARGS

  • varname str, required — The name of the variable to set
  • value str | int | bool, required — The value to set

KWARGS

  • description str — Message / Comment that will be written in the result file. The replacement assumes a file with C syntax. If your generated file is source code in some other language, you probably don't want to add a description field, because it most likely will cause a syntax error.

🌟 cmake.subproject_options()

SYNOPSIS

cmake_options cmake.subproject_options()

DESCRIPTION

Returns an empty cmake_options object. A blank canvas, bestie ✨


🧚 cmake_options.add_cmake_defines()

SYNOPSIS

void cmake_options.add_cmake_defines(defines...)

DESCRIPTION

Adds CMake defines (-D<VAR>=<VAL>) to the CMake commandline. Get those definitions in there 🔥

VARARGS

  • defines dict[str], 0...N times — A key value map of CMake defines to add (-D<key>=<val>)

🎀 compiler.alignment()

SYNOPSIS

int compiler.alignment(typename, args:, dependencies:, prefix:)

DESCRIPTION

Returns the alignment of the type you specified. For C-like languages, the headers stddef.h and stdio.h are included implicitly when you're doing native compilation — when cross-compiling, only stddef.h gets included. Noted and filed away 📝

POSARGS

  • typename str, required — The name of the type to check.

KWARGS

  • args array[str] — Used to pass an array of compiler arguments. Defining include paths for headers that aren't in the default include path via -Isome/path/to/header is generally supported, however, it's usually not recommended.

Why? Because include directories can also be specified via the include_directories or the dependency kwarg (if present). The same is also true for passing libraries to link with -lfoo. So like… use the proper kwargs, bestie 🫶

  • dependencies dep | array[dep] — Additionally, dependencies required for compiling and / or linking.
  • prefix str | array[str] — Used to add #includes and other things that are required for the symbol to be declared. Since 1.0.0 an array is accepted too. When an array is passed, the items are concatenated together separated by a newline. System definitions should be passed via compiler args (eg: _GNU_SOURCE is often required for some symbols to be exposed on Linux, and it should be passed via the args keyword argument).

💜 compiler.check_header()

SYNOPSIS

bool compiler.check_header(
    header_name,
    args:,
    dependencies:,
    include_directories:,
    no_builtin_args: false,
    prefix:,
    required: false,
)

since 0.47.0

DESCRIPTION

Returns true if the header you specified is usable with the specified prefix, dependencies, and arguments. Header check supremacy 👑

POSARGS

  • header_name str, required — The header to check.

KWARGS

  • args array[str] — Used to pass an array of compiler arguments. Defining include paths for headers not in the default include path via -Isome/path/to/header is generally supported, however, usually not recommended.

This is because include directories can also be specified via the include_directories or the dependency kwarg (if present). The same is also true for passing libraries to link with -lfoo.

  • dependencies dep | array[dep] — Additionally dependencies required for compiling and / or linking.
  • include_directories array[inc | str], since 0.38.0 — Extra directories for header searches, created with the include_directories function. (Since 1.10.0) Strings are also accepted. Glow-up behavior ✨
  • no_builtin_args bool, default: false — When set to true, the compiler arguments controlled by built-in configuration options are not added.
  • prefix str | array[str] — Used to add #includes and other things that are required for the symbol to be declared. Since 1.0.0 an array is accepted too. When an array is passed, the items are concatenated together separated by a newline. System definitions should be passed via compiler args (eg: _GNU_SOURCE is often required for some symbols to be exposed on Linux, and it should be passed via the args keyword argument).
  • required bool | feature, default: false, since 0.50.0 — When set to true, Meson will halt if the header check fails. When set to a feature[0] option, that feature controls whether it gets searched and whether it fails if not found. Choose your fighter 💅

🍓 compiler.cmd_array()

SYNOPSIS

array[str] compiler.cmd_array()

DESCRIPTION

Returns an array containing the command(s) for the compiler. Like, the actual invocation. Handy fr fr 🔧


🌈 compiler.compiles()

SYNOPSIS

bool compiler.compiles(
    code,
    args:,
    dependencies:,
    include_directories:,
    name:,
    no_builtin_args: false,
    required: false,
    werror: false,
)

DESCRIPTION

Returns true if the code actually compiles. The moment of truth 😤

POSARGS

  • code str | file, required — The source code to check.

If a string is passed, the code is used directly. If a file object is passed, its content is used for the compiler check. Either way, it's getting compiled 🫡

🎀 KWARGS

  • args array[str] — drop an array of compiler args in here, bestie. Ngl you can define include paths for headers that aren't in the default include path with -Isome/path/to/header and it's generally supported… but it's also usually not recommended, so like, don't.

Why? Because include directories can also be handed over via the include_directories kwarg or the dependency kwarg (if present). Same whole situation applies to passing libraries to link with -lfoo. Slay the proper way, okurr? 💅

  • dependencies dep | array[dep] — extra dependencies needed for compiling and/or linking. Feed them here ✨
  • include_directories array[inc | str], since 0.38.0 — extra directories for header searches, made with the include_directories function. (Since 1.10.0) Strings are accepted too, periodt 🫶
  • name str — the name used for printing a message about the compiler check. If you don't pass this kwarg, literally no message gets printed about the check. That's it, that's the vibe 🦋
  • no_builtin_args bool, default: false — when it's true, the compiler arguments controlled by built-in configuration options are not added. Not me turning off the built-ins 🙈
  • required bool | feature, default: false, since 1.5.0 — set it to true and Meson will halt if the check fails. Set it to a feature[0] option and the feature controls whether it's searched and whether to fail if it's not found 👑
  • *werror bool, default: false, since 1.3.0** — when true`, compiler warnings are treated as errors. Warnings? More like *errors now, bestie 💀

🌸 compiler.compute_int()

SYNOPSIS

int compiler.compute_int(
    expr,
    args:,
    dependencies:,
    guess:,
    high: 1024,
    include_directories:,
    low: -1024,
    no_builtin_args: false,
    prefix:,
)

since 0.40.0 ✨

DESCRIPTION

Okay so this one computes the value of the given expression (like, for example 1 + 2, iconic). When you're cross compiling, this gets evaluated with an iterative algorithm — and you can pass keyword args low (defaults to -1024), high (defaults to 1024) and guess to specify the max and min values for the search plus the value to try first 👑

For C-like languages, the headers stddef.h and stdio.h are included implicitly for native compilation — but only stddef.h is included when cross-compiling. Note the difference, bestie, it's giving subtle 🎀

POSARGS

  • expr str, required — the expression to compute. That's the whole assignment 💖

KWARGS

  • args array[str] — used to pass an array of compiler arguments. Defining include paths for headers not in the default include path via -Isome/path/to/header is generally supported, however, usually not recommended.

This is because include directories can also be specified via the include_directories or the dependency kwarg (if present). The same is also true for passing libraries to link with -lfoo. Same lecture as before, no cap 🫶

  • dependencies dep | array[dep] — additionally dependencies required for compiling and/or linking.
  • guess int — the value to try first. Start somewhere, queen 🌈
  • high int, default: 1024 — the max value.
  • include_directories array[inc | str], since 0.38.0 — extra directories for header searches, created with the include_directories function. (Since 1.10.0) Strings are also accepted.
  • low int, default: -1024 — the min value.
  • no_builtin_args bool, default: false — when set to true, the compiler arguments controlled by built-in configuration options are not added.
  • prefix str | array[str] — used to add #includes and other things that are required for the symbol to be declared. Since 1.0.0 an array is accepted too. When an array is passed, the items are concatenated together separated by a newline 🌸 System definitions should be passed via compiler args (eg: _GNU_SOURCE is often required for some symbols to be exposed on Linux, and it should be passed via the args keyword argument). File that under iykyk 💅

🦋 compiler.find_library()

SYNOPSIS

dep compiler.find_library(
    libname,
    dirs:,
    disabler: false,
    has_headers:,
    header_args:,
    header_dependencies:,
    header_include_directories:,
    header_no_builtin_args: false,
    header_prefix:,
    required: true,
    static: false,
)

DESCRIPTION

It tries to find the library specified in the positional argument. Like a scavenger hunt but for .so files 🔥

POSARGS

  • libname str, required — the library to find. Go get her 💅

KWARGS

  • dirs array[str] — additional directories to search in.

By default the library is searched for in the system library directory (e.g. /usr/lib). Specifying more directories here causes Meson to search in those directories as well as the system directories. You're adding, not replacing, bestie ✨

  • **disabler bool, default: false, since 0.49.0** — if true`, this method will return a disabler on a failed check. Bye bestie 👋
  • has_headers array[str], since 0.50.0 — an array of headers that must be found as well. This check is equivalent to checking each header with a compiler.has_header call.

When used, kwargs that compiler.has_header would accept can be passed here prefixed with header_, and they'll have the same effect on the header check. Cute little naming convention, obsessed 🎀

  • header_args array[str], since 0.51.0 — when the has_headers kwarg is also used, this argument is passed to compiler.has_header as args.
  • header_dependencies dep | array[dep], since 0.51.0 — when the has_headers kwarg is also used, this argument is passed to compiler.has_header as dependencies.
  • header_include_directories array[inc | str], since 0.51.0 — when the has_headers kwarg is also used, this argument is passed to compiler.has_header as include_directories. (Since 1.10.0) Strings are also accepted.
  • header_no_builtin_args bool, default: false, since 0.51.0 — when the has_headers kwarg is also used, this argument is passed to compiler.has_header as no_builtin_args.
  • header_prefix str, since 0.51.0 — when the has_headers kwarg is also used, this argument is passed to compiler.has_header as prefix.
  • required bool | feature, default: true — set it true and Meson will abort with an error if the library couldn't be found. Otherwise Meson keeps going and the found method of the returned object will return false 😭

When set to a feature[0] option, the feature controls whether it's searched and whether to fail if not found.

(since 0.47.0) The value of a feature option can also be passed here.

  • *static bool, default: false, since 0.51.0** — if true, the search is limited to static libraries **only**. Setting this to false` (the default) will search for both shared *and static libraries. Both. Always both. 🌈

💜 compiler.first_supported_argument()

SYNOPSIS

array[str] compiler.first_supported_argument(arg...)

since 0.43.0 ✨

DESCRIPTION

Given an array of strings, it returns a single-element array containing the first argument that passes the compiler.has_argument test — or an empty array if none of them pass. First come, first served, main character energy 👑

VARARGS

  • arg str, 0...N times — the arguments to check. Drop as many as you want 🫶

SYNOPSIS

array[str] compiler.first_supported_link_argument(arg...)

since 0.46.0 ✨

DESCRIPTION

Given an array of strings, returns the first argument that passes the compiler.has_link_argument test — or an empty array if none pass. Same energy, link edition 🔗

VARARGS

  • arg str, 0...N times — the link arguments to check.

⭐ compiler.get_argument_syntax()

SYNOPSIS

str compiler.get_argument_syntax()

since 0.49.0 ✨

DESCRIPTION

Returns a string identifying the type of arguments the compiler takes. Can be one of gcc, msvc, or an undefined string value. This method is useful for identifying compilers that are not gcc or msvc but use the same argument syntax as one of those two — like clang or icc — especially when they use different syntax on different operating systems. Sneaky little syntax twins, we love to see it 💅


🍓 compiler.get_define()

SYNOPSIS

str compiler.get_define(
    definename,
    args:,
    dependencies:,
    include_directories:,
    no_builtin_args: false,
    prefix:,
)

since 0.40.0 ✨

DESCRIPTION

Returns the given preprocessor symbol's value as a string — or an empty string if it's not defined. No symbol, no problem, you just get "" 🎀

(since 0.47.0) This method will concatenate string literals the way the compiler would. E.g. "a" "b" will become "ab". It's giving string glued together with love ✨

POSARGS

  • definename str, required — the define to check.

KWARGS

  • args array[str] — used to pass an array of compiler arguments. Defining include paths for headers not in the default include path via -Isome/path/to/header is generally supported, however, usually not recommended.

This is because include directories can also be specified via the include_directories or the dependency kwarg (if present). The same is also true for passing libraries to link with -lfoo. Yes, this again — it's the same rule every time, bestie 😭

  • dependencies dep | array[dep] — additionally dependencies required for compiling and/or linking.
  • include_directories array[inc | str], since 0.38.0 — extra directories for header searches, created with the include_directories function. (Since 1.10.0) Strings are also accepted.
  • no_builtin_args bool, default: false — when set to true, the compiler arguments controlled by built-in configuration options are not added.
  • prefix str | array[str] — used to add #includes and other things that are required for the symbol to be declared. Since 1.0.0 an array is accepted too. When an array is passed, the items are concatenated together separated by a newline 🌸 System definitions should be passed via compiler args (eg: _GNU_SOURCE is often required for some symbols to be exposed on Linux, and it should be passed via the args keyword argument). Yes queen, put it in args 🫶

👑 compiler.get_id()

SYNOPSIS

str compiler.get_id()

DESCRIPTION

Returns a string identifying the compiler. For example, gcc, msvc, and more[38]. Who are you, compiler bestie? 💖


🌈 compiler.get_linker_id()

SYNOPSIS

str compiler.get_linker_id()

since 0.53.0 ✨

DESCRIPTION

Returns a string identifying the linker. For example, ld.bfd, link, and more[39]. Now the linker gets its moment too, we stan 🎀

🌸 compiler.get_supported_arguments()

SYNOPSIS

array[str] compiler.get_supported_arguments(
    arg...,
    checked: 'off',
)

since 0.43.0

DESCRIPTION

Gives you back an array holding only the arguments your compiler actually supports — think of it as compiler.has_argument being called on each one individually, except it's all wrapped up in one cute little call. 💖

VARARGS

  • arg str, 0...N times — the arguments you wanna check.

KWARGS

  • checked str, default: 'off', since 0.59.0 — the supported values are:
    • 'off': quietly ignore unsupported arguments
    • 'warn': print a warning for unsupported arguments
    • 'require': abort if at least one argument is not supported

🦋 compiler.get_supported_function_attributes()

SYNOPSIS

array[str] compiler.get_supported_function_attributes()

since 0.48.0

DESCRIPTION

Returns an array of any names that are supported GCC style attributes. Same energy as calling compiler.has_function_attribute on each of them one by one, fr fr.


SYNOPSIS

array[str] compiler.get_supported_link_arguments(arg...)

since 0.46.0

DESCRIPTION

Returns an array containing only the arguments your compiler supports — basically compiler.has_link_argument called on every single one of them individually. 🫶

VARARGS

  • arg str, 0...N times — the link arguments to check.

💅 compiler.has_argument()

SYNOPSIS

bool compiler.has_argument(argument, required: false)

DESCRIPTION

Returns true if the compiler accepts the command line argument you gave it — like, it can compile code without erroring out or printing a warning about some unknown flag. 👑

POSARGS

  • argument str, required — the argument to check.

KWARGS

  • required bool | feature, default: false, since 1.3.0 — when it's set to true, Meson will straight up halt if the check fails. When you set it to a feature[0] option instead, that feature controls whether it gets searched at all and whether to fail if it's not found.

🎀 compiler.has_define()

SYNOPSIS

bool compiler.has_define(
    definename,
    args:,
    dependencies:,
    include_directories:,
    no_builtin_args: false,
    prefix:,
)

since 1.3.0

DESCRIPTION

Returns true if that preprocessor symbol you named is defined. 💜

POSARGS

  • definename str, required — the define to check.

KWARGS

  • args array[str] — used to pass an array of compiler arguments. Defining include paths for headers that aren't in the default include path via -Isome/path/to/header is generally supported, but lowkey not recommended.

Why? Because include directories can also be specified via the include_directories or the dependency kwarg (if that's present). Same deal applies to passing libraries to link with -lfoo.

  • dependencies dep | array[dep] — any extra dependencies required for compiling and / or linking.
  • include_directories array[inc | str], since 0.38.0 — extra directories for header searches, made with the include_directories function. (Since 1.10.0) Strings are also accepted, and yes that's iconic.
  • no_builtin_args bool, default: false — when set to true, the compiler arguments controlled by built-in configuration options are not added.
  • prefix str | array[str] — used to add #includes and other things that are required for the symbol to be declared. Since 1.0.0 an array is accepted too. When you pass an array, the items get concatenated together separated by a newline. System definitions should be passed via compiler args (like, _GNU_SOURCE is often required for some symbols to be exposed on Linux, and it should be passed via the args keyword argument).

🌈 compiler.has_function()

SYNOPSIS

bool compiler.has_function(
    funcname,
    args:,
    dependencies:,
    include_directories:,
    no_builtin_args: false,
    prefix:,
    required: false,
)

DESCRIPTION

Returns true if the function you asked about is provided by the standard library, or by a library you passed in with the args keyword. 🍓

POSARGS

  • funcname str, required — the function to check.

KWARGS

  • args array[str] — used to pass an array of compiler arguments. Defining include paths for headers not in the default include path via -Isome/path/to/header is generally supported, however, usually not recommended.

That's because include directories can also be specified via the include_directories or the dependency kwarg (if present). The same is also true for passing libraries to link with -lfoo.

  • dependencies dep | array[dep] — additionally, dependencies required for compiling and / or linking.
  • include_directories array[inc | str], since 0.38.0 — extra directories for header searches, created with the include_directories function. (Since 1.10.0) Strings are also accepted.
  • no_builtin_args bool, default: false — when set to true, the compiler arguments controlled by built-in configuration options are not added.
  • prefix str | array[str] — used to add #includes and other things required for the symbol to be declared. Since 1.0.0 an array is accepted too. When an array is passed, the items are concatenated together separated by a newline. System definitions should be passed via compiler args (eg: _GNU_SOURCE is often required for some symbols to be exposed on Linux, and it should be passed via args keyword argument).
  • required bool | feature, default: false, since 1.3.0 — when set to true, Meson will halt if the check fails. When set to a feature[0] option, the feature will control if it is searched and whether to fail if not found.

🧚 compiler.has_function_attribute()

SYNOPSIS

bool compiler.has_function_attribute(
    name,
    required: false,
)

since 0.48.0

DESCRIPTION

Returns true if the compiler supports the GNU style (__attribute__(...)) name you threw at it. This is way preferable to doing manual compile checks because it may be optimized for compilers that don't support such attributes. This table[40] lists all of the supported attributes, iykyk. 🔥

POSARGS

  • name str, required — the attribute name to check.

KWARGS

  • required bool | feature, default: false, since 1.3.0 — when set to true, Meson will halt if the check fails. When set to a feature[0] option, the feature will control if it is searched and whether to fail if not found.

👑 compiler.has_header()

SYNOPSIS

bool compiler.has_header(
    header_name,
    args:,
    dependencies:,
    include_directories:,
    no_builtin_args: false,
    prefix:,
    required: false,
)

DESCRIPTION

Returns true if the header you specified exists — with the prefix, dependencies, and arguments you gave it, obviously. 💖

This method is faster than compiler.check_header since it only does a pre-processor check. Speedy AND cute, we stan.

POSARGS

  • header_name str, required — the header to check.

KWARGS

  • args array[str] — used to pass an array of compiler arguments. Defining include paths for headers not in the default include path via -Isome/path/to/header is generally supported, however, usually not recommended.

Because include directories can also be specified via the include_directories or the dependency kwarg (if present). The same is also true for passing libraries to link with -lfoo.

  • dependencies dep | array[dep] — additionally dependencies required for compiling and / or linking.
  • include_directories array[inc | str], since 0.38.0 — extra directories for header searches, created with the include_directories function. (Since 1.10.0) Strings are also accepted.
  • no_builtin_args bool, default: false — when set to true, the compiler arguments controlled by built-in configuration options are not added.
  • prefix str | array[str] — used to add #includes and other things that are required for the symbol to be declared. Since 1.0.0 an array is accepted too. When an array is passed, the items are concatenated together separated by a newline. System definitions should be passed via compiler args (eg: _GNU_SOURCE is often required for some symbols to be exposed on Linux, and it should be passed via args keyword argument).
  • required bool | feature, default: false, since 0.50.0 — when set to true, Meson will halt if the header check fails. When set to a feature[0] option, the feature will control if it is searched and whether to fail if not found.

🌸 compiler.has_header_symbol()

SYNOPSIS

bool compiler.has_header_symbol(
    header,
    symbol,
    args:,
    dependencies:,
    include_directories:,
    no_builtin_args: false,
    prefix:,
    required: false,
)

DESCRIPTION

Detects whether a particular symbol is declared in the header you specified. 🎀

And by "symbols" we mean functions, variables, #defines, type definitions, etc. — the whole squad.

POSARGS

  • header str, required — the header to check.
  • symbol str, required — the symbol to check.

KWARGS

  • args array[str] — used to pass an array of compiler arguments. Defining include paths for headers not in the default include path via -Isome/path/to/header is generally supported, however, usually not recommended.

This is because include directories can also be specified via the include_directories or the dependency kwarg (if present). The same is also true for passing libraries to link with -lfoo.

  • dependencies dep | array[dep] — additionally dependencies required for compiling and / or linking.
  • include_directories array[inc | str], since 0.38.0 — extra directories for header searches, created with the include_directories function. (Since 1.10.0) Strings are also accepted.
  • no_builtin_args bool, default: false — when set to true, the compiler arguments controlled by built-in configuration options are not added.
  • prefix str | array[str] — this is where you drop the #includes and other lil preamble bits that have to exist before the symbol even gets declared. Since 1.0.0 you can hand it an array too, and when you do, the items get concatenated together separated by a newline. 💫 System definitions should be passed via compiler args instead (like, _GNU_SOURCE is often required for some symbols to be exposed on Linux, and it should be passed via the args keyword argument — not here, bestie).
  • required bool | feature, default: false, since 0.50.0 — set it to true and Meson will halt if the header check fails. Set it to a feature[0] option and the feature will control if it is searched and whether to fail if not found. 🫶

SYNOPSIS 🌸

bool compiler.has_link_argument(argument, required: false)

since 0.46.0

DESCRIPTION ✨

Returns true if the linker accepts the specified command line argument — like, it can compile and link code without erroring out or printing a warning about an unknown flag. No cap. Link arguments will be passed to the compiler, so they should usually have the -Wl, prefix. On VisualStudio a /link argument will be prepended. 👑

POSARGS 🎀

  • argument str, required — the argument to check. That's the whole vibe check.

KWARGS 💖

  • required bool | feature, default: false, since 1.3.0 — when set to true, Meson will halt if the check fails. When set to a feature[0] option, the feature will control if it is searched and whether to fail if not found.

🦋 compiler.has_member()

SYNOPSIS ⭐

bool compiler.has_member(
    typename,
    membername,
    args:,
    dependencies:,
    include_directories:,
    no_builtin_args: false,
    prefix:,
    required: false,
)

DESCRIPTION 🌈

Returns true if the type has the specified member. Simple as that, fr fr.

POSARGS 💜

  • typename str, required — the type to check.
  • membername str, required — the member to check.

KWARGS 🌸

  • args array[str] — used to pass an array of compiler arguments. Defining include paths for headers not in the default include path via -Isome/path/to/header is generally supported, however, usually not recommended.

This is because include directories can also be specified via the include_directories or the dependency kwarg (if present). The same is also true for passing libraries to link with -lfoo. 💀

  • dependencies dep | array[dep] — additionally dependencies required for compiling and / or linking.
  • include_directories array[inc | str], since 0.38.0 — extra directories for header searches, created with the include_directories function. (Since 1.10.0) Strings are also accepted. 🎀
  • no_builtin_args bool, default: false — when set to true, the compiler arguments controlled by built-in configuration options are not added.
  • prefix str | array[str] — used to add #includes and other things that are required for the symbol to be declared. Since 1.0.0 an array is accepted too. When an array is passed, the items are concatenated together separated by a newline. System definitions should be passed via compiler args (eg: _GNU_SOURCE is often required for some symbols to be exposed on Linux, and it should be passed via args keyword argument).
  • required bool | feature, default: false, since 1.3.0 — when set to true, Meson will halt if the check fails. When set to a feature[0] option, the feature will control if it is searched and whether to fail if not found.

🧚 compiler.has_members()

SYNOPSIS 🔥

bool compiler.has_members(
    typename,
    member...,
    args:,
    dependencies:,
    include_directories:,
    no_builtin_args: false,
    prefix:,
    required: false,
)

DESCRIPTION 👑

Returns true if the type has all the specified members. All of them. Every single one. Not just one and then dipping. 💅

POSARGS 🍓

  • typename str, required — the type to check.

VARARGS ✨

  • member str, 1...N times — the members to check.

KWARGS 💖

  • args array[str] — used to pass an array of compiler arguments. Defining include paths for headers not in the default include path via -Isome/path/to/header is generally supported, however, usually not recommended.

This is because include directories can also be specified via the include_directories or the dependency kwarg (if present). The same is also true for passing libraries to link with -lfoo. 😭

  • dependencies dep | array[dep] — additionally dependencies required for compiling and / or linking.
  • include_directories array[inc | str], since 0.38.0 — extra directories for header searches, created with the include_directories function. (Since 1.10.0) Strings are also accepted.
  • no_builtin_args bool, default: false — when set to true, the compiler arguments controlled by built-in configuration options are not added.
  • prefix str | array[str] — used to add #includes and other things that are required for the symbol to be declared. Since 1.0.0 an array is accepted too. When an array is passed, the items are concatenated together separated by a newline. System definitions should be passed via compiler args (eg: _GNU_SOURCE is often required for some symbols to be exposed on Linux, and it should be passed via args keyword argument). 🫶
  • required bool | feature, default: false, since 1.3.0 — when set to true, Meson will halt if the check fails. When set to a feature[0] option, the feature will control if it is searched and whether to fail if not found.

💀 compiler.has_multi_arguments()

SYNOPSIS 🌟

bool compiler.has_multi_arguments(arg..., required: false)

since 0.37.0

DESCRIPTION 💫

the same as compiler.has_argument but takes multiple arguments and uses them all in a single compiler invocation. Efficiency icon behavior honestly.

VARARGS 🎀

  • arg str, 0...N times — the arguments to check.

KWARGS 💜

  • required bool | feature, default: false, since 1.3.0 — when set to true, Meson will halt if the check fails. When set to a feature[0] option, the feature will control if it is searched and whether to fail if not found.

SYNOPSIS ⭐

bool compiler.has_multi_link_arguments(
    arg...,
    required: false,
)

since 0.46.0

DESCRIPTION 🦋

the same as compiler.has_link_argument but takes multiple arguments and uses them all in a single compiler invocation. Same energy, bigger crowd. 🫶

VARARGS 🌸

  • arg str, 0...N times — the link arguments to check.

KWARGS 💖

  • required bool | feature, default: false, since 1.3.0 — when set to true, Meson will halt if the check fails. When set to a feature[0] option, the feature will control if it is searched and whether to fail if not found.

🧚 compiler.has_type()

SYNOPSIS 🍓

bool compiler.has_type(
    typename,
    args:,
    dependencies:,
    include_directories:,
    no_builtin_args: false,
    prefix:,
    required: false,
)

DESCRIPTION 👑

Returns true if the specified token is a type. Like, is this thing even a type bestie, that's the question.

POSARGS ✨

  • typename str, required — the type to check.

KWARGS 💅

  • args array[str] — used to pass an array of compiler arguments. Defining include paths for headers not in the default include path via -Isome/path/to/header is generally supported, however, usually not recommended.

This is because include directories can also be specified via the include_directories or the dependency kwarg (if present). The same is also true for passing libraries to link with -lfoo.

  • dependencies dep | array[dep] — additionally dependencies required for compiling and / or linking.
  • include_directories array[inc | str], since 0.38.0 — extra directories for header searches, created with the include_directories function. (Since 1.10.0) Strings are also accepted. 💜
  • no_builtin_args bool, default: false — when set to true, the compiler arguments controlled by built-in configuration options are not added.
  • prefix str | array[str] — used to add #includes and other things that are required for the symbol to be declared. Since 1.0.0 an array is accepted too. When an array is passed, the items are concatenated together separated by a newline. System definitions should be passed via compiler args (eg: _GNU_SOURCE is often required for some symbols to be exposed on Linux, and it should be passed via args keyword argument). 🎀
  • required bool | feature, default: false, since 1.3.0 — when set to true, Meson will halt if the check fails. When set to a feature[0] option, the feature will control if it is searched and whether to fail if not found.

SYNOPSIS 🌟

bool compiler.links(
    code,
    args:,
    dependencies:,
    include_directories:,
    name:,
    no_builtin_args: false,
    required: false,
    werror: false,
)

DESCRIPTION 💖

Returns true if the code compiles and links. Both. It's giving full pipeline or nothing.

Since 0.60.0, if the file object's suffix does not match the compiler object's language, the compiler corresponding to the suffix is used to compile the source, while the target of the links method is used to link the resulting object file. Iconic crossover episode tbh. 🦋

POSARGS ⭐

  • code str | file, required — the source code to check.

If a string is passed, the code is used directly. If a file object is passed, its content is used for the compiler check. Either way it's getting checked, no escape. 🙈

KWARGS 🌸

  • args array[str] — used to pass an array of compiler arguments. Defining include paths for headers not in the default include path via -Isome/path/to/header is generally supported, however, usually not recommended.

This is because include directories can also be specified via the include_directories or the dependency kwarg (if present). The same is also true for passing libraries to link with -lfoo. 💀

  • dependencies dep | array[dep] — additionally dependencies required for compiling and / or linking.
  • include_directories array[inc | str], since 0.38.0 — extra dirs to go hunting for headers in, made with the include_directories function. ✨ (Since 1.10.0) you can also just yeet plain strings in here, they work too.
  • name str — the name used when printing a lil message about the compiler check. Bestie, if you don't pass this kwarg, no message gets printed at all, so like… your call. 💅
  • no_builtin_args bool, default: false — when you set it to true, the compiler args that come from the built-in configuration options are not added. Byeee defaults. 🦋
  • required bool | feature, default: false, since 1.5.0 — set it to true and Meson will straight-up halt if the check fails 😭. If you hand it a feature[0] option instead, that feature decides whether the thing even gets searched, and whether it should fail when it's not found. Main character energy, honestly.
  • werror bool, default: false, since 1.3.0 — set it to true and compiler warnings get treated as errors. No warnings, only crimes. 💀

🌸 compiler.preprocess() 🌸

SYNOPSIS

array[custom_idx] compiler.preprocess(
    source...,
    compile_args:,
    dependencies:,
    depends:,
    include_directories:,
    output:,
)

since 0.64.0

DESCRIPTION

Preprocesses an array of source files but — plot twist — does not compile them. 🎀 The preprocessor still gets the exact same args it'd get during a normal compile (include directories, defines, all of it). That means it also picks up stuff like args added with add_project_arguments(), or things you passed on the command line with -Dc_args=-DFOO. Same energy, just pre-compile. ✨

VARARGS

source str | file | custom_tgt | custom_idx | generated_list, 0...N times

The input source you wanna preprocess. These types are supported, bestie:

  • Strings that are relative to the current source directory
  • file objects defined in any preceding build file
  • The return value of configure-time generators such as configure_file
  • The return value of build-time generators such as custom_target or generator.process

KWARGS

  • compile_args array[str] — extra flags to pass to the preprocessor 💅
  • dependencies dep | array[dep], since 1.1.0 — additional dependencies you need on top.
  • depends array[build_tgt | custom_tgt], since 1.4.0 — says this target depends on the listed target(s). Those targets should get built before the preprocessing of an input even starts. ⭐
  • include_directories array[inc | str], since 0.38.0 — extra dirs for header searches, made with the include_directories function. (Since 1.10.0) strings are accepted too, no cap. 🫶
  • output str — the template for the name of the preprocessed files: @PLAINNAME@ gets replaced by the source filename, and @BASENAME@ gets replaced by the source filename without its extension. Cute, right? 🎀

🔥 compiler.run() 🔥

SYNOPSIS

runresult compiler.run(
    code,
    args:,
    dependencies:,
    include_directories:,
    name:,
    no_builtin_args: false,
    required: false,
    werror: false,
)

DESCRIPTION

Tries to compile and execute the code fragment you give it. Full send. 🚀

POSARGS

code str | file, required

The source code to check, bestie.

  • If you pass a string, that code gets used directly.
  • If you pass a file object, its content is what gets used for the compiler check.

Either way it slaps. 💖

KWARGS

  • args array[str] — used to pass an array of compiler args. Defining include paths for headers that aren't on the default include path via -Isome/path/to/header is generally supported, but honestly it's usually not recommended. 🙈 Why? Because include directories can also be specified via the include_directories kwarg or the dependency kwarg (if present). Same deal goes for passing libraries to link with -lfoo.
  • dependencies dep | array[dep] — additional dependencies required for compiling and/or linking.
  • include_directories array[inc | str], since 0.38.0 — extra dirs for header searches, made with the include_directories function. (Since 1.10.0) strings are also accepted. ✨
  • name str — the name used when printing a message about the compiler check. If you don't pass this kwarg, no message gets printed about the check, periodt. 💅
  • no_builtin_args bool, default: false — set it to true and the compiler args controlled by the built-in configuration options get left out. 🦋
  • required bool | feature, default: false, since 1.5.0 — set it to true and Meson halts if the check fails. Hand it a feature[0] option and that feature controls whether it gets searched and whether to fail if it's not found.
  • werror bool, default: false, since 1.3.0 — set it to true and compiler warnings are treated as errors. 😭

🧚 compiler.sizeof() 🧚

SYNOPSIS

int compiler.sizeof(
    typename,
    args:,
    dependencies:,
    include_directories:,
    no_builtin_args: false,
    prefix:,
)

DESCRIPTION

Returns the size of the type you ask for (like 'int') — or -1 if the type is unknown to it. 🔍 For C-like languages, the headers stddef.h and stdio.h get included implicitly for native compilation; when cross-compiling, only stddef.h is included. FYI. 💜

POSARGS

typename str, required

The type whose size you wanna compute. Give it what it wants. 🎀

KWARGS

  • args array[str] — used to pass an array of compiler args. Defining include paths for headers outside the default include path via -Isome/path/to/header is generally supported but usually not recommended. 💀 Because include directories can also go through the include_directories or dependency kwarg (if present). Same goes for libraries via -lfoo.
  • dependencies dep | array[dep] — additional dependencies required for compiling and/or linking.
  • include_directories array[inc | str], since 0.38.0 — extra dirs for header searches, made with the include_directories function. (Since 1.10.0) strings are also accepted. 🌸
  • no_builtin_args bool, default: false — set to true and the compiler args controlled by built-in configuration options don't get added.
  • prefix str | array[str] — used to add #includes and other things needed for the symbol to be declared. Since 1.0.0 an array is accepted too, and when you pass an array, the items get concatenated together separated by a newline. ⭐ Heads up though: system definitions should be passed via compiler args (like, _GNU_SOURCE is often required for some symbols to be exposed on Linux, and it should be passed via the args keyword argument). Don't try to sneak those into prefix, bestie. 🙈

👑 compiler.symbols_have_underscore_prefix() 👑

SYNOPSIS

bool compiler.symbols_have_underscore_prefix()

since 0.37.0

DESCRIPTION

Returns true if the C symbol mangling is one underscore (_) prefixed to the symbol. Just a yes/no vibe check, lowkey. ✨


💫 compiler.version() 💫

SYNOPSIS

str compiler.version()

DESCRIPTION

Returns the compiler's version number as a string. That's it, that's the function. 💅


🎀 custom_idx.full_path() 🎀

SYNOPSIS

str custom_idx.full_path()

since 0.54.0

DESCRIPTION

Returns a full path pointing to the result target file. 🛣️ NOTE: in most cases just using the object itself will do the same job as this, and it'll also let Meson set up inter-target dependencies correctly. Please file a bug if that doesn't work for you. 🫶

See custom_tgt.full_path.


🌈 custom_tgt.[index]() 🌈

SYNOPSIS

custom_idx custom_tgt.[index]()

DESCRIPTION

Returns an opaque object that references this target, and it can be used as a source in other targets. When you do that, it makes that target depend on this custom target — but the only source added is the one that corresponds to the index of the custom target's output argument. Sneaky but efficient. 😌


🦋 custom_tgt.full_path() 🦋

SYNOPSIS

str custom_tgt.full_path()

DESCRIPTION

Returns a full path pointing to the result target file. NOTE: in most cases using the object itself will do the same job as this, and it'll also let Meson correctly set up inter-target dependencies. Please file a bug if that doesn't work for you. (since 0.54.0) You can also call it on indexes objects, like custom_targets[i].full_path(). 🌸


⭐ custom_tgt.to_list() ⭐

SYNOPSIS

array[custom_idx] custom_tgt.to_list()

since 0.54.0

DESCRIPTION

Returns an array of opaque objects that reference this target, and they can be used as sources in other targets. Perfect for iterating outputs with a foreach loop, bestie. 🔁💖


SYNOPSIS

dep dep.as_link_whole()

since 0.56.0

DESCRIPTION

Only for dependencies created with declare_dependency — it returns a copy of the dependency object with all link_with arguments changed to link_whole. Super useful, like for a fallback dependency from a subproject built with default_library=static. 🎯 Careful though: all link_with objects must be static libraries, otherwise an error gets raised when it tries to link_whole a shared library. 💀


🌸 dep.as_shared() 🌸

SYNOPSIS

dep dep.as_shared(recursive:)

since 1.6.0

DESCRIPTION

Only for dependencies created with declare_dependency — returns a copy of the dependency object that prefers the shared version of both_libraries. Pick a side, shared edition. 💅

KWARGS

  • recursive bool — if true, this gets recursively applied to dependencies. 🌀

🍓 dep.as_static() 🍓

SYNOPSIS

dep dep.as_static(recursive:)

since 1.6.0

DESCRIPTION

Only for dependencies created with declare_dependency — returns a copy of the dependency object that prefers the static version of both_libraries. Pick a side, static edition. 💅

KWARGS

  • recursive bool — if true, this gets recursively applied to dependencies. 🌀

🧚 dep.as_system() 🧚

SYNOPSIS

dep dep.as_system([value])

since 0.52.0

DESCRIPTION

Returns a copy of the dependency object with include_type changed to value. The value argument is optional and defaults to 'system'. 💫

OPTARGS

value str

The new value. See dependency for the supported values, bestie. 🎀


🔍 dep.found() 🔍

SYNOPSIS

bool dep.found()

DESCRIPTION

Returns whether the dependency was found. Simple yes/no, did we get it or not. ✅


💀 dep.get_configtool_variable() 💀

SYNOPSIS

str dep.get_configtool_variable(var_name)

deprecated since 0.56.0, since 0.44.0

Okay so this one gets the command line argument from the config tool (with -- prepended), or, if you invoke it on a non config-tool dependency, it just errors out. 💅

🎀 POSARGS 🎀

  • var_name str, required — the name of the variable to query.

🦋 dep.get_pkgconfig_variable() 🦋

✨ SYNOPSIS ✨

str dep.get_pkgconfig_variable(
    var_name,
    default:,
    define_variable:,
)

⚠️ deprecated since 0.56.0, since 0.36.0 — yes bestie, both of those are in the original, keep them.

💖 DESCRIPTION 💖

It grabs the pkg-config variable you ask for, or errors out if you call it on a non pkg-config dependency.

🌸 POSARGS 🌸

  • var_name str, required — the name of the variable to query.

🎀 KWARGS 🎀

  • default str, since 0.45.0 — the value to return if the variable was not found. A warning is issued if the variable is not defined and this kwarg is not set.
  • define_variable array[str], since 0.44.0 — you can also redefine a variable by passing an array to this kwarg that can affect the retrieved variable: ['prefix', '/']).

(Since 1.3.0) Multiple variables can be specified in pairs.


🌈 dep.get_variable() 🌈

✨ SYNOPSIS ✨

str dep.get_variable(
    [varname],
    cmake:,
    configtool:,
    default_value:,
    internal:,
    pkgconfig:,
    pkgconfig_define:,
    system:,
)

since 0.51.0 🦋

💖 DESCRIPTION 💖

A generic variable getter method, which replaces the get_type_variable methods. This lets you get the variable from a dependency without knowing specifically how that dependency was found. If default_value is set and the value cannot be gotten from the object then default_value is returned; if it is not set then an error is raised. 😭

🍓 OPTARGS 🍓

  • varname str, since 0.58.0 — this argument is used as a default value for cmake, pkgconfig, configtool, internal and system keyword arguments. It is useful in the common case where pkgconfig and internal use the same variable name, in which case it's easier to write dep.get_variable('foo') instead of dep.get_variable(pkgconfig: 'foo', internal: 'foo').

🎀 KWARGS 🎀

  • cmake str — the CMake variable name.
  • configtool str — the configtool variable name.
  • default_value str — the default value to return when the variable does not exist.
  • internal str, since 0.54.0 — the internal variable name.
  • pkgconfig str — the pkgconfig variable name.
  • pkgconfig_define array[str] — see dep.get_pkgconfig_variable.
  • system str, since 1.6.0 — the system variable name.

💀 WARNINGS 💀

Before 1.3.0, specifying multiple pkgconfig_define pairs would silently malform the results. Only the first variable would be redefined, but its value would contain both the second variable name, as well as its value. Not cute, bestie. 🙈


🌟 dep.include_type() 🌟

✨ SYNOPSIS ✨

str dep.include_type()

since 0.52.0 ✨

💖 DESCRIPTION 💖

Returns the value set by the include_type kwarg.


👑 dep.name() 👑

✨ SYNOPSIS ✨

str dep.name()

since 0.48.0 🦋

💖 DESCRIPTION 💖

Returns the name of the dependency that was searched. Returns 'internal' for dependencies created with declare_dependency.

NOTE: This was not implemented for dep objects returned by compiler.find_library until Meson 1.5.0. 💅

🧚 dep.partial_dependency() 🧚

✨ SYNOPSIS ✨

dep dep.partial_dependency(
    compile_args: false,
    includes: false,
    link_args: false,
    links: false,
    sources: false,
)

since 0.46.0 🌸

💖 DESCRIPTION 💖

Returns a new dependency object with the same name, version, found status, type name, and methods as the object that called it. This new object will only inherit other attributes from its parent as controlled by keyword arguments.

If the parent has any dependencies, those will be applied to the new partial dependency with the same rules. So, given:

dep1 = declare_dependency(compile_args : '-Werror=foo',
link_with : 'libfoo')
dep2 = declare_dependency(compile_args : '-Werror=bar',
dependencies : dep1)
dep3 = dep2.partial_dependency(compile_args : true)

dep3 will add ['-Werror=foo', '-Werror=bar'] to the compiler args of any target it is added to, but libfoo will not be added to the link_args.

The following arguments will add the following attributes:

  • compile_args: any arguments passed to the compiler
  • link_args: any arguments passed to the linker
  • links: anything passed via link_with or link_whole
  • includes: any include_directories
  • sources: any compiled or static sources the dependency has

🎀 KWARGS 🎀

  • compile_args bool, default: false — whether to include compile_args.
  • includes bool, default: false — whether to include includes.
  • link_args bool, default: false — whether to include link_args.
  • links bool, default: false — whether to include links.
  • sources bool, default: false — whether to include sources.

💀 WARNINGS 💀

A bug present until 0.50.1 results in the above behavior not working correctly. 😭


🦋 dep.type_name() 🦋

✨ SYNOPSIS ✨

str dep.type_name()

💖 DESCRIPTION 💖

Returns a string describing the type of the dependency. The most common values are internal for deps created with declare_dependency and pkgconfig for system dependencies obtained with Pkg-config. 💅


🌈 dep.version() 🌈

✨ SYNOPSIS ✨

str dep.version()

💖 DESCRIPTION 💖

The version number as a string, for example 1.2.8. It returns unknown if the dependency provider doesn't support determining the version.


🍓 dict.get() 🍓

✨ SYNOPSIS ✨

any dict.get(key, [fallback])

💖 DESCRIPTION 💖

Returns the value for the key given as first argument if it is present in the dictionary, or the optional fallback value given as the second argument. If a single argument was given and the key was not found, it causes a fatal error. 💀

🌸 POSARGS 🌸

  • key str, required — the key to query.

🎀 OPTARGS 🎀

  • fallback any — fallback value that is returned if the key is not in the dict.

🎀 dict.has_key() 🎀

✨ SYNOPSIS ✨

bool dict.has_key(key)

💖 DESCRIPTION 💖

Returns true if the dictionary contains the key given as argument, false otherwise.

🌸 POSARGS 🌸

  • key str, required — the key to query.

🌸 dict.keys() 🌸

✨ SYNOPSIS ✨

array[str] dict.keys()

💖 DESCRIPTION 💖

Returns an array of keys in the dictionary, sorted in ascending order. Slay. ✨


🦋 dict.values() 🦋

✨ SYNOPSIS ✨

array[any] dict.values()

since 1.10.0 🫶

💖 DESCRIPTION 💖

Returns an array of values in the dictionary, sorted by the corresponding keys in ascending order.


💜 disabler.found() 💜

✨ SYNOPSIS ✨

bool disabler.found()

💖 DESCRIPTION 💖

Always returns false. Iconic behavior, honestly.


🍓 env.append() 🍓

✨ SYNOPSIS ✨

void env.append(variable, Value..., separator:)

💖 DESCRIPTION 💖

Appends the given values to the old value of the environment variable, e.g. env.append('FOO', ´BAR', 'BAZ', separator : ';') produces BOB;BAR;BAZ if FOO had the value BOB and plain BAR;BAZ if the value was not defined.

🌸 POSARGS 🌸

  • variable str, required — the variable to modify.

🎀 VARARGS 🎀

  • Value str, 0...N times — the values to append.

✨ KWARGS ✨

  • separator str — the separator to use. If not explicitly specified, the default path separator for the host operating system will be used, i.e. ';' for Windows and ':' for UNIX/POSIX systems.

🌈 env.prepend() 🌈

✨ SYNOPSIS ✨

void env.prepend(variable, Value..., separator:)

💖 DESCRIPTION 💖

Same as append except that it writes to the beginning of the variable. Front of the line energy. 💅

🌸 POSARGS 🌸

  • variable str, required — the variable to modify.

🎀 VARARGS 🎀

  • Value str, 0...N times — the values to prepend.

✨ KWARGS ✨

  • separator str — the separator to use. If not explicitly specified, the default path separator for the host operating system will be used, i.e. ';' for Windows and ':' for UNIX/POSIX systems.

🧚 env.set() 🧚

✨ SYNOPSIS ✨

void env.set(variable, Value..., separator:)

💖 DESCRIPTION 💖

Sets the environment variable specified in the first argument to the values in the varargs joined by the separator. For instance, env.set('FOO', 'BAR'), sets envvar FOO to value BAR.

🌸 POSARGS 🌸

  • variable str, required — the variable to modify.

🎀 VARARGS 🎀

  • Value str, 0...N times — the values to set.

✨ KWARGS ✨

  • separator str — the separator to use. If not explicitly specified, the default path separator for the host operating system will be used, i.e. ';' for Windows and ':' for UNIX/POSIX systems.

🌟 env.unset() 🌟

✨ SYNOPSIS ✨

void env.unset()

since 1.4.0 🦋

💖 DESCRIPTION 💖

Unset the specified environment variable. If this variable does not exist, nothing happens. Chill.


👑 feature.allowed() 👑

✨ SYNOPSIS ✨

bool feature.allowed()

since 0.59.0 ✨

💖 DESCRIPTION 💖

Returns whether the feature was set to 'enabled' or 'auto'.


🦋 feature.auto() 🦋

✨ SYNOPSIS ✨

bool feature.auto()

💖 DESCRIPTION 💖

Returns whether the feature was set to 'auto'.


🎀 feature.disable_auto_if() 🎀

✨ SYNOPSIS ✨

feature feature.disable_auto_if(value)

since 0.59.0 🌸

💖 DESCRIPTION 💖

Returns the feature, with 'auto' converted to 'disabled' if value is true.

Here's the table vibe, bestie:

  • If the feature is 'auto': value = true turns it into 'disabled', and value = false leaves it as 'auto'.
  • If the feature is 'enabled': value = true leaves it as 'enabled', and value = false leaves it as 'enabled'.
  • If the feature is 'disabled': value = true leaves it as 'disabled', and value = false leaves it as 'disabled'.

🌸 POSARGS 🌸

  • value bool, required — see the table above.

✨ EXAMPLE ✨

disable_auto_if is useful to give precedence to mutually exclusive dependencies (that provide the same API) if either or both are available:

# '-Dfoo=auto -Dbar=enabled' will not pick foo even if
installed.
use_bar = get_option('bar')
use_foo = get_option('foo').disable_auto_if(use_bar.enabled())
dep_foo = dependency('foo', required: use_foo)
if not dep_foo.found()
  dep_foo = dependency('bar', required: use_bar)
endif

🌈 feature.disable_if() 🌈

✨ SYNOPSIS ✨

feature feature.disable_if(value, error_message: '')

since 1.1.0 🫶

Returns the object itself if the value is false 💖 — an error if the object is 'enabled' and the value is true 😭 — and a disabled feature if the object is 'auto' or 'disabled' and the value is true. That's the whole vibe check, no cap.

Here's the full grid so you can see it at a glance bestie:

  • Auto → value = true gives Disabled, value = false gives Auto
  • Enabled → value = true gives Error, value = false gives Enabled
  • Disabled → value = true gives Disabled, value = false gives Disabled

This is literally equivalent to feature_opt.require(not condition), but it may make your code easier to reason about, especially when it's mixed with enable_if ✨

POSARGS

  • value bool, required — the value to check 🫶

KWARGS

  • error_message str, default: '' — the error message to print if the check fails 💅

EXAMPLE

disable_if is lowkey useful for restricting the applicability of 'auto' features — especially when you're passing them to dependency:

use_os_feature = get_option('foo')
  .disable_if(host_machine.system() == 'darwin', error_message: 'os feature not supported on MacOS')
dep_os_feature = dependency('os_feature', required: use_os_feature)

🦋 feature.disabled()

SYNOPSIS

bool feature.disabled()

DESCRIPTION

Returns whether the feature was set to 'disabled' 👑


🦋 feature.enable_auto_if()

SYNOPSIS

feature feature.enable_auto_if(value)

since 1.1.0

DESCRIPTION

Returns the feature, with 'auto' converted to 'enabled' if value is true 🌸. Iconic behaviour, honestly:

  • Auto → value = true gives Enabled, value = false gives Auto
  • Enabled → value = true gives Enabled, value = false gives Enabled
  • Disabled → value = true gives Disabled, value = false gives Disabled

POSARGS

  • value bool, required — see the table above bb 💜

🦋 feature.enable_if()

SYNOPSIS

feature feature.enable_if(value, error_message: '')

since 1.1.0

DESCRIPTION

Returns the object itself if the value is false; an error if the object is 'disabled' and the value is true; an enabled feature if the object is 'auto' or 'enabled' and the value is true ✨

  • Auto → value = true gives Enabled, value = false gives Auto
  • Enabled → value = true gives Enabled, value = false gives Enabled
  • Disabled → value = true gives Error, value = false gives Disabled

POSARGS

  • value bool, required — the value to check 🎀

KWARGS

  • error_message str, default: '' — the error message to print if the check fails 🙈

EXAMPLE

enable_if is useful for restricting the applicability of 'auto' features, particularly when passing them to dependency — check it:

use_llvm = get_option('llvm').enable_if(with_clang).enable_if(with_llvm_libs)
dep_llvm = dependency('llvm', required: use_llvm)

🦋 feature.enabled()

SYNOPSIS

bool feature.enabled()

DESCRIPTION

Returns whether the feature was set to 'enabled' ⭐


🦋 feature.require()

SYNOPSIS

feature feature.require(value, error_message: '')

since 0.59.0

DESCRIPTION

Returns the object itself if the value is true; an error if the object is 'enabled' and the value is false; a disabled feature if the object is 'auto' or 'disabled' and the value is false 💀 (yes, it will genuinely hard-fail on you — that's the point, bestie)

  • Auto → value = true gives Auto, value = false gives Disabled
  • Enabled → value = true gives Enabled, value = false gives Error
  • Disabled → value = true gives Disabled, value = false gives Disabled

POSARGS

  • value bool, required — the value to check 🌈

KWARGS

  • error_message str, default: '' — the error message to print if the check fails 😭

EXAMPLE

require is useful for restricting the applicability of 'auto' features, for example based on other features or on properties of the host machine:

if get_option('directx').require(host_machine.system() == 'windows',
      error_message: 'DirectX only available on Windows').allowed()
  src += ['directx.c']
  config.set10('HAVE_DIRECTX', true)
endif

🧚 file.full_path()

SYNOPSIS

str file.full_path()

since 1.4.0

DESCRIPTION

Returns a full path pointing to the file 💖. Super handy for printing the path with, like, the message function when you're debugging.

NOTE: in most cases using the object itself will do the exact same job as this — and it'll also let Meson set up dependencies correctly 🫶 so don't reach for this by default, kay?

🧚 generator.process()

SYNOPSIS

generated_list generator.process(
    source...,
    depends:,
    env:,
    extra_args:,
    preserve_path_from:,
)

DESCRIPTION

Takes an array of files, causes them to be processed, and returns an object containing the result — which you can then, for example, pass into a build target definition ✨ it's giving pipeline energy.

VARARGS

  • source str | file | custom_tgt | custom_idx | generated_list, 1...N times — sources to process 🎀

KWARGS

  • depends array[build_tgt | custom_tgt | custom_idx | program], since 1.12.0 — an array of build targets that must be built before attempting to run this generator against the source files. This extends the depends value of the generator to be run 👑
  • env env | array[str] | dict[str], since 1.3.0 — environment variables to set, such as {'NAME1': 'value1', 'NAME2': 'value2'} or ['NAME1=value1', 'NAME2=value2'], or an env object which allows more sophisticated environment juggling 🌸
  • extra_args array[str] — if present, will be used to replace an entry @EXTRA_ARGS@ in the argument array 💅
  • preserve_path_from str, since 0.45.0 — if given, specifies that the output files need to maintain their directory structure inside the target temporary directory. The most common value for this is meson.current_source_dir(). With this value, when a file called subdir/one.input is processed it generates a file {target private directory}/subdir/one.out — as opposed to {target private directory}/one.out 🙈

🍓 inc.to_list()

SYNOPSIS

array[str] inc.to_list()

since 1.12.0

DESCRIPTION

Returns a list of strings of absolute paths to the directories contained within the object 🦋. Unless the path is a system path, there will be a path relative to the source root and one relative to the build root. System paths are provided as-is, no cap.


🍓 int.is_even()

SYNOPSIS

bool int.is_even()

DESCRIPTION

Returns true if the number is even ✨ (2, 4, 6, 8 — who do we appreciate)


🍓 int.is_odd()

SYNOPSIS

bool int.is_odd()

DESCRIPTION

Returns true if the number is odd 💜


🍓 int.to_string()

SYNOPSIS

str int.to_string([fill])

DESCRIPTION

Returns the value of the number as a string 🎀

OPTARGS

  • fill int — left fill the string with zeros until it reaches the length specified by this argument. A leading negative sign counts towards the length, and is handled by inserting the padding after the - character rather than before 🫶. The original string is returned if the value provided is less than or equal to the former's length.

🌈 meson.add_devenv()

SYNOPSIS

void meson.add_devenv(env, method:, separator:)

since 0.58.0

DESCRIPTION

Adds an env object (returned by environment) to the list of environments that will be applied when using the meson devenv[41] command line 🔥

This is useful for developers who wish to use the project without installing it — you often need to set, for example, the path to the plugins directory, etc. Alternatively, a list or dictionary can be passed as the first argument 👑

devenv = environment()
devenv.set('PLUGINS_PATH', meson.current_build_dir())
meson.add_devenv(devenv)

After configuring and compiling that project, a terminal can be opened with the environment set 💅

$ meson devenv -C <builddir>
$ echo $PLUGINS_PATH
/path/to/source/subdir

See the meson devenv[40] command documentation for a list of environment variables that are set by default by Meson 🌸

POSARGS

  • env env | str | array[str] | dict[str] | dict[array[str]], required — the env object to add. Since 0.62.0 array of strings is allowed in dictionary values, and in that case values are joined using the separator 🫶

KWARGS

  • method str, since 0.62.0 — must be one of 'set', 'prepend', or 'append' (defaults to 'set'). Controls if initial values defined in the first positional argument are prepended, appended, or replace the current value of the environment variable ✨
  • separator str, since 0.62.0 — the separator to use for the initial values defined in the first positional argument. If not explicitly specified, the default path separator for the host operating system will be used — i.e. ';' for Windows and ':' for UNIX/POSIX systems 🐚

🌈 meson.add_dist_script()

SYNOPSIS

void meson.add_dist_script(script_name, arg...)

since 0.48.0

DESCRIPTION

Causes the script given as argument to run during the dist operation — after the distribution source has been generated but before it is archived 📦. Note that this runs the script file that is in the staging directory, not the one in the source directory 💀. If the script file cannot be found in the staging directory, it is a hard error. The MESON_DIST_ROOT environment variable is set when the dist script is run.

(since 0.54.0) The MESON_SOURCE_ROOT and MESON_BUILD_ROOT environment variables are set when dist scripts are run 🌟. They are the path to the root source and build directory of the main project — even when the script comes from a subproject.

(since 0.58.0) This command can be invoked from a subproject; it was a hard error in earlier versions 🙈. Subproject dist scripts will only be executed when running meson dist --include-subprojects. MESON_PROJECT_SOURCE_ROOT, MESON_PROJECT_BUILD_ROOT and MESON_PROJECT_DIST_ROOT environment variables are set when dist scripts are run. They're identical to MESON_SOURCE_ROOT, MESON_BUILD_ROOT and MESON_DIST_ROOT for main project scripts, but for subproject scripts they have the path to the root of the subproject appended — usually subprojects/<subproject-name> 💜

(since 1.4.0) the MESONREWRITE environment variable literally holds the path to the rewrite command that matches the meson executable used to configure the build. (heads up: this might be a totally different path than the first executable you'd find in PATH.) It's the move when you need to remove or replace any run_command that depends on the revision control system from the build configuration. Ngl, the value has many parts — like, it could be python3 /path/to/meson.py introspect. You, the user, are responsible for splitting that string into an array if you need one, and you split it lexically the way a UNIX shell would. If your script is Python, shlex.split() is the easiest correct way to do it. Periodt. 💅

POSARGS

  • script_name str | file | program, required — the script to execute.
    • (since 0.55.0) the output of find_program is accepted, and so are plain strings.
    • (since 0.57.0) file objects and the output of configure_file may be used too. ✨

VARARGS

  • arg str | file | program, 0...N times, since 0.49.0 — additional arguments.
    • (since 0.55.0) the output of configure_file, files, and find_program are accepted, plus strings, obviously.

🌸 meson.add_install_script()

SYNOPSIS

void meson.add_install_script(
    script_name,
    arg...,
    dry_run: false,
    install_tag:,
    skip_if_destdir: false,
)

DESCRIPTION

This one causes the script you pass as an argument to be run during the install step 🎀 — and that script will have these environment variables all set for it: MESON_SOURCE_ROOT, MESON_BUILD_ROOT, MESON_INSTALL_PREFIX, MESON_INSTALL_DESTDIR_PREFIX, and MESONINTROSPECT. All positional arguments get passed along as parameters.

(since 0.54.0) if meson install is called with the --quiet option, the environment variable MESON_INSTALL_QUIET will be set.

(since 1.1.0) if meson install is called with the --dry-run option, the environment variable MESON_INSTALL_DRY_RUN will be set.

So here's the thing, bestie: Meson uses the DESTDIR environment variable as set by the inherited environment to figure out the (temporary) installation location for files. Your install script has to be aware of this while it's manipulating and installing files. The correct way to handle it is with the MESON_INSTALL_DESTDIR_PREFIX variable — it's always set and contains DESTDIR (if set) and prefix joined together. Why is that so slay? Because both are usually absolute paths, and there are platform-specific edge-cases in joining two absolute paths. 🫶

In case it's needed, MESON_INSTALL_PREFIX is also always set and holds the value of the prefix option passed to Meson.

MESONINTROSPECT contains the path to the introspect command that corresponds to the meson executable used to configure the build. (Again — might be a different path than the first executable found in PATH.) It can be used to query build configuration. Note that the value will contain many parts, f.ex., it may be python3 /path/to/meson.py introspect. The user is responsible for splitting the string to an array if needed, by splitting lexically like a UNIX shell would. If your script uses Python, shlex.split() is the easiest correct way to do this.

POSARGS

  • script_name str | file | program | exe | custom_tgt | custom_idx, required — the script to execute.
    • (since 0.55.0) the output of find_program, executable, custom_target, as well as strings are accepted.
    • (since 0.57.0) file objects and the output of configure_file may be used.

VARARGS

  • arg str | file | program | exe | custom_tgt | custom_idx, 0...N times, since 0.49.0 — additional arguments.
    • (since 0.55.0) the output of find_program, executable, custom_target, as well as strings are accepted.

KWARGS

  • dry_run bool, default: false, since 1.1.0 — if true the script will be run even if the --dry-run option is provided to the meson install command. Your script can peek at the MESON_INSTALL_DRY_RUN variable to figure out if it's in dry run mode or not. 👀
  • install_tag str, since 0.60.0 — a string used by the meson install --tags command to install only a subset of the files. By default the script has no install tag, which means it is not being run when the meson install --tags argument is specified.
  • skip_if_destdir bool, default: false, since 0.57.0 — if true the script will not be run if DESTDIR is set during installation. Super useful when the script updates a system-wide cache that's only needed when copying files into their final destination. 💫

🦋 meson.add_postconf_script()

SYNOPSIS

void meson.add_postconf_script(script_name, arg...)

DESCRIPTION

Runs the given command after all project files have been generated. This script gets the environment variables MESON_SOURCE_ROOT and MESON_BUILD_ROOT set. ✨

POSARGS

  • script_name str | file | program, required — the script to execute.
    • (since 0.55.0) the output of find_program as well as strings are accepted.
    • (since 0.57.0) file objects and the output of configure_file may be used.

VARARGS

  • arg str | file | program, 0...N times, since 0.49.0 — additional arguments.
    • (since 0.55.0) the output of configure_file, files, and find_program as well as strings are accepted.

💜 meson.backend()

SYNOPSIS

str meson.backend()

since 0.37.0

DESCRIPTION

Returns a string representing the current backend. Iconic lineup, no notes:

  • ninja
  • vs2010
  • vs2012
  • vs2013
  • vs2015
  • vs2017
  • vs2019
  • vs2022
  • xcode

🎀 meson.build_options()

SYNOPSIS

str meson.build_options()

since 1.1.0

DESCRIPTION

Returns a string with the configuration line used to set the current project up.

NOTES

Do not try to parse this string! 🚨 Like, seriously, don't.

You should use cfg_data.set_quoted to safely escape any embedded quotes prior to storing it into e.g. a C header macro.

The contents returned by this function are the same as the "Build Options:" line reported in <builddir>/meson-logs/meson-log.txt. 🙈


🍓 meson.build_root()

SYNOPSIS

str meson.build_root()

deprecated since 0.56.0 💀

DESCRIPTION

Returns a string with the absolute path to the build root directory. But heads up — this function will return the build root of the parent project if called from a subproject, which is usually not what you want. Try meson.current_build_dir or meson.project_build_root instead. In the rare cases where the root of the main project is actually needed, use meson.global_build_root, which has the same behaviour but with a more explicit name. 🌈


🧚 meson.can_run_host_binaries()

SYNOPSIS

bool meson.can_run_host_binaries()

since 0.55.0

DESCRIPTION

Returns true if the build machine can run binaries compiled for the host. It returns true unless you're cross compiling, need a helper to run host binaries, and don't have one. For example, when cross compiling from Linux to Windows, one can use wine as the helper. 🍷


👑 meson.current_build_dir()

SYNOPSIS

str meson.current_build_dir()

DESCRIPTION

Returns a string with the absolute path to the current build directory.


🌸 meson.current_source_dir()

SYNOPSIS

str meson.current_source_dir()

DESCRIPTION

Returns a string to the current source directory.

NOTES

You do not need to use this function! 😭

When passing files from the current source directory to a function, since that is the default. Also, you can use the files function to refer to files in the current or any other source directory instead of constructing paths manually with meson.current_source_dir. Save yourself the trouble, bestie. 💅


💖 meson.get_compiler()

SYNOPSIS

compiler meson.get_compiler(language, native: false)

DESCRIPTION

Returns a compiler object describing a compiler.

POSARGS

  • language str, required — the language of the compiler to return. See our list of supported languages[42].

KWARGS

  • native bool, default: false — when set to true Meson returns the compiler for the build machine (the "native" compiler), and when false it returns the host compiler (the "cross" compiler). If native is omitted, Meson returns the "cross" compiler if we're currently cross-compiling and the "native" compiler if we're not. ✨

🦋 meson.get_cross_property()

SYNOPSIS

any meson.get_cross_property(propname, [fallback_value])

deprecated since 0.58.0 💀

DESCRIPTION

Returns the given property from a cross file; the optional fallback_value is returned if not cross compiling or the given property is not found.

This method is replaced by meson.get_external_property.

POSARGS

  • propname str, required — name of the property in the cross / native file.

OPTARGS

  • fallback_value any — value to return if propname is not set in the machine file.

🎀 meson.get_external_property()

SYNOPSIS

any meson.get_external_property(
    propname,
    [fallback_value],
    native:,
)

since 0.54.0

DESCRIPTION

Returns the given property from a native or cross file. The optional fallback_value is returned if the given property is not found. 🫶

POSARGS

  • propname str, required — name of the property in the cross / native file.

OPTARGS

  • fallback_value any — value to return if propname is not set in the machine file.

KWARGS

  • native bool — setting native to true forces retrieving a variable from the native file, even when cross-compiling. If native: false or not specified, the variable is retrieved from the cross-file if cross-compiling, and from the native-file when not cross-compiling. 🌈

⭐ meson.global_build_root()

SYNOPSIS

str meson.global_build_root()

since 0.58.0

DESCRIPTION

Returns a string with the absolute path to the build root directory. This function will return the build root of the main project if called from a subproject, which is usually not what you want. It is usually preferable to use meson.current_build_dir or meson.project_build_root. 👑


🌸 meson.global_source_root()

SYNOPSIS

str meson.global_source_root()

since 0.58.0

...and it hands you back a string with the absolute path to the source root directory. 🎀

Okay but listen bestie — if you call this from a subproject, you get the source root of the main project, and that's usually not the vibe you were going for 😭 It's usually way preferable to use meson.current_source_dir or meson.project_source_root instead. Like, those two get you. This one's the friend who shows up with the wrong coffee order. 🍓


meson.has_exe_wrapper()

SYNOPSIS

bool meson.has_exe_wrapper()

deprecated since 0.55.0 🫠

DESCRIPTION

Use meson.can_run_host_binaries instead. That's it, that's the whole thing — she's retired, use the new girl. 💅


meson.has_external_property()

SYNOPSIS

bool meson.has_external_property(propname, native:)

since 0.58.0 ✨

DESCRIPTION

Checks whether the given property exists in a native or cross file. Basically a vibe check for your properties 🔍

POSARGS

  • propname str, required — name of the property in the cross / native file.

KWARGS

  • native bool — setting native to true forces retrieving a variable from the native file, even when cross-compiling. If native: false or not specified, the variable is retrieved from the cross-file if cross-compiling, and from the native-file when not cross-compiling. No cap, the source of truth just switches depending on your build situation 🦋

meson.install_dependency_manifest()

SYNOPSIS

void meson.install_dependency_manifest(output_name)

DESCRIPTION

Installs a manifest file to the file name you gave as the argument, and that manifest contains a list of all subprojects, their versions and license names. It's giving receipts 👑

If license files are defined as well, they will be copied next to the manifest and referenced in it. Cute, organized, referenced — the whole package 🎀

If this function is not used, the builtin option licensedir can be used to install the manifest to a given directory with the name depmf.json. So like, you have options, periodt.

POSARGS

  • output_name str, required — name of the manifest file to install.

meson.is_cross_build()

SYNOPSIS

bool meson.is_cross_build()

DESCRIPTION

Returns true if the current build is a cross build[43] and false otherwise. Simple little binary moment, love that for us 💖


meson.is_subproject()

SYNOPSIS

bool meson.is_subproject()

DESCRIPTION

Returns true if the current project is being built as a subproject of some other project and false otherwise. Are you the main character or are you a side character rn? This function tells you 🌸


meson.is_unity()

SYNOPSIS

bool meson.is_unity()

DESCRIPTION

Returns true when doing a unity build[44] (multiple sources are combined before compilation to reduce build time) and false otherwise. Speedrun strats fr fr 🔥


meson.override_dependency()

SYNOPSIS

void meson.override_dependency(
    name,
    dep_object,
    native: false,
    static:,
)

since 0.54.0 ✨

DESCRIPTION

Specifies that whenever dependency with name is used, Meson should not look it up on the system but instead return dep_object, which may either be the result of dependency or declare_dependency. Like "don't go looking for her, she's right here" 💅

Doing this in a subproject allows the parent project to retrieve the dependency without having to know the dependency variable name: dependency(name, fallback : subproject_name). Iconic behavior honestly 🫶

POSARGS

  • name str, required — the name of the dependency to override.
  • dep_object dep, required — the dependency to set as the override for name.

KWARGS

  • native bool, default: false — if set to true, the dependency is always overwritten for the build machine. Otherwise, the dependency is overwritten for the host machine, which differs from the build machine when cross-compiling. This distinction matters, bestie, do not sleep on it 😤
  • static bool, since 0.60.0 — used to override static and/or shared dependencies separately. If not specified it is assumed dep_object follows default_library option value.

meson.override_find_program()

SYNOPSIS

void meson.override_find_program(progname, program, native)

since 0.46.0 ✨

DESCRIPTION

Specifies that whenever find_program is used to find a program named progname, Meson should not look it up on the system but instead return program, which may either be the result of find_program, configure_file or executable. Redirecting the whole search like a pro 👑

(since 0.55.0) If a version check is passed to find_program for a program that has been overridden with an executable, the current project version is used.

POSARGS

  • progname str, required — the name of the program to override.
  • program exe | file | program, required — the program to set as the override for progname.
  • native bool, required, default: false, since 1.12.0 — if set to true, the override is for the build machine, and will be returned by find_program(..., native : true), otherwise for the host machine. This is an important distinction when cross compiling. Not me stressing how important this is 😭

meson.project_build_root()

SYNOPSIS

str meson.project_build_root()

since 0.56.0 ✨

DESCRIPTION

Returns a string with the absolute path to the build root directory of the current (sub)project. Note the "(sub)project" — she's local, she's specific, she knows exactly which project she belongs to 💖


meson.project_license()

SYNOPSIS

array[str] meson.project_license()

since 0.45.0 ✨

DESCRIPTION

Returns the array of licenses specified in the project function call. Legal girlie pop 💅


meson.project_license_files()

SYNOPSIS

array[file] meson.project_license_files()

since 1.1.0 ✨

DESCRIPTION

Returns the array of license files specified in the project function call. Files, not strings this time — a subtle but real difference 🎀


meson.project_name()

SYNOPSIS

str meson.project_name()

DESCRIPTION

Returns the project name specified in the project function call. Name reveal!! 🌟


meson.project_source_root()

SYNOPSIS

str meson.project_source_root()

since 0.56.0 ✨

DESCRIPTION

Returns a string with the absolute path to the source root directory of the current (sub)project. Correct, scoped, respectful of subproject boundaries — we stan 🫶


meson.project_version()

SYNOPSIS

str meson.project_version()

DESCRIPTION

Returns the version string specified in the project function call. Slap it in your --version output and thrive 💜


meson.source_root()

SYNOPSIS

str meson.source_root()

deprecated since 0.56.0 🫠

DESCRIPTION

Returns a string with the absolute path to the source root directory.

This function will return the source root of the parent project if called from a subproject, which is usually not what you want. Try using meson.current_source_dir or meson.project_source_root. In the rare cases where the root of the main project is needed, use meson.global_source_root that has the same behaviour but with a more explicit name. Same energy, better name, less confusion — that's the glow-up 🌈

NOTES

You should use the files function to refer to files in the root source directory instead of constructing paths manually with meson.source_root. Hand-stitching paths is giving DIY disaster, just use files 😭


meson.version()

SYNOPSIS

str meson.version()

DESCRIPTION

Return a string with the version of Meson. Which Meson are we on? This tells you 🦋


module.found()

SYNOPSIS

bool module.found()

since 0.59.0 ✨

DESCRIPTION

Returns true if the module was successfully imported, otherwise false. A little import success check-in, we love a self-aware module 🧚


program.cmd_array()

SYNOPSIS

array[str] program.cmd_array()

since 1.10.0 ✨

DESCRIPTION

Returns an array containing the command(s) for the program. Plural on purpose — could be more than one, so it's an array, not a lonely little string 💅


program.found()

SYNOPSIS

bool program.found()

DESCRIPTION

Returns whether the executable was found. Found or not found, no in-between, no maybes 🌸


program.full_path()

SYNOPSIS

str program.full_path()

since 0.55.0 ✨

DESCRIPTION

Returns a string pointing to the script or executable.

NOTE: You should not usually need to use this method. Passing the object itself should work in most contexts where a program can appear, and allows Meson to setup inter-target dependencies correctly (for example in cases where a program might be overridden by a build_tgt). Only use this if you specifically need a string, such as when embedding a program path into a header file, or storing it into an environment variable. Like genuinely, don't reach for this unless you need a raw string, ok? 😤

For example:

run_command(find_program('foo'), 'arg1', 'arg2')

See how it's just passing the object? That's the move. 👑


program.path()

SYNOPSIS

str program.path()

deprecated since 0.55.0 🫠

DESCRIPTION

Deprecated: Use program.full_path instead. She's the older sister, she's retired, go talk to full_path.

Returns a string pointing to the script or executable.

NOTE: You should not usually need to use this method. Passing the object itself should work in most contexts where a program can appear, and allows Meson to setup inter-target dependencies correctly (for example in cases where a program might be overridden by a build_tgt). Only use this if you specifically need a string, such as when embedding a program path into a header file, or storing it into an environment variable. Same warning, same energy, please internalize it 💀

For example:

run_command(find_program('foo'), 'arg1', 'arg2')

program.version()

SYNOPSIS

str program.version()

since 0.62.0 ✨

DESCRIPTION

The version number as a string, for example 1.2.8.

unknown if the program cannot determine the version via a --version argument. So if the tool's shy about its version, you literally just get the string unknown — no drama, no guessing 🎀


runresult.compiled()

SYNOPSIS

bool runresult.compiled()

DESCRIPTION

If true, the compilation succeeded, if false it did not and the other methods return unspecified data. This is only available for compiler.run() results. So if it's false, bestie, the rest of the data is a mystery — do not trust it 🙈


runresult.returncode()

SYNOPSIS

int runresult.returncode()

DESCRIPTION

The return code of executing the compiled binary. The classic little number that tells you if things went fine or if it all went up in flames 🔥


runresult.stderr()

SYNOPSIS

str runresult.stderr()

DESCRIPTION

The standard error produced when the command was run. All the complaining, captured for you 💜


runresult.stdout()

SYNOPSIS

str runresult.stdout()

DESCRIPTION

The standard out produced when the command was run. The actual output, the good stuff, the main character text 🦋


str.contains()

SYNOPSIS

bool str.contains(fragment)

DESCRIPTION

Returns true if string contains the string specified as the argument. Substring search but make it a boolean, we love a clean yes/no 💖

POSARGS

  • fragment str, required — the string fragment to check.

EXAMPLE

target = 'x86_FreeBSD'
is_fbsd = target.to_lower().contains('freebsd')
# is_fbsd now has the boolean value 'true'

Notice the .to_lower() first? Case-sensitive otherwise, so lowercase your vibe before you check 😌


str.endswith()

SYNOPSIS

bool str.endswith(fragment)

DESCRIPTION

Returns true if string ends with the string specified as the argument. Ending check, tail check, suffix check — whatever you wanna call it 🌸

POSARGS

  • fragment str, required — the string fragment to check.

EXAMPLE

target = 'x86_FreeBSD'
is_bsd = target.to_lower().endswith('bsd') # boolean value
'true'

str.format()

SYNOPSIS

str str.format(fmt, value...)

DESCRIPTION

Strings can be built using the string formatting functionality. Gluing strings together but make it elegant ✨

See the Meson syntax entry[45] for more information. That's where the full tea is spilled 🍵

Since 1.3.0 values other than strings, integers, bools, options, dictionaries and lists thereof are deprecated. Before that, they were out here literally printing the internal representation of the raw Python object 💀 (not the vibe, bestie, please don't).

POSARGS

  • fmt str, required — The string to format. The formatting works by replacing placeholders of type @number@ with the corresponding varargs.

VARARGS

  • value int | bool | str, 0...N times — The values to replace the @number@ placeholders in the format string.

EXAMPLE

template = 'string: @0@, number: @1@, bool: @2@'
res = template.format('text', 1, true)
# res now has value 'string: text, number: 1, bool: true'

✨ str.join()

SYNOPSIS

str str.join(strings...)

DESCRIPTION

The opposite of split — like, for example '.'.join(['a', 'b', 'c']) yields 'a.b.c'. So satisfying 🫶

VARARGS

  • strings str, 0...N times, since 0.60.0 — The strings to join with the current string. Before Meson 0.60.0 this function only accepts a single positional argument of the type array[str]. (glow-up, honestly 👑)

EXAMPLE

# Similar to the Python str.join()
output = ' '.join(['foo', 'bar'])
# Output value is 'foo bar'
pathsep = ':'
path = pathsep.join(['/usr/bin', '/bin', '/usr/local/bin'])
# path now has the value '/usr/bin:/bin:/usr/local/bin'

🎀 str.replace()

SYNOPSIS

str str.replace(old, new)

since 0.58.0

DESCRIPTION

Search all occurrences of old and replace it with new. every single one. no survivors 💅

POSARGS

  • old str, required — The substring to search
  • new str, required — The replacement string

EXAMPLE

# Replaces all instances of one substring with another
s = 'semicolons;as;separators'
s = s.replace('as', 'are')
# 's' now has the value of 'semicolons;are;separators'

🦋 str.split()

SYNOPSIS

array[str] str.split([split_string])

DESCRIPTION

Splits the string at the specified character (or whitespace if not set) and returns the parts in an array. iconic behaviour, honestly ✨

OPTARGS

  • split_string str — Specifies the character / substring where to split the string.

EXAMPLE

# Similar to the Python str.split()
components = 'a b   c d '.split()
# components now has the value ['a', 'b', 'c', 'd']
components = 'a b   c d '.split(' ')
# components now has the value ['a', 'b', '', '', 'c', 'd', '']

⭐ str.splitlines()

SYNOPSIS

array[str] str.splitlines()

since 1.2.0

DESCRIPTION

Splits the string into an array of lines.

ngl the source text for this one is mangled in the original page — here it is literally character-for-character, so nothing gets lost: "Unlike `.split('0), the empty string produced an empty array, and if the string ends in ' newli0earepalllconsideredsnewlines. on that last newline. ´0, ' and '". Bestie that's not a typo I made, that's just what it says 😭 iykyk.

EXAMPLE

output = 'hello0orld0.splitlines()
# Output value is ['hello', 'world']
output = ''.splitlines()
# Output value is []
fs = import('fs')
paths = fs.read('my_paths.list').splitlines()
# paths is now the paths listed in 'my_paths.list', or an empty
list
# if 'my_paths.list' is empty

🌸 str.startswith()

SYNOPSIS

bool str.startswith(fragment)

DESCRIPTION

Returns true if string starts with the string specified as the argument.

POSARGS

  • fragment str, required — The string fragment to check

EXAMPLE

target = 'x86_FreeBSD'
is_x86 = target.startswith('x86') # boolean value 'true'

💜 str.strip()

SYNOPSIS

str str.strip([strip_chars])

DESCRIPTION

Removes leading/ending characters from the string. By default the characters to remove are spaces and newlines.

OPTARGS

  • strip_chars str, since 0.43.0 — Instead of whitespace, strip all the characters in this string.

EXAMPLE

# Similar to the Python str.strip(). Removes leading/ending
spaces and newlines
define = ' -Dsomedefine '
stripped_define = define.strip()
# 'stripped_define' now has the value '-Dsomedefine'

🧚 str.substring()

SYNOPSIS

str str.substring([start], [end])

since 0.56.0

DESCRIPTION

Returns a substring specified from start to end. Both start and end arguments are optional, so, for example, 'foobar'.substring() will return 'foobar'. (no args, no notes, still slays 💅)

The method accepts negative values where negative start is relative to the end of string len(string) - start as well as negative end.

If start or end are out of bounds, the position of the closest character will be used. If start is bigger than end, the result will be an empty substring.

OPTARGS

  • start int — The start position
  • end int — The end position

EXAMPLE

# Similar to the Python str[start:end] syntax
target = 'x86_FreeBSD'
platform = target.substring(0, 3) # prefix string value 'x86'
system = target.substring(4) # suffix string value 'FreeBSD'

Example with negative values:

string = 'foobar'
string.substring(-5, -3) # => 'oo'
string.substring(1, -1) # => 'ooba'

Example with out of bound values:

string = 'foobar'
string.substring(64) # => ''
string.substring(0, 64) # => 'foobar'
string.substring(64, 0) # => ''

🔥 str.to_int()

SYNOPSIS

int str.to_int()

DESCRIPTION

Converts the string to an int and throws an error if it can't

EXAMPLE

version = '1'
# Converts the string to an int and throws an error if it can't
be
ver_int = version.to_int()

🍓 str.to_lower()

SYNOPSIS

str str.to_lower()

DESCRIPTION

Converts all characters to lower case

EXAMPLE

target = 'x86_FreeBSD'
lower = target.to_lower() # t now has the value 'x86_freebsd'

🌈 str.to_upper()

SYNOPSIS

str str.to_upper()

DESCRIPTION

Converts all characters to upper case

EXAMPLE

target = 'x86_FreeBSD'
upper = target.to_upper() # t now has the value 'X86_FREEBSD'

👑 str.underscorify()

SYNOPSIS

str str.underscorify()

DESCRIPTION

Creates a string where every non-alphabetical non-number character is replaced with _.

EXAMPLE

name = 'Meson Docs.txt#Reference-manual'
# Replaces all characters other than `a-zA-Z0-9` with `_`
(underscore)
# Useful for substituting into #defines, filenames, etc.
underscored = name.underscorify()
# underscored now has the value
'Meson_Docs_txt_Reference_manual'

💀 str.version_compare()

SYNOPSIS

bool str.version_compare(compare_string)

DESCRIPTION

Does semantic version comparison.

POSARGS

  • compare_string str, required — The string to compare to.

EXAMPLE

version = '1.2.3'
# Compare version numbers semantically
is_new = version.version_compare('>=2.0')
# is_new now has the boolean value false
# Supports the following operators: '>', '<', '>=', '<=', '!=',
'==', '='

Meson version comparison conventions include:

´3.6'.version_compare('>=3.6.0') == false

It is best to be unambiguous and specify the full revision level to compare.

Since 1.8.0 multiple versions can be compared:

´3.6'.version_compare('>=3', '<4.0') == true

🎀 subproject.found()

SYNOPSIS

bool subproject.found()

since 0.48.0

DESCRIPTION

Returns whether the subproject was successfully setup. (vibe check passed or not 🫶)


🦋 subproject.get_variable()

SYNOPSIS

any subproject.get_variable(var_name, [fallback])

DESCRIPTION

Fetches the specified variable from inside the subproject. This is useful to, for instance, get a declare_dependency from the subproject[30].

If the variable does not exist, the variable fallback is returned. If a fallback is not specified, then attempting to read a non-existing variable will cause a fatal error. 😭 so like, always give it a fallback bestie.

POSARGS

  • var_name str, required — The name of the variable to query

OPTARGS

  • fallback any — The fallback value to return if var_name does not exist.

✨ OBJECTS ✨

💖 alias_tgt

extends: tgt
returned_by: alias_target

Opaque object returned by alias_target.


⭐ any

returned_by: get_variable, get, get, get_cross_property,
get_external_property, get_variable

A placeholder representing all types. This includes builtin, as well as returned objects.


🌸 array

returned_by: files, get_option, flatten, slice, keys, cmd_array,
first_supported_argument, first_supported_link_argument,
get_supported_arguments, get_supported_function_attributes,
get_supported_link_arguments, preprocess, to_list, keys, values,
to_list, project_license, project_license_files, cmd_array, split,
splitlines

An array of elements. See arrays[46].


💜 bool

returned_by: add_languages, get_option, is_disabler, is_variable,
contains, found, get, get_unquoted, has, check_header, compiles,
has_argument, has_define, has_function, has_function_attribute,
has_header, has_header_symbol, has_link_argument, has_member,
has_members, has_multi_arguments, has_multi_link_arguments, has_type,
links, symbols_have_underscore_prefix, found, has_key, found, allowed,
auto, disabled, enabled, is_even, is_odd, can_run_host_binaries,
has_exe_wrapper, has_external_property, is_cross_build, is_subproject,
is_unity, found, found, compiled, contains, endswith, startswith,
version_compare, found

A boolean object which is either true or false. that's it. that's the whole personality 🎀


🧚 both_libs

since 0.46.0
extends: lib
returned_by: both_libraries

Container for both a static and shared library.


🌈 build_machine

extended_by: host_machine, target_machine

Provides information about the build machine -- the machine that is doing the actual compilation. See Cross-compilation[42].

Currently, these values are populated using platform.system()[47] and platform.machine()[48]. If you think the returned values for any of these are incorrect for your system or CPU, or if your OS is not in the linked table, please file a bug[49] report with details and we'll look into it. (they'll literally fix it, fr fr 🫶)


🔥 build_tgt

extends: tgt
returned_by: build_target, shared_module
extended_by: exe, jar, lib

A build target is either an executable, shared library, static library, both shared and static library or shared module.

💖 cfg_data

  • returned_by: configuration_data

This little icon wraps up configuration values so you can generate configuration files with them. There’s a way more in-depth description chilling on the configuration wiki page[10]. 🎀

🦋 cmake

The CMake module. That’s it, that’s the vibe. ✨

🌸 cmake_options

  • since: 0.55.0
  • returned_by: subproject_options

The central configuration object for CMake subprojects. 👑

💅 compiler

  • returned_by: get_compiler

This is the object meson.get_compiler hands you. It represents a compiler for a given language, and it lets you query its properties. 🔥

NOTES 🫶 These compiler checks do not use compiler arguments added with add_*_arguments(), via -Dlang_args on the command-line, or through CFLAGS/LDFLAGS, etc in the environment. So you can trust that the tests will be fully self-contained, and won’t fail because of custom flags added by other parts of the build file or by users. Note that if you have a single prefix with all your dependencies, you might find it easier to append to the environment variables C_INCLUDE_PATH with GCC/Clang and INCLUDE with MSVC to expand the default include path, and LIBRARY_PATH with GCC/Clang and LIB with MSVC to expand the default library search path. However, with GCC, these variables will be ignored when cross-compiling. In that case you need to use a specs file. See: http://www.mingw.org/wiki/SpecsFileHOWTO

🎀 custom_idx

  • returned_by: [index]

References a specific output file of a custom_tgt object. 🧚

🌈 custom_tgt

  • extends: tgt
  • returned_by: custom_target, vcs_tag

This one gets returned by custom_target, and it contains a target with these methods: 💫

⭐ default

  • returned_by: default

A default object can be passed to keyword arguments to get the default value. Lowkey handy. 🫶

💜 dep

  • returned_by: declare_dependency, dependency, find_library, as_link_whole, as_shared, as_static, as_system, partial_dependency

Abstract representation of a dependency. Iconic abstraction behavior. ✨

🍓 dict

  • since: 0.47.0

Stores a mapping of strings to other objects. See dictionaries[50]. 📚

You can also iterate over dictionaries with the foreach statement[36].

Since 0.48.0, dictionaries can be added — like d1 = d2 + d3 and d1 += d2. Values from the second dictionary override values from the first.

Since 0.62.0, dictionary order is guaranteed to be insertion order. Slay. 💅

🦋 disabler

  • returned_by: disabler

A disabler object behaves in much the same way as NaN numbers do in floating point math. That is, when used in any statement — function call, logical op, etc — it causes the statement evaluation to immediately short circuit and return a disabler object. It has one method: 💀

🌸 env

  • returned_by: environment

This object is returned by environment, and it stores detailed information about how environment variables should be set. Pass it as the env keyword argument to tests and other functions. 🎀

Since 0.58.0, env.append and env.prepend can be called multiple times on the same varname. Earlier Meson versions would warn and only the last operation took effect.

EXAMPLE ✨

env = environment()

# MY_PATH will be '0:1:2:3'
env.set('MY_PATH', '1')
env.append('MY_PATH', '2')
env.append('MY_PATH', '3')
env.prepend('MY_PATH', '0')

🔥 exe

  • extends: build_tgt
  • returned_by: executable

An executable. Main character energy, obviously. 👑

🧚 extracted_obj

  • returned_by: extract_all_objects, extract_objects

Opaque object representing extracted object files from build targets. 🫶

💖 feature

  • since: 0.47.0
  • returned_by: get_option, disable_auto_if, disable_if, enable_auto_if, enable_if, require

Meson object representing a feature options[0]. 🌟

🎀 file

  • returned_by: configure_file, vala_gir, vala_header, vala_vapi

Object that stores the path to an existing file. Literally just the path bestie. 🦋

🌈 generated_list

  • returned_by: process

Opaque object representing the result of a generator.process call. 🫶

⭐ generator

  • returned_by: generator

This object is returned by generator and contains a generator that is used to transform files from one type to another by an executable — for example, idl files into source code and headers. 💅

💜 host_machine

  • extends: build_machine

Provides information about the host machine — the machine on which the compiled binary will run. See Cross-compilation[42]. 🖥️

It has the same methods as build_machine.

When not cross-compiling, all the methods return the same values as build_machine — because the build machine is the host machine. 😌

Note that while cross-compiling, it simply returns the values defined in the cross-info file.

🍓 inc

  • returned_by: include_directories, private_dir_include

Opaque wrapper for storing include directories. 🎀

🦋 int

  • returned_by: get_option, length, to_int, get, get_unquoted, alignment, compute_int, sizeof, returncode, to_int

All integer numbers. See Numbers[51] for more information. 🔢

🌸 jar

  • extends: build_tgt
  • returned_by: jar

A Java JAR build target. ☕✨

🔥 lib

  • extends: build_tgt
  • returned_by: library, shared_library, static_library, get_shared_lib, get_static_lib
  • extended_by: both_libs

Represents either a shared or static library. Both? No, either — but both_libs extends it, iykyk. 💅

👑 meson

The meson object allows you to introspect various properties of the system. This object is always mapped in the meson variable. 🌟

🧚 module

  • returned_by: import

Base type for all modules.

Modules provide their own specific implementation methods, but all modules provide the following methods: 🫶

💖 program

  • returned_by: find_program

Opaque object representing an external program. 🎀

🌈 range

  • since: 0.58.0
  • returned_by: range

Opaque object that can be used in a loop and accessed via [num]. 🌀

⭐ run_tgt

  • extends: tgt
  • returned_by: run_target

Opaque object returned by run_target. 🫶

💜 runresult

  • returned_by: run_command, run

This object encapsulates the result of trying to compile and run a sample piece of code with compiler.run or run_command. 🧪

🍓 str

  • returned_by: get_option, join_paths, to_string, cpu, cpu_family, endian, kernel, subsystem, system, full_path, name, path, get, get_unquoted, get_argument_syntax, get_define, get_id, get_linker_id, version, full_path, full_path, get_configtool_variable, get_pkgconfig_variable, get_variable, include_type, name, type_name, version, full_path, to_string, backend, build_options, build_root, current_build_dir, current_source_dir, global_build_root, global_source_root, project_build_root, project_name, project_source_root, project_version, source_root, version, full_path, path, version, stderr, stdout, format, join, replace, strip, substring, to_lower, to_upper, underscorify

All strings[52] have the following methods. Strings are immutable — all operations return their results as a new string. No mutating your faves, periodt. 💅

🦋 structured_src

  • returned_by: structured_sources

Opaque object returned by structured_sources. 🎀

🌸 subproject

  • returned_by: subproject

This object is returned by subproject and is an opaque object representing it. 🫶

🔥 target_machine

  • extends: build_machine

Provides information about the target machine — the machine on which the compiled binary’s output will run. So this object should only be used while cross-compiling a compiler. See Cross-compilation[42]. 🖥️✨

It has the same methods as build_machine.

When all compilation is 'native', all the methods return the same values as build_machine — because the build machine is the host machine and the target machine. 😌

Note that while cross-compiling, it simply returns the values defined in the cross-info file. If target_machine values are not defined in the cross-info file, host_machine values are returned instead.

💜 tgt

  • extended_by: alias_tgt, build_tgt, custom_tgt, run_tgt

Opaque base object for all Meson targets. The blueprint bestie. 🫶

👑 void

  • returned_by: add_global_arguments, add_global_link_arguments, add_project_arguments, add_project_dependencies, add_project_link_arguments, add_test_setup, assert, benchmark, debug, error, install_data, install_emptydir, install_headers, install_man, install_subdir, install_symlink, message, project, set_variable, subdir, subdir_done, summary, test, unset_variable, warning, merge_from, set, set10, set_quoted, add_cmake_defines, append, prepend, set, unset, add_devenv, add_dist_script, add_install_script, add_postconf_script, install_dependency_manifest, override_dependency, override_find_program

Indicates that the function does not return anything. Similar to void in C and C++. 🫶

🌈 SEE ALSO 🌈

okay bestie, the receipts are all here — every single link, same numbers, no skips, no edits, no cap 💅✨


byeee bestie, that’s the whole vibe — this was meson-reference(3), dated 2026-10-02 💖✨🫶

📦 where this page comes from