docs/faq: Add a section on user defined functions and macros [skip ci]

Fixes #3234
pull/8449/head
Dylan Baker 6 years ago
parent 0c663d056a
commit 1ac4358eae
  1. 79
      docs/markdown/FAQ.md

@ -551,4 +551,81 @@ libA = library('libA', 'fileA.cpp', link_with : [])
This means that you HAVE to write your `library(...)` calls in the order that the
dependencies flow. While ideas to make arbitrary orders possible exist, they were
rejected because reordering the `library(...)` calls was considered the "proper"
way. See [here](https://github.com/mesonbuild/meson/issues/8178) for the discussion.
way. See [here](https://github.com/mesonbuild/meson/issues/8178) for the discussion.
## Why doesn't meson have user defined functions/macros?
The tl;dr answer to this is that meson's design is focused on solving specific
problems rather than providing a general purpose language to write complex
code solutions in build files. Build systems should be quick to write and
quick to understand, functions muddle this simplicity.
The long answer is twofold:
First, Meson aims to provide a rich set of tools that solve specific problems
simply out of the box. This is similar to the "batteries included" mentality of
Python. By providing tools that solve common problems in the simplest way
possible *in* Meson we are solving that problem for everyone instead of forcing
everyone to solve that problem for themselves over and over again, often
badly. One example of this are Meson's dependency wrappers around various
config-tool executables (sdl-config, llvm-config, etc). In other build
systems each user of that dependency writes a wrapper and deals with the
corner cases (or doesn't, as is often the case), in Meson we handle them
internally, everyone gets fixes and the corner cases are ironed out for
*everyone*. Providing user defined functions or macros goes directly against
this design goal.
Second, functions and macros makes the build system more difficult to reason
about. When you encounter some function call, you can refer to the reference
manual to see that function and its signature. Instead of spending
frustrating hours trying to interpret some bit of m4 or follow long include
paths to figure out what `function1` (which calls `function2`, which calls
`function3`, ad infinitum), you know what the build system is doing. Unless
you're actively developing Meson itself, it's just a tool to orchestrate
building the thing you actually care about. We want you to spend as little
time worrying about build systems as possible so you can spend more time on
*your code*.
Many times user defined functions are used due to a lack of loops or
because loops are tedious to use in the language. Meson has both arrays/lists
and hashes/dicts natively. Compare the following pseudo code:
```meson
func(name, sources, extra_args)
executable(
name,
sources,
c_args : extra_args
)
endfunc
func(exe1, ['1.c', 'common.c'], [])
func(exe2, ['2.c', 'common.c'], [])
func(exe2_a, ['2.c', 'common.c'], ['-arg'])
```
```meson
foreach e : [['1', '1.c', []],
['2', '2.c', []],
['2', '2.c', ['-arg']]]
executable(
'exe' + e[0],
e[1],
c_args : e[2],
)
endforeach
```
The loop is both less code and is much easier to reason about than the function
version is, especially if the function were to live in a separate file, as is
common in other popular build systems.
Build system DSLs also tend to be badly thought out as generic programming
languages, Meson tries to make it easy to use external scripts or programs
for handling complex problems. While one can't always convert build logic
into a scripting language (or compiled language), when it can be done this is
often a better solution. External languages tend to be well-thought-out and
tested, generally don't regress, and users are more likely to have domain
knowledge about them. They also tend to have better tooling (such as
autocompletion, linting, testing solutions), which make them a lower
maintenance burden over time.

Loading…
Cancel
Save