meson.build(5)

✨ NAME ✨

okay bestie, gather round, because we're reading the meson.build(5) page from the File Formats Manual πŸ’– β€” this is the whole tea on meson.build, aka a build system dsl πŸ’…


πŸ¦‹ DESCRIPTION πŸ¦‹

so the meson dsl is a dynamically typed language, lowkey like other interpreted languages such as python and ruby πŸπŸ’Ž

  • every single object is immutable β€” no cap, you literally cannot mutate anything πŸ‘‘
  • you cannot define functions β€” only the built-in functions are available, periodt πŸ™…β€β™€οΈ

here's the little map of what's coming up, iykyk:

  • STRUCTURE β€” overview of source and project layout πŸ—‚οΈ
  • TYPES β€” information on all primitive types 🌈
  • SYNTAX β€” description of syntax and keywords ✍️

πŸŽ€ STRUCTURE πŸŽ€

every meson project must have a file called meson.build at the project root 🫢 that's the root build file, bestie. and it must have a call to the project() function as its first statement β€” first, like, no skipping the line πŸ’€

you can also have extra meson.build files chilling in any subdirectories of the project 🌸 those build files get executed with the subdir() function. iconic behaviour honestly.


πŸ’œ TYPES πŸ’œ

the meson build system dsl has most of the common types you'd expect, no surprises here:

  • booleans (written as true and false) βœ…
  • integers πŸ”’
  • strings 🧡
  • arrays πŸ“š
  • dictionaries πŸ“–

πŸ’– Booleans πŸ’–

booleans are either true or false. that's it, that's the whole vibe πŸ¦‹

OPERATORS

  • and β€” logical and
  • or β€” logical or
  • not β€” logical and

πŸ”₯ Integers πŸ”₯

you can specify an integer literal using decimal, hexadecimal, octal, and binary β€” so many flavours, so many options πŸ“

int_1 = 1
int_42 = 42
int_255 = 0xFF
int_493 = 0o755
int_1365 = 0b10101010101

all the common arithmetic operations are implemented for integers: addition, subtraction, division, multiplication, and modulo. the whole squad is here πŸ’…

OPERATORS

  • * β€” multiplication
  • / β€” integer division
  • % β€” modulo (remainder)
  • + β€” addition
  • - β€” subtraction
  • == β€” equal to
  • != β€” not equal to
  • < β€” less than
  • > β€” greater than
  • <= β€” less than or equal to
  • >= β€” greater than or equal to

🌸 Strings 🌸

strings in Meson are declared with single quotes ✨ and the backslash (\) is the escape character.

the full list of escape sequences is, and yes you're getting all of them:

  • \\ β€” Backslash
  • \' β€” Single quote
  • \a β€” Bell
  • \b β€” Backspace
  • \f β€” Formfeed
  • \n β€” Newline
  • \r β€” Carriage Return
  • \t β€” Horizontal Tab
  • \v β€” Vertical Tab
  • \ooo β€” Character with octal value ooo, up to 3 digits long
  • \xhh β€” Character with hex value hh
  • \uxxxx β€” Character with 16-bit hex value xxxx
  • \Uxxxxxxxx β€” Character with 32-bit hex value xxxxxxxx
  • \N{name} β€” Character named name in Unicode database

Multi-line strings are surrounded by 3 consecutive quotes πŸ’… these are raw strings, which means they do not support any of the escape sequences listed above. not one. so don't come crying to me about your \n 😭

Format strings are expressed by placing a leading f before the first opening quote 🧚 inside of a format string, sequences of the form @[a-z_]+@ will be substituted with the value of the matching variable. that variable can be of type bool, int, or str.

name = 'Alice'

# prints "Hello Alice"
message(f'Hello @name@')

OPERATORS

  • + β€” concatenate two strings
  • / β€” concatenate two strings as if join_paths() was called
  • [int] β€” access the character at index
  • <str> in <str> β€” check if str is a substring
  • <str> not in <str> β€” check if str is not a substring
  • == β€” equal to
  • != β€” not equal to

πŸ“š Arrays πŸ“š

arrays are delimited by brackets. an array can contain an arbitrary number of objects of any type β€” go feral, bestie πŸŽ‰

OPERATORS

  • + β€” if the rhs operand is an array, it will be joined to the lhs array. if it is a scalar, it will be appended to the lhs array.
  • [int] β€” access the object at index
  • <any> in <array> β€” check if object is in array
  • <any> not in <array> β€” check if object is not in array
  • == β€” equal to
  • != β€” not equal to

πŸ“– Dictionaries πŸ“–

dictionaries are delimited by curly braces. a dictionary can contain an arbitrary number of key: value pairs 🫢 keys are required to be strings, but values can be objects of any type. dictionaries are immutable and do not have a guaranteed order β€” so don't you dare rely on ordering, that's giving chaos πŸŒͺ️

OPERATORS

  • + β€” merge two dictionaries. in case of a conflicting key, the value from the rhs dictionary will be taken.
  • [str] β€” access the object with key key
  • <str> in <dict> β€” check if key is in dict
  • <str> not in <dict> β€” check if key is not in dict
  • == β€” equal to
  • != β€” not equal to

🌈 SYNTAX 🌈

a meson build file is composed of statements, which are terminated by newlines ✍️ other than the statement-terminating newline, white space has no syntactic meaning. so go ahead and format it however, it's not that deep πŸ’…

πŸŽ€ Comments πŸŽ€

a comment starts with the # character and extends until the end of the line. classic πŸ’¬

πŸ¦‹ Variables πŸ¦‹

a variable can contain a value of any type, and does not need to be predeclared 🫢

var1 = 'hello'
var2 = 102

one important difference in how variables work in the dsl is that all objects are immutable πŸ‘‘ when you see an operation which appears like a mutation, actually a new object is created and assigned to the name. it's giving "new me, who dis" 😌

var1 = [1, 2, 3]
var2 = var1
var2 += [4]
# var2 is now [1, 2, 3, 4]
# var1 is still [1, 2, 3]

πŸ’œ Function and method calls πŸ’œ

builtin functions are called by their name followed by parenthesis containing optional, comma-separated arguments 🌸 arguments are either positional or keyword. keyword arguments are expressed using the keyword without quotes, followed by a colon.

foo()
foo('bar')
foo('bar', baz: true)

method calls are expressed by a . followed by the same function call syntax as above ✨

foo.bar()
foo.bar('baz', qux: false)

for a complete list of functions and methods, please see meson-reference(3) πŸ“–

πŸ”₯ If statements πŸ”₯

start an if statement with the if keyword followed by a boolean expression. further conditions can be expressed using the elif keyword followed by a boolean expression. the else keyword can be used to handle the case when no conditions are matched. an if statement is terminated with the endif keyword βœ…

if conditon1
     ...
elif condition2
     ...
else condition3
     ...
endif

🧚 Foreach statements 🧚

to loop over values in an iterable, use the foreach keyword followed by a comma separated list of names to assign the values of the iterable to, a colon, and an iterable expression 🌈 only arrays and dictionaries are iterable. a foreach statement is terminated with the endforeach keyword.

arrays have one value to assign to.

foreach value : array
     foo(value)
endforeach

dictionaries have one two values to assign to.

foreach key, value : dictionary
     foo(key)
     bar(value)
endforeach

inside a foreach block you may use the break and continue keywords πŸ’… break exits the loop immediately. continue skips the rest of the current iteration.

no cap, those two are your besties when you need out early or need to skip ahead πŸ™ˆ

πŸ‘‘ SEE ALSO πŸ‘‘


and that's the whole page, bestie 🫢 this was meson.build(5) from the File Formats Manual, dated 2026-02-23 ⭐ go forth and build something iconic πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from