diff options
Diffstat (limited to 'meson/docs')
176 files changed, 25036 insertions, 0 deletions
diff --git a/meson/docs/.editorconfig b/meson/docs/.editorconfig new file mode 100644 index 000000000..b5276f173 --- /dev/null +++ b/meson/docs/.editorconfig @@ -0,0 +1,2 @@ +[sitemap.txt] +indent_style = tab diff --git a/meson/docs/README.md b/meson/docs/README.md new file mode 100644 index 000000000..55fc3ec81 --- /dev/null +++ b/meson/docs/README.md @@ -0,0 +1,40 @@ +# Meson Documentation + +## Build dependencies + +Meson uses itself and [hotdoc](https://github.com/hotdoc/hotdoc) for generating documentation. + +Minimum required version of hotdoc is *0.8.9*. + +Instructions on how to install hotdoc are [here](https://hotdoc.github.io/installing.html). + +## Building the documentation + +From the Meson repository root dir: +``` +$ cd docs/ +$ meson built_docs +$ ninja -C built_docs/ upload +``` +Now you should be able to open the documentation locally +``` +built_docs/Meson documentation-doc/html/index.html +``` + +## Upload + +Meson uses the git-upload hotdoc plugin which basically +removes the html pages and replaces with the new content. + +You can simply run: +``` +$ ninja -C built_docs/ upload +``` + +## Contributing to the documentation + +Commits that only change documentation should have `[skip ci]` in their commit message, so CI is not run (it is quite slow). +For example: +``` +A commit message [skip ci] +``` diff --git a/meson/docs/genrelnotes.py b/meson/docs/genrelnotes.py new file mode 100755 index 000000000..082ab45f0 --- /dev/null +++ b/meson/docs/genrelnotes.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 + +# Copyright 2019 The Meson development team +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +''' + Generates release notes for new releases of Meson build system +''' +import subprocess +import sys +import os +from glob import glob + +RELNOTE_TEMPLATE = '''--- +title: Release {} +short-description: Release notes for {} +... + +# New features + +''' + + +def add_to_sitemap(from_version, to_version): + ''' + Adds release note entry to sitemap.txt. + ''' + sitemapfile = '../sitemap.txt' + s_f = open(sitemapfile, encoding='utf-8') + lines = s_f.readlines() + s_f.close() + with open(sitemapfile, 'w', encoding='utf-8') as s_f: + for line in lines: + if 'Release-notes' in line and from_version in line: + new_line = line.replace(from_version, to_version) + s_f.write(new_line) + s_f.write(line) + +def generate(from_version, to_version): + ''' + Generate notes for Meson build next release. + ''' + ofilename = f'Release-notes-for-{to_version}.md' + with open(ofilename, 'w', encoding='utf-8') as ofile: + ofile.write(RELNOTE_TEMPLATE.format(to_version, to_version)) + for snippetfile in glob('snippets/*.md'): + snippet = open(snippetfile, encoding='utf-8').read() + ofile.write(snippet) + if not snippet.endswith('\n'): + ofile.write('\n') + ofile.write('\n') + subprocess.check_call(['git', 'rm', snippetfile]) + subprocess.check_call(['git', 'add', ofilename]) + add_to_sitemap(from_version, to_version) + +if __name__ == '__main__': + if len(sys.argv) != 3: + print(sys.argv[0], 'from_version to_version') + sys.exit(1) + FROM_VERSION = sys.argv[1] + TO_VERSION = sys.argv[2] + os.chdir('markdown') + generate(FROM_VERSION, TO_VERSION) diff --git a/meson/docs/markdown/ARM-performance-test.md b/meson/docs/markdown/ARM-performance-test.md new file mode 100644 index 000000000..4be6e4aab --- /dev/null +++ b/meson/docs/markdown/ARM-performance-test.md @@ -0,0 +1,81 @@ +# Arm performance test + +Performance differences in build systems become more apparent on +slower platforms. To examine this difference we compared the +performance of Meson with GNU Autotools. We took the GLib software +project and rewrote its build setup with Meson. GLib was chosen +because it is a relatively large C code base which requires lots of +low level configuration. + +The Meson version of the build system is not fully equivalent to the +original Autotools one. It does not do all the same configuration +steps and does not build all the same targets. The biggest missing +piece being internationalisation support with Gettext. However it does +configure the system enough to build all C source and run all unit +tests. + +All measurements were done on a Nexus 4 smart phone running the latest +Ubuntu touch image (updated on September 9th 2013). + +Measurements +------ + +The first thing we measured was the time it took to run the configure step. + +![GLib config time](images/glib_conf.png) + +Meson takes roughly 20 seconds whereas Autotools takes 220. This is a +difference of one order of magnitude. Autotools' time contains both +autogen and configure. Again it should be remembered that Meson does +not do all the configure steps that Autotools does. It does do about +90% of them and it takes just 10% of the time to do it. + +Then we measured the build times. Two parallel compilation processes +were used for both systems. + +![GLib build time](images/glib_build.png) + +On desktop machines Ninja based build systems are 10-20% faster than +Make based ones. On this platform the difference grows to 50%. The +difference is probably caused by Make's inefficient disk access +patterns. Ninja is better at keeping both cores running all the time +which yields impressive performance improvements. + +![GLib no-op time](images/glib_empty.png) + +Next we measured the "empty build" case. That is, how long does it +take for the build system to detect that no changes need to be +made. This is one of the most important metrics of build systems +because it places a hard limit on how fast you can iterate on your +code. Autotools takes 14 seconds to determine that no work needs to be +done. Meson (or, rather, Ninja) takes just one quarter of a second. + +![GLib link time](images/glib_link.png) + +One step which takes quite a lot of time is linking. A common case is +that you are working on a library and there are tens of small test +executables that link to it. Even if the compilation step would be +fast, relinking all of the test executables takes time. It is common +for people to manually compile only one test application with a +command such as `make sometest` rather than rebuild everything. + +Meson has an optimization for this case. Whenever a library is +rebuilt, Meson inspects the ABI it exports. If it has not changed, +Meson will skip all relinking steps as unnecessary. The difference +this makes can be clearly seen in the chart above. In that test the +source was fully built, then the file `glib/gbytes.c` was touched to +force the rebuild of the base glib shared library. As can be seen, +Autotools then relinks all test executables that link with glib. Since +Meson can detect that the ABI is the same it can skip those steps. The +end result being that Meson is almost one hundred times faster on this +very common use case. + +Conclusions +----- + +One of the main drawbacks of C and C++ compared to languages such as +Java are long compilation times. However at least some of the blame +can be found in the build tools used rather than the languages +themselves or their compilers. Choosing proper tools can bring C and +C++ compilation very close to instantaneous rebuilds. This has a +direct impact on programmer productivity. diff --git a/meson/docs/markdown/Adding-arguments.md b/meson/docs/markdown/Adding-arguments.md new file mode 100644 index 000000000..adbc23e13 --- /dev/null +++ b/meson/docs/markdown/Adding-arguments.md @@ -0,0 +1,72 @@ +--- +short-description: Adding compiler arguments +... + +# Adding arguments + +Often you need to specify extra compiler arguments. Meson provides two +different ways to achieve this: global arguments and per-target +arguments. + +Global arguments +-- + +Global compiler arguments are set with the following command. As an +example you could do this. + +```meson +add_global_arguments('-DFOO=bar', language : 'c') +``` + +This makes Meson add the define to all C compilations. Usually you +would use this setting for flags for global settings. Note that for +setting the C/C++ language standard (the `-std=c99` argument in GCC), +you would probably want to use a default option of the `project()` +function. For details see the [reference manual](Reference-manual.md). + +Global arguments have certain limitations. They all have to be defined +before any build targets are specified. This ensures that the global +flags are the same for every single source file built in the entire +project with one exception. Compilation tests that are run as part of +your project configuration do not use these flags. The reason for that +is that you may need to run a test compile with and without a given +flag to determine your build setup. For this reason tests do not use +these global arguments. + +You should set only the most essential flags with this setting, you +should *not* set debug or optimization flags. Instead they should be +specified by selecting an appropriate build type. + +Project arguments +-- + +Project arguments work similar to global arguments except that they +are valid only within the current subproject. The usage is simple: + +```meson +add_project_arguments('-DMYPROJ=projname', language : 'c') +``` + +This would add the compiler flags to all C sources in the current +project. + +Per target arguments +-- + +Per target arguments are just as simple to define. + +```meson +executable('prog', 'prog.cc', cpp_args : '-DCPPTHING') +``` + +Here we create a C++ executable with an extra argument that is used +during compilation but not for linking. + +You can find the parameter name for other languages in the [reference +tables](Reference-tables.md). + +Specifying extra linker arguments is done in the same way: + +```meson +executable('prog', 'prog.cc', link_args : '-Wl,--linker-option') +``` diff --git a/meson/docs/markdown/Adding-new-projects-to-wrapdb.md b/meson/docs/markdown/Adding-new-projects-to-wrapdb.md new file mode 100644 index 000000000..51a0d7171 --- /dev/null +++ b/meson/docs/markdown/Adding-new-projects-to-wrapdb.md @@ -0,0 +1,267 @@ +# Adding new projects to WrapDB + + +## How it works + +Each wrap repository has a master branch with only one initial commit +and *no* wrap files. And that is the only commit ever made on that +branch. + +For every release of a project a new branch is created. The new branch +is named after the the upstream release number (e.g. `1.0.0`). This +branch holds a wrap file for this particular release. + +There are two types of wraps on WrapDB - regular wraps and wraps with +Meson build definition patches. A wrap file in a repository on WrapDB +must have a name `upstream.wrap`. + +Wraps with Meson build definition patches work in much the same way as +Debian: we take the unaltered upstream source package and add a new +build system to it as a patch. These build systems are stored as Git +repositories on GitHub. They only contain build definition files. You +may also think of them as an overlay to upstream source. + +Whenever a new commit is pushed into GitHub's project branch, a new +wrap is generated with an incremented version number. All the old +releases remain unaltered. New commits are always done via GitHub +merge requests and must be reviewed by someone other than the +submitter. + +Note that your Git repo with wrap must not contain the subdirectory of +the source release. That gets added automatically by the service. You +also must not commit any source code from the original tarball into +the wrap repository. + +## Choosing the repository name + +Wrapped subprojects are used much like external dependencies. Thus +they should have the same name as the upstream projects. + +NOTE: Repo names must fully match this regexp: `[a-z0-9._]+`. + +If the project provides a pkg-config file, then the repository name +should be the same as the pkg-config name. Usually this is the name of +the project, such as `libpng`. Sometimes it is slightly different, +however. As an example the libogg project's chosen pkg-config name is +`ogg` instead of `libogg`, which is the reason why the repository is +named plain `ogg`. + +If there is no a pkg-config file, the name the project uses/promotes +should be used, lowercase only (Catch2 -> catch2). + +If the project name is too generic or ambiguous (e.g. `benchmark`), +consider using `organization-project` naming format (e.g. +`google-benchmark`). + +## How to contribute a new wrap + +If the project already uses Meson build system, then only a wrap file +- `upstream.wrap` should be provided. In other case a Meson build +definition patch - a set of `meson.build` files - should be also +provided. + +### Request a new repository + +*Note:* you should only do this if you have written the build files +and want to contribute them for inclusion to WrapDB. The maintainers +have only limited reesources and unfortunately can not take requests +to write Meson build definitions for arbitrary projects. + +The submission starts by creating an issue on the [wrapdb bug +tracker](https://github.com/mesonbuild/wrapdb/issues) using *Title* +and *Description* below as a template. + +*Title:* `new wrap: <project_name>` + +*Description:* +``` +upstream url: <link_to_updastream> +version: <version_you_have_a_wrap_for> +``` + +Wait until the new repository or branch is created. A link to the new +repository or branch will be posted in a comment to this issue. After +this you can createa a merge request in that repository for your build +files. + +NOTE: Requesting a branch is not necessary. WrapDB maintainer can +create the branch and modify the PR accordingly if the project +repository exists. + +### Creating the wrap contents + +Setting up the contents might seem a bit counterintuitive at first. +Just remember that the outcome needs to have one (and only one) commit +that has all the build definition files (i.e. `meson.build` and +`meson_options.txt` files) and _nothing else_. It is good practice to +have this commit in a branch whose name matches the release as +described above. + +First you need to fork the repository to your own page using GitHub's +fork button. Then you can clone the repo to your local machine. + + +``` +git clone git@github.com:yourusername/libfoo.git foo-wrap +``` + +Create a new branch for your work: + +``` +git checkout -b 1.0.0 +``` + +If you are adding new changes to an existing branch, leave out the +`-b` argument. + +Now you need to copy the source code for the original project to this +directory. If you already have it extracted somewhere, you'd do +something like this: + +``` +cd /path/to/source/extract/dir +cp -r * /path/to/foo-wrap +``` + +Now all the files should be in the wrap directory. Do _not_ add them +to Git, though. Neither now or at any time during this process. The +repo must contain only the newly created build files. + +New release branches require an `upstream.wrap` file, so create one if +needed. + +``` +${EDITOR} upstream.wrap +``` + +The file format is simple, see any existing wrapdb repo for the +content. The checksum is SHA-256 and can be calculated with the +following command on most unix-like operating systems: + +``` +sha256sum path/to/libfoo-1.0.0.tar.gz +``` + +Under macOS the command is the following: + +``` +shasum -a 256 path/to/libfoo-1.0.0.tar.gz +``` + +Next you need to add the entries that define what dependencies the +current project provides. This is important, as it is what makes +Meson's automatic dependency resolver work. It is done by adding a +`provide` entry at the end of the `upstream.wrap` file. Using the Ogg +library as an example, this is what it would look like: + +```ini +[provide] +ogg = ogg_dep +``` + +The `ogg` part on the left refers to the dependency name, which should +be the same as its Pkg-Config name. `ogg_dep` on the right refers to +the variable in the build definitions that provides the dependency. +Most commonly it holds the result of a `declare_dependency` call. If a +variable of that name is not defined, Meson will exit with a hard +error. For further details see [the main Wrap +manual](Wrap-dependency-system-manual.md). + +Now you can create the build files and work on them until the project +builds correctly. + +``` +${EDITOR} meson.build meson_options.txt +``` + +When you are satisfied with the results, add the build files to Git +and push the result to GitHub. + +``` +<verify that your project builds and runs> +git add upstream.wrap meson.build +git commit -a -m 'Add wrap files for libfoo-1.0.0' +git push -u origin 1.0.0 +``` + +Now you should create a pull request on GitHub. Try to create it +against the correct branch rather than master (`1.0.0` branch in this +example). GitHub should do this automatically. + +If the branch doesn't exist file a pull request against master. +WrapDB maintainers can fix it before merging. + +If packaging review requires you to do changes, use the `--amend` +argument to `commit` so that your branch will continue to have only +one commit. + +``` +${EDITOR} meson.build +git commit -a --amend +git push --force +``` + +### Request a new release version to an existing repository + +Adding new releases to an existing repo is straightforward. All you +need to do is to follow the rules discussed above but when you create +the merge request, file it against the master branch. The repository +reviewer will create the necessary branch and retarget your merge +request accordingly. + +## What is done by WrapDB maintainers + +[mesonwrap tools](Wrap-maintainer-tools.md) must be used for the tasks +below. + +### Adding new project to the Wrap provider service + +Each project gets its own repo. It is initialized like this: + +``` +mesonwrap new_repo --homepage=$HOMEPAGE --directory=$NEW_LOCAL_PROJECT_DIR $PROJECT_NAME +``` + +The command creates a new repository and uploads it to GitHub. + +`--version` flag may be used to create a branch immediately. + +### Adding a new branch to an existing project + +Create a new branch whose name matches the upstream release number. + +``` +git checkout master +git checkout -b 1.0.0 +git push origin 1.0.0 +(or from GitHub web page, remember to branch from master) +``` + +Branch names must fully match this regexp: `[a-z0-9._]+`. + +## Changes to original source + +The point of a wrap is to provide the upstream project with as few +changes as possible. Most projects should not contain anything more +than a few Meson definition files. Sometimes it may be necessary to +add a template header file or something similar. These should be held +at a minimum. + +It should especially be noted that there must **not** be any patches +to functionality. All such changes must be submitted to upstream. You +may also host your own Git repo with the changes if you wish. The Wrap +system has native support for Git subprojects. + +## Passing automatic validation + +Every submitted wrap goes through an automated correctness review and +passing it is a requirement for merging. Therefore it is highly +recommended that you run the validation checks yourself so you can fix +any issues faster. + +Instructions on how to install and run the review tool can be found on +the [Wrap review guidelines page](Wrap-review-guidelines.md). If your +submission is merge request number 5 for a repository called `mylib`, +then you'd run the following command: + + mesonwrap review --pull-request 5 mylib diff --git a/meson/docs/markdown/Additional.md b/meson/docs/markdown/Additional.md new file mode 100644 index 000000000..2fff48842 --- /dev/null +++ b/meson/docs/markdown/Additional.md @@ -0,0 +1,8 @@ +--- +short-description: Misc documentation +... + +# Additional documentation + +This section references documents miscellaneous design, benchmarks, or +basically anything concerning Meson. diff --git a/meson/docs/markdown/Build-options.md b/meson/docs/markdown/Build-options.md new file mode 100644 index 000000000..4a0b17800 --- /dev/null +++ b/meson/docs/markdown/Build-options.md @@ -0,0 +1,229 @@ +--- +short-description: Build options to configure project properties +... + +# Build options + +Most non-trivial builds require user-settable options. As an example a +program may have two different data backends that are selectable at +build time. Meson provides for this by having a option definition +file. Its name is `meson_options.txt` and it is placed at the root of +your source tree. + +Here is a simple option file. + +```meson +option('someoption', type : 'string', value : 'optval', description : 'An option') +option('other_one', type : 'boolean', value : false) +option('combo_opt', type : 'combo', choices : ['one', 'two', 'three'], value : 'three') +option('integer_opt', type : 'integer', min : 0, max : 5, value : 3) # Since 0.45.0 +option('free_array_opt', type : 'array', value : ['one', 'two']) # Since 0.44.0 +option('array_opt', type : 'array', choices : ['one', 'two', 'three'], value : ['one', 'two']) +option('some_feature', type : 'feature', value : 'enabled') # Since 0.47.0 +option('long_desc', type : 'string', value : 'optval', + description : 'An option with a very long description' + + 'that does something in a specific context') # Since 0.55.0 +``` + +For built-in options, see [Built-in options][builtin_opts]. + +## Build option types + +All types allow a `description` value to be set describing the option, +if no description is set then the name of the option will be used instead. + +### Strings + +The string type is a free form string. If the default value is not set +then an empty string will be used as the default. + +### Booleans + +Booleans may have values of either `true` or `false`. If no default +value is supplied then `true` will be used as the default. + +### Combos + +A combo allows any one of the values in the `choices` parameter to be +selected. If no default value is set then the first value will be the +default. + +### Integers + +An integer option contains a single integer with optional upper and +lower values that are specified with the `min` and `max` keyword +arguments. + +This type is available since Meson version 0.45.0. + +### Arrays + +Arrays represent an array of strings. By default the array can contain +arbitrary strings. To limit the possible values that can used set the +`choices` parameter. Meson will then only allow the value array to +contain strings that are in the given list. The array may be +empty. The `value` parameter specifies the default value of the option +and if it is unset then the values of `choices` will be used as the +default. + +As of 0.47.0 -Dopt= and -Dopt=[] both pass an empty list, before this +-Dopt= would pass a list with an empty string. + +This type is available since version 0.44.0 + +### Features + +A `feature` option has three states: `enabled`, `disabled` or `auto`. +It is intended to be passed as value for the `required` keyword +argument of most functions. Currently supported in +[`dependency()`](Reference-manual.md#dependency), +[`find_library()`](Reference-manual.md#compiler-object), +[`find_program()`](Reference-manual.md#find_program) and +[`add_languages()`](Reference-manual.md#add_languages) functions. + +- `enabled` is the same as passing `required : true`. +- `auto` is the same as passing `required : false`. +- `disabled` do not look for the dependency and always return 'not-found'. + +When getting the value of this type of option using `get_option()`, a +special [feature option +object](Reference-manual.md#feature-option-object) is returned instead +of the string representation of the option's value. This object can be +passed to `required`: + +```meson +d = dependency('foo', required : get_option('myfeature')) +if d.found() + app = executable('myapp', 'main.c', dependencies : [d]) +endif +``` + +To check the value of the feature, the object has three methods +returning a boolean and taking no argument: + +- `.enabled()` +- `.disabled()` +- `.auto()` + +This is useful for custom code depending on the feature: + +```meson +if get_option('myfeature').enabled() + # ... +endif +``` + +If the value of a `feature` option is set to `auto`, that value is +overridden by the global `auto_features` option (which defaults to +`auto`). This is intended to be used by packagers who want to have +full control on which dependencies are required and which are +disabled, and not rely on build-deps being installed (at the right +version) to get a feature enabled. They could set +`auto_features=enabled` to enable all features and disable explicitly +only the few they don't want, if any. + +This type is available since version 0.47.0 + +## Using build options + +```meson +optval = get_option('opt_name') +``` + +This function also allows you to query the value of Meson's built-in +project options. For example, to get the installation prefix you would +issue the following command: + +```meson +prefix = get_option('prefix') +``` + +It should be noted that you can not set option values in your Meson +scripts. They have to be set externally with the `meson configure` +command line tool. Running `meson configure` without arguments in a +build dir shows you all options you can set. + +To change their values use the `-D` +option: + +```console +$ meson configure -Doption=newvalue +``` + +Setting the value of arrays is a bit special. If you only pass a +single string, then it is considered to have all values separated by +commas. Thus invoking the following command: + +```console +$ meson configure -Darray_opt=foo,bar +``` + +would set the value to an array of two elements, `foo` and `bar`. + +If you need to have commas in your string values, then you need to +pass the value with proper shell quoting like this: + +```console +$ meson configure "-Doption=['a,b', 'c,d']" +``` + +The inner values must always be single quotes and the outer ones +double quotes. + +To change values in subprojects prepend the name of the subproject and +a colon: + +```console +$ meson configure -Dsubproject:option=newvalue +``` + +**NOTE:** If you cannot call `meson configure` you likely have a old + version of Meson. In that case you can call `mesonconf` instead, but + that is deprecated in newer versions + +## Yielding to superproject option + +Suppose you have a master project and a subproject. In some cases it +might be useful to have an option that has the same value in both of +them. This can be achieved with the `yield` keyword. Suppose you have +an option definition like this: + +```meson +option('some_option', type : 'string', value : 'value', yield : true) +``` + +If you build this project on its own, this option behaves like +usual. However if you build this project as a subproject of another +project which also has an option called `some_option`, then calling +`get_option` returns the value of the superproject. If the value of +`yield` is `false`, `get_option` returns the value of the subproject's +option. + + +## Built-in build options + +There are a number of [built-in options][builtin_opts]. To get the +current list execute `meson configure` in the build directory. + +[builtin_opts]: https://mesonbuild.com/Builtin-options.html + +### Visual Studio + +#### Startup project + +The `backend_startup_project` option can be set to define the default +project that will be executed with the "Start debugging F5" action in +visual studio. It should be the same name as an executable target +name. + +```meson +project('my_project', 'c', default_options: ['backend_startup_project=my_exe']) +executable('my_exe', ...) +``` + +### Ninja + +#### Max links + +The `backend_max_links` can be set to limit the number of processes +that ninja will use to link. diff --git a/meson/docs/markdown/Build-system-converters.md b/meson/docs/markdown/Build-system-converters.md new file mode 100644 index 000000000..1c0b4fc50 --- /dev/null +++ b/meson/docs/markdown/Build-system-converters.md @@ -0,0 +1,27 @@ +--- +short-description: Converting other build systems to Meson +... + +# Build system converters + +Moving from one build system into another includes a fair bit of +work. To make things easier, Meson provides scripts to convert other +build systems into Meson. At the time of writing, scripts for CMake +and autotools exist. It can be found in the `tools` subdirectory in +Meson's source tree. + +The scripts do not try to do a perfect conversion. This would be +extremely difficult because the data models of other build systems are +very different. The goal of the converter script is to convert as much +of the low level drudgery as possible. Using the scripts is +straightforward. We'll use the CMake one as an example but the +Autotools one works exactly the same way. + + cmake2meson.py path/to/CMake/project/root + +This command generates a skeleton Meson project definition that tries +to mirror CMake's setup as close as possible. Once this is done, you +need to go through these files manually and finalize the +conversion. To make this task as simple as possible, the converter +script will transfer all comments from the CMake definition into Meson +definition. diff --git a/meson/docs/markdown/Build-targets.md b/meson/docs/markdown/Build-targets.md new file mode 100644 index 000000000..83f959f0b --- /dev/null +++ b/meson/docs/markdown/Build-targets.md @@ -0,0 +1,100 @@ +--- +short-description: Definition of build targets +... + +# Build targets + +Meson provides four kinds of build targets: executables, libraries +(which can be set to be built as static or shared or both of them at +the build configuration time), static libraries, and shared libraries. +They are created with the commands `executable`, `library`, +`static_library` and `shared_library`, respectively. All objects created +in this way are **immutable**. That is, you can not change any aspect of +them after they have been constructed. This ensures that all information +pertaining to a given build target is specified in one well defined +place. + +Libraries and executables +-- + +As an example, here is how you would build a library. + +```meson +project('shared lib', 'c') +library('mylib', 'source.c') +``` + +It is generally preferred to use the `library` command instead of +`shared_library` and `static_library` and then configure which +libraries (static or shared or both of them) will be built at the +build configuration time using the `default_library` +[built-in option](Builtin-options.md). + +In Unix-like operating systems, shared libraries can be +versioned. Meson supports this with keyword arguments, which will be +ignored if the library is configured as static at the compile time. + +```meson +project('shared lib', 'c') +library('mylib', 'source.c', version : '1.2.3', soversion : '0') +``` + +It is common to build a library and then an executable that links +against it. This is supported as well. + +```meson +project('shared lib', 'c') +lib = library('mylib', 'source.c') +executable('program', 'prog.c', link_with : lib) +``` + +Meson sets things up so that the resulting executable can be run +directly from the build directory. There is no need to write shell +scripts or set environment variables. + +One target can have multiple language source files. + +```meson +project('multilang', 'c', 'cpp') +executable('multiexe', 'file.c', 'file2.cc') +``` + +Object files +-- + +Sometimes you can't build files from sources but need to utilize an +existing object file. A typical case is using an object file provided +by a third party. Object files can be specified just like sources. + +```meson +exe = executable('myexe', 'source.cpp', objects : 'third_party_object.o') +``` + +A different case is when you want to use object files built in one +target directly in another. A typical case is when you build a shared +library and it has an internal class that is not exported in the +ABI. This means you can't access it even if you link against the +library. Typical workarounds for this include building both a shared +and static version of the library or putting the source file in the +test executable's source list. Both of these approaches cause the +source to be built twice, which is slow. + +In Meson you can extract object files from targets and use them as-is +on other targets. This is the syntax for it. + +```meson +lib = shared_library('somelib', 'internalclass.cc', 'file.cc', ...) +eo = lib.extract_objects('internalclass.cc') +executable('classtest', 'classtest.cpp', objects : eo) +``` + +Here we take the internal class object and use it directly in the +test. The source file is only compiled once. + +Note that careless use of this feature may cause strange bugs. As an +example trying to use objects of an executable or static library in a +shared library will not work because shared library objects require +special compiler flags. Getting this right is the user's +responsibility. For this reason it is strongly recommended that you +only use this feature for generating unit test executables in the +manner described above. diff --git a/meson/docs/markdown/Builtin-options.md b/meson/docs/markdown/Builtin-options.md new file mode 100644 index 000000000..0536e77bc --- /dev/null +++ b/meson/docs/markdown/Builtin-options.md @@ -0,0 +1,262 @@ +--- +short-description: Built-in options to configure project properties +... + +# Built-in options + +Meson provides two kinds of options: [build options provided by the +build files](Build-options.md) and built-in options that are either +universal options, base options, compiler options. + +## Universal options + +A list of these options can be found by running `meson --help`. All +these can be set by passing `-Doption=value` to `meson` (aka `meson +setup`), or by setting them inside `default_options` of `project()` in +your `meson.build`. Some options can also be set by `--option=value`, +or `--option value`--- a list is shown by running `meson setup +--help`. + +For legacy reasons `--warnlevel` is the cli argument for the +`warning_level` option. + +They can also be edited after setup using `meson configure +-Doption=value`. + +Installation options are all relative to the prefix, except: + +* When the prefix is `/usr`: `sysconfdir` defaults to `/etc`, +* `localstatedir` defaults to `/var`, and `sharedstatedir` defaults to +* `/var/lib` When the prefix is `/usr/local`: `localstatedir` defaults +* to `/var/local`, and `sharedstatedir` defaults to `/var/local/lib` + +### Directories + +| Option | Default value | Description | +| ------ | ------------- | ----------- | +| prefix | see below | Installation prefix | +| bindir | bin | Executable directory | +| datadir | share | Data file directory | +| includedir | include | Header file directory | +| infodir | share/info | Info page directory | +| libdir | see below | Library directory | +| libexecdir | libexec | Library executable directory | +| localedir | share/locale | Locale data directory | +| localstatedir | var | Localstate data directory | +| mandir | share/man | Manual page directory | +| sbindir | sbin | System executable directory | +| sharedstatedir | com | Architecture-independent data directory | +| sysconfdir | etc | Sysconf data directory | + + +`prefix` defaults to `C:/` on Windows, and `/usr/local` otherwise. You +should always override this value. + +`libdir` is automatically detected based on your platform, it should +be correct when doing "native" (build machine == host machine) +compilation. For cross compiles Meson will try to guess the correct +libdir, but it may not be accurate, especially on Linux where +different distributions have different defaults. Using a [cross +file](Cross-compilation.md#defining-the-environment), particularly the +paths section may be necessary. + +### Core options + +Options that are labeled "per machine" in the table are set per +machine. See the [specifying options per +machine](#specifying-options-per-machine) section for details. + +| Option | Default value | Description | Is per machine | Is per subproject | +| ------ | ------------- | ----------- | -------------- | ----------------- | +| auto_features {enabled, disabled, auto} | auto | Override value of all 'auto' features | no | no | +| backend {ninja, vs,<br>vs2010, vs2012, vs2013, vs2015, vs2017, vs2019, xcode} | ninja | Backend to use | no | no | +| buildtype {plain, debug,<br>debugoptimized, release, minsize, custom} | debug | Build type to use | no | no | +| debug | true | Debug | no | no | +| default_library {shared, static, both} | shared | Default library type | no | yes | +| errorlogs | true | Whether to print the logs from failing tests. | no | no | +| install_umask {preserve, 0000-0777} | 022 | Default umask to apply on permissions of installed files | no | no | +| layout {mirror,flat} | mirror | Build directory layout | no | no | +| optimization {0, g, 1, 2, 3, s} | 0 | Optimization level | no | no | +| pkg_config_path {OS separated path} | '' | Additional paths for pkg-config to search before builtin paths | yes | no | +| cmake_prefix_path | [] | Additional prefixes for cmake to search before builtin paths | yes | no | +| stdsplit | true | Split stdout and stderr in test logs | no | no | +| strip | false | Strip targets on install | no | no | +| unity {on, off, subprojects} | off | Unity build | no | no | +| unity_size {>=2} | 4 | Unity file block size | no | no | +| warning_level {0, 1, 2, 3} | 1 | Set the warning level. From 0 = none to 3 = highest | no | yes | +| werror | false | Treat warnings as errors | no | yes | +| wrap_mode {default, nofallback,<br>nodownload, forcefallback, nopromote} | default | Wrap mode to use | no | no | +| force_fallback_for | [] | Force fallback for those dependencies | no | no | + +<a name="build-type-options"></a> For setting optimization levels and +toggling debug, you can either set the `buildtype` option, or you can +set the `optimization` and `debug` options which give finer control +over the same. Whichever you decide to use, the other will be deduced +from it. For example, `-Dbuildtype=debugoptimized` is the same as +`-Ddebug=true -Doptimization=2` and vice-versa. This table documents +the two-way mapping: + +| buildtype | debug | optimization | +| --------- | ----- | ------------ | +| plain | false | 0 | +| debug | true | 0 | +| debugoptimized | true | 2 | +| release | false | 3 | +| minsize | true | s | + +All other combinations of `debug` and `optimization` set `buildtype` to `'custom'`. + +## Base options + +These are set in the same way as universal options, either by +`-Doption=value`, or by setting them inside `default_options` of +`project()` in your `meson.build`. However, they cannot be shown in +the output of `meson --help` because they depend on both the current +platform and the compiler that will be selected. The only way to see +them is to setup a builddir and then run `meson configure` on it with +no options. + +The following options are available. Note that they may not be +available on all platforms or with all compilers: + +| Option | Default value | Possible values | Description | +|---------------|----------------|------------------------------------------------------------------|-------------------------------------------------------------------------------| +| b_asneeded | true | true, false | Use -Wl,--as-needed when linking | +| b_bitcode | false | true, false | Embed Apple bitcode, see below | +| b_colorout | always | auto, always, never | Use colored output | +| b_coverage | false | true, false | Enable coverage tracking | +| b_lundef | true | true, false | Don't allow undefined symbols when linking | +| b_lto | false | true, false | Use link time optimization | +| b_lto_threads | 0 | Any integer* | Use multiple threads for lto. *(Added in 0.57.0)* | +| b_lto_mode | default | default, thin | Select between lto modes, thin and default. *(Added in 0.57.0)* | +| b_ndebug | false | true, false, if-release | Disable asserts | +| b_pch | true | true, false | Use precompiled headers | +| b_pgo | off | off, generate, use | Use profile guided optimization | +| b_sanitize | none | see below | Code sanitizer to use | +| b_staticpic | true | true, false | Build static libraries as position independent | +| b_pie | false | true, false | Build position-independent executables (since 0.49.0) | +| b_vscrt | from_buildtype | none, md, mdd, mt, mtd, from_buildtype, static_from_buildtype | VS runtime library to use (since 0.48.0) (static_from_buildtype since 0.56.0) | + +The value of `b_sanitize` can be one of: `none`, `address`, `thread`, +`undefined`, `memory`, `address,undefined`, but note that some +compilers might not support all of them. For example Visual Studio +only supports the address sanitizer. + +* < 0 means disable, == 0 means automatic selection, > 0 sets a specific number to use + +LLVM supports `thin` lto, for more discussion see [LLVM's documentation](https://clang.llvm.org/docs/ThinLTO.html) + +<a name="b_vscrt-from_buildtype"></a> +The default value of `b_vscrt` is `from_buildtype`. The following table is +used internally to pick the CRT compiler arguments for `from_buildtype` or +`static_from_buildtype` *(since 0.56)* based on the value of the `buildtype` +option: + +| buildtype | from_buildtype | static_from_buildtype | +| -------- | -------------- | --------------------- | +| debug | `/MDd` | `/MTd` | +| debugoptimized | `/MD` | `/MT` | +| release | `/MD` | `/MT` | +| minsize | `/MD` | `/MT` | +| custom | error! | error! | + +### Notes about Apple Bitcode support + +`b_bitcode` will pass `-fembed-bitcode` while compiling and will pass +`-Wl,-bitcode_bundle` while linking. These options are incompatible +with `b_asneeded`, so that option will be silently disabled. + +[Shared modules](Reference-manual.md#shared_module) will not have +bitcode embedded because `-Wl,-bitcode_bundle` is incompatible with +both `-bundle` and `-Wl,-undefined,dynamic_lookup` which are necessary +for shared modules to work. + +## Compiler options + +Same caveats as base options above. + +The following options are available. They can be set by passing +`-Doption=value` to `meson`. Note that both the options themselves and +the possible values they can take will depend on the target platform +or compiler being used: + +| Option | Default value | Possible values | Description | +| ------ | ------------- | --------------- | ----------- | +| c_args | | free-form comma-separated list | C compile arguments to use | +| c_link_args | | free-form comma-separated list | C link arguments to use | +| c_std | none | none, c89, c99, c11, c17, c18, c2x, gnu89, gnu99, gnu11, gnu17, gnu18, gnu2x | C language standard to use | +| c_winlibs | see below | free-form comma-separated list | Standard Windows libs to link against | +| c_thread_count | 4 | integer value ≥ 0 | Number of threads to use with emcc when using threads | +| cpp_args | | free-form comma-separated list | C++ compile arguments to use | +| cpp_link_args | | free-form comma-separated list | C++ link arguments to use | +| cpp_std | none | none, c++98, c++03, c++11, c++14, c++17, c++20 <br/>c++2a, c++1z, gnu++03, gnu++11, gnu++14, gnu++17, gnu++1z, <br/> gnu++2a, gnu++20, vc++14, vc++17, vc++latest | C++ language standard to use | +| cpp_debugstl | false | true, false | C++ STL debug mode | +| cpp_eh | default | none, default, a, s, sc | C++ exception handling type | +| cpp_rtti | true | true, false | Whether to enable RTTI (runtime type identification) | +| cpp_thread_count | 4 | integer value ≥ 0 | Number of threads to use with emcc when using threads | +| cpp_winlibs | see below | free-form comma-separated list | Standard Windows libs to link against | +| fortran_std | none | [none, legacy, f95, f2003, f2008, f2018] | Fortran language standard to use | +| cuda_ccbindir | | filesystem path | CUDA non-default toolchain directory to use (-ccbin) *(Added in 0.57.1)* | + +The default values of `c_winlibs` and `cpp_winlibs` are in +compiler-specific argument forms, but the libraries are: kernel32, +user32, gdi32, winspool, shell32, ole32, oleaut32, uuid, comdlg32, +advapi32. + +All these `<lang>_*` options are specified per machine. See below in +the [specifying options per machine](#specifying-options-per-machine) +section on how to do this in cross builds. + +When using MSVC, `cpp_eh=none` will result in no exception flags being +passed, while the `cpp_eh=[value]` will result in `/EH[value]`. Since +*0.51.0* `cpp_eh=default` will result in `/EHsc` on MSVC. When using +gcc-style compilers, nothing is passed (allowing exceptions to work), +while `cpp_eh=none` passes `-fno-exceptions`. + +Since *0.54.0* The `<lang>_thread_count` option can be used to control +the value passed to `-s PTHREAD_POOL_SIZE` when using emcc. No other +c/c++ compiler supports this option. + +## Specifying options per machine + +Since *0.51.0*, some options are specified per machine rather than +globally for all machine configurations. Prefixing the option with +`build.` just affects the build machine configuration, while +unprefixed just affects the host machine configuration, respectively. +For example: + + - `build.pkg_config_path` controls the paths pkg-config will search + for just `native: true` dependencies (build machine). + + - `pkg_config_path` controls the paths pkg-config will search for + just `native: false` dependencies (host machine). + +This is useful for cross builds. In the native builds, build = host, +and the unprefixed option alone will suffice. + +Prior to *0.51.0*, these options just effected native builds when +specified on the command line, as there was no `build.` prefix. +Similarly named fields in the `[properties]` section of the cross file +would effect cross compilers, but the code paths were fairly different +allowing differences in behavior to crop out. + +## Specifying options per subproject + +Since *0.54.0* `default_library` and `werror` built-in options can be +defined per subproject. This is useful for example when building +shared libraries in the main project, but static link a subproject, or +when the main project must build with no warnings but some subprojects +cannot. + +Most of the time this would be used either by the parent project by +setting subproject's default_options (e.g. `subproject('foo', +default_options: 'default_library=static')`), or by the user using the +command line `-Dfoo:default_library=static`. + +The value is overridden in this order: +- Value from parent project +- Value from subproject's default_options if set +- Value from subproject() default_options if set +- Value from command line if set + +Since 0.56.0 `warning_level` can also be defined per subproject. diff --git a/meson/docs/markdown/CMake-module.md b/meson/docs/markdown/CMake-module.md new file mode 100644 index 000000000..b82227d9b --- /dev/null +++ b/meson/docs/markdown/CMake-module.md @@ -0,0 +1,289 @@ +# CMake module + +**Note**: the functionality of this module is governed by [Meson's + rules on mixing build systems](Mixing-build-systems.md). + +This module provides helper tools for generating cmake package files. +It also supports the usage of CMake based subprojects, similar to +the normal [Meson subprojects](Subprojects.md). + + +## Usage + +To use this module, just do: **`cmake = import('cmake')`**. The +following functions will then be available as methods on the object +with the name `cmake`. You can, of course, replace the name `cmake` +with anything else. + +It is generally recommended to use the latest Meson version and +CMake >=3.17 for best compatibility. CMake subprojects will +usually also work with older CMake versions. However, this can +lead to unexpected issues in rare cases. + +## CMake subprojects + +Using CMake subprojects is similar to using the "normal" Meson +subprojects. They also have to be located in the `subprojects` +directory. + +Example: + +```cmake +add_library(cm_lib SHARED ${SOURCES}) +``` + +```meson +cmake = import('cmake') + +# Configure the CMake project +sub_proj = cmake.subproject('libsimple_cmake') + +# Fetch the dependency object +cm_lib = sub_proj.dependency('cm_lib') + +executable(exe1, ['sources'], dependencies: [cm_lib]) +``` + +The `subproject` method is almost identical to the normal Meson +`subproject` function. The only difference is that a CMake project +instead of a Meson project is configured. + +The returned `sub_proj` supports the same options as a "normal" +subproject. Meson automatically detects CMake build targets, which can +be accessed with the methods listed [below](#subproject-object). + +It is usually enough to just use the dependency object returned by the +`dependency()` method in the build targets. This is almost identical +to using `declare_dependency()` object from a normal Meson subproject. + +It is also possible to use executables defined in the CMake project as code +generators with the `target()` method: + +```cmake +add_executable(cm_exe ${EXE_SRC}) +``` + +```meson +cmake = import('cmake') + +# Subproject with the "code generator" +sub_pro = cmake.subproject('cmCodeGen') + +# Fetch the code generator exe +sub_exe = sub_pro.target('cm_exe') + +# Use the code generator +generated = custom_target( + 'cmake-generated', + input: [], + output: ['test.cpp'], + command: [sub_exe, '@OUTPUT@'] +) +``` + +It should be noted that not all projects are guaranteed to work. The +safest approach would still be to create a `meson.build` for the +subprojects in question. + +### Configuration options + +*New in meson 0.55.0* + +Meson also supports passing configuration options to CMake and overriding +certain build details extracted from the CMake subproject. + +```meson +cmake = import('cmake') +opt_var = cmake.subproject_options() + +# Call CMake with `-DSOME_OTHER_VAR=ON` +opt_var.add_cmake_defines({'SOME_OTHER_VAR': true}) + +# Globally override the C++ standard to c++11 +opt_var.set_override_option('cpp_std', 'c++11') + +# Override the previous global C++ standard +# with c++14 only for the CMake target someLib +opt_var.set_override_option('cpp_std', 'c++14', target: 'someLib') + +sub_pro = cmake.subproject('someLibProject', options: opt_var) + +# Further changes to opt_var have no effect +``` + +See [the CMake options object](#cmake-options-object) for a complete +reference of all supported functions. + +The CMake configuration options object is very similar to the +[configuration data +object](Reference-manual.md#configuration-data-object) object returned +by [`configuration_data`](Reference-manual.md#configuration_data). It +is generated by the `subproject_options` function + +All configuration options have to be set *before* the subproject is +configured and must be passed to the `subproject` method via the +`options` key. Altering the configuration object won't have any effect +on previous `cmake.subproject` calls. + +In earlier Meson versions CMake command-line parameters could be set +with the `cmake_options` kwarg. However, this feature is deprecated +since 0.55.0 and only kept for compatibility. It will not work +together with the `options` kwarg. + +### `subproject` object + +This object is returned by the `subproject` function described above +and supports the following methods: + + - `dependency(target)` returns a dependency object for any CMake target. The + `include_type` kwarg *(new in 0.56.0)* controls the include type of the + returned dependency object similar to the same kwarg in the + [`dependency()`](Reference-manual.md#dependency) function. + - `include_directories(target)` returns a Meson `include_directories()` + object for the specified target. Using this function is not necessary + if the dependency object is used. + - `target(target)` returns the raw build target. + - `target_type(target)` returns the type of the target as a string + - `target_list()` returns a list of all target *names*. + - `get_variable(name)` fetches the specified variable from inside + the subproject. Usually `dependency()` or `target()` should be + preferred to extract build targets. + - `found` returns true if the subproject is available, otherwise false + *new in Meson 0.53.2* + +### `cmake options` object + +This object is returned by the `subproject_options()` function and +consumed by the `options` kwarg of the `subproject` function. The +following methods are supported: + + - `add_cmake_defines({'opt1': val1, ...})` add additional CMake commandline defines + - `set_override_option(opt, val)` set specific [build options](Build-options.md) + for targets. This will effectively add `opt=val` to the `override_options` + array of the [build target](Reference-manual.md#executable) + - `set_install(bool)` override wether targets should be installed or not + - `append_compile_args(lang, arg1, ...)` append compile flags for a specific + language to the targets + - `append_link_args(arg1, ...)` append linger args to the targets + - `clear()` reset all data in the `cmake options` object + +The methods `set_override_option`, `set_install`, +`append_compile_args` and `append_link_args` support the optional +`target` kwarg. If specified, the set options affect the specific +target. The effect of the option is global for the subproject +otherwise. + +If, for instance, `opt_var.set_install(false)` is called, no target +will be installed regardless of what is set by CMake. However, it is +still possible to install specific targets (here `foo`) by setting the +`target` kwarg: `opt_var.set_install(true, target: 'foo')` + +Options that are not set won't affect the generated subproject. So, if +for instance, `set_install` was not called then the values extracted +from CMake will be used. + +### Cross compilation + +*New in 0.56.0* + +Meson will try to automatically guess most of the required CMake +toolchain variables from existing entries in the cross and native +files. These variables will be stored in an automatically generate +CMake toolchain file in the build directory. The remaining variables +that can't be guessed can be added by the user in the `[cmake]` +cross/native file section (*new in 0.56.0*). + +Adding a manual CMake toolchain file is also supported with the +`cmake_toolchain_file` setting in the `[properties]` section. Directly +setting a CMake toolchain file with +`-DCMAKE_TOOLCHAIN_FILE=/path/to/some/Toolchain.cmake` in the +`meson.build` is **not** supported since the automatically generated +toolchain file is also used by Meson to inject arbitrary code into +CMake to enable the CMake subproject support. + +The closest configuration to only using a manual CMake toolchain file +would be to set these options in the machine file: + +```ini +[properties] + +cmake_toolchain_file = '/path/to/some/Toolchain.cmake' +cmake_defaults = false + +[cmake] + +# No entries in this section +``` + +This will result in a toolchain file with just the bare minimum to +enable the CMake subproject support and `include()` the +`cmake_toolchain_file` as the last instruction. + +For more information see the [cross and native file +specification](Machine-files.md). + +## CMake configuration files + +### cmake.write_basic_package_version_file() + +This function is the equivalent of the corresponding [CMake +function](https://cmake.org/cmake/help/v3.11/module/CMakePackageConfigHelpers.html#generating-a-package-version-file), +it generates a `name` package version file. + +* `name`: the name of the package. +* `version`: the version of the generated package file. +* `compatibility`: a string indicating the kind of compatibility, the accepted values are +`AnyNewerVersion`, `SameMajorVersion`, `SameMinorVersion` or `ExactVersion`. +It defaults to `AnyNewerVersion`. Depending on your cmake installation some kind of +compatibility may not be available. +* `install_dir`: optional installation directory, it defaults to `$(libdir)/cmake/$(name)` + + +Example: + +```meson +cmake = import('cmake') + +cmake.write_basic_package_version_file(name: 'myProject', version: '1.0.0') +``` + +### cmake.configure_package_config_file() + +This function is the equivalent of the corresponding [CMake +function](https://cmake.org/cmake/help/v3.11/module/CMakePackageConfigHelpers.html#generating-a-package-configuration-file), +it generates a `name` package configuration file from the `input` +template file. Just like the cmake function in this file the +`@PACKAGE_INIT@` statement will be replaced by the appropriate piece +of cmake code. The equivalent `PATH_VARS` argument is given through +the `configuration` parameter. + +* `name`: the name of the package. +* `input`: the template file where that will be treated for variable substitutions contained in `configuration`. +* `install_dir`: optional installation directory, it defaults to `$(libdir)/cmake/$(name)`. +* `configuration`: a `configuration_data` object that will be used for variable substitution in the template file. + + +Example: + +meson.build: + +```meson +cmake = import('cmake') + +conf = configuration_data() +conf.set_quoted('VAR', 'variable value') + +cmake.configure_package_config_file( + name: 'myProject', + input: 'myProject.cmake.in', + configuration: conf +) +``` + +myProject.cmake.in: + +```text +@PACKAGE_INIT@ + +set(MYVAR VAR) +``` diff --git a/meson/docs/markdown/Code-formatting.md b/meson/docs/markdown/Code-formatting.md new file mode 100644 index 000000000..386c78725 --- /dev/null +++ b/meson/docs/markdown/Code-formatting.md @@ -0,0 +1,58 @@ +--- +short-description: Code formatting +... + +# clang-format + +*Since 0.50.0* + +When `clang-format` is installed and a `.clang-format` file is found at the main +project's root source directory, Meson automatically adds a `clang-format` target +that reformat all C and C++ files (currently only with Ninja backend). + +```sh +ninja -C builddir clang-format +``` + +*Since 0.58.0* + +It is possible to restrict files to be reformatted with optional +`.clang-format-include` and `.clang-format-ignore` files. + +The file `.clang-format-include` contains a list of patterns matching the files +that will be reformatted. The `**` pattern matches this directory and all +subdirectories recursively. Empty lines and lines starting with `#` are ignored. +If `.clang-format-include` is not found, the pattern defaults to `**/*` which +means all files recursively in the source directory but has the disadvantage to +walk the whole source tree which could be slow in the case it contains lots of +files. + +Example of `.clang-format-include` file: +``` +# All files in src/ and its subdirectories +src/**/* + +# All files in include/ but not its subdirectories +include/* +``` + +The file `.clang-format-ignore` contains a list of patterns matching the files +that will be excluded. Files matching the include list (see above) that match +one of the ignore pattern will not be reformatted. Unlike include patters, ignore +patterns does not support `**` and a single `*` match any characters including +path separators. Empty lines and lines starting with `#` are ignored. + +The build directory and file without a well known C or C++ suffix are always +ignored. + +Example of `.clang-format-ignore` file: +``` +# Skip C++ files in src/ directory +src/*.cpp +``` + +Note that `.clang-format-ignore` has the same format as used by +[`run-clang-format.py`](https://github.com/Sarcasm/run-clang-format). + +A new target `clang-format-check` has been added. It returns an error code if +any file needs to be reformatted. This is intended to be used by CI. diff --git a/meson/docs/markdown/Commands.md b/meson/docs/markdown/Commands.md new file mode 100644 index 000000000..3f3cf9f09 --- /dev/null +++ b/meson/docs/markdown/Commands.md @@ -0,0 +1,312 @@ +# Command-line commands + +There are two different ways of invoking Meson. First, you can run it +directly from the source tree with the command +`/path/to/source/meson.py`. Meson may also be installed in which case +the command is simply `meson`. In this manual we only use the latter +format for simplicity. + +Meson is invoked using the following syntax: +`meson [COMMAND] [COMMAND_OPTIONS]` + +This section describes all available commands and some of their +Optional arguments. The most common workflow is to run +[`setup`](#setup), followed by [`compile`](#compile), and then +[`install`](#install). + +For the full list of all available options for a specific command use +the following syntax: `meson COMMAND --help` + +### configure + +{{ configure_usage.inc }} + +Changes options of a configured meson project. + +{{ configure_arguments.inc }} + +Most arguments are the same as in [`setup`](#setup). + +Note: reconfiguring project will not reset options to their default +values (even if they were changed in `meson.build`). + +#### Examples: + +List all available options: +``` +meson configure builddir +``` + +Change value of a single option: +``` +meson configure builddir -Doption=new_value +``` + +### compile + +*(since 0.54.0)* + +{{ compile_usage.inc }} + +Builds a default or a specified target of a configured Meson project. + +{{ compile_arguments.inc }} + +`--verbose` argument is available since 0.55.0. + +#### Targets + +*(since 0.55.0)* + +`TARGET` has the following syntax `[PATH/]NAME[:TYPE]`, where: +- `NAME`: name of the target from `meson.build` (e.g. `foo` from `executable('foo', ...)`). +- `PATH`: path to the target relative to the root `meson.build` file. Note: relative path for a target specified in the root `meson.build` is `./`. +- `TYPE`: type of the target. Can be one of the following: 'executable', 'static_library', 'shared_library', 'shared_module', 'custom', 'run', 'jar'. + +`PATH` and/or `TYPE` can be omitted if the resulting `TARGET` can be +used to uniquely identify the target in `meson.build`. + +#### Backend specific arguments + +*(since 0.55.0)* + +`BACKEND-args` use the following syntax: + +If you only pass a single string, then it is considered to have all +values separated by commas. Thus invoking the following command: + +``` +$ meson compile --ninja-args=-n,-d,explain +``` + +would add `-n`, `-d` and `explain` arguments to ninja invocation. + +If you need to have commas or spaces in your string values, then you +need to pass the value with proper shell quoting like this: + +``` +$ meson compile "--ninja-args=['a,b', 'c d']" +``` + +#### Examples: + +Build the project: +``` +meson compile -C builddir +``` + +Execute a dry run on ninja backend with additional debug info: + +``` +meson compile --ninja-args=-n,-d,explain +``` + +Build three targets: two targets that have the same `foo` name, but +different type, and a `bar` target: + +``` +meson compile foo:shared_library foo:static_library bar +``` + +Produce a coverage html report (if available): + +``` +meson compile coverage-html +``` + +### dist + +*(since 0.52.0)* + +{{ dist_usage.inc }} + +Generates a release archive from the current source tree. + +{{ dist_arguments.inc }} + +See [notes about creating releases](Creating-releases.md) for more info. + +#### Examples: + +Create a release archive: +``` +meson dist -C builddir +``` + +### init + +*(since 0.45.0)* + +{{ init_usage.inc }} + +Creates a basic set of build files based on a template. + +{{ init_arguments.inc }} + +#### Examples: + +Create a project in `sourcedir`: +``` +meson init -C sourcedir +``` + +### introspect + +{{ introspect_usage.inc }} + +Displays information about a configured Meson project. + +{{ introspect_arguments.inc }} + +#### Examples: + +Display basic information about a configured project in `builddir`: + +``` +meson introspect builddir --projectinfo +``` + +### install + +*(since 0.47.0)* + +{{ install_usage.inc }} + +Installs the project to the prefix specified in [`setup`](#setup). + +{{ install_arguments.inc }} + +See [the installation documentation](Installing.md) for more info. + +#### Examples: + +Install project to `prefix`: +``` +meson install -C builddir +``` + +Install project to `$DESTDIR/prefix`: +``` +DESTDIR=/path/to/staging/area meson install -C builddir +``` + +### rewrite + +*(since 0.50.0)* + +{{ rewrite_usage.inc }} + +Modifies the Meson project. + +{{ rewrite_arguments.inc }} + +See [the Meson file rewriter documentation](Rewriter.md) for more info. + +### setup + +{{ setup_usage.inc }} + +Configures a build directory for the Meson project. + +This is the default Meson command (invoked if there was no COMMAND supplied). + +{{ setup_arguments.inc }} + +See [Meson introduction +page](Running-Meson.md#configuring-the-build-directory) for more info. + +#### Examples: + +Configures `builddir` with default values: +``` +meson setup builddir +``` + +### subprojects + +*(since 0.49.0)* + +{{ subprojects_usage.inc }} + +Manages subprojects of the Meson project. *Since 0.59.0* commands are run on +multiple subprojects in parallel by default, use `--num-processes=1` if it is +not desired. + +{{ subprojects_arguments.inc }} + +### test + +{{ test_usage.inc }} + +Run tests for the configure Meson project. + +{{ test_arguments.inc }} + +See [the unit test documentation](Unit-tests.md) for more info. + +#### Examples: + +Run tests for the project: +``` +meson test -C builddir +``` + +Run only `specific_test_1` and `specific_test_2`: +``` +meson test -C builddir specific_test_1 specific_test_2 +``` + +### wrap + +{{ wrap_usage.inc }} + +An utility to manage WrapDB dependencies. + +{{ wrap_arguments.inc }} + +See [the WrapDB tool documentation](Using-wraptool.md) for more info. + +### devenv + +*(since 0.58.0)* + +{{ devenv_usage.inc }} + +Runs a command, or open interactive shell if no command is provided, with +environment setup to run project from the build directory, without installation. + +We automatically handle `bash` and set `$PS1` accordingly. If the automatic `$PS1` +override is not desired (maybe you have a fancy custom prompt), set the +`$MESON_DISABLE_PS1_OVERRIDE` environment variable and use `$MESON_PROJECT_NAME` +when setting the custom prompt, for example with a snippet like the following: + +```bash +... +if [[ -n "${MESON_PROJECT_NAME-}" ]]; +then + PS1+="[ ${MESON_PROJECT_NAME} ]" +fi +... +``` + +These variables are set in environment in addition to those set using `meson.add_devenv()`: +- `MESON_DEVENV` is defined to `'1'`. +- `MESON_PROJECT_NAME` is defined to the main project's name. +- `PKG_CONFIG_PATH` includes the directory where Meson generates `-uninstalled.pc` + files. +- `PATH` includes every directory where there is an executable that would be + installed into `bindir`. On windows it also includes every directory where there + is a DLL needed to run those executables. +- `LD_LIBRARY_PATH` includes every directory where there is a shared library that + would be installed into `libdir`. This allows to run system application using + custom build of some libraries. For example running system GEdit when building + GTK from git. On OSX the environment variable is `DYLD_LIBRARY_PATH` and + `PATH` on Windows. +- `GI_TYPELIB_PATH` includes every directory where a GObject Introspection + typelib is built. This is automatically set when using `gnome.generate_gir()`. +- `GSETTINGS_SCHEMA_DIR` *Since 0.59.0* includes every directory where a GSettings + schemas is compiled. This is automatically set when using `gnome.compile_schemas()`. + Note that this requires GLib >= 2.64 when `gnome.compile_schemas()` is used in + more than one directory. + +{{ devenv_arguments.inc }} diff --git a/meson/docs/markdown/Comparisons.md b/meson/docs/markdown/Comparisons.md new file mode 100644 index 000000000..1deef6979 --- /dev/null +++ b/meson/docs/markdown/Comparisons.md @@ -0,0 +1,78 @@ +--- +title: Comparisons +... + +# Comparing Meson with other build systems + +A common question is *Why should I choose Meson over a different build +system X?* There is no one true answer to this as it depends on the +use case. Almost all build systems have all the functionality needed +to build medium-to-large projects so the decision is usually made on +other points. Here we list some pros and cons of various build systems +to help you do the decision yourself. + +## GNU Autotools + +### Pros + +Excellent support for legacy Unix platforms, large selection of +existing modules. + +### Cons + +Needlessly slow, complicated, hard to use correctly, unreliable, +painful to debug, incomprehensible for most people, poor support for +non-Unix platforms (especially Windows). + +## CMake + +### Pros + +Great support for multiple backends (Visual Studio, XCode, etc). + +### Cons + +The scripting language is cumbersome to work with. Some simple things +are more complicated than necessary. + +## SCons + +### Pros + +Full power of Python available for defining your build. + +### Cons + +Slow. Requires you to pass your configuration settings on every +invocation. That is, if you do `scons OPT1 OPT2` and then just +`scons`, it will reconfigure everything without settings `OPT1` and +`OPT2`. Every other build system remembers build options from the +previous invocation. + +## Bazel + +### Pros + +Proven to scale to very large projects. + +### Cons + +Implemented in Java. Poor Windows support. Heavily focused on Google's +way of doing things (which may be a good or a bad thing). Contributing +code requires [signing a CLA](https://bazel.build/contributing.html). + +## Meson + +### Pros + +The fastest build system [see +measurements](Performance-comparison.md), user friendly, designed to +be as invisible to the developer as possible, native support for +modern tools (precompiled headers, coverage, Valgrind etc). Not Turing +complete so build definition files are easy to read and understand. + +### Cons + +Relatively new so it does not have a large user base yet, and may thus +contain some unknown bugs. Visual Studio and XCode backends not as +high quality as Ninja one. diff --git a/meson/docs/markdown/Compiler-properties.md b/meson/docs/markdown/Compiler-properties.md new file mode 100644 index 000000000..e231e162f --- /dev/null +++ b/meson/docs/markdown/Compiler-properties.md @@ -0,0 +1,230 @@ +# Compiler properties + +Not all compilers and platforms are alike. Therefore Meson provides +the tools to detect properties of the system during configure time. To +get most of this information, you first need to extract the *compiler +object* from the main *meson* variable. + +```meson +compiler = meson.get_compiler('c') +``` + +Here we extract the C compiler. We could also have given the argument +`cpp` to get the C++ compiler, `objc` to get the objective C compiler +and so on. The call is valid for all languages specified in the +*project* declaration. Trying to obtain some other compiler will lead +to an unrecoverable error. + +## System information + +This is a bit complex and more thoroughly explained on the page on +[cross compilation](Cross-compilation.md). But if you just want to +know the operating system your code will run on, issue this command: + +```meson +host_machine.system() +``` + +## Compiler id + +The compiler object method `get_id` returns a +lower case string describing the "family" of the compiler. Since 0.53.0 +`get_linker_id` returns a lower case string with the linker name. Since +compilers can often choose from multiple linkers depending on operating +system, `get_linker_id` can be useful for handling or mitigating effects +of particular linkers. + +The compiler object also has a method `get_argument_syntax` which +returns a lower case string of `gcc`, `msvc`, or another undefined string +value; identifying whether the compiler arguments use the same syntax as +either `gcc` or `msvc`, or that its arguments are not like either. This should +only be used to select the syntax of the arguments, such as those to test +with `has_argument`. + +See [reference tables](Reference-tables.md#compiler-ids) for a list of +supported compiler ids and their argument type. + +## Does code compile? + +Sometimes the only way to test the system is to try to compile some +sample code and see if it works. For example, this can test that a +"C++17" compiler actually supports a particular C++17 feature, +without resorting to maintaining a feature list vs. compiler vendor, +compiler version and operating system. +Testing that a code snippet runs is a two-phase operation. First +we define some code using the multiline string operator: + +```meson +code = '''#include<stdio.h> +void func() { printf("Compile me.\n"); } +''' +``` + +Then we can run the test. + +```meson +result = compiler.compiles(code, name : 'basic check') +``` + +The variable *result* will now contain either `true` or `false` +depending on whether the compilation succeeded or not. The keyword +argument `name` is optional. If it is specified, Meson will write the +result of the check to its log. + +## Does code compile and link? + +Sometimes it is necessary to check whether a certain code fragment not +only compiles, but also links successfully, e.g. to check if a symbol +is actually present in a library. This can be done using the +'''.links()''' method on a compiler object like this: + +```meson +code = '''#include<stdio.h> +void func() { printf("Compile me.\n"); } +''' +``` + +Then we can run the test. + +```meson +result = compiler.links(code, args : '-lfoo', name : 'link check') +``` + +The variable *result* will now contain either `true` or `false` +depending on whether the compilation and linking succeeded or not. The +keyword argument `name` is optional. If it is specified, Meson will +write the result of the check to its log. + +## Compile and run test application + +Here is how you would compile and run a small test application. +Testing if a code snippets **runs** versus merely that it links +is particularly important for some dependencies such as MPI. + +```meson +code = '''#include<stdio.h> +int main(int argc, char **argv) { + printf("%s\n", "stdout"); + fprintf(stderr, "%s\n", "stderr"); + return 0; +} +''' +result = compiler.run(code, name : 'basic check') +``` + +The `result` variable encapsulates the state of the test, which can be +extracted with the following methods. The `name` keyword argument +works the same as with `compiles`. + +| Method | Return value | +| ------ | ------------ | +| compiled | `True` if compilation succeeded. If `false` then all other methods return undefined values. | +| returncode | The return code of the application as an integer | +| stdout | Program's standard out as text. | +| stderr | Program's standard error as text. | + +Here is an example usage: + +```meson +if result.stdout().strip() == 'some_value' + # do something +endif +``` + +## Does a header exist? + +Header files provided by different platforms vary quite a lot. Meson +has functionality to detect whether a given header file is available +on the system. The test is done by trying to compile a simple test +program that includes the specified header. The following snippet +describes how this feature can be used. + +```meson +if compiler.has_header('sys/fstat.h') + # header exists, do something +endif +``` + +## Expression size + +Often you need to determine the size of a particular element (such as +`int`, `wchar_t` or `char*`). Using the `compiler` variable mentioned +above, the check can be done like this. + +```meson +wcharsize = compiler.sizeof('wchar_t', prefix : '#include<wchar.h>') +``` + +This will put the size of `wchar_t` as reported by sizeof into +variable `wcharsize`. The keyword argument `prefix` is optional. If +specified its contents is put at the top of the source file. This +argument is typically used for setting `#include` directives in +configuration files. + +In older versions (<= 0.30) Meson would error out if the size could +not be determined. Since version 0.31 it returns -1 if the size could +not be determined. + +## Does a function exist? + +Just having a header doesn't say anything about its contents. +Sometimes you need to explicitly check if some function exists. This +is how we would check whether the function `open_memstream` exists in +header `stdio.h` + +```meson +if compiler.has_function('open_memstream', prefix : '#include <stdio.h>') + # function exists, do whatever is required. +endif +``` + +Note that, on macOS programs can be compiled targeting older macOS +versions than the one that the program is compiled on. It can't be +assumed that the OS version that is compiled on matches the OS version +that the binary will run on. + +Therefore when detecting function availability with `has_function`, it +is important to specify the correct header in the prefix argument. + +In the example above, the function `open_memstream` is detected, which +was introduced in macOS 10.13. When the user builds on macOS 10.13, +but targeting macOS 10.11 (`-mmacosx-version-min=10.11`), this will +correctly report the function as missing. Without the header however, +it would lack the necessary availability information and incorrectly +report the function as available. + +## Does a structure contain a member? + +Some platforms have different standard structures. Here's how one +would check if a struct called `mystruct` from header `myheader.h` +contains a member called `some_member`. + +```meson +if compiler.has_member('struct mystruct', 'some_member', prefix : '#include<myheader.h>') + # member exists, do whatever is required +endif +``` + +## Type alignment + +Most platforms can't access some data types at any address. For +example it is common that a `char` can be at any address but a 32 bit +integer only at locations which are divisible by four. Determining the +alignment of data types is simple. + +```meson +int_alignment = compiler.alignment('int') # Will most likely contain the value 4. +``` + +## Has argument + +This method tests if the compiler supports a given command line +argument. This is implemented by compiling a small file with the given +argument. + +```meson +has_special_flags = compiler.has_argument('-Wspecialthing') +``` + +*Note*: some compilers silently swallow command line arguments they do +not understand. Thus this test can not be made 100% reliable. diff --git a/meson/docs/markdown/Conference-presentations.md b/meson/docs/markdown/Conference-presentations.md new file mode 100644 index 000000000..b800129ac --- /dev/null +++ b/meson/docs/markdown/Conference-presentations.md @@ -0,0 +1,31 @@ +# Conference presentations on Meson + +- FOSDEM 2014, [Introducing the Meson build + system](https://video.fosdem.org/2014/H2215_Ferrer/Sunday/Introducing_the_Meson_build_system.webm) + (jpakkane) + +- LCA 2015, [Making build systems not + suck](https://www.youtube.com/watch?v=KPi0AuVpxLI) (jpakkane) + +- GUADEC 2015, [Improving the way Gnome apps are + built](https://www.youtube.com/watch?v=wTf0NjjNwTU) (jpakkane) + +- GStreamer conference 2015, [Done in 6.0 + seconds](https://gstconf.ubicast.tv/videos/done-in-60-seconds-a-new-build-system-for-gstreamer) + (jpakkane) + +- LCA 2016, [Builds, dependencies and deployment in the modern + multiplatform world](https://www.youtube.com/watch?v=CTJtKtQ8R5k) + (jpakkane) + +- GUADEC 2016, [Making your GNOME app compile 2.4x + faster](https://media.ccc.de/v/44-making_your_gnome_app_compile_24x_faster) + (nirbheek) + +- Libre Application Summit 2016, [New world, new + tools](https://youtu.be/0-gx1qU2pPo) (jpakkane) + +- GStreamer conference 2016, [GStreamer Development on Windows and + faster builds everywhere with + Meson](https://gstconf.ubicast.tv/videos/gstreamer-development-on-windows-ans-faster-builds-everywhere-with-meson/) + (tpm) diff --git a/meson/docs/markdown/Configuration.md b/meson/docs/markdown/Configuration.md new file mode 100644 index 000000000..55f01709e --- /dev/null +++ b/meson/docs/markdown/Configuration.md @@ -0,0 +1,198 @@ +--- +short-description: Build-time configuration options +... + +# Configuration + +If there are multiple configuration options, passing them through +compiler flags becomes very burdensome. It also makes the +configuration settings hard to inspect. To make things easier, Meson +supports the generation of configure files. This feature is similar to +one found in other build systems such as CMake. + +Suppose we have the following Meson snippet: + +```meson +conf_data = configuration_data() +conf_data.set('version', '1.2.3') +configure_file(input : 'config.h.in', + output : 'config.h', + configuration : conf_data) +``` + +and that the contents of `config.h.in` are + +```c +#define VERSION_STR "@version@" +``` + +Meson will then create a file called `config.h` in the corresponding +build directory whose contents are the following. + +```c +#define VERSION_STR "1.2.3" +``` + +More specifically, Meson will find all strings of the type `@varname@` +and replace them with respective values set in `conf_data`. You can +use a single `configuration_data` object as many times as you like, +but it becomes immutable after being passed to the `configure_file` +function. That is, after it has been used once to generate output the +`set` function becomes unusable and trying to call it causes an error. +Copy of immutable `configuration_data` is still immutable. + +For more complex configuration file generation Meson provides a second +form. To use it, put a line like this in your configuration file. + + #mesondefine TOKEN + +The replacement that happens depends on what the value and type of TOKEN is: + +```c +#define TOKEN // If TOKEN is set to boolean true. +#undef TOKEN // If TOKEN is set to boolean false. +#define TOKEN 4 // If TOKEN is set to an integer or string value. +/* undef TOKEN */ // If TOKEN has not been set to any value. +``` + +Note that if you want to define a C string, you need to do the quoting +yourself like this: + +```meson +conf_data.set('TOKEN', '"value"') +``` + +Since this is such a common operation, Meson provides a convenience +method: + +```meson +plain_var = 'value' +conf_data.set_quoted('TOKEN', plain_var) # becomes #define TOKEN "value" +``` + +Often you have a boolean value in Meson but need to define the C/C++ +token as 0 or 1. Meson provides a convenience function for this use +case. + +```meson +conf_data.set10(token, boolean_value) +# The line above is equivalent to this: +if boolean_value + conf_data.set(token, 1) +else + conf_data.set(token, 0) +endif +``` + +## Configuring without an input file + +If the input file is not defined then Meson will generate a header +file all the entries in the configuration data object. The +replacements are the same as when generating `#mesondefine` entries: + +```meson +conf_data.set('FOO', '"string"') => #define FOO "string" +conf_data.set('FOO', 'a_token') => #define FOO a_token +conf_data.set('FOO', true) => #define FOO +conf_data.set('FOO', false) => #undef FOO +conf_data.set('FOO', 1) => #define FOO 1 +conf_data.set('FOO', 0) => #define FOO 0 +``` + +In this mode, you can also specify a comment which will be placed +before the value so that your generated files are self-documenting. + +```meson +conf_data.set('BAR', true, description : 'Set BAR if it is available') +``` + +Will produce: + +```c +/* Set BAR if it is available */ +#define BAR +``` + +## Dealing with file encodings + +The default Meson file encoding to configure files is utf-8. If you +need to configure a file that is not utf-8 encoded the encoding +keyword will allow you to specify which file encoding to use. It is +however strongly advised to convert your non utf-8 file to utf-8 +whenever possible. Supported file encodings are those of python3, see +[standard-encodings](https://docs.python.org/3/library/codecs.html#standard-encodings). + +## Using dictionaries + +Since *0.49.0* `configuration_data()` takes an optional dictionary as +first argument. If provided, each key/value pair is added into the +`configuration_data` as if `set()` method was called for each of them. +`configure_file()`'s `configuration` kwarg also accepts a dictionary +instead of a configuration_data object. + +Example: +```meson +cdata = configuration_data({ + 'STRING' : '"foo"', + 'INT' : 42, + 'DEFINED' : true, + 'UNDEFINED' : false, +}) + +configure_file(output : 'config1.h', + configuration : cdata, +) + +configure_file(output : 'config2.h', + configuration : { + 'STRING' : '"foo"', + 'INT' : 42, + 'DEFINED' : true, + 'UNDEFINED' : false, + } +) + +``` + +# A full example + +Generating and using a configuration file requires the following steps: + + - generate the file + - create an include directory object for the directory that holds the file + - use it in a target + +We are going to use the traditional approach of generating a header +file in the top directory. The common name is `config.h` but we're +going to use an unique name. This avoids the problem of accidentally +including the wrong header file when building a project with many +subprojects. + +At the top level we generate the file: + +```meson +conf_data = configuration_data() +# Set data +configure_file(input : 'projconfig.h.in', + output : 'projconfig.h', + configuration : conf_data) +``` + +Immediately afterwards we generate the include object. + +```meson +configuration_inc = include_directories('.') +``` + +Finally we specify this in a target that can be in any subdirectory. + +```meson +executable(..., include_directories : configuration_inc) +``` + +Now any source file in this target can include the configuration +header like this: + +```c +#include<projconfig.h> +``` diff --git a/meson/docs/markdown/Configuring-a-build-directory.md b/meson/docs/markdown/Configuring-a-build-directory.md new file mode 100644 index 000000000..c55267656 --- /dev/null +++ b/meson/docs/markdown/Configuring-a-build-directory.md @@ -0,0 +1,120 @@ +--- +short-description: Configuring a pre-generated build directory +... + +# Configuring a build directory + +Often you want to change the settings of your build after it has been +generated. For example you might want to change from a debug build +into a release build, set custom compiler flags, change the build +options provided in your `meson_options.txt` file and so on. + +The main tool for this is the `meson configure` command. + +You invoke `meson configure` by giving it the location of your build +dir. If omitted, the current working directory is used instead. Here's +a sample output for a simple project. + + Core properties + + Source dir /home/jpakkane/clangdemo/2_address + Build dir /home/jpakkane/clangdemo/2_address/buildmeson + + Core options: + Option Current Value Possible Values Description + ------ ------------- --------------- ----------- + auto_features auto [enabled, disabled, auto] Override value of all 'auto' features + backend ninja [ninja, vs, vs2010, vs2015, vs2017, vs2019, xcode] Backend to use + buildtype release [plain, debug, debugoptimized, release, minsize, custom] Build type to use + debug false [true, false] Debug + default_library shared [shared, static, both] Default library type + install_umask 0022 [preserve, 0000-0777] Default umask to apply on permissions of installed files + layout mirror [mirror, flat] Build directory layout + optimization 3 [0, g, 1, 2, 3, s] Optimization level + strip false [true, false] Strip targets on install + unity off [on, off, subprojects] Unity build + warning_level 1 [0, 1, 2, 3] Compiler warning level to use + werror false [true, false] Treat warnings as errors + + Backend options: + Option Current Value Possible Values Description + ------ ------------- --------------- ----------- + backend_max_links 0 >=0 Maximum number of linker processes to run or 0 for no limit + + Base options: + Option Current Value Possible Values Description + ------ ------------- --------------- ----------- + b_asneeded true [true, false] Use -Wl,--as-needed when linking + b_colorout always [auto, always, never] Use colored output + b_coverage false [true, false] Enable coverage tracking. + b_lto false [true, false] Use link time optimization + b_lundef true [true, false] Use -Wl,--no-undefined when linking + b_ndebug false [true, false, if-release] Disable asserts + b_pch true [true, false] Use precompiled headers + b_pgo off [off, generate, use] Use profile guided optimization + b_sanitize none [none, address, thread, undefined, memory, address,undefined] Code sanitizer to use + b_staticpic true [true, false] Build static libraries as position independent + + Compiler options: + Option Current Value Possible Values Description + ------ ------------- --------------- ----------- + c_args [] Extra arguments passed to the C compiler + c_link_args [] Extra arguments passed to the C linker + c_std c99 [none, c89, c99, c11, c17, c18, c2x, gnu89, gnu99, gnu11, gnu17, gnu18, gnu2x] C language standard to use + cpp_args [] Extra arguments passed to the C++ compiler + cpp_debugstl false [true, false] STL debug mode + cpp_link_args [] Extra arguments passed to the C++ linker + cpp_std c++11 [none, c++98, c++03, c++11, c++14, c++17, c++1z, c++2a, c++20, gnu++03, gnu++11, gnu++14, gnu++17, gnu++1z, gnu++2a, gnu++20] C++ language standard to use + fortran_std [] [none, legacy, f95, f2003, f2008, f2018] language standard to use + + Directories: + Option Current Value Description + ------ ------------- ----------- + bindir bin Executable directory + datadir share Data file directory + includedir include Header file directory + infodir share/info Info page directory + libdir lib/x86_64-linux-gnu Library directory + libexecdir libexec Library executable directory + localedir share/locale Locale data directory + localstatedir /var/local Localstate data directory + mandir share/man Manual page directory + prefix /usr/local Installation prefix + sbindir sbin System executable directory + sharedstatedir /var/local/lib Architecture-independent data directory + sysconfdir etc Sysconf data directory + + Project options: + Option Current Value Possible Values Description + ------ ------------- --------------- ----------- + array_opt [one, two] [one, two, three] array_opt + combo_opt three [one, two, three] combo_opt + free_array_opt [one, two] free_array_opt + integer_opt 3 >=0, <=5 integer_opt + other_one false [true, false] other_one + some_feature enabled [enabled, disabled, auto] some_feature + someoption optval An option + + Testing options: + Option Current Value Possible Values Description + ------ ------------- --------------- ----------- + errorlogs true [true, false] Whether to print the logs from failing tests + stdsplit true [true, false] Split stdout and stderr in test logs + +These are all the options available for the current project arranged +into related groups. The first column in every field is the name of +the option. To set an option you use the `-D` option. For example, +changing the installation prefix from `/usr/local` to `/tmp/testroot` +you would issue the following command. + + meson configure -Dprefix=/tmp/testroot + +Then you would run your build command (usually `meson compile`), which +would cause Meson to detect that the build setup has changed and do +all the work required to bring your build tree up to date. + +Since 0.50.0, it is also possible to get a list of all build options +by invoking [`meson configure`](Commands.md#configure) with the +project source directory or the path to the root `meson.build`. In +this case, Meson will print the default values of all options similar +to the example output from above. diff --git a/meson/docs/markdown/Contact-information.md b/meson/docs/markdown/Contact-information.md new file mode 100644 index 000000000..e908a3f7c --- /dev/null +++ b/meson/docs/markdown/Contact-information.md @@ -0,0 +1,14 @@ +# Contact information + +For general discussion and questions, it is strongly recommended that +you use the [mailing +list](https://groups.google.com/forum/#!forum/mesonbuild). + +If you find bugs, please file them in the [issue +tracker](https://github.com/jpakkane/meson/issues). + +The maintainer of Meson is Jussi Pakkanen. You should usually not +contact him privately but rather use the channels listed above. +However if such a need arises, he can be reached at gmail where his +username is `jpakkane` (that is not a typo, the last letter is indeed +*e*). diff --git a/meson/docs/markdown/Continuous-Integration.md b/meson/docs/markdown/Continuous-Integration.md new file mode 100644 index 000000000..f24bdb06d --- /dev/null +++ b/meson/docs/markdown/Continuous-Integration.md @@ -0,0 +1,279 @@ +# Continuous Integration + +Here you will find snippets to use Meson with various CI such as +Travis and AppVeyor. + +Please [file an issue](https://github.com/mesonbuild/meson/issues/new) +if these instructions don't work for you. + +## Travis-CI with Docker + +Travis with Docker gives access to newer non-LTS Ubuntu versions with +pre-installed libraries of your choice. + +This `yml` file is derived from the +[configuration used by Meson](https://github.com/mesonbuild/meson/blob/master/.travis.yml) +for running its own tests. + +```yaml +os: + - linux + - osx + +language: + - cpp + +services: + - docker + +before_install: + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install python3 ninja; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then pip3 install meson; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker pull YOUR/REPO:eoan; fi + +script: + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo FROM YOUR/REPO:eoan > Dockerfile; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo ADD . /root >> Dockerfile; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker build -t withgit .; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run withgit /bin/sh -c "cd /root && TRAVIS=true CC=$CC CXX=$CXX meson builddir && meson test -C builddir"; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then SDKROOT=$(xcodebuild -version -sdk macosx Path) meson builddir && meson test -C builddir; fi +``` + +## CircleCi for Linux (with Docker) + +[CircleCi](https://circleci.com/) can work for spinning all of the +Linux images you wish. Here's a sample `yml` file for use with that. + +```yaml +version: 2.1 + +executors: + # Your dependencies would go in the docker images that represent + # the Linux distributions you are supporting + meson_ubuntu_builder: + docker: + - image: your_dockerhub_username/ubuntu-sys + + meson_debian_builder: + docker: + - image: your_dockerhub_username/debian-sys + + meson_fedora_builder: + docker: + - image: your_dockerhub_username/fedora-sys + +jobs: + meson_ubuntu_build: + executor: meson_ubuntu_builder + steps: + - checkout + - run: meson setup builddir --backend ninja + - run: meson compile -C builddir + - run: meson test -C builddir + + meson_debian_build: + executor: meson_debian_builder + steps: + - checkout + - run: meson setup builddir --backend ninja + - run: meson compile -C builddir + - run: meson test -C builddir + + meson_fedora_build: + executor: meson_fedora_builder + steps: + - checkout + - run: meson setup builddir --backend ninja + - run: meson compile -C builddir + - run: meson test -C builddir + +workflows: + version: 2 + linux_workflow: + jobs: + - meson_ubuntu_build + - meson_debian_build + - meson_fedora_build +``` + +## AppVeyor for Windows + +For CI on Windows, [AppVeyor](https://www.appveyor.com/) has a wide +selection of [default +configurations](https://www.appveyor.com/docs/windows-images-software/). +AppVeyor also has +[MacOS](https://www.appveyor.com/docs/macos-images-software/) and +[Linux](https://www.appveyor.com/docs/linux-images-software/) CI +images. This is a sample `appveyor.yml` file for Windows with Visual +Studio 2015 and 2017. + +```yaml +image: Visual Studio 2017 + +environment: + matrix: + - arch: x86 + compiler: msvc2015 + - arch: x64 + compiler: msvc2015 + - arch: x86 + compiler: msvc2017 + - arch: x64 + compiler: msvc2017 + +platform: + - x64 + +install: + # Set paths to dependencies (based on architecture) + - cmd: if %arch%==x86 (set PYTHON_ROOT=C:\python37) else (set PYTHON_ROOT=C:\python37-x64) + # Print out dependency paths + - cmd: echo Using Python at %PYTHON_ROOT% + # Add necessary paths to PATH variable + - cmd: set PATH=%cd%;%PYTHON_ROOT%;%PYTHON_ROOT%\Scripts;%PATH% + # Install meson and ninja + - cmd: pip install ninja meson + # Set up the build environment + - cmd: if %compiler%==msvc2015 ( call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %arch% ) + - cmd: if %compiler%==msvc2017 ( call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" %arch% ) + +build_script: + - cmd: echo Building on %arch% with %compiler% + - cmd: meson --backend=ninja builddir + - cmd: meson compile -C builddir + +test_script: + - cmd: meson test -C builddir +``` + +### Qt + +For Qt 5, add the following line near the `PYTHON_ROOT` assignment: + +```yaml + - cmd: if %arch%==x86 (set QT_ROOT=C:\Qt\5.11\%compiler%) else (set QT_ROOT=C:\Qt\5.11\%compiler%_64) +``` + +And afterwards add `%QT_ROOT%\bin` to the `PATH` variable. + +You might have to adjust your build matrix as there are, for example, +no msvc2017 32-bit builds. Visit the [Build +Environment](https://www.appveyor.com/docs/build-environment/) page in +the AppVeyor docs for more details. + +### Boost + +The following statement is sufficient for Meson to find Boost: + +```yaml + - cmd: set BOOST_ROOT=C:\Libraries\boost_1_67_0 +``` + +## Travis without Docker + +Non-Docker Travis-CI builds can use Linux, MacOS or Windows. +Set the desired compiler(s) in the build **matrix**. +This example is for **Linux** (Ubuntu 18.04) and **C**. + +```yaml +dist: bionic +group: travis_latest + +os: linux +language: python + +matrix: + include: + - env: CC=gcc + - env: CC=clang + +install: + - pip install meson ninja + +script: + - meson builddir + - meson compile -C builddir + - meson test -C builddir +``` + +## GitHub Actions + +GitHub Actions are distinct from Azure Pipelines in their workflow +syntax. It can be easier to setup specific CI tasks in Actions than +Pipelines, depending on the particular task. This is an example file: +.github/workflows/ci_meson.yml supposing the project is C-based, using +GCC on Linux, Mac and Windows. The optional `on:` parameters only run +this CI when the C code is changed--corresponding ci_python.yml might +run only on "**.py" file changes. + +```yml +name: ci_meson + +on: + push: + paths: + - "**.c" + - "**.h" + pull_request: + paths: + - "**.c" + - "**.h" + +jobs: + + linux: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-python@v1 + with: + python-version: '3.x' + - run: pip install meson ninja + - run: meson setup builddir/ + env: + CC: gcc + - run: meson test -C builddir/ -v + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: Linux_Meson_Testlog + path: builddir/meson-logs/testlog.txt + + macos: + runs-on: macos-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-python@v1 + with: + python-version: '3.x' + - run: brew install gcc + - run: pip install meson ninja + - run: meson setup builddir/ + env: + CC: gcc + - run: meson test -C builddir/ -v + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: MacOS_Meson_Testlog + path: builddir/meson-logs/testlog.txt + + windows: + runs-on: windows-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-python@v1 + with: + python-version: '3.x' + - run: pip install meson ninja + - run: meson setup builddir/ + env: + CC: gcc + - run: meson test -C builddir/ -v + - uses: actions/upload-artifact@v1 + if: failure() + with: + name: Windows_Meson_Testlog + path: builddir/meson-logs/testlog.txt +``` diff --git a/meson/docs/markdown/Contributing.md b/meson/docs/markdown/Contributing.md new file mode 100644 index 000000000..bb2f60488 --- /dev/null +++ b/meson/docs/markdown/Contributing.md @@ -0,0 +1,568 @@ +--- +short-description: Contributing to Meson +... + +# Contributing to Meson + +A large fraction of Meson is contributed by people outside the core +team. This documentation explains some of the design rationales of +Meson as well as how to create and submit your patches for inclusion +to Meson. + +Thank you for your interest in participating to the development. + +## Submitting patches + +All changes must be submitted as [pull requests to +Github](https://github.com/mesonbuild/meson/pulls). This causes them +to be run through the CI system. All submissions must pass a full CI +test run before they are even considered for submission. + +## Keeping pull requests up to date + +It is possible that while your pull request is being reviewed, other +changes are committed to master that cause merge conflicts that must +be resolved. The basic rule for this is very simple: keep your pull +request up to date using rebase _only_. + +Do not merge head back to your branch. Any merge commits in your pull +request make it not acceptable for merging into master and you must +remove them. + +## Special procedure for new features + +Every new feature requires some extra steps, namely: + +- Must include a project test under `test cases/`, or if that's not + possible or if the test requires a special environment, it must go + into `run_unittests.py`. +- Must be registered with the [FeatureChecks + framework](Release-notes-for-0.47.0.md#feature-detection-based-on-meson_version-in-project) + that will warn the user if they try to use a new feature while + targeting an older Meson version. +- Needs a release note snippet inside `docs/markdown/snippets/` with + a heading and a brief paragraph explaining what the feature does + with an example. + +## Acceptance and merging + +The kind of review and acceptance any merge proposal gets depends on +the changes it contains. All pull requests must be reviewed and +accepted by someone with commit rights who is not the original +submitter. Merge requests can be roughly split into three different +categories. + +The first one consists of MRs that only change the markdown +documentation under `docs/markdown`. Anyone with access rights can +push changes to these directly to master. For major changes it is +still recommended to create a MR so other people can comment on it. + +The second group consists of merges that don't change any +functionality, fixes to the CI system and bug fixes that have added +regression tests (see below) and don't change existing +functionality. Once successfully reviewed anyone with merge rights can +merge these to master. + +The final kind of merges are those that add new functionality or +change existing functionality in a backwards incompatible way. These +require the approval of the project lead. + +In a simplified list form the split would look like the following: + +- members with commit access can do: + - documentation changes (directly to master if warranted) + - bug fixes that don't change functionality + - refactorings + - new dependency types + - new tool support (e.g. a new Doxygen-kind of tool) + - support for new compilers to existing languages +- project leader decision is needed for: + - new modules + - new functions in the Meson language + - syntax changes for Meson files + - changes breaking backwards compatibility + - support for new languages + +## Strategy for merging pull requests to trunk + +Meson's merge strategy should fulfill the following guidelines: + +- preserve as much history as possible + +- have as little junk in the repo as possible + +- everything in the "master lineage" should always pass all tests + +These goals are slightly contradictory so the correct thing to do +often requires some judgement on part of the person doing the +merge. Github provides three different merge options, The rules of +thumb for choosing between them goes like this: + +- single commit pull requests should always be rebased + +- a pull request with one commit and one "fixup" commit (such as + testing something to see if it passes CI) should be squashed + +- large branches with many commits should be merged with a merge + commit, especially if one of the commits does not pass all tests + (which happens in e.g. large and difficult refactorings) + +If in doubt, ask for guidance on IRC. + +## Tests + +All new features must come with automatic tests that thoroughly prove +that the feature is working as expected. Similarly bug fixes must come +with a unit test that demonstrates the bug, proves that it has been +fixed and prevents the feature from breaking in the future. + +Sometimes it is difficult to create a unit test for a given bug. If +this is the case, note this in your pull request. We may permit bug +fix merge requests in these cases. This is done on a case by case +basis. Sometimes it may be easier to write the test than convince the +maintainers that one is not needed. Exercise judgment and ask for help +in problematic cases. + +The tests are split into two different parts: unit tests and full +project tests. To run all tests, execute `./run_tests.py`. Unit tests +can be run with `./run_unittests.py` and project tests with +`./run_project_tests.py`. + +### Project tests + +Subsets of project tests can be selected with +`./run_project_tests.py --only` option. This can save a great deal of +time when only a certain part of Meson is being tested. +For example, a useful and easy contribution to Meson is making +sure the full set of compilers is supported. One could for example test +various Fortran compilers by setting `FC=ifort` or `FC=flang` or similar +with `./run_project_test.py --only fortran`. +Some families of tests require a particular backend to run. +For example, all the CUDA project tests run and pass on Windows via +`./run_project_tests.py --only cuda --backend ninja` + +Each project test is a standalone project that can be compiled on its +own. They are all in the `test cases` subdirectory. The simplest way to +run a single project test is to do something like `./meson.py test\ +cases/common/1\ trivial builddir`. The one exception to this is `test +cases/unit` directory discussed below. + +The test cases in the `common` subdirectory are meant to be run always +for all backends. They should only depend on C and C++, without any +external dependencies such as libraries. Tests that require those are +in the `test cases/frameworks` directory. If there is a need for an +external program in the common directory, such as a code generator, it +should be implemented as a Python script. The goal of test projects is +also to provide sample projects that end users can use as a base for +their own projects. + +All project tests follow the same pattern: they are configured, +compiled, tests are run and finally install is run. Passing means that +configuring, building and tests succeed and that installed files match +those expected. + +Any tests that require more thorough analysis, such as checking that +certain compiler arguments can be found in the command line or that +the generated pkg-config files actually work should be done with a +unit test. + +Additionally: + +* `crossfile.ini` and `nativefile.ini` are passed to the configure step with +`--cross-file` and `--native-file` options, respectively. + +* `mlog.cmd_ci_include()` can be called from anywhere inside Meson to +capture the contents of an additional file into the CI log on failure. + +Projects needed by unit tests are in the `test cases/unit` +subdirectory. They are not run as part of `./run_project_tests.py`. + +### Configuring project tests + +The (optional) `test.json` file, in the root of a test case, is used +for configuring the test. All of the following root entries in the `test.json` +are independent of each other and can be combined as needed. + +Exanple `test.json`: + +```json +{ + "env": { + "VAR": "VAL" + }, + "installed": [ + { "type": "exe", "file": "usr/bin/testexe" }, + { "type": "pdb", "file": "usr/bin/testexe" }, + { "type": "shared_lib", "file": "usr/lib/z", "version": "1.2.3" }, + ], + "matrix": { + "options": { + "opt1": [ + { "val": "abc" }, + { "val": "qwert" }, + { "val": "bad" } + ], + "opt2": [ + { "val": null }, + { "val": "true" }, + { "val": "false" }, + ] + }, + "exclude": [ + { "opt1": "qwert", "opt2": "false" }, + { "opt1": "bad" } + ] + }, + "tools": { + "cmake": ">=3.11" + } +} +``` + +#### env + +The `env` key contains a dictionary which specifies additional +environment variables to be set during the configure step of the test. + +There is some basic support for configuring the string with the `@<VAR>@` syntax: + +- `@ROOT@`: absolute path of the source directory +- `@PATH@`: current value of the `PATH` env variable + +#### installed + +The `installed` dict contains a list of dicts, describing which files are expected +to be installed. Each dict contains the following keys: + +- `file` +- `type` +- `platform` (optional) +- `version` (optional) +- `language` (optional) + +The `file` entry contains the relative path (from the install root) to the +actually installed file. + +The `type` entry specifies how the `file` path should be interpreted based on the +current platform. The following values are currently supported: + +| type | Description | +| ------------- | ------------------------------------------------------------------------------------------------------- | +| `file` | No postprocessing, just use the provided path | +| `python_file` | Use the provided path while replacing the python directory. | +| `dir` | To include all files inside the directory (for generated docs, etc). The path must be a valid directory | +| `exe` | For executables. On Windows the `.exe` suffix is added to the path in `file` | +| `shared_lib` | For shared libraries, always written as `name`. The appropriate suffix and prefix are added by platform | +| `python_lib` | For python libraries, while replacing the python directory. The appropriate suffix is added by platform | +| `pdb` | For Windows PDB files. PDB entries are ignored on non Windows platforms | +| `implib` | For Windows import libraries. These entries are ignored on non Windows platforms | +| `py_implib` | For Windows import libraries. These entries are ignored on non Windows platforms | +| `implibempty` | Like `implib`, but no symbols are exported in the library | +| `expr` | `file` is an expression. This type should be avoided and removed if possible | + +Except for the `file`, `python_file` and `expr` types, all paths should be provided *without* a suffix. + +| Argument | Applies to | Description | +| -----------|----------------------------|-------------------------------------------------------------------------------| +| `version` | `shared_lib`, `pdb` | Sets the version to look for appropriately per-platform | +| `language` | `pdb` | Determines which compiler/linker determines the existence of this file | + +The `shared_lib` and `pdb` types takes an optional additional +parameter, `version`, this is us a string in `X.Y.Z` format that will +be applied to the library. Each version to be tested must have a +single version. The harness will apply this correctly per platform: + +The `python_file`, `python_lib`, and `py_implib` types have basic support for configuring the string with the `@<VAR>@` syntax: + +- `@PYTHON_PLATLIB@`: python `get_install_dir` directory relative to prefix +- `@PYTHON_PURELIB@`: python `get_install_dir(pure: true)` directory relative to prefix + +`pdb` takes an optional `language` argument. This determines which +compiler/linker should generate the pdb file. Because it's possible to +mix compilers that do and don't generate pdb files (dmd's optlink +doesn't). Currently this is only needed when mixing D and C code. + +```json +{ + "type": "shared_lib", "file": "usr/lib/lib", + "type": "shared_lib", "file": "usr/lib/lib", "version": "1", + "type": "shared_lib", "file": "usr/lib/lib", "version": "1.2.3.", +} +``` + +This will be applied appropriately per platform. On windows this +expects `lib.dll` and `lib-1.dll`. on MacOS it expects `liblib.dylib` +and `liblib.1.dylib`. On other Unices it expects `liblib.so`, +`liblib.so.1`, and `liblib.so.1.2.3`. + +If the `platform` key is present, the installed file entry is only +considered if the platform matches. The following values for +`platform` are currently supported: + +| platform | Description | +| ---------- | -------------------------------------------------------------------- | +| `msvc` | Matches when a msvc like compiler is used (`msvc`, `clang-cl`, etc.) | +| `gcc` | Not `msvc` | +| `cygwin` | Matches when the platform is cygwin | +| `!cygwin` | Not `cygwin` | + +#### matrix + +The `matrix` section can be used to define a test matrix to run +project tests with different Meson options. + +In the `options` dict, all possible options and their values are +specified. Each key in the `options` dict is a Meson option. It stores +a list of all potential values in a dict format. + +Each value must contain the `val` key for the value of the option. +`null` can be used for adding matrix entries without the current +option. + +The `skip_on_env`, `skip_on_jobname` and `skip_on_os` keys (as described below) +may be used in the value to skip that matrix entry, based on the current +environment. + +Similarly, the `compilers` key can be used to define a mapping of +compilers to languages that are required for this value. + +```json +{ + "compilers": { + "c": "gcc", + "cpp": "gcc", + "d": "gdc" + } +} +``` + +Specific option combinations can be excluded with the `exclude` +section. It should be noted that `exclude` does not require exact +matches. Instead, any matrix entry containing all option value +combinations in `exclude` will be excluded. Thus an empty dict (`{}`) +to will match **all** elements in the test matrix. + +The above example will produce the following matrix entries: +- `opt1=abc` +- `opt1=abc opt2=true` +- `opt1=abc opt2=false` +- `opt1=qwert` +- `opt1=qwert opt2=true` + +#### do_not_set_opts + +Currently supported values are: +- `prefix` +- `libdir` + +#### tools + +This section specifies a dict of tool requirements in a simple +key-value format. If a tool is specified, it has to be present in the +environment, and the version requirement must be fulfilled. Otherwise, +the entire test is skipped (including every element in the test +matrix). + +#### stdout + +The `stdout` key contains a list of dicts, describing the expected +stdout. + +Each dict contains the following keys: + +- `line` +- `match` (optional) + +Each item in the list is matched, in order, against the remaining +actual stdout lines, after any previous matches. If the actual stdout +is exhausted before every item in the list is matched, the expected +output has not been seen, and the test has failed. + +The `match` element of the dict determines how the `line` element is +matched: + +| Type | Description | +| -------- | ----------------------- | +| `literal` | Literal match (default) | +| `re` | regex match | + +#### skip_on_env + +The `skip_on_env` key can be used to specify a list of environment variables. If +at least one environment variable in the `skip_on_env` list is present, the test +is skipped. + +#### skip_on_jobname + +The `skip_on_jobname` key contains a list of strings. If the `MESON_CI_JOBNAME` +environment variable is set, and any of them are a sub-string of it, the test is +expected to be skipped (that is, it is expected that the test will output +`MESON_SKIP_TEST`, because the CI environment is not one in which it can run, +for whatever reason). + +The test is failed if it skips or runs unexpectedly. + +#### skip_on_os + +The `skip_on_os` key can be used to specify a list of OS names (or their +negations, prefixed with a `!`). If at least one item in the `skip_on_os` list +is matched, the test is expected to be skipped. + +The test is failed if it skips or runs unexpectedly. + +### Skipping integration tests + +Meson uses several continuous integration testing systems that have +slightly different interfaces for indicating a commit should be +skipped. + +Continuous integration systems currently used: +- [Azure Pipelines](https://docs.microsoft.com/en-us/azure/devops/pipelines/scripts/git-commands?view=vsts&tabs=yaml#how-do-i-avoid-triggering-a-ci-build-when-the-script-pushes) + allows `***NO_CI***` in the commit message. +- [Sider](https://sider.review) + runs Flake8 ([see below](#python-coding-style)) + +To promote consistent naming policy, use: + +- `[skip ci]` in the commit title if you want to disable all + integration tests + +## Documentation + +The `docs` directory contains the full documentation that will be used +to generate [the Meson web site](http://mesonbuild.com). Every change +in functionality must change the documentation pages. In most cases +this means updating the reference documentation page but bigger +changes might need changes in other documentation, too. + +All new functionality needs to have a mention in the release +notes. These features should be written in standalone files in the +`docs/markdown/snippets` directory. The release manager will combine +them into one page when doing the release. + +[Integration tests should be disabled](#skipping-integration-tests) for +documentation-only commits by putting `[skip ci]` into commit title. +Reviewers should ask contributors to put `[skip ci]` into the title because +tests are run again after merge for `master`. + +## Python Coding style + +Meson follows the basic Python coding style. Additional rules are the +following: + +- indent 4 spaces, no tabs ever +- indent meson.build files with two spaces +- try to keep the code as simple as possible +- contact the mailing list before embarking on large scale projects + to avoid wasted effort + +Meson uses Flake8 for style guide enforcement. The Flake8 options for +the project are contained in .flake8. + +To run Flake8 on your local clone of Meson: + +```console +$ python3 -m pip install flake8 +$ cd meson +$ flake8 +``` + +To run it automatically before committing: + +```console +$ flake8 --install-hook=git +$ git config --bool flake8.strict true +``` + +## C/C++ coding style + +Meson has a bunch of test code in several languages. The rules for +those are simple. + +- indent 4 spaces, no tabs ever +- brace always on the same line as if/for/else/function definition + +## External dependencies + +The goal of Meson is to be as easily usable as possible. The user +experience should be "get Python3 and Ninja, run", even on +Windows. Unfortunately this means that we can't have dependencies on +projects outside of Python's standard library. This applies only to +core functionality, though. For additional helper programs etc the use +of external dependencies may be ok. If you feel that you are dealing +with this kind of case, please contact the developers first with your +use case. + +## Turing completeness + +The main design principle of Meson is that the definition language is +not Turing complete. Any change that would make Meson Turing complete +is automatically rejected. In practice this means that defining your +own functions inside `meson.build` files and generalised loops will +not be added to the language. + +## Do I need to sign a CLA in order to contribute? + +No you don't. All contributions are welcome. + +## No lingering state + +Meson operates in much the same way as functional programming +languages. It has inputs, which include `meson.build` files, values of +options, compilers and so on. These are passed to a function, which +generates output build definition. This function is pure, which means that: + +- for any given input the output is always the same +- running Meson twice in a row _always_ produce the same output in both runs + +The latter one is important, because it enforces that there is no way +for "secret state" to pass between consecutive invocations of +Meson. This is the reason why, for example, there is no `set_option` +function even though there is a `get_option` one. + +If this were not the case, we could never know if the build output is +"stable". For example suppose there were a `set_option` function and a +boolean variable `flipflop`. Then you could do this: + +```meson +set_option('flipflop', not get_option('flipflop')) +``` + +This piece of code would never converge. Every Meson run would change +the value of the option and thus the output you get out of this build +definition would be random. + +Meson does not permit this by forbidding these sorts of covert +channels. + +There is one exception to this rule. Users can call into external +commands with `run_command`. If the output of that command does not +behave like a pure function, this problem arises. Meson does not try +to guard against this case, it is the responsibility of the user to +make sure the commands they run behave like pure functions. + +## Environment variables + +Environment variables are like global variables, except that they are +also hidden by default. Envvars should be avoided whenever possible, +all functionality should be exposed in better ways such as command +line switches. + +## Random design points that fit nowhere else + +- All features should follow the 90/9/1 rule. 90% of all use cases + should be easy, 9% should be possible and it is totally fine to not + support the final 1% if it would make things too complicated. + +- Any build directory will have at most two toolchains: one native and + one cross. + +- Prefer specific solutions to generic frameworks. Solve the end + user's problems rather than providing them tools to do it + themselves. + +- Never use features of the Unix shell (or Windows shell for that + matter). Doing things like forwarding output with `>` or invoking + multiple commands with `&&` are not permitted. Whenever these sorts + of requirements show up, write an internal Python script with the + desired functionality and use that instead. diff --git a/meson/docs/markdown/Creating-Linux-binaries.md b/meson/docs/markdown/Creating-Linux-binaries.md new file mode 100644 index 000000000..71c96e470 --- /dev/null +++ b/meson/docs/markdown/Creating-Linux-binaries.md @@ -0,0 +1,133 @@ +--- +short-description: Creating universal Linux binaries +... + +# Creating Linux binaries + +Creating Linux binaries that can be downloaded and run on any distro +(like .dmg packages for OSX or .exe installers for Windows) has +traditionally been difficult. This is even more tricky if you want to +use modern compilers and features, which is especially desired in game +development. There is still no simple turn-key solution for this +problem but with a bit of setup it can be relatively straightforward. + +## Installing system and GCC + +First you need to do a fresh operating system install. You can use +spare hardware, VirtualBox, cloud or whatever you want. Note that the +distro you install must be *at least as old* as the oldest release you +wish to support. Debian stable is usually a good choice, though +immediately after its release you might want to use Debian oldstable +or the previous Ubuntu LTS. The oldest supported version of CentOS is +also a good choice. + +Once you have installed the system, you need to install +build-dependencies for GCC. In Debian-based distros this can be done +with the following commands: + +```console +$ apt-get build-dep g++ +$ apt-get install pkg-config libgmp-dev libmpfr-dev libmpc-dev +``` + +Then create a `src` subdirectory in your home directory. Copy-paste +the following into `install_gcc.sh` and execute it. + +```bash +#!/bin/sh + +wget ftp://ftp.fu-berlin.de/unix/languages/gcc/releases/gcc-4.9.2/gcc-4.9.2.tar.bz2 +tar xf gcc-4.9.2.tar.bz2 + +mkdir objdir +cd objdir +../gcc-4.9.2/configure --disable-bootstrap --prefix=${HOME}/devroot \ + --disable-multilib --enable-languages=c,c++ +make -j 4 +make install-strip +ln -s gcc ${HOME}/devroot/bin/cc +``` + +Then finally add the following lines to your `.bashrc`. + +```console +$ export LD_LIBRARY_PATH=${HOME}/devroot/lib +$ export PATH=${HOME}/devroot/bin:$PATH +$ export PKG_CONFIG_PATH=${HOME}/devroot/lib/pkgconfig +``` + +Log out and back in and now your build environment is ready to use. + +## Adding other tools + +Old distros might have too old versions of some tools. For Meson this +could include Python 3 and Ninja. If this is the case you need to +download, build and install new versions into `~/devroot` in the usual +way. + +## Adding dependencies + +You want to embed and statically link every dependency you can +(especially C++ dependencies). Meson's [Wrap package +manager](Wrap-dependency-system-manual.md) might be of use here. This +is equivalent to what you would do on Windows, OSX, Android etc. +Sometimes static linking is not possible. In these cases you need to +copy the .so files inside your package. Let's use SDL2 as an example. +First we download and install it as usual giving it our custom install +prefix (that is, `./configure --prefix=${HOME}/devroot`). This makes +Meson's dependency detector pick it up automatically. + +## Building and installing + +Building happens in much the same way as normally. There are just two +things to note. First, you must tell GCC to link the C++ standard +library statically. If you don't then your app is guaranteed to break +as different distros have binary-incompatible C++ libraries. The +second thing is that you need to point your install prefix to some +empty staging area. Here's the Meson command to do that: + +```console +$ LDFLAGS=-static-libstdc++ meson --prefix=/tmp/myapp <other args> +``` + +The aim is to put the executable in `/tmp/myapp/bin` and shared +libraries to `/tmp/myapp/lib`. The next thing you need is the +embedder. It takes your dependencies (in this case only +`libSDL2-2.0.so.0`) and copies them in the lib directory. Depending on +your use case you can either copy the files by hand or write a script +that parses the output of `ldd binary_file`. Be sure not to copy +system libraries (`libc`, `libpthread`, `libm` etc). For an example, +see the [sample +project](https://github.com/jpakkane/meson/tree/master/manual%20tests/4%20standalone%20binaries). + +Make the script run during install with this: + +```meson +meson.add_install_script('linux_bundler.sh') +``` + +## Final steps + +If you try to run the program now it will most likely fail to start or +crashes. The reason for this is that the system does not know that the +executable needs libraries from the `lib` directory. The solution for +this is a simple wrapper script. Create a script called `myapp.sh` +with the following content: + +```bash +#!/bin/bash + +cd "${0%/*}" +export LD_LIBRARY_PATH="$(pwd)/lib" +bin/myapp +``` + +Install it with this Meson snippet: + +```meson +install_data('myapp.sh', install_dir : '.') +``` + +And now you are done. Zip up your `/tmp/myapp` directory and you have +a working binary ready for deployment. To run the program, just unzip +the file and run `myapp.sh`. diff --git a/meson/docs/markdown/Creating-OSX-packages.md b/meson/docs/markdown/Creating-OSX-packages.md new file mode 100644 index 000000000..849d5fd5d --- /dev/null +++ b/meson/docs/markdown/Creating-OSX-packages.md @@ -0,0 +1,158 @@ +--- +short-description: Tools to create OS X packages +... + +# Creating OSX packages + +Meson does not have native support for building OSX packages but it +does provide all the tools you need to create one yourself. The reason +for this is that it is a very hard task to write a system that +provides for all the different ways to do that but it is very easy to +write simple scripts for each application. + +Sample code for this can be found in [the Meson manual test +suite](https://github.com/jpakkane/meson/tree/master/manual%20tests/4%20standalone%20binaries). + +## Creating an app bundle + +OSX app bundles are actually extremely simple. They are just a +directory of files in a certain format. All the details you need to +know are on [this +page](https://stackoverflow.com/questions/1596945/building-osx-app-bundle) +and it is highly recommended that you read it first. + +Let's assume that we are creating our app bundle into +`/tmp/myapp.app`. Suppose we have one executable, so we need to +install that into `Contents/MacOS`. If we define the executable like +this: + +```meson +executable('myapp', 'foo1.c', ..., install : true) +``` + +then we just need to initialize our build tree with this command: + +```console +$ meson --prefix=/tmp/myapp.app \ + --bindir=Contents/MacOS \ + builddir \ + <other flags you might need> +``` + +Now when we do `meson install` the bundle is properly staged. If you +have any resource files or data, you need to install them into +`Contents/Resources` either by custom install commands or specifying +more install paths to the Meson command. + +Next we need to install an `Info.plist` file and an icon. For those we +need the following two Meson definitions. + +```meson +install_data('myapp.icns', install_dir : 'Contents/Resources') +install_data('Info.plist', install_dir : 'Contents') +``` + +The format of `Info.plist` can be found in the link or the sample +project linked above. The simplest way to get an icon in the `icns` +format is to save your image as a tiff an then use the `tiff2icns` helper +application that comes with XCode. + +Some applications assume that the working directory of the app process +is the same where the binary executable is. If this is the case for +you, then you need to create a wrapper script that looks like this: + +```bash +#!/bin/bash + +cd "${0%/*}" +./myapp +``` + +install it with this: + +```meson +install_data('myapp.sh', install_dir : 'Contents/MacOS') +``` + +and make sure that you specify `myapp.sh` as the executable to run in +your `Info.plist`. + +If you are not using any external libraries, this is all you need to +do. You now have a full app bundle in `/tmp/myapp.app` that you can +use. Most applications use third party frameworks and libraries, +though, so you need to add them to the bundle so it will work on other +peoples' machines. + +As an example we are going to use the [SDL2](https://libsdl.org/) +framework. In order to bundle it in our app, we first specify an +installer script to run. + +```meson +meson.add_install_script('install_script.sh') +``` + +The install script does two things. First it copies the whole +framework into our bundle. + +```console +$ mkdir -p ${MESON_INSTALL_PREFIX}/Contents/Frameworks +$ cp -R /Library/Frameworks/SDL2.framework \ + ${MESON_INSTALL_PREFIX}/Contents/Frameworks +``` + +Then it needs to alter the library search path of our +executable(s). This tells OSX that the libraries your app needs are +inside your bundle. In the case of SDL2, the invocation goes like +this: + +```console +$ install_name_tool -change @rpath/SDL2.framework/Versions/A/SDL2 \ + @executable_path/../FrameWorks/SDL2.framework/Versions/A/SDL2 \ + ${MESON_INSTALL_PREFIX}/Contents/MacOS/myapp +``` + +This is the part of OSX app bundling that you must always do +manually. OSX dependencies come in many shapes and forms and +unfortunately there is no reliable automatic way to determine how each +dependency should be handled. Frameworks go to the `Frameworks` +directory while plain `.dylib` files usually go to +`Contents/Resources/lib` (but you can put them wherever you like). To +get this done you have to check what your program links against with +`otool -L /path/to/binary` and manually add the copy and fix steps to +your install script. Do not copy system libraries inside your bundle, +though. + +After this you have a fully working, self-contained OSX app bundle +ready for distribution. + +## Creating a .dmg installer + +A .dmg installer is similarly quite simple, at its core it is +basically a fancy compressed archive. A good description can be found +on [this page](https://el-tramo.be/guides/fancy-dmg/). Please read it +and create a template image file according to its instructions. + +The actual process of creating the installer is very simple: you mount +the template image, copy your app bundle in it, unmount it and convert +the image into a compressed archive. The actual commands to do this +are not particularly interesting, feel free to steal them from either +the linked page above or from the sample script in Meson's test suite. + +## Putting it all together + +There are many ways to put the .dmg installer together and different +people will do it in different ways. The linked sample code does it by +having two different scripts. This separates the different pieces +generating the installer into logical pieces. + +`install_script.sh` only deals with embedding dependencies and fixing +the library paths. + +`build_osx_installer.sh` sets up the build with the proper paths, +compiles, installs and generates the .dmg package. + +The main reasoning here is that in order to build a complete OSX +installer package from source, all you need to do is to cd into the +source tree and run `./build_osx_installer.sh`. To build packages on +other platforms you would write scripts such as +`build_windows_installer.bat` and so on. diff --git a/meson/docs/markdown/Creating-releases.md b/meson/docs/markdown/Creating-releases.md new file mode 100644 index 000000000..b8244596e --- /dev/null +++ b/meson/docs/markdown/Creating-releases.md @@ -0,0 +1,80 @@ +--- +short-description: Creating releases +... + +# Creating releases + +In addition to development, almost all projects provide periodical +source releases. These are standalone packages (usually either in +tar or zip format) of the source code. They do not contain any +revision control metadata, only the source code. Meson provides +a simple way of generating these, with the `meson dist` command. + +Meson provides a simple way of generating these. It consists of a +single command *(available since 0.52.0)*: + +```sh +meson dist +``` + +or alternatively (on older Meson versions with `ninja` backend): + +```sh +ninja dist +``` + +This creates a file called `projectname-version.tar.xz` in the build +tree subdirectory `meson-dist`. This archive contains the full +contents of the latest commit in revision control including all the +submodules (recursively). All revision control metadata is removed. +Meson then takes this archive and tests that it works by doing a full +`compile` + `test` + `install` cycle. If all these pass, Meson will +then create a `SHA-256` checksum file next to the archive. + + +## Autotools dist VS Meson dist + +Meson behaviour is different from Autotools. The Autotools "dist" +target packages up the current source tree. Meson packages the latest +revision control commit. The reason for this is that it prevents +developers from doing accidental releases where the distributed +archive does not match any commit in revision control (especially the +one tagged for the release). + + +## Include subprojects in your release + +The `meson dist` command has `--include-subprojects` command line +option. When enabled, the source tree of all subprojects used by the +current build will also be included in the final tarball. This is +useful to distribute self contained tarball that can be built offline +(i.e. `--wrap-mode=nodownload`). + + +## Skip build and test with `--no-tests` + +The `meson dist` command has a `--no-tests` option to skip build and +tests steps of generated packages. It can be used to not waste time +for example when done in CI that already does its own testing. + +So with `--no-tests` you can tell Meson "Do not build and test generated +packages.". + +## Release a subproject separately + +*Since 0.57.0* the `meson dist` command can now create a distribution tarball +for a subproject in the same git repository as the main project. This can be +useful if parts of the project (e.g. libraries) can be built and distributed +separately. In that case they can be moved into `subprojects/mysub` and running +`meson dist` in that directory will now create a tarball containing only the +source code from that subdir and not the rest of the main project or other +subprojects. + +For example: +```sh +git clone https://github.com/myproject +cd myproject/subprojects/mysubproject +meson builddir +meson dist -C builddir +``` +This produces `builddir/meson-dist/mysubproject-1.0.tar.xz` tarball. diff --git a/meson/docs/markdown/Cross-compilation.md b/meson/docs/markdown/Cross-compilation.md new file mode 100644 index 000000000..4410c0363 --- /dev/null +++ b/meson/docs/markdown/Cross-compilation.md @@ -0,0 +1,348 @@ +--- +short-description: Setting up cross-compilation +... + +# Cross compilation + +Meson has full support for cross compilation. Since cross compiling is +more complicated than native building, let's first go over some +nomenclature. The three most important definitions are traditionally +called *build*, *host* and *target*. This is confusing because those +terms are used for quite many different things. To simplify the issue, +we are going to call these the *build machine*, *host machine* and +*target machine*. Their definitions are the following: + +* *build machine* is the computer that is doing the actual compiling. +* *host machine* is the machine on which the compiled binary will run. +* *target machine* is the machine on which the compiled binary's + output will run, *only meaningful* if the program produces + machine-specific output. + +The `tl/dr` summary is the following: if you are doing regular cross +compilation, you only care about `build_machine` and +`host_machine`. Just ignore `target_machine` altogether and you will +be correct 99% of the time. Only compilers and similar tools care +about the target machine. In fact, for so-called "multi-target" tools +the target machine need not be fixed at build-time like the others but +chosen at runtime, so `target_machine` *still* doesn't matter. If your +needs are more complex or you are interested in the actual details, do +read on. + +This might be easier to understand through examples. Let's start with +the regular, not cross-compiling case. In these cases all of these +three machines are the same. Simple so far. + +Let's next look at the most common cross-compilation setup. Let's +suppose you are on a 64 bit OSX machine and you are cross compiling a +binary that will run on a 32 bit ARM Linux board. In this case your +*build machine* is 64 bit OSX, your *host machine* is 32 bit ARM Linux +and your *target machine* is irrelevant (but defaults to the same +value as the *host machine*). This should be quite understandable as +well. + +The usual mistake in this case is to call the OSX system the *host* +and the ARM Linux board the *target*. That's because these were their +actual names when the cross-compiler itself was compiled! Let's assume +the cross-compiler was created on OSX too. When that happened the +*build* and *host machines* were the same OSX and different from the +ARM Linux *target machine*. + +In a nutshell, the typical mistake assumes that the terms *build*, +*host* and *target* refer to some fixed positions whereas they're +actually relative to where the current compiler is running. Think of +*host* as a *child* of the current compiler and *target* as an +optional *grand-child*. Compilers don't change their terminology when +they're creating another compiler, that would at the very least make +their user interface much more complex. + +The most complicated case is when you cross-compile a cross compiler. +As an example you can, on a Linux machine, generate a cross compiler +that runs on Windows but produces binaries on MIPS Linux. In this case +*build machine* is x86 Linux, *host machine* is x86 Windows and +*target machine* is MIPS Linux. This setup is known as the [Canadian +Cross](https://en.wikipedia.org/wiki/Cross_compiler#Canadian_Cross). +As a side note, be careful when reading cross compilation articles on +Wikipedia or the net in general. It is very common for them to get +build, host and target mixed up, even in consecutive sentences, which +can leave you puzzled until you figure it out. + +Again note that when you cross-compile something, the 3 systems +(*build*, *host*, and *target*) used when building the cross compiler +don't align with the ones used when building something with that +newly-built cross compiler. To take our Canadian Cross scenario from +above (for full generality), since its *host machine* is x86 Windows, +the *build machine* of anything we build with it is *x86 Windows*. And +since its *target machine* is MIPS Linux, the *host machine* of +anything we build with it is *MIPS Linux*. Only the *target machine* +of whatever we build with it can be freely chosen by us, say if we +want to build another cross compiler that runs on MIPS Linux and +targets Aarch64 iOS. As this example hopefully makes clear to you, the +machine names are relative and shifted over to the left by one +position. + +If you did not understand all of the details, don't worry. For most +people it takes a while to wrap their head around these concepts. +Don't panic, it might take a while to click, but you will get the hang +of it eventually. + +## Defining the environment + +Meson requires you to write a cross build definition file. It defines +various properties of the cross build environment. The cross file +consists of different sections. + +There are a number of options shared by cross and native files, +[here](Machine-files.md). It is assumed that you have read that +section already, as this documentation will only call out options +specific to cross files. + +### Binaries + +```ini +[binaries] +exe_wrapper = 'wine' # A command used to run generated executables. +``` + +The `exe_wrapper` option defines a *wrapper command* that can be used +to run executables for this host. In this case we can use Wine, which +runs Windows applications on Linux. Other choices include running the +application with qemu or a hardware simulator. If you have this kind +of a wrapper, these lines are all you need to write. Meson will +automatically use the given wrapper when it needs to run host +binaries. This happens e.g. when running the project's test suite. + +### Properties + +In addition to the properties allowed in [all machine +files](Machine-files.md#properties), the cross file may contain +specific information about the cross compiler or the host machine. It +looks like this: + +```ini +[properties] +sizeof_int = 4 +sizeof_wchar_t = 4 +sizeof_void* = 4 + +alignment_char = 1 +alignment_void* = 4 +alignment_double = 4 + +has_function_printf = true + +sys_root = '/some/path' +pkg_config_libdir = '/some/path/lib/pkgconfig' +``` + +In most cases you don't need the size and alignment settings, Meson +will detect all these by compiling and running some sample programs. +If your build requires some piece of data that is not listed here, +Meson will stop and write an error message describing how to fix the +issue. If you need extra compiler arguments to be used during cross +compilation you can set them with `[langname]_args = [args]`. Just +remember to specify the args as an array and not as a single string +(i.e. not as `'-DCROSS=1 -DSOMETHING=3'`). + +*Since 0.52.0* The `sys_root` property may point to the root of the +host system path (the system that will run the compiled binaries). +This is used internally by Meson to set the PKG_CONFIG_SYSROOT_DIR +environment variable for pkg-config. If this is unset the host system +is assumed to share a root with the build system. + +*Since 0.54.0* The pkg_config_libdir property may point to a list of +path used internally by Meson to set the PKG_CONFIG_LIBDIR environment +variable for pkg-config. This prevents pkg-config from searching cross +dependencies in system directories. + +One important thing to note, if you did not define an `exe_wrapper` in +the previous section, is that Meson will make a best-effort guess at +whether it can run the generated binaries on the build machine. It +determines whether this is possible by looking at the `system` and +`cpu_family` of build vs host. There will however be cases where they +do match up, but the build machine is actually not compatible with the +host machine. Typically this will happen if the libc used by the build +and host machines are incompatible, or the code relies on kernel +features not available on the build machine. One concrete example is a +macOS build machine producing binaries for an iOS Simulator x86-64 +host. They're both `darwin` and the same architecture, but their +binaries are not actually compatible. In such cases you may use the +`needs_exe_wrapper` property to override the auto-detection: + +```ini +[properties] +needs_exe_wrapper = true +``` + +### Machine Entries + +The next bit is the definition of host and target machines. Every +cross build definition must have one or both of them. If it had +neither, the build would not be a cross build but a native build. You +do not need to define the build machine, as all necessary information +about it is extracted automatically. The definitions for host and +target machines look the same. Here is a sample for host machine. + +```ini +[host_machine] +system = 'windows' +cpu_family = 'x86' +cpu = 'i686' +endian = 'little' +``` + +These values define the machines sufficiently for cross compilation +purposes. The corresponding target definition would look the same but +have `target_machine` in the header. These values are available in +your Meson scripts. There are three predefined variables called, +surprisingly, `build_machine`, `host_machine` and `target_machine`. +Determining the operating system of your host machine is simply a +matter of calling `host_machine.system()`. + +There are two different values for the CPU. The first one is +`cpu_family`. It is a general type of the CPU. This should have a +value from [the CPU Family table](Reference-tables.md#cpu-families). +*Note* that Meson does not add `el` to end cpu_family value for little +endian systems. Big endian and little endian mips are both just +`mips`, with the `endian` field set approriately. + +The second value is `cpu` which is a more specific subtype for the +CPU. Typical values for a `x86` CPU family might include `i386` or +`i586` and for `arm` family `armv5` or `armv7hl`. Note that CPU type +strings are very system dependent. You might get a different value if +you check its value on the same machine but with different operating +systems. + +If you do not define your host machine, it is assumed to be the build +machine. Similarly if you do not specify target machine, it is assumed +to be the host machine. + + +## Starting a cross build + + +Once you have the cross file, starting a build is simple + +```console +$ meson srcdir builddir --cross-file cross_file.txt +``` + +Once configuration is done, compilation is started by invoking `meson compile` +in the usual way. + +## Introspection and system checks + +The main *meson* object provides two functions to determine cross +compilation status. + +```meson +meson.is_cross_build() # returns true when cross compiling +meson.can_run_host_binaries() # returns true if the host binaries can be run, either with a wrapper or natively +``` + +You can run system checks on both the system compiler or the cross +compiler. You just have to specify which one to use. + +```meson +build_compiler = meson.get_compiler('c', native : true) +host_compiler = meson.get_compiler('c', native : false) + +build_int_size = build_compiler.sizeof('int') +host_int_size = host_compiler.sizeof('int') +``` + +## Mixing host and build targets + +Sometimes you need to build a tool which is used to generate source +files. These are then compiled for the actual target. For this you +would want to build some targets with the system's native compiler. +This requires only one extra keyword argument. + +```meson +native_exe = executable('mygen', 'mygen.c', native : true) +``` + +You can then take `native_exe` and use it as part of a generator rule or anything else you might want. + +## Using a custom standard library + +Sometimes in cross compilation you need to build your own standard +library instead of using the one provided by the compiler. Meson has +built-in support for switching standard libraries transparently. The +invocation to use in your cross file is the following: + +```ini +[properties] +c_stdlib = ['mylibc', 'mylibc_dep'] # Subproject name, variable name +``` + +This specifies that C standard library is provided in the Meson +subproject `mylibc` in internal dependency variable `mylibc_dep`. It +is used on every cross built C target in the entire source tree +(including subprojects) and the standard library is disabled. The +build definitions of these targets do not need any modification. + +Note that it is supported for any language, not only `c`, using `<lang>_stdlib` +property. + +Since *0.56.0* the variable name parameter is no longer required as long as the +subproject calls `meson.override_dependency('c_stdlib', mylibc_dep)`. +The above example becomes: + +```ini +[properties] +c_stdlib = 'mylibc' +``` + +## Changing cross file settings + +Cross file settings are only read when the build directory is set up +the first time. Any changes to them after the fact will be ignored. +This is the same as regular compiles where you can't change the +compiler once a build tree has been set up. If you need to edit your +cross file, then you need to wipe your build tree and recreate it from +scratch. + +## Custom data + +You can store arbitrary data in `properties` and access them from your +Meson files. As an example if you cross file has this: + +```ini +[properties] +somekey = 'somevalue' +``` + +then you can access that using the `meson` object like this: + +```meson +myvar = meson.get_external_property('somekey') +# myvar now has the value 'somevalue' +``` + +## Cross file locations + +As of version 0.44.0 Meson supports loading cross files from system +locations (except on Windows). This will be +$XDG_DATA_DIRS/meson/cross, or if XDG_DATA_DIRS is undefined, then +/usr/local/share/meson/cross and /usr/share/meson/cross will be tried +in that order, for system wide cross files. User local files can be +put in $XDG_DATA_HOME/meson/cross, or ~/.local/share/meson/cross if +that is undefined. + +The order of locations tried is as follows: + - A file relative to the local dir + - The user local location + - The system wide locations in order + +Distributions are encouraged to ship cross files either with their +cross compiler toolchain packages or as a standalone package, and put +them in one of the system paths referenced above. + +These files can be loaded automatically without adding a path to the +cross file. For example, if a ~/.local/share/meson/cross contains a +file called x86-linux, then the following command would start a cross +build using that cross files: + +```sh +meson builddir/ --cross-file x86-linux +``` diff --git a/meson/docs/markdown/Cuda-module.md b/meson/docs/markdown/Cuda-module.md new file mode 100644 index 000000000..24a607a72 --- /dev/null +++ b/meson/docs/markdown/Cuda-module.md @@ -0,0 +1,186 @@ +--- +short-description: CUDA module +authors: + - name: Olexa Bilaniuk + years: [2019] + has-copyright: false +... + +# Unstable CUDA Module +_Since: 0.50.0_ + +This module provides helper functionality related to the CUDA Toolkit and +building code using it. + + +**Note**: this module is unstable. It is only provided as a technology preview. +Its API may change in arbitrary ways between releases or it might be removed +from Meson altogether. + + +## Importing the module + +The module may be imported as follows: + +``` meson +cuda = import('unstable-cuda') +``` + +It offers several useful functions that are enumerated below. + + +## Functions + +### `nvcc_arch_flags()` +_Since: 0.50.0_ + +``` meson +cuda.nvcc_arch_flags(cuda_version_string, ..., + detected: string_or_array) +``` + +Returns a list of `-gencode` flags that should be passed to `cuda_args:` in +order to compile a "fat binary" for the architectures/compute capabilities +enumerated in the positional argument(s). The flags shall be acceptable to +an NVCC with CUDA Toolkit version string `cuda_version_string`. + +A set of architectures and/or compute capabilities may be specified by: + +- The single positional argument `'All'`, `'Common'` or `'Auto'` +- As (an array of) + - Architecture names (`'Kepler'`, `'Maxwell+Tegra'`, `'Turing'`) and/or + - Compute capabilities (`'3.0'`, `'3.5'`, `'5.3'`, `'7.5'`) + +A suffix of `+PTX` requests PTX code generation for the given architecture. +A compute capability given as `A.B(X.Y)` requests PTX generation for an older +virtual architecture `X.Y` before binary generation for a newer architecture +`A.B`. + +Multiple architectures and compute capabilities may be passed in using + +- Multiple positional arguments +- Lists of strings +- Space (` `), comma (`,`) or semicolon (`;`)-separated strings + +The single-word architectural sets `'All'`, `'Common'` or `'Auto'` +cannot be mixed with architecture names or compute capabilities. Their +interpretation is: + +| Name | Compute Capability | +|-------------------|--------------------| +| `'All'` | All CCs supported by given NVCC compiler. | +| `'Common'` | Relatively common CCs supported by given NVCC compiler. Generally excludes Tegra and Tesla devices. | +| `'Auto'` | The CCs provided by the `detected:` keyword, filtered for support by given NVCC compiler. | + +The supported architecture names and their corresponding compute capabilities +are: + +| Name | Compute Capability | +|-------------------|--------------------| +| `'Fermi'` | 2.0, 2.1(2.0) | +| `'Kepler'` | 3.0, 3.5 | +| `'Kepler+Tegra'` | 3.2 | +| `'Kepler+Tesla'` | 3.7 | +| `'Maxwell'` | 5.0, 5.2 | +| `'Maxwell+Tegra'` | 5.3 | +| `'Pascal'` | 6.0, 6.1 | +| `'Pascal+Tegra'` | 6.2 | +| `'Volta'` | 7.0 | +| `'Xavier'` | 7.2 | +| `'Turing'` | 7.5 | +| `'Ampere'` | 8.0, 8.6 | + + +Examples: + + cuda.nvcc_arch_flags('10.0', '3.0', '3.5', '5.0+PTX') + cuda.nvcc_arch_flags('10.0', ['3.0', '3.5', '5.0+PTX']) + cuda.nvcc_arch_flags('10.0', [['3.0', '3.5'], '5.0+PTX']) + cuda.nvcc_arch_flags('10.0', '3.0 3.5 5.0+PTX') + cuda.nvcc_arch_flags('10.0', '3.0,3.5,5.0+PTX') + cuda.nvcc_arch_flags('10.0', '3.0;3.5;5.0+PTX') + cuda.nvcc_arch_flags('10.0', 'Kepler 5.0+PTX') + # Returns ['-gencode', 'arch=compute_30,code=sm_30', + # '-gencode', 'arch=compute_35,code=sm_35', + # '-gencode', 'arch=compute_50,code=sm_50', + # '-gencode', 'arch=compute_50,code=compute_50'] + + cuda.nvcc_arch_flags('10.0', '3.5(3.0)') + # Returns ['-gencode', 'arch=compute_30,code=sm_35'] + + cuda.nvcc_arch_flags('8.0', 'Common') + # Returns ['-gencode', 'arch=compute_30,code=sm_30', + # '-gencode', 'arch=compute_35,code=sm_35', + # '-gencode', 'arch=compute_50,code=sm_50', + # '-gencode', 'arch=compute_52,code=sm_52', + # '-gencode', 'arch=compute_60,code=sm_60', + # '-gencode', 'arch=compute_61,code=sm_61', + # '-gencode', 'arch=compute_61,code=compute_61'] + + cuda.nvcc_arch_flags('9.2', 'Auto', detected: '6.0 6.0 6.0 6.0') + cuda.nvcc_arch_flags('9.2', 'Auto', detected: ['6.0', '6.0', '6.0', '6.0']) + # Returns ['-gencode', 'arch=compute_60,code=sm_60'] + + cuda.nvcc_arch_flags(nvcc, 'All') + # Returns ['-gencode', 'arch=compute_20,code=sm_20', + # '-gencode', 'arch=compute_20,code=sm_21', + # '-gencode', 'arch=compute_30,code=sm_30', + # '-gencode', 'arch=compute_32,code=sm_32', + # '-gencode', 'arch=compute_35,code=sm_35', + # '-gencode', 'arch=compute_37,code=sm_37', + # '-gencode', 'arch=compute_50,code=sm_50', # nvcc.version() < 7.0 + # '-gencode', 'arch=compute_52,code=sm_52', + # '-gencode', 'arch=compute_53,code=sm_53', # nvcc.version() >= 7.0 + # '-gencode', 'arch=compute_60,code=sm_60', + # '-gencode', 'arch=compute_61,code=sm_61', # nvcc.version() >= 8.0 + # '-gencode', 'arch=compute_70,code=sm_70', + # '-gencode', 'arch=compute_72,code=sm_72', # nvcc.version() >= 9.0 + # '-gencode', 'arch=compute_75,code=sm_75'] # nvcc.version() >= 10.0 + +_Note:_ This function is intended to closely replicate CMake's FindCUDA module +function `CUDA_SELECT_NVCC_ARCH_FLAGS(out_variable, [list of CUDA compute architectures])` + + + +### `nvcc_arch_readable()` +_Since: 0.50.0_ + +``` meson +cuda.nvcc_arch_readable(cuda_version_string, ..., + detected: string_or_array) +``` + +Has precisely the same interface as [`nvcc_arch_flags()`](#nvcc_arch_flags), +but rather than returning a list of flags, it returns a "readable" list of +architectures that will be compiled for. The output of this function is solely +intended for informative message printing. + + archs = '3.0 3.5 5.0+PTX' + readable = cuda.nvcc_arch_readable('10.0', archs) + message('Building for architectures ' + ' '.join(readable)) + +This will print + + Message: Building for architectures sm30 sm35 sm50 compute50 + +_Note:_ This function is intended to closely replicate CMake's +FindCUDA module function `CUDA_SELECT_NVCC_ARCH_FLAGS(out_variable, +[list of CUDA compute architectures])` + + + +### `min_driver_version()` +_Since: 0.50.0_ + +``` meson +cuda.min_driver_version(cuda_version_string) +``` + +Returns the minimum NVIDIA proprietary driver version required, on the +host system, by kernels compiled with a CUDA Toolkit with the given +version string. + +The output of this function is generally intended for informative +message printing, but could be used for assertions or to conditionally +enable features known to exist within the minimum NVIDIA driver +required. diff --git a/meson/docs/markdown/Custom-build-targets.md b/meson/docs/markdown/Custom-build-targets.md new file mode 100644 index 000000000..b92bbc556 --- /dev/null +++ b/meson/docs/markdown/Custom-build-targets.md @@ -0,0 +1,46 @@ +--- +short-description: Build targets for custom languages or corner-cases +... + +# Custom build targets + +While Meson tries to support as many languages and tools as possible, +there is no possible way for it to cover all corner cases. For these +cases it permits you to define custom build targets. Here is how one +would use it. + +```meson +comp = find_program('custom_compiler') + +infile = 'source_code.txt' +outfile = 'output.bin' + +mytarget = custom_target('targetname', + output : outfile, + input : infile, + command : [comp, '@INPUT@', '@OUTPUT@'], + install : true, + install_dir : 'subdir') +``` + +This would generate the binary `output.bin` and install it to +`${prefix}/subdir/output.bin`. Variable substitution works just like +it does for source generation. + +See [Generating Sources](Generating-sources.md) for more information on this topic. + +## Details on command invocation + +Meson only permits you to specify one command to run. This is by +design as writing shell pipelines into build definition files leads to +code that is very hard to maintain. If your command requires multiple +steps you need to write a wrapper script that does all the necessary +work. + +When doing this you need to be mindful of the following issues: + +* do not assume that the command is invoked in any specific directory +* a target called `target` file `outfile` defined in subdir `subdir` + must be written to `build_dir/subdir/foo.dat` +* if you need a subdirectory for temporary files, use + `build_dir/subdir/target.dir` diff --git a/meson/docs/markdown/Cython.md b/meson/docs/markdown/Cython.md new file mode 100644 index 000000000..1d30c1f97 --- /dev/null +++ b/meson/docs/markdown/Cython.md @@ -0,0 +1,33 @@ +--- +title: Cython +short-description: Support for Cython in Meson +... + +# Cython + +Meson provides native support for cython programs starting with version 0.59.0. +This means that you can include it as a normal language, and create targets like +any other supported language: + +```meson +lib = static_library( + 'foo', + 'foo.pyx', +) +``` + +Generally Cython is most useful when combined with the python module's +extension_module method: + +```meson +project('my project', 'cython') + +py = import('python').find_installation() +dep_py = py.dependency() + +py.extension_module( + 'foo', + 'foo.pyx', + dependencies : dep_py, +) +``` diff --git a/meson/docs/markdown/D.md b/meson/docs/markdown/D.md new file mode 100644 index 000000000..4a00a3ba7 --- /dev/null +++ b/meson/docs/markdown/D.md @@ -0,0 +1,127 @@ +--- +title: D +short-description: Compiling D sources +... + +# Compiling D applications + +Meson has support for compiling D programs. A minimal `meson.build` +file for D looks like this: + +```meson +project('myapp', 'd') + +executable('myapp', 'app.d') +``` + +## [Conditional compilation](https://dlang.org/spec/version.html) + +If you are using the +[version()](https://dlang.org/spec/version.html#version-specification) +feature for conditional compilation, you can use it using the +`d_module_versions` target property: + +```meson +project('myapp', 'd') +executable('myapp', 'app.d', d_module_versions: ['Demo', 'FeatureA']) +``` + +For debugging, [debug()](https://dlang.org/spec/version.html#debug) +conditions are compiled automatically in debug builds, and extra +identifiers can be added with the `d_debug` argument: + +```meson +project('myapp', 'd') +executable('myapp', 'app.d', d_debug: [3, 'DebugFeatureA']) +``` + +## Using embedded unittests + +If you are using embedded [unittest +functions](https://dlang.org/spec/unittest.html), your source code +needs to be compiled twice, once in regular mode, and once with +unittests active. This is done by setting the `d_unittest` target +property to `true`. Meson will only ever pass the respective +compiler's `-unittest` flag, and never have the compiler generate an +empty main function. If you need that feature in a portable way, +create an empty `main()` function for unittests yourself, since the +GNU D compiler does not have this feature. + +This is an example for using D unittests with Meson: +```meson +project('myapp_tested', 'd') + +myapp_src = ['app.d', 'alpha.d', 'beta.d'] +executable('myapp', myapp_src) + +test_exe = executable('myapp_test', myapp_src, d_unittest: true) +test('myapptest', test_exe) +``` + +# Compiling D libraries and installing them + +Building D libraries is a straightforward process, not different from +how C libraries are built in Meson. You should generate a pkg-config +file and install it, in order to make other software on the system +find the dependency once it is installed. + +This is an example on how to build a D shared library: +```meson +project('mylib', 'd', version: '1.2.0') + +project_soversion = 0 +glib_dep = dependency('glib-2.0') + +my_lib = library('mylib', + ['src/mylib/libfunctions.d'], + dependencies: [glib_dep], + install: true, + version: meson.project_version(), + soversion: project_soversion, + d_module_versions: ['FeatureA', 'featureB'] +) + +pkgc = import('pkgconfig') +pkgc.generate(name: 'mylib', + libraries: my_lib, + subdirs: 'd/mylib', + version: meson.project_version(), + description: 'A simple example D library.', + d_module_versions: ['FeatureA'] +) +install_subdir('src/mylib/', install_dir: 'include/d/mylib/') +``` + +It is important to make the D sources install in a subdirectory in the +include path, in this case `/usr/include/d/mylib/mylib`. All D +compilers include the `/usr/include/d` directory by default, and if +your library would be installed into `/usr/include/d/mylib`, there is +a high chance that, when you compile your project again on a machine +where you installed it, the compiler will prefer the old installed +include over the new version in the source tree, leading to very +confusing errors. + +This is an example of how to use the D library we just built and +installed in an application: +```meson +project('myapp', 'd') + +mylib_dep = dependency('mylib', version: '>= 1.2.0') +myapp_src = ['app.d', 'alpha.d', 'beta.d'] +executable('myapp', myapp_src, dependencies: [mylib_dep]) +``` + +Please keep in mind that the library and executable would both need to +be built with the exact same D compiler and D compiler version. The D +ABI is not stable across compilers and their versions, and mixing +compilers will lead to problems. + +# Integrating with DUB + +DUB is a fully integrated build system for D, but it is also a way to +provide dependencies. Adding dependencies from the [D package +registry](https://code.dlang.org/) is pretty straight forward. You can +find how to do this in +[Dependencies](Dependencies.md#some-notes-on-dub). You can also +automatically generate a `dub.json` file as explained in +[Dlang](Dlang-module.md#generate_dub_file). diff --git a/meson/docs/markdown/Dependencies.md b/meson/docs/markdown/Dependencies.md new file mode 100644 index 000000000..b4cadb73e --- /dev/null +++ b/meson/docs/markdown/Dependencies.md @@ -0,0 +1,714 @@ +--- +short-description: Dependencies for external libraries and frameworks +... + +# Dependencies + +Very few applications are fully self-contained, but rather they use +external libraries and frameworks to do their work. Meson makes it +very easy to find and use external dependencies. Here is how one would +use the zlib compression library. + +```meson +zdep = dependency('zlib', version : '>=1.2.8') +exe = executable('zlibprog', 'prog.c', dependencies : zdep) +``` + +First Meson is told to find the external library `zlib` and error out +if it is not found. The `version` keyword is optional and specifies a +version requirement for the dependency. Then an executable is built +using the specified dependency. Note how the user does not need to +manually handle compiler or linker flags or deal with any other +minutiae. + +If you have multiple dependencies, pass them as an array: + +```meson +executable('manydeps', 'file.c', dependencies : [dep1, dep2, dep3, dep4]) +``` + +If the dependency is optional, you can tell Meson not to error out if +the dependency is not found and then do further configuration. + +```meson +opt_dep = dependency('somedep', required : false) +if opt_dep.found() + # Do something. +else + # Do something else. +endif +``` + +You can pass the `opt_dep` variable to target construction functions +whether the actual dependency was found or not. Meson will ignore +non-found dependencies. + +Meson also allows to get variables that are defined in the +`pkg-config` file. This can be done by using the +`get_pkgconfig_variable` function. + +```meson +zdep_prefix = zdep.get_pkgconfig_variable('prefix') +``` + +These variables can also be redefined by passing the `define_variable` +parameter, which might be useful in certain situations: + +```meson +zdep_prefix = zdep.get_pkgconfig_variable('libdir', define_variable: ['prefix', '/tmp']) +``` + +The dependency detector works with all libraries that provide a +`pkg-config` file. Unfortunately several packages don't provide +pkg-config files. Meson has autodetection support for some of these, +and they are described [later in this +page](#dependencies-with-custom-lookup-functionality). + +# Arbitrary variables from dependencies that can be found multiple ways + +*Note* new in 0.51.0 +*new in 0.54.0, the `internal` keyword* + +When you need to get an arbitrary variables from a dependency that can +be found multiple ways and you don't want to constrain the type you +can use the generic `get_variable` method. This currently supports +cmake, pkg-config, and config-tool based variables. + +```meson +foo_dep = dependency('foo') +var = foo_dep.get_variable(cmake : 'CMAKE_VAR', pkgconfig : 'pkg-config-var', configtool : 'get-var', default_value : 'default') +``` + +It accepts the keywords 'cmake', 'pkgconfig', 'pkgconfig_define', +'configtool', 'internal', and 'default_value'. 'pkgconfig_define' +works just like the 'define_variable' argument to +`get_pkgconfig_variable`. When this method is invoked the keyword +corresponding to the underlying type of the dependency will be used to +look for a variable. If that variable cannot be found or if the caller +does not provide an argument for the type of dependency, one of the +following will happen: If 'default_value' was provided that value will +be returned, if 'default_value' was not provided then an error will be +raised. + +# Declaring your own + +You can declare your own dependency objects that can be used +interchangeably with dependency objects obtained from the system. The +syntax is straightforward: + +```meson +my_inc = include_directories(...) +my_lib = static_library(...) +my_dep = declare_dependency(link_with : my_lib, + include_directories : my_inc) +``` + +This declares a dependency that adds the given include directories and +static library to any target you use it in. + +# Building dependencies as subprojects + +Many platforms do not provide a system package manager. On these +systems dependencies must be compiled from source. Meson's subprojects +make it simple to use system dependencies when they are available and +to build dependencies manually when they are not. + +To make this work, the dependency must have Meson build definitions +and it must declare its own dependency like this: + +```meson + foo_dep = declare_dependency(...) +``` + +Then any project that wants to use it can write out the following +declaration in their main `meson.build` file. + +```meson + foo_dep = dependency('foo', fallback : ['foo', 'foo_dep']) +``` + +What this declaration means is that first Meson tries to look up the +dependency from the system (such as by using pkg-config). If it is not +available, then it builds subproject named `foo` and from that +extracts a variable `foo_dep`. That means that the return value of +this function is either an external or an internal dependency object. +Since they can be used interchangeably, the rest of the build +definitions do not need to care which one it is. Meson will take care +of all the work behind the scenes to make this work. + +# Dependency detection method + +You can use the keyword `method` to let Meson know what method to use +when searching for the dependency. The default value is `auto`. +Additional methods are `pkg-config`, `config-tool`, `cmake`, +`builtin`, `system`, `sysconfig`, `qmake`, `extraframework` and `dub`. + +```meson +cups_dep = dependency('cups', method : 'pkg-config') +``` + +For dependencies without [specific detection +logic](#dependencies-with-custom-lookup-functionality), the dependency method +order for `auto` is: + + 1. `pkg-config` + 2. `cmake` + 3. `extraframework` (OSX only) + +## System + +Some dependencies provide no valid methods for discovery, or do so only in +some cases. Some examples of this are Zlib, which provides both pkg-config +and cmake, except when it is part of the base OS image (such as in FreeBSD +and macOS); OpenGL which has pkg-config on Unices from glvnd or mesa, but has +no pkg-config on macOS and Windows. + +In these cases Meson provides convenience wrappers in the form of `system` +dependencies. Internally these dependencies do exactly what a user would do +in the build system DSL or with a script, likely calling +`compiler.find_library()`, setting `link_with` and `include_directories`. By +putting these in Meson upstream the barrier of using them is lowered, as +projects using Meson don't have to re-implement the logic. + +## Builtin + +Some dependencies provide no valid methods for discovery on some systems, +because they are provided internally by the language. One example of this is +intl, which is built into GNU or musl libc but otherwise comes as a `system` +dependency. + +In these cases Meson provides convenience wrappers for the `system` dependency, +but first checks if the functionality is usable by default. + +## CMake + +Meson can use the CMake `find_package()` function to detect +dependencies with the builtin `Find<NAME>.cmake` modules and exported +project configurations (usually in `/usr/lib/cmake`). Meson is able to +use both the old-style `<NAME>_LIBRARIES` variables as well as +imported targets. + +It is possible to manually specify a list of CMake targets that should +be used with the `modules` property. However, this step is optional +since Meson tries to automatically guess the correct target based on +the name of the dependency. + +Depending on the dependency it may be necessary to explicitly specify +a CMake target with the `modules` property if Meson is unable to guess +it automatically. + +```meson + cmake_dep = dependency('ZLIB', method : 'cmake', modules : ['ZLIB::ZLIB']) +``` + +Support for adding additional `COMPONENTS` for the CMake +`find_package` lookup is provided with the `components` kwarg +(*introduced in 0.54.0*). All specified componets will be passed +directly to `find_package(COMPONENTS)`. + +Support for packages which require a specified version for CMake +`find_package` to succeed is provided with the `cmake_package_version` +kwarg (*introduced in 0.57.0*). The specified `cmake_package_version` +will be passed directly as the second parameter to `find_package`. + +It is also possible to reuse existing `Find<name>.cmake` files with +the `cmake_module_path` property. Using this property is equivalent to +setting the `CMAKE_MODULE_PATH` variable in CMake. The path(s) given +to `cmake_module_path` should all be relative to the project source +directory. Absolute paths should only be used if the CMake files are +not stored in the project itself. + +Additional CMake parameters can be specified with the `cmake_args` +property. + +## Dub + +Please understand that Meson is only able to find dependencies that +exist in the local Dub repository. You need to manually fetch and +build the target dependencies. + +For `urld`. +``` +dub fetch urld +dub build urld +``` + +Other thing you need to keep in mind is that both Meson and Dub need +to be using the same compiler. This can be achieved using Dub's +`-compiler` argument and/or manually setting the `DC` environment +variable when running Meson. +``` +dub build urld --compiler=dmd +DC="dmd" meson builddir +``` + +## Config tool + +[CUPS](#cups), [LLVM](#llvm), [pcap](#pcap), [WxWidgets](#wxwidgets), +[libwmf](#libwmf), [GCrypt](#libgcrypt), [GPGME](#gpgme), and GnuStep either do not provide pkg-config +modules or additionally can be detected via a config tool +(cups-config, llvm-config, libgcrypt-config, etc). Meson has native support for these +tools, and they can be found like other dependencies: + +```meson +pcap_dep = dependency('pcap', version : '>=1.0') +cups_dep = dependency('cups', version : '>=1.4') +llvm_dep = dependency('llvm', version : '>=4.0') +libgcrypt_dep = dependency('libgcrypt', version: '>= 1.8') +gpgme_dep = dependency('gpgme', version: '>= 1.0') +``` + +*Since 0.55.0* Meson won't search $PATH any more for a config tool +binary when cross compiling if the config tool did not have an entry +in the cross file. + +# Dependencies with custom lookup functionality + +Some dependencies have specific detection logic. + +Generic dependency names are case-sensitive<sup>[1](#footnote1)</sup>, +but these dependency names are matched case-insensitively. The +recommended style is to write them in all lower-case. + +In some cases, more than one detection method exists, and the `method` +keyword may be used to select a detection method to use. The `auto` +method uses any checking mechanisms in whatever order Meson thinks is +best. + +e.g. libwmf and CUPS provide both pkg-config and config-tool support. +You can force one or another via the `method` keyword: + +```meson +cups_dep = dependency('cups', method : 'pkg-config') +wmf_dep = dependency('libwmf', method : 'config-tool') +``` + +## AppleFrameworks + +Use the `modules` keyword to list frameworks required, e.g. + +```meson +dep = dependency('appleframeworks', modules : 'foundation') +``` + +These dependencies can never be found for non-OSX hosts. + +## Blocks + +Enable support for Clang's blocks extension. + +```meson +dep = dependency('blocks') +``` + +*(added 0.52.0)* + +## Boost + +Boost is not a single dependency but rather a group of different +libraries. To use Boost headers-only libraries, simply add Boost as a +dependency. + +```meson +boost_dep = dependency('boost') +exe = executable('myprog', 'file.cc', dependencies : boost_dep) +``` + +To link against boost with Meson, simply list which libraries you +would like to use. + +```meson +boost_dep = dependency('boost', modules : ['thread', 'utility']) +exe = executable('myprog', 'file.cc', dependencies : boost_dep) +``` + +You can call `dependency` multiple times with different modules and +use those to link against your targets. + +If your boost headers or libraries are in non-standard locations you +can set the `BOOST_ROOT`, or the `BOOST_INCLUDEDIR` and +`BOOST_LIBRARYDIR` environment variables. *(added in 0.56.0)* You can +also set these parameters as `boost_root`, `boost_include`, and +`boost_librarydir` in your native or cross machine file. Note that +machine file variables are preferred to environment variables, and +that specifying any of these disables system-wide search for boost. + +You can set the argument `threading` to `single` to use boost +libraries that have been compiled for single-threaded use instead. + +## CUDA + +*(added 0.53.0)* + +Enables compiling and linking against the CUDA Toolkit. The `version` +and `modules` keywords may be passed to request the use of a specific +CUDA Toolkit version and/or additional CUDA libraries, correspondingly: + +```meson +dep = dependency('cuda', version : '>=10', modules : ['cublas']) +``` + +Note that explicitly adding this dependency is only necessary if you are +using CUDA Toolkit from a C/C++ file or project, or if you are utilizing +additional toolkit libraries that need to be explicitly linked to. + +## CUPS + +`method` may be `auto`, `config-tool`, `pkg-config`, `cmake` or `extraframework`. + +## Curses + +*(Since 0.54.0)* + +Curses (and ncurses) are a cross platform pain in the butt. Meson +wraps up these dependencies in the `curses` dependency. This covers +both `ncurses` (preferred) and other curses implementations. + +`method` may be `auto`, `pkg-config`, `config-tool`, or `system`. + +*New in 0.56.0* The `config-tool` and `system` methods. + +To define some of the the preprocessor symbols mentioned in the +[curses autoconf documentation](http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_with_curses.m4): + +```meson +conf = configuration_data() +check_headers = [ + ['ncursesw/menu.h', 'HAVE_NCURSESW_MENU_H'], + ['ncurses/menu.h', 'HAVE_NCURSES_MENU_H'], + ['menu.h', 'HAVE_MENU_H'], + ['ncursesw/curses.h', 'HAVE_NCURSESW_CURSES_H'], + ['ncursesw.h', 'HAVE_NCURSESW_H'], + ['ncurses/curses.h', 'HAVE_NCURSES_CURSES_H'], + ['ncurses.h', 'HAVE_NCURSES_H'], + ['curses.h', 'HAVE_CURSES_H'], +] + +foreach h : check_headers + if compiler.has_header(h.get(0)) + conf.set(h.get(1), 1) + endif +endforeach +``` + +## Fortran Coarrays + +*(added 0.50.0)* + + Coarrays are a Fortran language intrinsic feature, enabled by +`dependency('coarray')`. + +GCC will use OpenCoarrays if present to implement coarrays, while Intel and NAG +use internal coarray support. + +## GPGME + +*(added 0.51.0)* + +`method` may be `auto`, `config-tool` or `pkg-config`. + +## GL + +This finds the OpenGL library in a way appropriate to the platform. + +`method` may be `auto`, `pkg-config` or `system`. + +## GTest and GMock + +GTest and GMock come as sources that must be compiled as part of your +project. With Meson you don't have to care about the details, just +pass `gtest` or `gmock` to `dependency` and it will do everything for +you. If you want to use GMock, it is recommended to use GTest as well, +as getting it to work standalone is tricky. + +You can set the `main` keyword argument to `true` to use the `main()` +function provided by GTest: + +```meson +gtest_dep = dependency('gtest', main : true, required : false) +e = executable('testprog', 'test.cc', dependencies : gtest_dep) +test('gtest test', e) +``` + +## HDF5 + +*(added 0.50.0)* + +HDF5 is supported for C, C++ and Fortran. Because dependencies are +language-specific, you must specify the requested language using the +`language` keyword argument, i.e., + * `dependency('hdf5', language: 'c')` for the C HDF5 headers and libraries + * `dependency('hdf5', language: 'cpp')` for the C++ HDF5 headers and libraries + * `dependency('hdf5', language: 'fortran')` for the Fortran HDF5 headers and libraries + +Meson uses pkg-config to find HDF5. The standard low-level HDF5 +function and the `HL` high-level HDF5 functions are linked for each +language. + +`method` may be `auto`, `config-tool` or `pkg-config`. + +*New in 0.56.0* the `config-tool` method. +*New in 0.56.0* the dependencies now return proper dependency types + and `get_variable` and similar methods should work as expected. + +## intl + +*(added 0.59.0)* + +Provides access to the `*gettext` family of C functions. On systems where this +is not built into libc, tries to find an external library providing them +instead. + +`method` may be `auto`, `builtin` or `system`. + +## libgcrypt + +*(added 0.49.0)* + +`method` may be `auto`, `config-tool` or `pkg-config`. + +## libwmf + +*(added 0.44.0)* + +`method` may be `auto`, `config-tool` or `pkg-config`. + +## LLVM + +Meson has native support for LLVM going back to version LLVM version +3.5. It supports a few additional features compared to other +config-tool based dependencies. + +As of 0.44.0 Meson supports the `static` keyword argument for LLVM. +Before this LLVM >= 3.9 would always dynamically link, while older +versions would statically link, due to a quirk in `llvm-config`. + +`method` may be `auto`, `config-tool`, or `cmake`. + +### Modules, a.k.a. Components + +Meson wraps LLVM's concept of components in it's own modules concept. +When you need specific components you add them as modules as Meson +will do the right thing: + +```meson +llvm_dep = dependency('llvm', version : '>= 4.0', modules : ['amdgpu']) +``` + +As of 0.44.0 it can also take optional modules (these will affect the arguments +generated for a static link): + +```meson +llvm_dep = dependency( + 'llvm', version : '>= 4.0', modules : ['amdgpu'], optional_modules : ['inteljitevents'], +) +``` + +### Using LLVM tools + +When using LLVM as library but also needing its tools, it is often +beneficial to use the same version. This can partially be achieved +with the `version` argument of `find_program()`. However, +distributions tend to package different LLVM versions in rather +different ways. Therefore, it is often better to use the llvm +dependency directly to retrieve the tools: + +```meson +llvm_dep = dependency('llvm', version : ['>= 8', '< 9']) +llvm_link = find_program(llvm_dep.get_variable(configtool: 'bindir') / 'llvm-link') +``` + +## MPI + +*(added 0.42.0)* + +MPI is supported for C, C++ and Fortran. Because dependencies are +language-specific, you must specify the requested language using the +`language` keyword argument, i.e., + * `dependency('mpi', language: 'c')` for the C MPI headers and libraries + * `dependency('mpi', language: 'cpp')` for the C++ MPI headers and libraries + * `dependency('mpi', language: 'fortran')` for the Fortran MPI headers and libraries + +Meson prefers pkg-config for MPI, but if your MPI implementation does +not provide them, it will search for the standard wrapper executables, +`mpic`, `mpicxx`, `mpic++`, `mpifort`, `mpif90`, `mpif77`. If these +are not in your path, they can be specified by setting the standard +environment variables `MPICC`, `MPICXX`, `MPIFC`, `MPIF90`, or +`MPIF77`, during configuration. It will also try to use the Microsoft +implementation on windows via the `system` method. + +`method` may be `auto`, `config-tool`, `pkg-config` or `system`. + +*New in 0.54.0* The `config-tool` and `system` method values. Previous +versions would always try `pkg-config`, then `config-tool`, then `system`. + +## NetCDF + +*(added 0.50.0)* + +NetCDF is supported for C, C++ and Fortran. Because NetCDF dependencies are +language-specific, you must specify the requested language using the +`language` keyword argument, i.e., + * `dependency('netcdf', language: 'c')` for the C NetCDF headers and libraries + * `dependency('netcdf', language: 'cpp')` for the C++ NetCDF headers and libraries + * `dependency('netcdf', language: 'fortran')` for the Fortran NetCDF headers and libraries + +Meson uses pkg-config to find NetCDF. + +## OpenMP + +*(added 0.46.0)* + +This dependency selects the appropriate compiler flags and/or libraries to use +for OpenMP support. + +The `language` keyword may used. + +## pcap + +*(added 0.42.0)* + +`method` may be `auto`, `config-tool` or `pkg-config`. + +## Python3 + +Python3 is handled specially by Meson: +1. Meson tries to use `pkg-config`. +2. If `pkg-config` fails Meson uses a fallback: + - On Windows the fallback is the current `python3` interpreter. + - On OSX the fallback is a framework dependency from `/Library/Frameworks`. + +Note that `python3` found by this dependency might differ from the one +used in `python3` module because modules uses the current interpreter, +but dependency tries `pkg-config` first. + +`method` may be `auto`, `extraframework`, `pkg-config` or `sysconfig` + +## Qt4 & Qt5 + +Meson has native Qt support. Its usage is best demonstrated with an +example. + +```meson +qt5_mod = import('qt5') +qt5widgets = dependency('qt5', modules : 'Widgets') + +processed = qt5_mod.preprocess( + moc_headers : 'mainWindow.h', # Only headers that need moc should be put here + moc_sources : 'helperFile.cpp', # must have #include"moc_helperFile.cpp" + ui_files : 'mainWindow.ui', + qresources : 'resources.qrc', +) + +q5exe = executable('qt5test', + sources : ['main.cpp', + 'mainWindow.cpp', + processed], + dependencies: qt5widgets) +``` + +Here we have an UI file created with Qt Designer and one source and +header file each that require preprocessing with the `moc` tool. We +also define a resource file to be compiled with `rcc`. We just have to +tell Meson which files are which and it will take care of invoking all +the necessary tools in the correct order, which is done with the +`preprocess` method of the `qt5` module. Its output is simply put in +the list of sources for the target. The `modules` keyword of +`dependency` works just like it does with Boost. It tells which +subparts of Qt the program uses. + +You can set the `main` keyword argument to `true` to use the +`WinMain()` function provided by qtmain static library (this argument +does nothing on platforms other than Windows). + +Setting the optional `private_headers` keyword to true adds the +private header include path of the given module(s) to the compiler +flags. (since v0.47.0) + +**Note** using private headers in your project is a bad idea, do so at +your own risk. + +`method` may be `auto`, `pkg-config` or `qmake`. + +## SDL2 + +SDL2 can be located using `pkg-confg`, the `sdl2-config` config tool, +or as an OSX framework. + +`method` may be `auto`, `config-tool`, `extraframework` or +`pkg-config`. + +## Shaderc + +*(added 0.51.0)* + +Shaderc currently does not ship with any means of detection. +Nevertheless, Meson can try to detect it using `pkg-config`, but will +default to looking for the appropriate library manually. If the +`static` keyword argument is `true`, `shaderc_combined` is preferred. +Otherwise, `shaderc_shared` is preferred. Note that it is not possible +to obtain the shaderc version using this method. + +`method` may be `auto`, `pkg-config` or `system`. + +## Threads + +This dependency selects the appropriate compiler flags and/or +libraries to use for thread support. + +See [threads](Threads.md). + +## Valgrind + +Meson will find valgrind using `pkg-config`, but only uses the +compilation flags and avoids trying to link with it's non-PIC static +libs. + +## Vulkan + +*(added 0.42.0)* + +Vulkan can be located using `pkg-config`, or the `VULKAN_SDK` +environment variable. + +`method` may be `auto`, `pkg-config` or `system`. + +## WxWidgets + +Similar to [Boost](#boost), WxWidgets is not a single library but rather +a collection of modules. WxWidgets is supported via `wx-config`. +Meson substitutes `modules` to `wx-config` invocation, it generates +- `compile_args` using `wx-config --cxxflags $modules...` +- `link_args` using `wx-config --libs $modules...` + +### Example + +```meson +wx_dep = dependency( + 'wxwidgets', version : '>=3.0.0', modules : ['std', 'stc'], +) +``` + +```shell +# compile_args: +$ wx-config --cxxflags std stc + +# link_args: +$ wx-config --libs std stc +``` + +## Zlib + +Zlib ships with pkg-config and cmake support, but on some operating +systems (windows, macOs, FreeBSD, dragonflybsd), it is provided as +part of the base operating system without pkg-config support. The new +System finder can be used on these OSes to link with the bundled +version. + +`method` may be `auto`, `pkg-config`, `cmake`, or `system`. + +*New in 0.54.0* the `system` method. + +<hr> +<a name="footnote1">1</a>: They may appear to be case-insensitive, if the + underlying file system happens to be case-insensitive. diff --git a/meson/docs/markdown/Design-rationale.md b/meson/docs/markdown/Design-rationale.md new file mode 100644 index 000000000..462129e9c --- /dev/null +++ b/meson/docs/markdown/Design-rationale.md @@ -0,0 +1,261 @@ +--- +title: Design rationale +... + +This is the original design rationale for Meson. The syntax it +describes does not match the released version +== + +A software developer's most important tool is the editor. If you talk +to coders about the editors they use, you are usually met with massive +enthusiasm and praise. You will hear how Emacs is the greatest thing +ever or how vi is so elegant or how Eclipse's integration features +make you so much more productive. You can sense the enthusiasm and +affection that the people feel towards these programs. + +The second most important tool, even more important than the compiler, +is the build system. + +Those are pretty much universally despised. + +The most positive statement on build systems you can usually get (and +it might require some coaxing) is something along the lines of *well, +it's a terrible system, but all other options are even worse*. It is +easy to see why this is the case. For starters, commonly used free +build systems have obtuse syntaxes. They use for the most part global +variables that are set in random locations so you can never really be +sure what a given line of code does. They do strange and unpredictable +things at every turn. + +Let's illustrate this with a simple example. Suppose we want to run a +program built with GNU Autotools under GDB. The instinctive thing to +do is to just run `gdb programname`. The problem is that this may or +may not work. In some cases the executable file is a binary whereas at +other times it is a wrapper shell script that invokes the real binary +which resides in a hidden subdirectory. GDB invocation fails if the +binary is a script but succeeds if it is not. The user has to remember +the type of each one of his executables (which is an implementation +detail of the build system) just to be able to debug them. Several +other such pain points can be found in [this blog +post](http://voices.canonical.com/jussi.pakkanen/2011/09/13/autotools/). + +Given these idiosyncrasies it is no wonder that most people don't want +to have anything to do with build systems. They'll just copy-paste +code that works (somewhat) in one place to another and hope for the +best. They actively go out of their way not to understand the system +because the mere thought of it is repulsive. Doing this also provides +a kind of inverse job security. If you don't know tool X, there's less +chance of finding yourself responsible for its use in your +organisation. Instead you get to work on more enjoyable things. + +This leads to a vicious circle. Since people avoid the tools and don't +want to deal with them, very few work on improving them. The result is +apathy and stagnation. + +Can we do better? +-- + +At its core, building C and C++ code is not a terribly difficult +task. In fact, writing a text editor is a lot more complicated and +takes more effort. Yet we have lots of very high quality editors but +only few build systems with questionable quality and usability. + +So, in the grand tradition of own-itch-scratching, I decided to run a +scientific experiment. The purpose of this experiment was to explore +what would it take to build a "good" build system. What kind of syntax +would suit this problem? What sort of problems would this application +need to solve? What sort of solutions would be the most appropriate? + +To get things started, here is a list of requirements any modern +cross-platform build system needs to provide. + +### 1. Must be simple to use + +One of the great virtues of Python is the fact that it is very +readable. It is easy to see what a given block of code does. It is +concise, clear and easy to understand. The proposed build system must +be syntactically and semantically clean. Side effects, global state +and interrelations must be kept at a minimum or, if possible, +eliminated entirely. + +### 2. Must do the right thing by default + +Most builds are done by developers working on the code. Therefore the +defaults must be tailored towards that use case. As an example the +system shall build objects without optimization and with debug +information. It shall make binaries that can be run directly from the +build directory without linker tricks, shell scripts or magic +environment variables. + +### 3. Must enforce established best practices + +There really is no reason to compile source code without the +equivalent of `-Wall`. So enable it by default. A different kind of +best practice is the total separation of source and build +directories. All build artifacts must be stored in the build +directory. Writing stray files in the source directory is not +permitted under any circumstances. + +### 4. Must have native support for platforms that are in common use + +A lot of free software projects can be used on non-free platforms such +as Windows or OSX. The system must provide native support for the +tools of choice on those platforms. In practice this means native +support for Visual Studio and XCode. Having said IDEs invoke external +builder binaries does not count as native support. + +### 5. Must not add complexity due to obsolete platforms + +Work on this build system started during the Christmas holidays of 2012. +This provides a natural hard cutoff line of 2012/12/24. Any +platform, tool or library that was not in active use at that time is +explicitly not supported. These include Unixes such as IRIX, SunOS, +OSF-1, Ubuntu versions older than 12/10, GCC versions older than 4.7 +and so on. If these old versions happen to work, great. If they don't, +not a single line of code will be added to the system to work around +their bugs. + +### 6. Must be fast + +Running the configuration step on a moderate sized project must not +take more than five seconds. Running the compile command on a fully up +to date tree of 1000 source files must not take more than 0.1 seconds. + +### 7. Must provide easy to use support for modern sw development features + +An example is precompiled headers. Currently no free software build +system provides native support for them. Other examples could include +easy integration of Valgrind and unit tests, test coverage reporting +and so on. + +### 8. Must allow override of default values + +Sometimes you just have to compile files with only given compiler +flags and no others, or install files in weird places. The system must +allow the user to do this if he really wants to. + +Overview of the solution +-- + +Going over these requirements it becomes quite apparent that the only +viable approach is roughly the same as taken by CMake: having a domain +specific language to declare the build system. Out of this declaration +a configuration is generated for the backend build system. This can be +a Makefile, Visual Studio or XCode project or anything else. + +The difference between the proposed DSL and existing ones is that the +new one is declarative. It also tries to work on a higher level of +abstraction than existing systems. As an example, using external +libraries in current build systems means manually extracting and +passing around compiler flags and linker flags. In the proposed system +the user just declares that a given build target uses a given external +dependency. The build system then takes care of passing all flags and +settings to their proper locations. This means that the user can focus +on his own code rather than marshalling command line arguments from +one place to another. + +A DSL is more work than the approach taken by SCons, which is to +provide the system as a Python library. However it allows us to make +the syntax more expressive and prevent certain types of bugs by +e.g. making certain objects truly immutable. The end result is again +the same: less work for the user. + +The backend for Unix requires a bit more thought. The default choice +would be Make. However it is extremely slow. It is not uncommon on +large code bases for Make to take several minutes just to determine +that nothing needs to be done. Instead of Make we use +[Ninja](https://ninja-build.org/), which is extremely fast. The +backend code is abstracted away from the core, so other backends can +be added with relatively little effort. + +Sample code +-- + +Enough design talk, let's get to the code. Before looking at the +examples we would like to emphasize that this is not in any way the +final code. It is proof of concept code that works in the system as it +currently exists (February 2013), but may change at any time. + +Let's start simple. Here is the code to compile a single executable +binary. + +```meson +project('compile one', 'c') +executable('program', 'prog.c') +``` + +This is about as simple as one can get. First you declare the project +name and the languages it uses. Then you specify the binary to build +and its sources. The build system will do all the rest. It will add +proper suffixes (e.g. '.exe' on Windows), set the default compiler +flags and so on. + +Usually programs have more than one source file. Listing them all in +the function call can become unwieldy. That is why the system supports +keyword arguments. They look like this. + +```meson +project('compile several', 'c') +sourcelist = ['main.c', 'file1.c', 'file2.c', 'file3.c'] +executable('program', sources : sourcelist) +``` + +External dependencies are simple to use. + +```meson +project('external lib', 'c') +libdep = find_dep('extlibrary', required : true) +sourcelist = ['main.c', 'file1.c', 'file2.c', 'file3.c'] +executable('program', sources : sourcelist, dep : libdep) +``` + +In other build systems you have to manually add the compile and link +flags from external dependencies to targets. In this system you just +declare that extlibrary is mandatory and that the generated program +uses that. The build system does all the plumbing for you. + +Here's a slightly more complicated definition. It should still be +understandable. + +```meson +project('build library', 'c') +foolib = shared_library('foobar', sources : 'foobar.c',\ +install : true) +exe = executable('testfoobar', 'tester.c', link : foolib) +add_test('test library', exe) +``` + +First we build a shared library named foobar. It is marked +installable, so running `meson install` installs it to the library +directory (the system knows which one so the user does not have to +care). Then we build a test executable which is linked against the +library. It will not be installed, but instead it is added to the list +of unit tests, which can be run with the command `meson test`. + +Above we mentioned precompiled headers as a feature not supported by +other build systems. Here's how you would use them. + +```meson +project('pch demo', 'cxx') +executable('myapp', 'myapp.cpp', pch : 'pch/myapp.hh') +``` + +The main reason other build systems can not provide pch support this +easily is because they don't enforce certain best practices. Due to +the way include paths work, it is impossible to provide pch support +that always works with both in-source and out-of-source +builds. Mandating separate build and source directories makes this and +many other problems a lot easier. + +Get the code +-- + +The code for this experiment can be found at [the Meson +repository](https://sourceforge.net/p/meson/code/). It should be noted +that it is not a build system. It is only a proposal for one. It does +not work reliably yet. You probably should not use it as the build +system of your project. + +All that said I hope that this experiment will eventually turn into a +full blown build system. For that I need your help. Comments and +especially patches are more than welcome. diff --git a/meson/docs/markdown/Disabler.md b/meson/docs/markdown/Disabler.md new file mode 100644 index 000000000..4aed7ad65 --- /dev/null +++ b/meson/docs/markdown/Disabler.md @@ -0,0 +1,68 @@ +--- +short-description: Disabling options +... + +# Disabling parts of the build + +*This feature is available since version 0.44.0.* + +The following is a common fragment found in many projects: + +```meson +dep = dependency('foo') + +# In some different directory + +lib = shared_library('mylib', 'mylib.c', + dependencies : dep) + +# And ín a third directory + +exe = executable('mytest', 'mytest.c', + link_with : lib) +test('mytest', exe) +``` + +This works fine but gets a bit inflexible when you want to make this +part of the build optional. Basically it reduces to adding `if/else` +statements around all target invocations. Meson provides a simpler way +of achieving the same with a disabler object. + +A disabler object is created with the `disabler` function: + +```meson +d = disabler() +``` + +The only thing you can do to a disabler object is to ask if it has +been found: + +```meson +f = d.found() # returns false +``` + +Any other statement that uses a disabler object will immediately +return a disabler. For example assuming that `d` contains a disabler +object then + +```meson +d2 = some_func(d) # value of d2 will be disabler +d3 = true or d2 # value of d3 will be true because of short-circuiting +d4 = false or d2 # value of d4 will be disabler +if d # neither branch is evaluated +``` + +Thus to disable every target that depends on the dependency given +above, you can do something like this: + +```meson +if use_foo_feature + d = dependency('foo') +else + d = disabler() +endif +``` + +This concentrates the handling of this option in one place and other +build definition files do not need to be sprinkled with `if` +statements. diff --git a/meson/docs/markdown/Dlang-module.md b/meson/docs/markdown/Dlang-module.md new file mode 100644 index 000000000..915f3a79e --- /dev/null +++ b/meson/docs/markdown/Dlang-module.md @@ -0,0 +1,44 @@ +# Dlang module + +This module provides tools related to the D programming language. + +## Usage + +To use this module, just do: **`dlang = import('dlang')`**. +You can, of course, replace the name `dlang` with anything else. + +The module only exposes one function, `generate_dub_file`, used to +automatically generate Dub configuration files. + +### generate_dub_file() +This method only has two required arguments, the project name and the +source folder. You can pass other arguments with additional keywords, +they will be automatically translated to json and added to the +`dub.json` file. + +**Structure** +```meson +generate_dub_file("project name", "source/folder", key: "value" ...) +``` + +**Example** +```meson +dlang = import('dlang') +dlang.generate_dub_file(meson.project_name().to_lower(), meson.source_root(), + authors: 'Meson Team', + description: 'Test executable', + copyright: 'Copyright © 2018, Meson Team', + license: 'MIT', + sourceFiles: 'test.d', + targetType: 'executable', + dependencies: my_dep +) +``` + +You can manually edit a Meson generated `dub.json` file or provide a +initial one. The module will only update the values specified in +`generate_dub_file()`. + +Although not required, you will need to have a `description` and +`license` if you want to publish the package in the [D package +registry](https://code.dlang.org/). diff --git a/meson/docs/markdown/External-Project-module.md b/meson/docs/markdown/External-Project-module.md new file mode 100644 index 000000000..866564ea6 --- /dev/null +++ b/meson/docs/markdown/External-Project-module.md @@ -0,0 +1,128 @@ +# External Project module + +**Note**: the functionality of this module is governed by [Meson's + rules on mixing build systems](Mixing-build-systems.md). + +*This is an experimental module, API could change.* + +This module allows building code that uses build systems other than +Meson. This module is intended to be used to build Autotools +subprojects as fallback if the dependency couldn't be found on the +system (e.g. too old distro version). + +The project will be compiled out-of-tree inside Meson's build +directory. The project will also be installed inside Meson's build +directory using make's +[`DESTDIR`](https://www.gnu.org/prep/standards/html_node/DESTDIR.html) +feature. During project installation step, that DESTDIR will be copied +verbatim into the desired location. + +External subprojects can use libraries built by Meson (main project, +or other subprojects) using pkg-config, thanks to `*-uninstalled.pc` +files generated by [`pkg.generate()`](Pkgconfig-module.md). + +External build system requirements: + +- Must support out-of-tree build. The configure script will be invoked with the + current workdir inside Meson's build directory and not subproject's top source + directory. +- Configure script must generate a `Makefile` in the current workdir. +- Configure script must take common directories like prefix, libdir, etc, as + command line arguments. +- Configure script must support common environment variable like CFLAGS, CC, etc. +- Compilation step must detect when a reconfigure is needed, and do it + transparently. + +Known limitations: + +- Executables from external projects cannot be used uninstalled, because they + would need its libraries to be installed in the final location. This is why + there is no `find_program()` method. +- The configure script must generate a `Makefile`, other build systems are not + yet supported. +- When cross compiling, if `PKG_CONFIG_SYSROOT_DIR` is set in environment or + `sys_root` in the cross file properties, the external subproject will not be + able to find dependencies built by Meson using pkg-config. The reason is + pkg-config and pkgconf both prepend the sysroot path to `-I` and `-L` arguments + from `-uninstalled.pc` files. This is arguably a bug that could be fixed in + future version of pkg-config/pkgconf. + +*Added 0.56.0* + +## Functions + +### `add_project()` + +This function should be called at the root directory of a project +using another build system. Usually in a `meson.build` file placed in +the top directory of a subproject, but could be also in any subdir. + +Its first positional argument is the name of the configure script to +be executed (e.g. `configure`), that file must be in the current +directory and executable. Note that if a bootstrap script is required +(e.g. `autogen.sh` when building from git instead of tarball), it can +be done using `run_command()` before calling `add_project()` method. + +Keyword arguments: + +- `configure_options`: An array of strings to be passed as arguments to the + configure script. Some special tags will be replaced by Meson before passing + them to the configure script: `@PREFIX@`, `@LIBDIR@` and `@INCLUDEDIR@`. + Note that `libdir` and `includedir` paths are relative to `prefix` in Meson + but some configure scripts requires absolute path, in that case they can be + passed as `'--libdir=@PREFIX@/@LIBDIR@'`. *Since 0.57.0* default arguments are + added in case some tags are not found in `configure_options`: + `'--prefix=@PREFIX@'`, `'--libdir=@PREFIX@/@LIBDIR@'`, and + `'--includedir=@PREFIX@/@INCLUDEDIR@'`. It was previously considered a fatal + error to not specify them. +- `cross_configure_options`: Extra options appended to `configure_options` only + when cross compiling. special tag `@HOST@` will be replaced by + `'{}-{}-{}'.format(host_machine.cpu_family(), build_machine.system(), host_machine.system()`. + If omitted it defaults to `['--host=@HOST@']`. +- `verbose`: If set to `true` the output of sub-commands ran to configure, build + and install the project will be printed onto Meson's stdout. +- `env` : environment variables to set, such as `['NAME1=value1', 'NAME2=value2']`, + a dictionary, or an [`environment()` object](Reference-manual.md#environment-object). + +Returns an [`ExternalProject`](#ExternalProject_object) object + +## `ExternalProject` object + +### Methods + +#### `dependency(libname)` + +Return a dependency object that can be used to build targets against a library +from the external project. + +Keyword arguments: +- `subdir` path relative to `includedir` to be added to the header search path. + +## Example `meson.build` file for a subproject + +```meson +project('My Autotools Project', 'c', + meson_version : '>=0.56.0', +) + +mod = import('unstable_external_project') + +p = mod.add_project('configure', + configure_options : ['--prefix=@PREFIX@', + '--libdir=@LIBDIR@', + '--incdir=@INCLUDEDIR@', + '--enable-foo', + ], +) + +mylib_dep = p.dependency('mylib') +``` + +## Using wrap file + +Most of the time the project will be built as a subproject, and +fetched using a `.wrap` file. In that case the simple `meson.build` +file needed to build the subproject can be provided by adding +`patch_directory=mysubproject` line in the wrap file, and place the +build definition file at +`subprojects/packagefiles/mysubproject/meson.build`. diff --git a/meson/docs/markdown/External-commands.md b/meson/docs/markdown/External-commands.md new file mode 100644 index 000000000..be9d171b6 --- /dev/null +++ b/meson/docs/markdown/External-commands.md @@ -0,0 +1,52 @@ +--- +short-description: Running external commands +... + +# External commands + +As a part of the software configuration, you may want to get extra +data by running external commands. The basic syntax is the following. + +```meson +r = run_command('command', 'arg1', 'arg2', 'arg3') +if r.returncode() != 0 + # it failed +endif +output = r.stdout().strip() +errortxt = r.stderr().strip() +``` + +Since 0.52.0, you can pass the command environment as a dictionary: + +```meson +run_command('command', 'arg1', 'arg2', env: {'FOO': 'bar'}) +``` + +Since 0.50.0, you can also pass the command +[`environment`](Reference-manual.md#environment-object) object: + +```meson +env = environment() +env.set('FOO', 'bar') +run_command('command', 'arg1', 'arg2', env: env) +``` + +The `run_command` function returns an object that can be queried for +return value and text written to stdout and stderr. The `strip` method +call is used to strip trailing and leading whitespace from strings. +Usually output from command line programs ends in a newline, which is +unwanted in string variables. The first argument can be either a +string or an executable you have detected earlier with `find_program`. + +Meson will autodetect scripts with a shebang line and run them with +the executable/interpreter specified in it both on Windows and on +Unixes. + +Note that you can not pass your command line as a single string. That +is, calling `run_command('do_something foo bar')` will not work. You +must either split up the string into separate arguments or pass the +split command as an array. It should also be noted that Meson will not +pass the command to the shell, so any command lines that try to use +things such as environment variables, backticks or pipelines will not +work. If you require shell semantics, write your command into a script +file and call that with `run_command`. diff --git a/meson/docs/markdown/FAQ.md b/meson/docs/markdown/FAQ.md new file mode 100644 index 000000000..0ed731e51 --- /dev/null +++ b/meson/docs/markdown/FAQ.md @@ -0,0 +1,631 @@ +--- +title: FAQ +... +# Meson Frequently Asked Questions + +See also [How do I do X in Meson](howtox.md). + +## Why is it called Meson? + +When the name was originally chosen, there were two main limitations: +there must not exist either a Debian package or a Sourceforge project +of the given name. This ruled out tens of potential project names. At +some point the name Gluon was considered. Gluons are elementary +particles that hold protons and neutrons together, much like a build +system's job is to take pieces of source code and a compiler and bind +them to a complete whole. + +Unfortunately this name was taken, too. Then the rest of subatomic +particles were examined and Meson was found to be available. + +## What is the correct way to use threads (such as pthreads)? + +```meson +thread_dep = dependency('threads') +``` + +This will set up everything on your behalf. People coming from +Autotools or CMake want to do this by looking for `libpthread.so` +manually. Don't do that, it has tricky corner cases especially when +cross compiling. + +## How to use Meson on a host where it is not available in system packages? + +Starting from version 0.29.0, Meson is available from the [Python +Package Index](https://pypi.python.org/pypi/meson/), so installing it +simply a matter of running this command: + +```console +$ pip3 install <your options here> meson +``` + +If you don't have access to PyPI, that is not a problem either. Meson +has been designed to be easily runnable from an extracted source +tarball or even a git checkout. First you need to download Meson. Then +use this command to set up you build instead of plain `meson`. + +```console +$ /path/to/meson.py <options> +``` + +After this you don't have to care about invoking Meson any more. It +remembers where it was originally invoked from and calls itself +appropriately. As a user the only thing you need to do is to `cd` into +your build directory and invoke `meson compile`. + +## Why can't I specify target files with a wildcard? + +Instead of specifying files explicitly, people seem to want to do this: + +```meson +executable('myprog', sources : '*.cpp') # This does NOT work! +``` + +Meson does not support this syntax and the reason for this is simple. +This can not be made both reliable and fast. By reliable we mean that +if the user adds a new source file to the subdirectory, Meson should +detect that and make it part of the build automatically. + +One of the main requirements of Meson is that it must be fast. This +means that a no-op build in a tree of 10 000 source files must take no +more than a fraction of a second. This is only possible because Meson +knows the exact list of files to check. If any target is specified as +a wildcard glob, this is no longer possible. Meson would need to +re-evaluate the glob every time and compare the list of files produced +against the previous list. This means inspecting the entire source +tree (because the glob pattern could be `src/\*/\*/\*/\*.cpp` or +something like that). This is impossible to do efficiently. + +The main backend of Meson is Ninja, which does not support wildcard +matches either, and for the same reasons. + +Because of this, all source files must be specified explicitly. + +## But I really want to use wildcards! + +If the tradeoff between reliability and convenience is acceptable to +you, then Meson gives you all the tools necessary to do wildcard +globbing. You are allowed to run arbitrary commands during +configuration. First you need to write a script that locates the files +to compile. Here's a simple shell script that writes all `.c` files in +the current directory, one per line. + + +```bash +#!/bin/sh + +for i in *.c; do + echo $i +done +``` + +Then you need to run this script in your Meson file, convert the +output into a string array and use the result in a target. + +```meson +c = run_command('grabber.sh') +sources = c.stdout().strip().split('\n') +e = executable('prog', sources) +``` + +The script can be any executable, so it can be written in shell, +Python, Lua, Perl or whatever you wish. + +As mentioned above, the tradeoff is that just adding new files to the +source directory does *not* add them to the build automatically. To +add them you need to tell Meson to reinitialize itself. The simplest +way is to touch the `meson.build` file in your source root. Then Meson +will reconfigure itself next time the build command is run. Advanced +users can even write a small background script that utilizes a +filesystem event queue, such as +[inotify](https://en.wikipedia.org/wiki/Inotify), to do this +automatically. + +## Should I use `subdir` or `subproject`? + +The answer is almost always `subdir`. Subproject exists for a very +specific use case: embedding external dependencies into your build +process. As an example, suppose we are writing a game and wish to use +SDL. Let us further suppose that SDL comes with a Meson build +definition. Let us suppose even further that we don't want to use +prebuilt binaries but want to compile SDL for ourselves. + +In this case you would use `subproject`. The way to do it would be to +grab the source code of SDL and put it inside your own source +tree. Then you would do `sdl = subproject('sdl')`, which would cause +Meson to build SDL as part of your build and would then allow you to +link against it or do whatever else you may prefer. + +For every other use you would use `subdir`. As an example, if you +wanted to build a shared library in one dir and link tests against it +in another dir, you would do something like this: + +```meson +project('simple', 'c') +subdir('src') # library is built here +subdir('tests') # test binaries would link against the library here +``` + +## Why is there not a Make backend? + +Because Make is slow. This is not an implementation issue, Make simply +can not be made fast. For further info we recommend you read [this +post](http://neugierig.org/software/chromium/notes/2011/02/ninja.html) +by Evan Martin, the author of Ninja. Makefiles also have a syntax that +is very unpleasant to write which makes them a big maintenance burden. + +The only reason why one would use Make instead of Ninja is working on +a platform that does not have a Ninja port. Even in this case it is an +order of magnitude less work to port Ninja than it is to write a Make +backend for Meson. + +Just use Ninja, you'll be happier that way. I guarantee it. + +## Why is Meson not just a Python module so I could code my build setup in Python? + +A related question to this is *Why is Meson's configuration language +not Turing-complete?* + +There are many good reasons for this, most of which are summarized on +this web page: [Against The Use Of Programming Languages in +Configuration Files](https://taint.org/2011/02/18/001527a.html). + +In addition to those reasons, not exposing Python or any other "real" +programming language makes it possible to port Meson's implementation +to a different language. This might become necessary if, for example, +Python turns out to be a performance bottleneck. This is an actual +problem that has caused complications for GNU Autotools and SCons. + +## How do I do the equivalent of Libtools export-symbol and export-regex? + +Either by using [GCC symbol +visibility](https://gcc.gnu.org/wiki/Visibility) or by writing a +[linker +script](https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_mono/ld.html). This +has the added benefit that your symbol definitions are in a standalone +file instead of being buried inside your build definitions. An example +can be found +[here](https://github.com/jpakkane/meson/tree/master/test%20cases/linuxlike/3%20linker%20script). + +## My project works fine on Linux and MinGW but fails to link with MSVC due to a missing .lib file (fatal error LNK1181). Why? + +With GCC, all symbols on shared libraries are exported automatically +unless you specify otherwise. With MSVC no symbols are exported by +default. If your shared library exports no symbols, MSVC will silently +not produce an import library file leading to failures. The solution +is to add symbol visibility definitions [as specified in GCC +wiki](https://gcc.gnu.org/wiki/Visibility). + +## I added some compiler flags and now the build fails with weird errors. What is happening? + +You probably did the equivalent to this: + +```meson +executable('foobar', ... + c_args : '-some_arg -other_arg') +``` + +Meson is *explicit*. In this particular case it will **not** +automatically split your strings at whitespaces, instead it will take +it as is and work extra hard to pass it to the compiler unchanged, +including quoting it properly over shell invocations. This is +mandatory to make e.g. files with spaces in them work flawlessly. To +pass multiple command line arguments, you need to explicitly put them +in an array like this: + +```meson +executable('foobar', ... + c_args : ['-some_arg', '-other_arg']) +``` + +## Why are changes to default project options ignored? + +You probably had a project that looked something like this: + +```meson +project('foobar', 'cpp') +``` + +This defaults to `c++11` on GCC compilers. Suppose you want to use +`c++14` instead, so you change the definition to this: + +```meson +project('foobar', 'cpp', default_options : ['cpp_std=c++14']) +``` + +But when you recompile, it still uses `c++11`. The reason for this is +that default options are only looked at when you are setting up a +build directory for the very first time. After that the setting is +considered to have a value and thus the default value is ignored. To +change an existing build dir to `c++14`, either reconfigure your build +dir with `meson configure` or delete the build dir and recreate it +from scratch. + +The reason we don't automatically change the option value when the +default is changed is that it is impossible to know to do that +reliably. The actual question that we need to solve is "if the +option's value is foo and the default value is bar, should we change +the option value to bar also". There are many choices: + + - if the user has changed the value themselves from the default, then + we must not change it back + + - if the user has not changed the value, but changes the default + value, then this section's premise would seem to indicate that the + value should be changed + + - suppose the user changes the value from the default to foo, then + back to bar and then changes the default value to bar, the correct + step to take is ambiguous by itself + +In order to solve the latter question we would need to remember not +only the current and old value, but also all the times the user has +changed the value and from which value to which other value. Since +people don't remember their own actions that far back, toggling +between states based on long history would be confusing. + +Because of this we do the simple and understandable thing: default +values are only defaults and will never affect the value of an option +once set. + +## Does wrap download sources behind my back? + +It does not. In order for Meson to download anything from the net +while building, two conditions must be met. + +First of all there needs to be a `.wrap` file with a download URL in +the `subprojects` directory. If one does not exist, Meson will not +download anything. + +The second requirement is that there needs to be an explicit +subproject invocation in your `meson.build` files. Either +`subproject('foobar')` or `dependency('foobar', fallback : ['foobar', +'foo_dep'])`. If these declarations either are not in any build file +or they are not called (due to e.g. `if/else`) then nothing is +downloaded. + +If this is not sufficient for you, starting from release 0.40.0 Meson +has a option called `wrap-mode` which can be used to disable wrap +downloads altogether with `--wrap-mode=nodownload`. You can also +disable dependency fallbacks altogether with `--wrap-mode=nofallback`, +which also implies the `nodownload` option. + +If on the other hand, you want Meson to always use the fallback +for dependencies, even when an external dependency exists and could +satisfy the version requirements, for example in order to make +sure your project builds when fallbacks are used, you can use +`--wrap-mode=forcefallback` since 0.46.0. + +## Why is Meson implemented in Python rather than [programming language X]? + +Because build systems are special in ways normal applications aren't. + +Perhaps the biggest limitation is that because Meson is used to build +software at the very lowest levels of the OS, it is part of the core +bootstrap for new systems. Whenever support for a new CPU architecture +is added, Meson must run on the system before software using it can be +compiled natively. This requirement adds two hard limitations. + +The first one is that Meson must have the minimal amount of +dependencies, because they must all be built during the bootstrap to +get Meson to work. + +The second is that Meson must support all CPU architectures, both +existing and future ones. As an example many new programming languages +have only an LLVM based compiler available. LLVM has limited CPU +support compared to, say, GCC, and thus bootstrapping Meson on such +platforms would first require adding new processor support to +LLVM. This is in most cases unfeasible. + +A further limitation is that we want developers on as many platforms +as possible to submit to Meson development using the default tools +provided by their operating system. In practice what this means is +that Windows developers should be able to contribute using nothing but +Visual Studio. + +At the time of writing (April 2018) there are only three languages +that could fulfill these requirements: + + - C + - C++ + - Python + +Out of these we have chosen Python because it is the best fit for our +needs. + +## I have proprietary compiler toolchain X that does not work with Meson, how can I make it work? + +Meson needs to know several details about each compiler in order to +compile code with it. These include things such as which compiler +flags to use for each option and how to detect the compiler from its +output. This information can not be input via a configuration file, +instead it requires changes to Meson's source code that need to be +submitted to Meson master repository. In theory you can run your own +forked version with custom patches, but that's not good use of your +time. Please submit the code upstream so everyone can use the +toolchain. + +The steps for adding a new compiler for an existing language are +roughly the following. For simplicity we're going to assume a C +compiler. + +- Create a new class with a proper name in + `mesonbuild/compilers/c.py`. Look at the methods that other + compilers for the same language have and duplicate what they do. + +- If the compiler can only be used for cross compilation, make sure to + flag it as such (see existing compiler classes for examples). + +- Add detection logic to `mesonbuild/environment.py`, look for a + method called `detect_c_compiler`. + +- Run the test suite and fix issues until the tests pass. + +- Submit a pull request, add the result of the test suite to your MR + (linking an existing page is fine). + +- If the compiler is freely available, consider adding it to the CI + system. + +## Why does building my project with MSVC output static libraries called `libfoo.a`? + +The naming convention for static libraries on Windows is usually +`foo.lib`. Unfortunately, import libraries are also called `foo.lib`. + +This causes filename collisions with the default library type where we +build both shared and static libraries, and also causes collisions +during installation since all libraries are installed to the same +directory by default. + +To resolve this, we decided to default to creating static libraries of +the form `libfoo.a` when building with MSVC. This has the following +advantages: + +1. Filename collisions are completely avoided. +1. The format for MSVC static libraries is `ar`, which is the same as the GNU + static library format, so using this extension is semantically correct. +1. The static library filename format is now the same on all platforms and with + all toolchains. +1. Both Clang and GNU compilers can search for `libfoo.a` when specifying + a library as `-lfoo`. This does not work for alternative naming schemes for + static libraries such as `libfoo.lib`. +1. Since `-lfoo` works out of the box, pkgconfig files will work correctly for + projects built with both MSVC, GCC, and Clang on Windows. +1. MSVC does not have arguments to search for library filenames, and [it does + not care what the extension is](https://docs.microsoft.com/en-us/cpp/build/reference/link-input-files?view=vs-2019), + so specifying `libfoo.a` instead of `foo.lib` does not change the workflow, + and is an improvement since it's less ambiguous. + +If, for some reason, you really need your project to output static +libraries of the form `foo.lib` when building with MSVC, you can set +the +[`name_prefix:`](https://mesonbuild.com/Reference-manual.html#library) +kwarg to `''` and the +[`name_suffix:`](https://mesonbuild.com/Reference-manual.html#library) +kwarg to `'lib'`. To get the default behaviour for each, you can +either not specify the kwarg, or pass `[]` (an empty array) to it. + +## Do I need to add my headers to the sources list like in Autotools? + +Autotools requires you to add private and public headers to the sources list so +that it knows what files to include in the tarball generated by `make dist`. +Meson's `dist` command simply gathers everything committed to your git/hg +repository and adds it to the tarball, so adding headers to the sources list is +pointless. + +Meson uses Ninja which uses compiler dependency information to automatically +figure out dependencies between C sources and headers, so it will rebuild +things correctly when a header changes. + +The only exception to this are generated headers, for which you must [declare +dependencies correctly](#how-do-i-tell-meson-that-my-sources-use-generated-headers). + +If, for whatever reason, you do add non-generated headers to the sources list +of a target, Meson will simply ignore them. + +## How do I tell Meson that my sources use generated headers? + +Let's say you use a [`custom_target()`](https://mesonbuild.com/Reference-manual.html#custom_target) +to generate the headers, and then `#include` them in your C code. Here's how +you ensure that Meson generates the headers before trying to compile any +sources in the build target: + +```meson +libfoo_gen_headers = custom_target('gen-headers', ..., output: 'foo-gen.h') +libfoo_sources = files('foo-utils.c', 'foo-lib.c') +# Add generated headers to the list of sources for the build target +libfoo = library('foo', sources: [libfoo_sources + libfoo_gen_headers]) +``` + +Now let's say you have a new target that links to `libfoo`: + +```meson +libbar_sources = files('bar-lib.c') +libbar = library('bar', sources: libbar_sources, link_with: libfoo) +``` + +This adds a **link-time** dependency between the two targets, but note that the +sources of the targets have **no compile-time** dependencies and can be built +in any order; which improves parallelism and speeds up builds. + +If the sources in `libbar` *also* use `foo-gen.h`, that's a *compile-time* +dependency, and you'll have to add `libfoo_gen_headers` to `sources:` for +`libbar` too: + +```meson +libbar_sources = files('bar-lib.c') +libbar = library('bar', sources: libbar_sources + libfoo_gen_headers, link_with: libfoo) +``` + +Alternatively, if you have multiple libraries with sources that link to +a library and also use its generated headers, this code is equivalent to above: + +```meson +# Add generated headers to the list of sources for the build target +libfoo = library('foo', sources: libfoo_sources + libfoo_gen_headers) + +# Declare a dependency that will add the generated headers to sources +libfoo_dep = declare_dependency(link_with: libfoo, sources: libfoo_gen_headers) + +... + +libbar = library('bar', sources: libbar_sources, dependencies: libfoo_dep) +``` + +**Note:** You should only add *headers* to `sources:` while declaring +a dependency. If your custom target outputs both sources and headers, you can +use the subscript notation to get only the header(s): + +```meson +libfoo_gen_sources = custom_target('gen-headers', ..., output: ['foo-gen.h', 'foo-gen.c']) +libfoo_gen_headers = libfoo_gen_sources[0] + +# Add static and generated sources to the target +libfoo = library('foo', sources: libfoo_sources + libfoo_gen_sources) + +# Declare a dependency that will add the generated *headers* to sources +libfoo_dep = declare_dependency(link_with: libfoo, sources: libfoo_gen_headers) +... +libbar = library('bar', sources: libbar_sources, dependencies: libfoo_dep) +``` + +A good example of a generator that outputs both sources and headers is +[`gnome.mkenums()`](https://mesonbuild.com/Gnome-module.html#gnomemkenums). + +## How do I disable exceptions and RTTI in my C++ project? + +With the `cpp_eh` and `cpp_rtti` options. A typical invocation would +look like this: + +``` +meson -Dcpp_eh=none -Dcpp_rtti=false <other options> +``` + +The RTTI option is only available since Meson version 0.53.0. + +## Should I check for `buildtype` or individual options like `debug` in my build files? + +This depends highly on what you actually need to happen. The +´buildtype` option is meant do describe the current build's +_intent_. That is, what it will be used for. Individual options are +for determining what the exact state is. This becomes clearer with a +few examples. + +Suppose you have a source file that is known to miscompile when using +`-O3` and requires a workaround. Then you'd write something like this: + +```meson +if get_option('optimization') == '3' + add_project_arguments('-DOPTIMIZATION_WORKAROUND', ...) +endif +``` + +On the other hand if your project has extra logging and sanity checks +that you would like to be enabled during the day to day development +work (which uses the `debug` buildtype), you'd do this instead: + +```meson +if get_option('buildtype') == 'debug' + add_project_arguments('-DENABLE_EXTRA_CHECKS', ...) +endif +``` + +In this way the extra options are automatically used during +development but are not compiled in release builds. Note that (since +Meson 0.57.0) you can set optimization to, say, 2 in your debug builds +if you want to. If you tried to set this flag based on optimization +level, it would fail in this case. + +## How do I use a library before declaring it? + +This is valid (and good) code: +``` +libA = library('libA', 'fileA.cpp', link_with : []) +libB = library('libB', 'fileB.cpp', link_with : [libA]) +``` +But there is currently no way to get something like this to work: +``` +libB = library('libB', 'fileB.cpp', link_with : [libA]) +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. + +## 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. diff --git a/meson/docs/markdown/Feature-autodetection.md b/meson/docs/markdown/Feature-autodetection.md new file mode 100644 index 000000000..4d366d939 --- /dev/null +++ b/meson/docs/markdown/Feature-autodetection.md @@ -0,0 +1,39 @@ +--- +short-description: Auto-detection of features like ccache and code coverage +... + +# Feature autodetection + +Meson is designed for high productivity. It tries to do as many things +automatically as it possibly can. + +Ccache +-- + +[Ccache](https://ccache.dev/) is a cache system designed to make +compiling faster. When you run Meson for the first time for a given +project, it checks if Ccache is installed. If it is, Meson will use it +automatically. + +If you do not wish to use Ccache for some reason, just specify your +compiler with environment variables `CC` and/or `CXX` when first +running Meson (remember that once specified the compiler can not be +changed). Meson will then use the specified compiler without Ccache. + +Coverage +-- + +When doing a code coverage build, Meson will check for existence of +the binaries `gcovr`, `lcov` and `genhtml`. If version 3.3 or higher +of the first is found, targets called *coverage-text*, *coverage-xml* +and *coverage-html* are generated. Alternatively, if the latter two +are found, only the target *coverage-html* is generated. Coverage +reports can then be produced simply by calling e.g. `meson compile +coverage-xml`. As a convenience, a high-level *coverage* target is +also generated which will produce all 3 coverage report types, if +possible. + +Note that generating any of the coverage reports described above +requires the tests (i.e. `meson test`) to finish running so the +information about the functions that are called in the tests can be +gathered for the report. diff --git a/meson/docs/markdown/Fs-module.md b/meson/docs/markdown/Fs-module.md new file mode 100644 index 000000000..663aba41b --- /dev/null +++ b/meson/docs/markdown/Fs-module.md @@ -0,0 +1,217 @@ +# FS (filesystem) module + +This module provides functions to inspect the file system. It is +available starting with version 0.53.0. + +Since 0.59.0, all functions accept `files()` objects if they can do something +useful with them (this excludes `exists`, `is_dir`, `is_file`, `is_absolute` +since a `files()` object is always the absolute path to an existing file). + +## File lookup rules + +Non-absolute paths are looked up relative to the directory where the +current `meson.build` file is. + +If specified, a leading `~` is expanded to the user home directory. +Environment variables are not available as is the rule throughout Meson. +That is, $HOME, %USERPROFILE%, $MKLROOT, etc. have no meaning to the Meson +filesystem module. If needed, pass such variables into Meson via command +line options in `meson_options.txt`, native-file or cross-file. + +Where possible, symlinks and parent directory notation are resolved to an +absolute path. + +### exists + +Takes a single string argument and returns true if an entity with that +name exists on the file system. This can be a file, directory or a +special entry such as a device node. + +### is_dir + +Takes a single string argument and returns true if a directory with +that name exists on the file system. + +### is_file + +Takes a single string argument and returns true if an file with that +name exists on the file system. + +### is_symlink + +Takes a single string or (since 0.59.0) `files()` argument and returns true if +the path pointed to by the string is a symbolic link. + +## File Parameters + +### is_absolute + +*since 0.54.0* + +Return a boolean indicating if the path string or (since 0.59.0) `files()` +specified is absolute, WITHOUT expanding `~`. + +Examples: + +```meson +fs.is_absolute('~') # false + +home = fs.expanduser('~') +fs.is_absolute(home) # true + +fs.is_absolute(home / 'foo') # true, even if ~/foo doesn't exist + +fs.is_absolute('foo/bar') # false, even if ./foo/bar exists +``` + +### hash + +The `fs.hash(filename, hash_algorithm)` method returns a string containing +the hexadecimal `hash_algorithm` digest of a file. +`hash_algorithm` is a string; the available hash algorithms include: +md5, sha1, sha224, sha256, sha384, sha512. + +### size + +The `fs.size(filename)` method returns the size of the file in integer bytes. + +### is_samepath + +The `fs.is_samepath(path1, path2)` returns boolean `true` if both +paths resolve to the same path. For example, suppose path1 is a +symlink and path2 is a relative path. If `path1` can be resolved to +`path2`, then `true` is returned. If `path1` is not resolved to +`path2`, `false` is returned. If `path1` or `path2` do not exist, +`false` is returned. + +Examples: + +```meson +x = 'foo.txt' +y = 'sub/../foo.txt' +z = 'bar.txt' # a symlink pointing to foo.txt +j = 'notafile.txt' # non-existent file + +fs.is_samepath(x, y) # true +fs.is_samepath(x, z) # true +fs.is_samepath(x, j) # false + +p = 'foo/bar' +q = 'foo/bar/baz/..' +r = 'buz' # a symlink pointing to foo/bar +s = 'notapath' # non-existent directory + +fs.is_samepath(p, q) # true +fs.is_samepath(p, r) # true +fs.is_samepath(p, s) # false +``` + +## Filename modification + +The files need not actually exist yet for these path string +manipulation methods. + +### expanduser + +*since 0.54.0* + +A path string with a leading `~` is expanded to the user home +directory + +Examples: + +```meson +fs.expanduser('~') # user home directory + +fs.expanduser('~/foo') # <homedir>/foo +``` + +### as_posix + +*since 0.54.0* + +`fs.as_posix(path)` assumes a Windows path, even if on a Unix-like +system. Thus, all `'\'` or `'\\'` are turned to '/', even if you meant +to escape a character. + +Examples + +```meson +fs.as_posix('\\') == '/' # true +fs.as_posix('\\\\') == '/' # true + +fs.as_posix('foo\\bar/baz') == 'foo/bar/baz' # true +``` + +### replace_suffix + +The `replace_suffix` method is a *string manipulation* convenient for +filename modifications. It allows changing the filename suffix like: + +#### swap suffix + +```meson +original = '/opt/foo.ini' +new = fs.replace_suffix(original, '.txt') # /opt/foo.txt +``` + +#### add suffix + +```meson +original = '/opt/foo' +new = fs.replace_suffix(original, '.txt') # /opt/foo.txt +``` + +#### compound suffix swap + +```meson +original = '/opt/foo.dll.a' +new = fs.replace_suffix(original, '.so') # /opt/foo.dll.so +``` + +#### delete suffix + +```meson +original = '/opt/foo.dll.a' +new = fs.replace_suffix(original, '') # /opt/foo.dll +``` + +### parent + +Returns the parent directory (i.e. dirname). + +```meson +new = fs.parent('foo/bar') # foo +new = fs.parent('foo/bar/baz.dll') # foo/bar +``` + +### name + +Returns the last component of the path (i.e. basename). + +```meson +fs.name('foo/bar/baz.dll.a') # baz.dll.a +``` + +### stem + +*since 0.54.0* + +Returns the last component of the path, dropping the last part of the +suffix + +```meson +fs.stem('foo/bar/baz.dll') # baz +fs.stem('foo/bar/baz.dll.a') # baz.dll +``` + +### read +- `read(path, encoding: 'utf-8')` *(since 0.57.0)*: + return a [string](Syntax.md#strings) with the contents of the given `path`. + If the `encoding` keyword argument is not specified, the file specified by + `path` is assumed to be utf-8 encoded. Binary files are not supported. The + provided paths should be relative to the current `meson.current_source_dir()` + or an absolute path outside the build directory is accepted. If the file + specified by `path` changes, this will trigger Meson to reconfigure the + project. If the file specified by `path` is a `files()` object it + cannot refer to a built file. diff --git a/meson/docs/markdown/Generating-sources.md b/meson/docs/markdown/Generating-sources.md new file mode 100644 index 000000000..c09819f60 --- /dev/null +++ b/meson/docs/markdown/Generating-sources.md @@ -0,0 +1,206 @@ +--- +short-description: Generation of source files before compilation +... + +# Generating sources + +Sometimes source files need to be preprocessed before they are passed +to the actual compiler. As an example you might want build an IDL +compiler and then run some files through that to generate actual +source files. In Meson this is done with +[`generator()`](Reference-manual.md#generator) or +[`custom_target()`](Reference-manual.md#custom_target). + +## Using custom_target() + +Let's say you have a build target that must be built using sources +generated by a compiler. The compiler can either be a built target: + +```meson +mycomp = executable('mycompiler', 'compiler.c') +``` + +Or an external program provided by the system, or script inside the +source tree: + +```meson +mycomp = find_program('mycompiler') +``` + +Custom targets can take zero or more input files and use them to +generate one or more output files. Using a custom target, you can run +this compiler at build time to generate the sources: + +```meson +gen_src = custom_target('gen-output', + input : ['somefile1.c', 'file2.c'], + output : ['out.c', 'out.h'], + command : [mycomp, '@INPUT@', + '--c-out', '@OUTPUT0@', + '--h-out', '@OUTPUT1@']) +``` + +The `@INPUT@` there will be transformed to `'somefile1.c' +'file2.c'`. Just like the output, you can also refer to each input +file individually by index. + +Then you just put that in your program and you're done. + +### Generating headers + +Adding a generated header to a source list will ensure that the header +is generated and that the proper include paths are created for the +target: + +```meson +prog_python = import('python').find_installation('python3') + +foo_c = custom_target( + 'foo.c', + output : 'foo.c', + input : 'my_gen.py', + command : [prog_python, '@INPUT@', '--code', '@OUTPUT@'], +) + +foo_h = custom_target( + 'foo.h', + output : 'foo.h', + input : 'my_gen.py', + command : [prog_python, '@INPUT@', '--header', '@OUTPUT@'], +) + +libfoo = static_library('foo', [foo_c, foo_h]) + +executable('myexe', ['main.c', foo_h], link_with : libfoo) +``` + +Each target that depends on a generated header should add that header +to it's sources, as seen above with `libfoo` and `myexe`. This is +because there is no way for Meson or the backend to know that `myexe` +depends on `foo.h` just because `libfoo` does, it could be a private +header. + +### Generating multiple files at a time + +Sometimes it makes sense for a single generator to create two or more +files at a time, (perhaps a header and source file), Meson has this +case covered as well. `custom_target`s can be indexed like a list to +get each output file separately. The order is the same as the order of +the output argument to `custom_target` + +```meson +prog_python = import('python').find_installation('python3') + +foo_ch = custom_target( + 'foo.[ch]', + output : ['foo.c', 'foo.h'], + input : 'my_gen.py', + command : [prog_python, '@INPUT@', '@OUTPUT@'], +) + +libfoo = static_library('foo', [foo_ch]) + +executable('myexe', ['main.c', foo_ch[1]], link_with : libfoo) +``` + +In this case `libfoo` depends on both `foo.c` and `foo.h` but `myexe` +only depends on `foo.h`, the second output. + +### Using dependencies to manage generated resources + +In some cases it might be easier to use `declare_dependency` to +"bundle" the header and library dependency, especially if there are +many generated headers: + +```meson +idep_foo = declare_dependency( + sources : [foo_h, bar_h], + link_with : [libfoo], +) +``` + +See [dependencies](Dependencies.md#declaring-your-own), and +[reference](Reference-manual.md#declare_dependency) for more +information. + +## Using generator() + +Generators are similar to custom targets, except that we define a +*generator*, which defines how to transform an input file into one or +more output files, and then use that on as many input files as we +want. + +Note that 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 such as for +generating headers to be used by several sources, or data that will be +installed, and so on, use a +[`custom_target()`](Reference-manual.md#custom_target) instead. + + +```meson +gen = generator(mycomp, + output : '@BASENAME@.c', + arguments : ['@INPUT@', '@OUTPUT@']) +``` + +The first argument is the executable file to run. The next file +specifies a name generation rule. It specifies how to build the output +file name for a given input name. `@BASENAME@` is a placeholder for +the input file name without preceding path or suffix (if any). So if +the input file name were `some/path/filename.idl`, then the output +name would be `filename.c`. You can also use `@PLAINNAME@`, which +preserves the suffix which would result in a file called +`filename.idl.c`. The last line specifies the command line arguments +to pass to the executable. `@INPUT@` and `@OUTPUT@` are placeholders +for the input and output files, respectively, and will be +automatically filled in by Meson. If your rule produces multiple +output files and you need to pass them to the command line, append the +location to the output holder like this: `@OUTPUT0@`, `@OUTPUT1@` and +so on. + +With this rule specified we can generate source files and add them to +a target. + +```meson +gen_src = gen.process('input1.idl', 'input2.idl') +executable('program', 'main.c', gen_src) +``` + +Generators can also generate multiple output files with unknown names: + +```meson +gen2 = generator(someprog, + output : ['@BASENAME@.c', '@BASENAME@.h'], + arguments : ['--out_dir=@BUILD_DIR@', '@INPUT@']) +``` + +In this case you can not use the plain `@OUTPUT@` variable, as it +would be ambiguous. This program only needs to know the output +directory, it will generate the file names by itself. + +To make passing different additional arguments to the generator +program at each use possible, you can use the `@EXTRA_ARGS@` string in +the `arguments` list. Note that this placeholder can only be present +as a whole string, and not as a substring. The main reason is that it +represents a list of strings, which may be empty, or contain multiple +elements; and in either case, interpolating it into the middle of a +single string would be troublesome. If there are no extra arguments +passed in from a `process()` invocation, the placeholder is entirely +omitted from the actual list of arguments, so an empty string won't be +passed to the generator program because of this. If there are multiple +elements in `extra_args`, they are inserted into to the actual +argument list as separate elements. + +```meson +gen3 = generator(genprog, + output : '@BASENAME@.cc', + arguments : ['@INPUT@', '@EXTRA_ARGS@', '@OUTPUT@']) +gen3_src1 = gen3.process('input1.y') +gen3_src2 = gen3.process('input2.y', extra_args: '--foo') +gen3_src3 = gen3.process('input3.y', extra_args: ['--foo', '--bar']) +``` diff --git a/meson/docs/markdown/Getting-meson.md b/meson/docs/markdown/Getting-meson.md new file mode 100644 index 000000000..ba3cdf73c --- /dev/null +++ b/meson/docs/markdown/Getting-meson.md @@ -0,0 +1,96 @@ +# Getting Meson + +Meson is implemented in Python 3, and requires 3.6 or newer. If your +operating system provides a package manager, you should install it +with that. For platforms that don't have a package manager, you need +to download it from [Python's home page]. See below for +[platform-specific Python3 quirks](#platformspecific-install-quirks). + +## Downloading Meson + +Meson releases can be downloaded from the [GitHub release page], and +you can run `./meson.py` from inside a release or the git repository +itself without doing anything special. + +On Windows, if you did not install Python with the installer options +that make Python scripts executable, you will have to run `python +/path/to/meson.py`, where `python` is Python 3.6 or newer. + +The newest development code can be obtained directly from [Git], and +we strive to ensure that it will always be working and usable. All +commits go through a pull-request process that runs CI and tests +several platforms. + +## Installing Meson with pip + +Meson is available in the [Python Package Index] and can be installed +with `sudo pip3 install meson` which requires root and will install it +system-wide. + +If you have downloaded a copy of the Meson sources already, you can +install it with `sudo pip3 install path/to/source/root/`. + +Alternatively, you can use `pip3 install --user meson` which will +install it for your user and does not require any special +privileges. This will install the package in `~/.local/`, so you will +have to add `~/.local/bin` to your `PATH`, and `sudo meson install` +will be completely broken since the program will not be available to +root. Only use a user copy of Meson if you do not care about +installing projects as root. + +## Installing Meson and Ninja with the MSI installer + +We provide an MSI installer on the [GitHub release page] that can be +used to install both Meson and Ninja at once for Windows. It also +contains an embedded copy of Python, so scripts that use the [Python +module](Python-module.md) and do not have any external dependencies +will continue to work as expected. + +Please note that this is a new feature, so bug reports are expected +and welcome! + +## Dependencies + +In the most common case, you will need the [Ninja executable] for +using the `ninja` backend, which is the default in Meson. This backend +can be used on all platforms and with all toolchains, including GCC, +Clang, Visual Studio, MinGW, ICC, ARMCC, etc. + +You can use the version provided by your package manager if possible, +otherwise download the binary executable from the [Ninja project's +release page](https://github.com/ninja-build/ninja/releases). + +If you will only use the Visual Studio backend (`--backend=vs`) to +generate Visual Studio solutions on Windows or the XCode backend +(`--backend=xcode`) to generate XCode projects on macOS, you do not +need Ninja. + +# Platform-specific install quirks + +## Windows Python3 quirks + +When installing Python 3, it is highly recommended (but not required) +that you select the installer options as follows: + +![installer step 1](images/py3-install-1.png "Enable 'Add Python 3.6 to PATH' and click 'Customize installation'") +![installer step 2](images/py3-install-2.png "Optional Features: ensure 'pip' is enabled") +![installer step 3](images/py3-install-3.png "Advanced Options: enable 'Install for all users'") + +With this, you will have `python` and `pip` in `PATH`, and you can +install Meson with pip. You will also be able to directly run `meson` +in any shell on Windows instead of having to run `py -3` with the full +path to the `meson.py` script. + +## MSYS2 Python3 quirks + +If you are using MSYS2 on Windows as your development environment, +please make sure that you **do not use** the `msys/python` package to +provide Python 3. Use either `mingw32/mingw-w64-i686-python3` or +`mingw64/mingw-w64-x86_64-python3` depending on which MinGW target you +are building for. + + [GitHub release page]: https://github.com/mesonbuild/meson/releases + [Python Package Index]: https://pypi.python.org/pypi/meson/ + [Git]: https://github.com/mesonbuild/meson + [Python's home page]: https://www.python.org/downloads/ + [Ninja executable]: https://ninja-build.org/ diff --git a/meson/docs/markdown/Getting-meson_ptbr.md b/meson/docs/markdown/Getting-meson_ptbr.md new file mode 100644 index 000000000..f2e2811ec --- /dev/null +++ b/meson/docs/markdown/Getting-meson_ptbr.md @@ -0,0 +1,93 @@ +# Obtendo o Meson + +Meson é implementado em Python 3, e requer a versão 3.6 ou mais nova. +se o seu sistema operacional provê um gerenciador de pacotes, você deve +instalar o Meson com ele. Para plataformas que não tem um gerenciador de +pacotes, você precisa baixa-lo da [página inicial do Python]. Veja abaixo +[peculiaridades do Python3 específicas de plataformas](#platformspecific-install-quirks). + +## Baixando o Meson + +*Releases* do Meson podem ser baixadas da [página de releases do GitHub] +e você pode executar `./meson.py` de dentro do *release* ou do próprio repositório +do git sem fazer nada de especial. + +No Windows, se você não instalar o Python com a opção do instalador que fazem +os *scripts* Python executáveis, você vai ter que executar `python +/path/to/meson.py`, onde `python` é o Python 3.6 ou mais novo. + +O código de desenvolvimento mais recente pode ser obtido diretamente do [Git], +e nós lutamos para garatir que ele vai estar sempre funcionando e usável. Todos +*commits* passam por um processo de *pull-request* que executa CI e testam diversas +plataformas. + +## Instalando o Meson com o pip + +O Meson está disponível no [Indice de Pacotes do Python] e pode ser instalado com +`sudo pip3 install meson` que requer root e vai instala-lo para todo o sistema. + +Se você já baixou uma cópia do código do Meson, você pode instalar com +`sudo pip3 install path/to/source/root/`. + +Como alternativa, você pode usar o `pip3 install --user meson` que vai instalar +o Meson para o seu usuário e não requer nenhum privilégio especial. Esse comando +vai instalar o pacote em `~/.local/`, então você terá que adicionar `~/.local/bin` +para o seu `PATH`, e `sudo meson install` vai estar completamente quebrado já que +o programa não vai estar disponível para o root. Apeas use uma cópia de usuário do Meson +se você não se importa sobre instalar os projetos como root. + +## Instalando o Meson e o Ninja com o instalador MSI + +Nós provemos um instalador MSI na [página de *release* do GitHub] que pode ser usada +para instalar tanto o Meson quanto o Ninja de uma vez para o Windows. O instalador também +contém uma cópia integrada do Python, então scripts que usam o [módulo Python](Python-module.md) +e não tem nenhuma dependência externa vão continuar funcionando como esperado. + +Por favor, note que essa é uma funcionalidade nova, então relatórios de bugs são esperados e bem-vindos! + +## Dependências + +Na maioria dos casos comums, você vai precisar do [executável do Ninja] para usar o *backend* do `ninja`, +que é o padrão no Meson. Esse *backend* pode ser usado em todas plataformas e com todas **toolchains**, incluindo o GCC, +Clang, Visual Studio, MinGW, ICC, ARMCC, etc. + +Você deve usar a versão provida pelo seu gerenciador de pacotes se possível, caso contrário, +baixe o binário executável da [página de *release* do projeto Ninja](https://github.com/ninja-build/ninja/releases). + +Se você apenas usa o *backend* do Visual Studio (`--backend=vs`) para gerar soluções do Visual Studio no Windows ou o +*backend* do XCode (`--backend=xcode`) para gerar projetos no macOS, você não precisa do Ninja. + + + +# Peculiaridades de instalação específicas de plataformas + +## Peculiaridades do Python 3 no Windows + +Quando estiver instalando o Python 3, é altamente recomendável (mas não obrigatório) +que você selecione as opções do instalador como a seguir: + +![passo 1 do instalador](images/py3-install-1.png "Ative 'Add Python 3.6 to PATH' e clique em 'Customize installation'") + +![passo 2 do instalador](images/py3-install-2.png "Funcionalidade Opcional: garanta que 'pip' está ativado") + +![passo 3 do instalador](images/py3-install-3.png "Opções Avançadas: ative 'Instalar para todos usuários'") + +Com isso, você terá o `python` e o `pip` no `PATH`, e você poderá instalar o Meson com o pip. Você também vai poder +executar o comando `meson` em qualquer shell no Windows ao invés de ter que executar `py -3` com o caminho completo para +o *script* `meson.py`. + +## Peculiaridades do Python 3 no MSYS2 + +Se você está usando o MSYS2 no Windows como seu ambiente de desenvolvimento, +por favor se certifique que você não esteja usando o pacote `msys/python` para +fornecer o Python 3. Uso o `mingw32/mingw-w64-i686-python3` ou o +If you are using MSYS2 on Windows as your development environment, +please make sure that you **do not use** the `msys/python` package to +provide Python 3. Use either `mingw32/mingw-w64-i686-python3` or `mingw64/mingw-w64-x86_64-python3` +dependendo de para qual *target* do MinGW você está compilando. + + [página de *release* do GitHub]: https://github.com/mesonbuild/meson/releases + [Indice de Pacotes do Python]: https://pypi.python.org/pypi/meson/ + [Git]: https://github.com/mesonbuild/meson + [página inicial do Python]: https://www.python.org/downloads/ + [executável do Ninja]: https://ninja-build.org/ diff --git a/meson/docs/markdown/Getting-meson_zh.md b/meson/docs/markdown/Getting-meson_zh.md new file mode 100644 index 000000000..4a4cb3431 --- /dev/null +++ b/meson/docs/markdown/Getting-meson_zh.md @@ -0,0 +1,56 @@ +# 获取Meson + +Meson基于Python3运行,要求Python版本3.5以上。 如果你的操作系统提供包管理器, 你应该用包管理器安装meson;如果没有包管理器,你应该在[Python主页]下载合适的Python3。相关请参阅[特殊平台的安装特例](#特殊平台的安装特例). + +## 下载Meson + +Meson发行版可在 [GitHub发行页面]下载, 你可以在release的解压目录或者git仓库目录里直接运行 `./meson.py` ,不需要进行任何特殊操作。 + +在Windows下,如果你安装Python时没有将Python路径添加到环境变量, 那你应该使用`python /path/to/meson.py`命令运行Meson,当然`python` 的版本应该大于3.5。 + +最新的开发版本的源码可以直接通过[Git]获得,我们尽可能保证它总是可以正常使用。所有的提交通过pull-request进行,此过程将运行 CI 并且会在多个平台进行测试。 + +## 使用pip安装Meson + +Meson在[Python包索引]中,可通过`pip3 install meson`命令安装,如果在root环境下,它会在系统范围内安装。 + +相反,你也可以使用 `pip3 install --user meson`命令来为`user`用户单独安装,此过程不需要任何特殊权限. Meson会被安装到`~/.local/`目录下,所以你需要将 `~/.local/bin`添加至你的`PATH`. + +## 使用MSI安装包安装Meson和Ninja + +我们也在[GitHub发行页面]提供MSI安装包,可以同时为Windows安装 Meson和Ninja。 它也包含一份嵌入性的Python拷贝, 所以[Python module](Python-module.md)可以不靠任何外部依赖的情况下正如期望般的正常工作。 + +因为这是新特性,请多留意,如果出现BUG欢迎反馈! + +## 所需依赖 + +最主要的, 你需要 [Ninja可执行程序] 来使用Meson默认的 +`ninja` 后端参数。这个参数可以用于所有平台和工具链包括 GCC, Clang, Visual Studio, MinGW,ICC, ARMCC. + +如果可能,你应该使用包管理器提供的版本,否则的话,你应该 +在[Ninja发行页面]下载可执行二进制文件。(https://github.com/ninja-build/ninja/releases). + +如果你只用Visual Studio后端参数 (`--backend=vs`)来生成Windows上的Visual Studio工程文件或者XCode后端参数 (`--backend=xcode`) 生成macOS上的 +XCode工程文件, 那么你不需要安装Ninja. + +# 特殊平台的安装特例 + +## Windows Python3 + +安装Python3时,强烈推荐以下安装器选项 (非必须,请结合实际) : + +![installer step 1](images/py3-install-1.png "Enable 'Add Python 3.6 to PATH' and click 'Customize installation'") +![installer step 2](images/py3-install-2.png "Optional Features: ensure 'pip' is enabled") +![installer step 3](images/py3-install-3.png "Advanced Options: enable 'Install for all users'") + +完成这个之后, `python` 和`pip`的路径会收录进`PATH`,你可以使用pip安装Meson. 你也可以在Windows任何终端下直接运行`meson`而不是不得不输入`py -3`完整路径去运行 `meson.py`脚本. + +## MSYS2 Python3 + +如果你使用MSYS2作为你的Windows开发环境,请确信你**没有**将 `msys/python` 当作你的默认Python使用. 请使用 `mingw32/mingw-w64-i686-python3` 或者 `mingw64/mingw-w64-x86_64-python3`,这取决于MinGW不同的构建对象. + + [GitHub发行页面]: https://github.com/mesonbuild/meson/releases + [Python包索引]: https://pypi.python.org/pypi/meson/ + [Git]: https://github.com/mesonbuild/meson + [Python主页]: https://www.python.org/downloads/ + [Ninja可执行程序]: https://ninja-build.org/ diff --git a/meson/docs/markdown/Gnome-module.md b/meson/docs/markdown/Gnome-module.md new file mode 100644 index 000000000..2b90e0ceb --- /dev/null +++ b/meson/docs/markdown/Gnome-module.md @@ -0,0 +1,378 @@ +# GNOME module + +This module provides helper tools for build operations needed when +building Gnome/GLib programs. + +**Note**: the compilation commands here might not work properly when + you change the source files. This is a bug in the respective + compilers which do not expose the required dependency + information. This has been reported upstream in [this bug]. Until + this is fixed you need to be careful when changing your source + files. + + [this bug]: https://bugzilla.gnome.org/show_bug.cgi?id=745754 + +## Usage + +To use this module, just do: **`gnome = import('gnome')`**. The +following functions will then be available as methods on the object +with the name `gnome`. You can, of course, replace the name `gnome` +with anything else. + +### gnome.compile_resources() + +This function compiles resources specified in an XML file into code +that can be embedded inside the main binary. Similar a build target it +takes two positional arguments. The first one is the name of the +resource and the second is the XML file containing the resource +definitions. If the name is `foobar`, Meson will generate a header +file called `foobar.h`, which you can then include in your sources. + +* `c_name`: passed to the resource compiler as an argument after + `--c-name` +* `dependencies`: extra targets to depend upon for building +* `export`: (*Added 0.37.0*) if true, export the symbols of the + generated sources +* `extra_args`: extra command line arguments to pass to the resource +* `gresource_bundle`: (*Added 0.37.0*) if true, output a `.gresource` + file instead of source +* `install`: (*Added 0.37.0*) if true, install the gresource file +* `install_dir`: (*Added 0.37.0*) location to install the header or + bundle depending on previous options +* `install_header`: (*Added 0.37.0*) if true, install the header file +* `source_dir`: a list of directories where the resource compiler + should look up the files + +Returns an array containing: `[c_source, header_file]` or +`[gresource_bundle]` + +Example: + +```meson +gnome = import('gnome') + +asresources = gnome.compile_resources( + 'as-resources', 'data/asresources.gresource.xml', + source_dir: 'data', + c_name: 'as' +) + +executable( + meson.project_name(), + asresources, + dependencies: my_deps, + install: true +) +``` + +### gnome.generate_gir() + +Generates GObject introspection data. + +Takes one or more positional arguments: + +Either one or more library objects you want to build gir data for, or a single +executable object. + +There are several keyword arguments. Many of these map directly to the +`g-ir-scanner` tool so see its documentation for more information. + +* `dependencies`: deps to use during introspection scanning +* `extra_args`: command line arguments to pass to gir compiler +* `export_packages`: extra packages the gir file exports +* `sources`: the list of sources to be scanned for gir data +* `nsversion`: namespace version +* `namespace`: the namespace for this gir object which determines + output files +* `identifier_prefix`: the identifier prefix for the gir object, + e.g. `Gtk` +* `includes`: list of gir names to be included, can also be a GirTarget +* `header`: *(Added 0.43.0)* name of main c header to include for the library, e.g. `glib.h` +* `include_directories`: extra include paths to look for gir files +* `install`: if true, install the generated files +* `install_dir_gir`: (*Added 0.35.0*) which directory to install the + gir file into +* `install_dir_typelib`: (*Added 0.35.0*) which directory to install + the typelib file into +* `link_with`: list of libraries to link with +* `symbol_prefix`: the symbol prefix for the gir object, e.g. `gtk`, + (*Since 0.43.0*) an ordered list of multiple prefixes is allowed +* `fatal_warnings`: *Since 0.55.0* turn scanner warnings into fatal errors. + +Returns an array of two elements which are: `[gir_target, +typelib_target]` + +### gnome.genmarshal() + +Generates a marshal file using the `glib-genmarshal` tool. The first +argument is the basename of the output files. + +* `extra_args`: (*Added 0.42.0*) additional command line arguments to + pass +* `install_header`: if true, install the generated header +* `install_dir`: directory to install header to +* `nostdinc`: if true, don't include the standard marshallers from + glib +* `internal`: if true, mark generated sources as internal to + `glib-genmarshal` (*Requires GLib 2.54*) +* `prefix`: the prefix to use for symbols +* `skip_source`: if true, skip source location comments +* `stdinc`: if true, include the standard marshallers from glib +* `sources`: the list of sources to use as inputs +* `valist_marshallers`: if true, generate va_list marshallers + +*Added 0.35.0* + +Returns an array of two elements which are: `[c_source, header_file]` + +### gnome.mkenums() + +Generates enum files for GObject using the `glib-mkenums` tool. The +first argument is the base name of the output files, unless +`c_template` and `h_template` are specified. In this case, the output +files will be the base name of the values passed as templates. + +This method is essentially a wrapper around the `glib-mkenums` tool's +command line API. It is the most featureful method for enum creation. + +Typically you either provide template files or you specify the various +template sections manually as strings. + +Most libraries and applications will be using the same standard +template with only minor tweaks, in which case the +`gnome.mkenums_simple()` convenience method can be used instead. + +Note that if you `#include` the generated header in any of the sources +for a build target, you must add the generated header to the build +target's list of sources to codify the dependency. This is true for +all generated sources, not just `mkenums`. + +* `c_template`: template to use for generating the source +* `comments`: comment passed to the command +* `h_template`: template to use for generating the header +* `identifier_prefix`: prefix to use for the identifiers +* `install_header`: if true, install the generated header +* `install_dir`: directory to install the header +* `sources`: the list of sources to make enums with +* `symbol_prefix`: prefix to use for the symbols +* `eprod`: enum text +* `fhead`: file header +* `fprod`: file text +* `ftail`: file tail +* `vhead`: value text +* `vtail`: value tail + +*Added 0.35.0* + +Returns an array of two elements which are: `[c_source, header_file]` + +### gnome.mkenums_simple() + +Generates enum `.c` and `.h` files for GObject using the +`glib-mkenums` tool with the standard template used by most +GObject-based C libraries. The first argument is the base name of the +output files. + +Note that if you `#include` the generated header in any of the sources +for a build target, you must add the generated header to the build +target's list of sources to codify the dependency. This is true for +all generated sources, not just `mkenums_simple`. + +* `body_prefix`: additional prefix at the top of the body file, + e.g. for extra includes +* `decorator`: optional decorator for the function declarations, + e.g. `GTK_AVAILABLE` or `GST_EXPORT` +* `function_prefix`: additional prefix for function names, e.g. in + case you want to add a leading underscore to functions used only + internally +* `header_prefix`: additional prefix at the top of the header file, + e.g. for extra includes (which may be needed if you specify a + decorator for the function declarations) +* `install_header`: if true, install the generated header +* `install_dir`: directory to install the header +* `identifier_prefix`: prefix to use for the identifiers +* `sources`: the list of sources to make enums with +* `symbol_prefix`: prefix to use for the symbols + +Example: + +```meson +gnome = import('gnome') + +my_headers = ['myheader1.h', 'myheader2.h'] +my_sources = ['mysource1.c', 'mysource2.c'] + +# will generate myenums.c and myenums.h based on enums in myheader1.h and myheader2.h +enums = gnome.mkenums_simple('myenums', sources : my_headers) + +mylib = library('my', my_sources, enums, + include_directories: my_incs, + dependencies: my_deps, + c_args: my_cargs, + install: true) +``` + +*Added 0.42.0* + +Returns an array of two elements which are: `[c_source, header_file]` + +### gnome.compile_schemas() + +When called, this method will compile the gschemas in the current +directory. Note that this is not for installing schemas and is only +useful when running the application locally for example during tests. + +* `build_by_default`: causes, when set to true, to have this target be + built by default, that is, when invoking plain `meson compile`, the default + value is true for all built target types +* `depend_files`: files ([`string`](Reference-manual.md#string-object), + [`files()`](Reference-manual.md#files), or + [`configure_file()`](Reference-manual.md#configure_file)) of + schema source XML files that should trigger a re-compile if changed. + +### gnome.gdbus_codegen() + +Compiles the given XML schema into gdbus source code. Takes two +positional arguments, the first one specifies the base name to use +while creating the output source and header and the second specifies +one XML file. + +* `sources`: list of XML files +* `interface_prefix`: prefix for the interface +* `namespace`: namespace of the interface +* `extra_args`: (*Added 0.47.0*) additional command line arguments to pass +* `autocleanup`: *(Added 0.47.0)* if set generates autocleanup code. Can be one of `none`, `objects` or `all` +* `object_manager`: *(Added 0.40.0)* if true generates object manager code +* `annotations`: *(Added 0.43.0)* list of lists of 3 strings for the annotation for `'ELEMENT', 'KEY', 'VALUE'` +* `docbook`: *(Added 0.43.0)* prefix to generate `'PREFIX'-NAME.xml` docbooks +* `build_by_default`: causes, when set to true, to have this target be + built by default, that is, when invoking plain `meson compile`, the default + value is true for all built target types +* `install_dir`: (*Added 0.46.0*) location to install the header or + bundle depending on previous options +* `install_header`: (*Added 0.46.0*) if true, install the header file + +Starting *0.46.0*, this function returns a list of at least two custom +targets (in order): one for the source code and one for the header. +The list will contain a third custom target for the generated docbook +files if that keyword argument is passed. + +Earlier versions return a single custom target representing all the +outputs. Generally, you should just add this list of targets to a top +level target's source list. + +Example: + +```meson +gnome = import('gnome') + +# The returned source would be passed to another target +gdbus_src = gnome.gdbus_codegen('example-interface', + sources: 'com.example.Sample.xml', + interface_prefix : 'com.example.', + namespace : 'Sample', + annotations : [ + ['com.example.Hello()', 'org.freedesktop.DBus.Deprecated', 'true'] + ], + docbook : 'example-interface-doc' +) +``` + +### gnome.generate_vapi() + +Creates a VAPI file from gir. The first argument is the name of the +library. + +* `gir_dirs`: extra directories to include for gir files +* `install`: if true, install the VAPI file +* `install_dir`: location to install the VAPI file (defaults to datadir/vala/vapi) +* `metadata_dirs`: extra directories to include for metadata files +* `packages`: VAPI packages that are depended upon +* `sources`: the gir source to generate the VAPI from +* `vapi_dirs`: extra directories to include for VAPI files + +Returns a custom dependency that can be included when building other +VAPI or Vala binaries. + +*Added 0.36.0* + +### gnome.yelp() + +Installs help documentation using Yelp. The first argument is the +project id. + +This also creates two targets for translations +`help-$project-update-po` and `help-$project-pot`. + +* `languages`: list of languages for translations +* `media`: list of media such as images +* `sources`: list of pages +* `symlink_media`: if media should be symlinked not copied (defaults to `true` since 0.42.0) + +Note that very old versions of yelp may not support symlinked media; +At least 3.10 should work. + +*Added 0.36.0* + +### gnome.gtkdoc() + +Compiles and installs gtkdoc documentation into +`prefix/share/gtk-doc/html`. Takes one positional argument: The name +of the module. + +* `content_files`: a list of content files +* `dependencies`: a list of dependencies +* `fixxref_args`: a list of arguments to pass to `gtkdoc-fixxref` +* `gobject_typesfile`: a list of type files +* `include_directories`: extra include paths to pass to `gtkdoc-scangobj` +* `ignore_headers`: a list of header files to ignore +* `html_assets`: a list of assets for the HTML pages +* `html_args` a list of arguments to pass to `gtkdoc-mkhtml` +* `install`: if true, installs the generated docs +* `install_dir`: the directory to install the generated docs relative + to the gtk-doc html dir or an absolute path (default: module name) +* `main_xml`: specifies the main XML file +* `main_sgml`: equal to `main_xml` +* `mkdb_args`: a list of arguments to pass to `gtkdoc-mkdb` +* `namespace`: specifies the name space to pass to `gtkdoc-mkdb` +* `module_version`: the version of the module, affects the installed location and the devhelp2 file location +* `scan_args`: a list of arguments to pass to `gtkdoc-scan` +* `scanobjs_args`: a list of arguments to pass to `gtkdoc-scangobj` +* `c_args`: (*Added 0.48.0*) additional compile arguments to pass +* `src_dir`: include_directories to include +* `check`: (*Since 0.52.0*) if `true` runs `gtkdoc-check` when running unit tests. + Note that this has the downside of rebuilding the doc for each build, which is + often very slow. It usually should be enabled only in CI. + +This also creates a `$module-doc` target that can be run to build +documentation. Normally the documentation is only built on install. + +*Since 0.52.0* Returns a target object that can be passed as +dependency to other targets using generated doc files (e.g. in +`content_files` of another doc). + +### gnome.gtkdoc_html_dir() + +Takes as argument a module name and returns the path where that +module's HTML files will be installed. Usually used with +`install_data` to install extra files, such as images, to the output +directory. + +### gnome.post_install() + +*Since 0.57.0* + +Post-install update of various system wide caches. Each script will be executed +only once even if `gnome.post_install()` is called multiple times from multiple +subprojects. If `DESTDIR` is specified during installation all scripts will be +skipped. + +It takes the following keyword arguments: +- `glib_compile_schemas`: If set to `true`, update `gschemas.compiled` file in + `<prefix>/<datadir>/glib-2.0/schemas`. +- `gio_querymodules`: List of directories relative to `prefix` where + `giomodule.cache` file will be updated. +- `gtk_update_icon_cache`: If set to `true`, update `icon-theme.cache` file in + `<prefix>/<datadir>/icons/hicolor`. +- `update_desktop_database`: *Since 0.59.0* If set to `true`, update cache of + MIME types handled by desktop files in `<prefix>/<datadir>/applications`. diff --git a/meson/docs/markdown/Hotdoc-module.md b/meson/docs/markdown/Hotdoc-module.md new file mode 100644 index 000000000..7d9fc555f --- /dev/null +++ b/meson/docs/markdown/Hotdoc-module.md @@ -0,0 +1,79 @@ +--- +short-description: Hotdoc module +authors: + - name: Thibault Saunier + email: tsaunier@igalia.com + years: [2018] + has-copyright: false +... + +# Hotdoc module + +This module provides helper functions for generating documentation using +[hotdoc]. + +*Added 0.48.0* + +## Usage + +To use this module, just do: **`hotdoc = import('hotdoc')`**. The +following functions will then be available as methods on the object +with the name `hotdoc`. You can, of course, replace the name `hotdoc` +with anything else. + +### hotdoc.generate_doc() + +Generates documentation using [hotdoc] and installs it into `$prefix/share/doc/html`. + +**Positional argument:** + +* `project_name`: The name of the hotdoc project + +**Keyworded arguments:** + +* `sitemap` (*[string] or [file]*) (**required**): The hotdoc sitemap file +* `index` (*[string] or [file]*) (**required**): Location of the index file +* `dependencies`(*[targets]*): Targets on which the documentation generation depends on. +* `subprojects`: A list of `HotdocTarget` that are used as subprojects for hotdoc to generate + the documentation. +* ... Any argument of `hotdoc` can be used replacing dashes (`-`) with underscores (`_`). + For a full list of available parameters, just have a look at `hotdoc help`. + +[file]: Reference-manual.md#files +[string]: Reference-manual.md#string-object +[targets]: Reference-manual.md#build-target-object + +**Returns:** + +`HotdocTarget`: A [`custom_target`](Reference-manual.md#custom-target-object) with the +following extra methods: + +* `config_path`: Path to the generated `hotdoc` configuration file. + +### hotdoc.has_extensions() + +**Positional arguments:** + +* `...`: The hotdoc extension names to look for + +**No keyworded arguments** + +**Returns:** `true` if all the extensions where found, `false` otherwise. + +### Example + +``` meson +hotdoc = import('hotdoc') + +hotdoc.generate_doc('foobar', + project_version: '0.1', + sitemap: 'sitemap.txt', + index: 'index.md', + c_sources: ['path/to/file.c'], + c_smart_index: true, + languages: ['c'], + install: true, +) +``` + +[hotdoc]: https://hotdoc.github.io/
\ No newline at end of file diff --git a/meson/docs/markdown/IDE-integration.md b/meson/docs/markdown/IDE-integration.md new file mode 100644 index 000000000..6f0b62916 --- /dev/null +++ b/meson/docs/markdown/IDE-integration.md @@ -0,0 +1,365 @@ +--- +short-description: Meson's API to integrate Meson support into an IDE +... + +# IDE integration + +Meson has exporters for Visual Studio and XCode, but writing a custom +backend for every IDE out there is not a scalable approach. To solve +this problem, Meson provides an API that makes it easy for any IDE or +build tools to integrate Meson builds and provide an experience +comparable to a solution native to the IDE. + +All the resources required for such a IDE integration can be found in +the `meson-info` directory in the build directory. + +The first thing to do when setting up a Meson project in an IDE is to +select the source and build directories. For this example we assume +that the source resides in an Eclipse-like directory called +`workspace/project` and the build tree is nested inside it as +`workspace/project/build`. First, we initialize Meson by running the +following command in the source directory. + + meson builddir + +With this command Meson will configure the project and also generate +introspection information that is stored in `intro-*.json` files in +the `meson-info` directory. The introspection dump will be +automatically updated when Meson is (re)configured, or the build +options change. Thus, an IDE can watch for changes in this directory +to know when something changed. Note that `meson-info.json` guaranteed +to be the last file written. + +The `meson-info` directory should contain the following files: + +| File | Description | +| ------------------------------ | ------------------------------------------------------------------- | +| `intro-benchmarks.json` | Lists all benchmarks | +| `intro-buildoptions.json` | Contains a full list of Meson configuration options for the project | +| `intro-buildsystem_files.json` | Full list of all Meson build files | +| `intro-dependencies.json` | Lists all dependencies used in the project | +| `intro-installed.json` | Contains mapping of files to their installed location | +| `intro-projectinfo.json` | Stores basic information about the project (name, version, etc.) | +| `intro-targets.json` | Full list of all build targets | +| `intro-tests.json` | Lists all tests with instructions how to run them | + +The content of the JSON files is further specified in the remainder of +this document. + +## The `targets` section + +The most important file for an IDE is probably `intro-targets.json`. +Here each target with its sources and compiler parameters is +specified. The JSON format for one target is defined as follows: + +```json +{ + "name": "Name of the target", + "id": "The internal ID meson uses", + "type": "<TYPE>", + "defined_in": "/Path/to/the/targets/meson.build", + "subproject": null, + "filename": ["list", "of", "generated", "files"], + "build_by_default": true / false, + "target_sources": [], + "extra_files": ["/path/to/file1.hpp", "/path/to/file2.hpp"], + "installed": true / false, +} +``` + +If the key `installed` is set to `true`, the key `install_filename` +will also be present. It stores the installation location for each +file in `filename`. If one file in `filename` is not installed, its +corresponding install location is set to `null`. + +The `subproject` key specifies the name of the subproject this target +was defined in, or `null` if the target was defined in the top level +project. + +*(New in 0.56.0)* The `extra_files` key lists all files specified via +the `extra_files` kwarg of a build target. See +[`executable()`](Reference-manual.md#executable). + +A target usually generates only one file. However, it is possible for +custom targets to have multiple outputs. + +### Target sources + +The `intro-targets.json` file also stores a list of all source objects +of the target in the `target_sources`. With this information, an IDE +can provide code completion for all source files. + +```json +{ + "language": "language ID", + "compiler": ["The", "compiler", "command"], + "parameters": ["list", "of", "compiler", "parameters"], + "sources": ["list", "of", "all", "source", "files", "for", "this", "language"], + "generated_sources": ["list", "of", "all", "source", "files", "that", "where", "generated", "somewhere", "else"] +} +``` + +It should be noted that the compiler parameters stored in the +`parameters` differ from the actual parameters used to compile the +file. This is because the parameters are optimized for the usage in an +IDE to provide autocompletion support, etc. It is thus not recommended +to use this introspection information for actual compilation. + +### Possible values for `type` + +The following table shows all valid types for a target. + +| value of `type` | Description | +| ---------------- | --------------------------------------------------------------------------------------------- | +| `executable` | This target will generate an executable file | +| `static library` | Target for a static library | +| `shared library` | Target for a shared library | +| `shared module` | A shared library that is meant to be used with dlopen rather than linking into something else | +| `custom` | A custom target | +| `run` | A Meson run target | +| `jar` | A Java JAR target | + +### Using `--targets` without a build directory + +It is also possible to get most targets without a build directory. +This can be done by running `meson introspect --targets +/path/to/meson.build`. + +The generated output is similar to running the introspection with a +build directory or reading the `intro-targets.json`. However, there +are some key differences: + +- The paths in `filename` now are _relative_ to the future build directory +- The `install_filename` key is completely missing +- There is only one entry in `target_sources`: + - With the language set to `unknown` + - Empty lists for `compiler` and `parameters` and `generated_sources` + - The `sources` list _should_ contain all sources of the target + +There is no guarantee that the sources list in `target_sources` is +correct. There might be differences, due to internal limitations. It +is also not guaranteed that all targets will be listed in the output. +It might even be possible that targets are listed, which won't exist +when Meson is run normally. This can happen if a target is defined +inside an if statement. Use this feature with care. + +## Build Options + +The list of all build options (build type, warning level, etc.) is +stored in the `intro-buildoptions.json` file. Here is the JSON format +for each option. + +```json +{ + "name": "name of the option", + "description": "the description", + "type": "type ID", + "value": "value depends on type", + "section": "section ID", + "machine": "machine ID" +} +``` + +The supported types are: + + - string + - boolean + - combo + - integer + - array + +For the type `combo` the key `choices` is also present. Here all valid +values for the option are stored. + +The possible values for `section` are: + + - core + - backend + - base + - compiler + - directory + - user + - test + +The `machine` key specifies the machine configuration for the option. +Possible values are: + + - any + - host + - build + +To set the options, use the `meson configure` command. + +Since Meson 0.50.0 it is also possible to get the default buildoptions +without a build directory by providing the root `meson.build` instead +of a build directory to `meson introspect --buildoptions`. + +Running `--buildoptions` without a build directory produces the same +output as running it with a freshly configured build directory. + +However, this behavior is not guaranteed if subprojects are present. +Due to internal limitations all subprojects are processed even if they +are never used in a real Meson run. Because of this options for the +subprojects can differ. + +## The dependencies section + +The list of all _found_ dependencies can be acquired from +`intro-dependencies.json`. Here, the name, version, compiler and +linker arguments for a dependency are listed. + +### Scanning for dependecie with `--scan-dependencies` + +It is also possible to get most dependencies used without a build +directory. This can be done by running `meson introspect +--scan-dependencies /path/to/meson.build`. + +The output format is as follows: + +```json +[ + { + "name": "The name of the dependency", + "required": true, + "version": [">=1.2.3"], + "conditional": false, + "has_fallback": false + } +] +``` + +The `required` keyword specifies whether the dependency is marked as +required in the `meson.build` (all dependencies are required by +default). The `conditional` key indicates whether the `dependency()` +function was called inside a conditional block. In a real Meson run +these dependencies might not be used, thus they _may_ not be required, +even if the `required` key is set. The `has_fallback` key just +indicates whether a fallback was directly set in the `dependency()` +function. The `version` key always contains a list of version +requirements from the `meson.build` and **not** the actual version of +the dependency on disc. The version list is empty if no version was +specified in the `meson.build`. + +## Tests + +Compilation and unit tests are done as usual by running the `meson +compile` and `meson test` commands. A JSON formatted result log can be +found in `workspace/project/builddir/meson-logs/testlog.json`. + +When these tests fail, the user probably wants to run the failing test +in a debugger. To make this as integrated as possible, extract the +tests from the `intro-tests.json` and `intro-benchmarks.json` files. +This provides you with all the information needed to run the test: +what command to execute, command line arguments, environment variable +settings and how to process the output. + +```json +{ + "name": "name of the test", + "workdir": "the working directory (can be null)", + "timeout": "the test timeout", + "suite": ["list", "of", "test", "suites"], + "is_parallel": true / false, + "protocol": "exitcode" / "tap", + "cmd": ["command", "to", "run"], + "depends": ["target1-id", "target2-id"], + "env": { + "VARIABLE1": "value 1", + "VARIABLE2": "value 2" + } +} +``` + +The `depends` entry *(since 0.56.0)* contains target ids; they can be +looked up in the targets introspection data. The executable pointed to +by `cmd` is also included in the entry, as are any arguments to the +test that are build products. + +## Build system files + +It is also possible to get Meson build files used in your current +project. This can be done by running `meson introspect +--buildsystem-files /path/to/builddir`. + +The output format is as follows: + +```json +[ + "/Path/to/the/targets/meson.build", + "/Path/to/the/targets/meson_options.txt", + "/Path/to/the/targets/subdir/meson.build" +] +``` + +# Programmatic interface + +Meson also provides the `meson introspect` for project introspection +via the command line. Use `meson introspect -h` to see all available +options. + +This API can also work without a build directory for the +`--projectinfo` command. + +# AST of a `meson.build` + +Since Meson *0.55.0* it is possible to dump the AST of a `meson.build` +as a JSON object. The interface for this is `meson introspect --ast +/path/to/meson.build`. + +Each node of the AST has at least the following entries: + +| Key | Description | +| ------------ | ------------------------------------------------------- | +| `node` | Type of the node (see following table) | +| `lineno` | Line number of the node in the file | +| `colno` | Column number of the node in the file | +| `end_lineno` | Marks the end of the node (may be the same as `lineno`) | +| `end_colno` | Marks the end of the node (may be the same as `colno`) | + +Possible values for `node` with additional keys: + +| Node type | Additional keys | +| -------------------- | ------------------------------------------------ | +| `BooleanNode` | `value`: bool | +| `IdNode` | `value`: str | +| `NumberNode` | `value`: int | +| `StringNode` | `value`: str | +| `ContinueNode` | | +| `BreakNode` | | +| `ArgumentNode` | `positional`: node list; `kwargs`: accept_kwargs | +| `ArrayNode` | `args`: node | +| `DictNode` | `args`: node | +| `EmptyNode` | | +| `OrNode` | `left`: node; `right`: node | +| `AndNode` | `left`: node; `right`: node | +| `ComparisonNode` | `left`: node; `right`: node; `ctype`: str | +| `ArithmeticNode` | `left`: node; `right`: node; `op`: str | +| `NotNode` | `right`: node | +| `CodeBlockNode` | `lines`: node list | +| `IndexNode` | `object`: node; `index`: node | +| `MethodNode` | `object`: node; `args`: node; `name`: str | +| `FunctionNode` | `args`: node; `name`: str | +| `AssignmentNode` | `value`: node; `var_name`: str | +| `PlusAssignmentNode` | `value`: node; `var_name`: str | +| `ForeachClauseNode` | `items`: node; `block`: node; `varnames`: list | +| `IfClauseNode` | `ifs`: node list; `else`: node | +| `IfNode` | `condition`: node; `block`: node | +| `UMinusNode` | `right`: node | +| `TernaryNode` | `condition`: node; `true`: node; `false`: node | + +We do not guarantee the stability of this format since it is heavily +linked to the internal Meson AST. However, breaking changes (removal +of a node type or the removal of a key) are unlikely and will be +announced in the release notes. + + +# Existing integrations + +- [Gnome Builder](https://wiki.gnome.org/Apps/Builder) +- [KDevelop](https://www.kdevelop.org) +- [Eclipse CDT](https://www.eclipse.org/cdt/) (experimental) +- [Meson Cmake Wrapper](https://github.com/prozum/meson-cmake-wrapper) (for cmake IDEs) (currently unmaintained !!) +- [Meson-UI](https://github.com/michaelbadcrumble/meson-ui) (Meson build GUI) +- [Meson Syntax Highlighter](https://plugins.jetbrains.com/plugin/13269-meson-syntax-highlighter) plugin for JetBrains IDEs. +- [asabil.meson](https://open-vsx.org/extension/asabil/meson) extension for VS Code/Codium +- [Qt Creator](https://doc.qt.io/qtcreator/creator-project-meson.html) diff --git a/meson/docs/markdown/Icestorm-module.md b/meson/docs/markdown/Icestorm-module.md new file mode 100644 index 000000000..10b64eff1 --- /dev/null +++ b/meson/docs/markdown/Icestorm-module.md @@ -0,0 +1,27 @@ +# Unstable IceStorm module + +This module is available since version 0.45.0. + +**Note**: this module is unstable. It is only provided as a technology +preview. Its API may change in arbitrary ways between releases or it +might be removed from Meson altogether. + +## Usage + +This module provides an experimental method to create FPGA bitstreams +using the [IceStorm](http://www.clifford.at/icestorm/) suite of tools. + +The module exposes only one method called `project` and it is used +like this: + + is.project('projname', + <verilog files>, + constraint_file : <pcf file>, + ) + +The input to this function is the set of Verilog files and a +constraint file. This produces output files called `projname.asc`, +`projname.blif` and `projname.bin`. In addition it creates two run +targets called `projname-time` for running timing analysis and +`projname-upload` that uploads the generated bitstream to an FPGA +device using the `iceprog` programming executable. diff --git a/meson/docs/markdown/In-the-press.md b/meson/docs/markdown/In-the-press.md new file mode 100644 index 000000000..aa6f2a8eb --- /dev/null +++ b/meson/docs/markdown/In-the-press.md @@ -0,0 +1,8 @@ +# In the press + +This page lists cases where Meson has been presented in the press. + +* [Linux Magazin](http://www.linux-magazin.de/Ausgaben/2014/08/), in German, August 2014, and also later in [Linux Magazine](http://www.linux-magazine.com/Issues/2014/166/Meson-Build-System) in English +* [Admin Magazine](http://www.admin-magazine.com/HPC/Articles/The-Meson-Build-System) +* [Phoronix](https://www.phoronix.com/scan.php?page=news_item&px=MTc1MDc) regarding compilation of Mesa3D +* [CppCast](http://cppcast.com/2015/12/jussi-pakkanen/) interviewed Jussi about Meson for C++ development in 12/2015 diff --git a/meson/docs/markdown/Include-directories.md b/meson/docs/markdown/Include-directories.md new file mode 100644 index 000000000..6dfed5e48 --- /dev/null +++ b/meson/docs/markdown/Include-directories.md @@ -0,0 +1,30 @@ +--- +short-description: Instructions on handling include directories +... + +# Include directories + +Most `C`/`C++` projects have headers in different directories than +sources. Thus you need to specify include directories. Let's assume +that we are at some subdirectory and wish to add its `include` +subdirectory to some target's search path. To create a include +directory object we do this: + +```meson +incdir = include_directories('include') +``` + +The `incdir` variable now holds a reference to the `include` subdir. +Now we pass that as an argument to a build target: + +```meson +executable('someprog', 'someprog.c', include_directories : incdir) +``` + +Note that these two commands can be given in any subdirectories and it +will still work. Meson will keep track of the locations and generate +proper compiler flags to make it all work. + +Another thing to note is that `include_directories` adds both the +source directory and corresponding build directory to include path, so +you don't have to care. diff --git a/meson/docs/markdown/IndepthTutorial.md b/meson/docs/markdown/IndepthTutorial.md new file mode 100644 index 000000000..edbbe5508 --- /dev/null +++ b/meson/docs/markdown/IndepthTutorial.md @@ -0,0 +1,150 @@ +# An in-depth tutorial + +In this tutorial we set up a project with multiple targets, unit tests +and dependencies between targets. Our main product is a shared library +called *foo* that is written in `C++11`. We are going to ignore the +contents of the source files, as they are not really important from a +build definition point of view. The library makes use of the `GLib` +library so we need to detect and link it properly. We also make the +resulting library installable. + +The source tree contains three subdirectories `src`, `include` and +`test` that contain, respectively, the source code, headers and unit +tests of our project. + +To start things up, here is the top level `meson.build` file. + +```meson +project('c++ foolib', 'cpp', + version : '1.0.0', + license : 'MIT') +add_global_arguments('-DSOME_TOKEN=value', language : 'cpp') +glib_dep = dependency('glib-2.0') + +inc = include_directories('include') + +subdir('include') +subdir('src') +subdir('test') + +pkg_mod = import('pkgconfig') +pkg_mod.generate(libraries : foolib, + version : '1.0', + name : 'libfoobar', + filebase : 'foobar', + description : 'A Library to barnicate your foos.') +``` + +The definition always starts with a call to the `project` function. In +it you must specify the project's name and programming languages to +use, in this case only `C++`. We also specify two additional +arguments, the project's version and the license it is under. Our +project is version `1.0.0` and is specified to be under the MIT +license. + +Then we find GLib, which is an *external dependency*. The `dependency` +function tells Meson to find the library (by default using +`pkg-config`). If the library is not found, Meson will raise an error +and stop processing the build definition. + +Then we add a global compiler argument `-DSOME_TOKEN=value`. This flag +is used for *all* C++ source file compilations. It is not possible to +unset it for some targets. The reason for this is that it is hard to +keep track of what compiler flags are in use if global settings change +per target. + +Since `include` directory contains the header files, we need a way to +tell compilations to add that directory to the compiler command line. +This is done with the `include_directories` command that takes a +directory and returns an object representing this directory. It is +stored in variable `inc` which makes it accessible later on. + +After this are three `subdir` commands. These instruct Meson to go to +the specified subdirectory, open the `meson.build` file that's in +there and execute it. The last few lines are a stanza to generate a +`pkg-config` file. We'll skip that for now and come back to it at the +end of this document. + +The first subdirectory we go into is `include`. In it we have a a +header file for the library that we want to install. This requires one +line. + +```meson +install_headers('foolib.h') +``` + +This installs the given header file to the system's header directory. +This is by default `/[install prefix]/include`, but it can be changed +with a command line argument. + +The Meson definition of `src` subdir is simple. + +```meson +foo_sources = ['source1.cpp', 'source2.cpp'] +foolib = shared_library('foo', + foo_sources, + include_directories : inc, + dependencies : glib_dep, + install : true) +``` + +Here we just tell Meson to build the library with the given sources. +We also tell it to use the include directories we stored to variable +`inc` earlier. Since this library uses GLib, we tell Meson to add all +necessary compiler and linker flags with the `dependencies` keyword +argument. Its value is `glib_dep` which we set at the top level +`meson.build` file. The `install` argument tells Meson to install the +result. As with the headers, the shared library is installed to the +system's default location (usually `/[install prefix]/lib`) but is +again overridable. + +The resulting library is stored in variable `foolib` just like the +include directory was stored in the previous file. + +Once Meson has processed the `src` subdir it returns to the main Meson +file and executes the next line that moves it into the `test` subdir. +Its contents look like this. + +```meson +testexe = executable('testexe', 'footest.cpp', + include_directories : inc, + link_with : foolib) +test('foolib test', testexe) +``` + +First we build a test executable that has the same include directory +as the main library and which also links against the freshly built +shared library. Note that you don't need to specify `glib_dep` here +just to be able to use the built library `foolib`. If the executable +used GLib functionality itself, then we would of course need to add it +as a keyword argument here. + +Finally we define a test with the name `foolib test`. It consists of +running the binary we just built. If the executable exits with a zero +return value, the test is considered passed. Nonzero return values +mark the test as failed. + +At this point we can return to the pkg-config generator line. All +shared libraries should provide a pkg-config file, which explains how +that library is used. Meson provides this simple generator that should +be sufficient for most simple projects. All you need to do is list a +few basic pieces of information and Meson takes care of generating an +appropriate file. More advanced users might want to create their own +pkg-config files using Meson's [configuration file generator +system](Configuration.md). + +With these four files we are done. To configure, build and run the +test suite, we just need to execute the following commands (starting +at source tree root directory). + +```console +$ meson builddir && cd builddir +$ meson compile +$ meson test +``` + +To then install the project you only need one command. + +```console +$ meson install +``` diff --git a/meson/docs/markdown/Installing.md b/meson/docs/markdown/Installing.md new file mode 100644 index 000000000..0e5cb1296 --- /dev/null +++ b/meson/docs/markdown/Installing.md @@ -0,0 +1,149 @@ +--- +short-description: Installing targets +... + +# Installing + +Invoked via the [following command](Commands.md#install) *(available +since 0.47.0)*: + +```sh +meson install +``` + +or alternatively (on older Meson versions with `ninja` backend): + +```sh +ninja install +``` + +By default Meson will not install anything. Build targets can be +installed by tagging them as installable in the definition. + +```meson +project('install', 'c') +shared_library('mylib', 'libfile.c', install : true) +``` + +There is usually no need to specify install paths or the like. Meson +will automatically install it to the standards-conforming location. In +this particular case the executable is installed to the `bin` +subdirectory of the install prefix. However if you wish to override +the install dir, you can do that with the `install_dir` argument. + +```meson +executable('prog', 'prog.c', install : true, install_dir : 'my/special/dir') +``` + +Other install commands are the following. + +```meson +install_headers('header.h', subdir : 'projname') # -> include/projname/header.h +install_man('foo.1') # -> share/man/man1/foo.1 +install_data('datafile.dat', install_dir : get_option('datadir') / 'progname') +# -> share/progname/datafile.dat +``` + +`install_data()` supports rename of the file *since 0.46.0*. + +```meson +# file.txt -> {datadir}/{projectname}/new-name.txt +install_data('file.txt', rename : 'new-name.txt') + +# file1.txt -> share/myapp/dir1/data.txt +# file2.txt -> share/myapp/dir2/data.txt +install_data(['file1.txt', 'file2.txt'], + rename : ['dir1/data.txt', 'dir2/data.txt'], + install_dir : 'share/myapp') +``` + +Sometimes you want to copy an entire subtree directly. For this use +case there is the `install_subdir` command, which can be used like +this. + +```meson +install_subdir('mydir', install_dir : 'include') # mydir subtree -> include/mydir +``` + +Most of the time you want to install files relative to the install +prefix. Sometimes you need to go outside of the prefix (such as writing +files to `/etc` instead of `/usr/etc`. This can be accomplished by +giving an absolute install path. + +```meson +install_data(sources : 'foo.dat', install_dir : '/etc') # -> /etc/foo.dat +``` + +## Custom install behavior + +Sometimes you need to do more than just install basic targets. Meson +makes this easy by allowing you to specify a custom script to execute +at install time. As an example, here is a script that generates an +empty file in a custom directory. + +```bash +#!/bin/sh + +mkdir "${DESTDIR}/${MESON_INSTALL_PREFIX}/mydir" +touch "${DESTDIR}/${MESON_INSTALL_PREFIX}/mydir/file.dat" +``` + +As you can see, Meson sets up some environment variables to help you +write your script (`DESTDIR` is not set by Meson, it is inherited from +the outside environment). In addition to the install prefix, Meson +also sets the variables `MESON_SOURCE_ROOT` and `MESON_BUILD_ROOT`. + +Telling Meson to run this script at install time is a one-liner. + +```meson +meson.add_install_script('myscript.sh') +``` + +The argument is the name of the script file relative to the current +subdirectory. + +## DESTDIR support + +Sometimes you need to install to a different directory than the +install prefix. This is most common when building rpm or deb +packages. This is done with the `DESTDIR` environment variable and it +is used just like with other build systems: + +```console +$ DESTDIR=/path/to/staging/area meson install +``` + +## Custom install behaviour + +Installation behaviour can be further customized using additional +arguments. + +For example, if you wish to install the current setup without +rebuilding the code (which the default install target always does) and +only installing those files that have changed, you would run this +command in the build tree: + +```console +$ meson install --no-rebuild --only-changed +``` + +## Finer control over install locations + +Sometimes it is necessary to only install a subsection of output files +or install them in different directories. This can be done by +specifying `install_dir` as an array rather than a single string. The +array must have as many items as there are outputs and each entry +specifies how the corresponding output file should be installed. For +example: + +```meson +custom_target(... + output: ['file1', 'file2', 'file3'], + install_dir: ['path1', false, 'path3'], + ... +) +``` + +In this case `file1` would be installed to `/prefix/path1/file1`, +`file2` would not be installed at all and `file3` would be installed +to `/prefix/path3/file3'. diff --git a/meson/docs/markdown/Java.md b/meson/docs/markdown/Java.md new file mode 100644 index 000000000..f0dd40380 --- /dev/null +++ b/meson/docs/markdown/Java.md @@ -0,0 +1,24 @@ +--- +title: Java +short-description: Compiling Java programs +... + +# Compiling Java applications + +Meson has experimental support for compiling Java programs. The basic +syntax consists of only one function and would be used like this: + +```meson +project('javaprog', 'java') + +myjar = jar('mything', 'com/example/Prog.java', + main_class : 'com.example.Prog') + +test('javatest', myjar) +``` + +However note that Meson places limitations on how you lay out your code. + +* all Java files for a jar must be under the subdirectory the jar definition is in +* all Java files must be in paths specified by their package, e.g. a class called `com.example.Something` must be in a Java file situated at `com/example/Something.java`. +* Meson only deals with jar files, you cannot poke individual class files (unless you do so manually) diff --git a/meson/docs/markdown/Keyval-module.md b/meson/docs/markdown/Keyval-module.md new file mode 100644 index 000000000..96d9c1566 --- /dev/null +++ b/meson/docs/markdown/Keyval-module.md @@ -0,0 +1,58 @@ +--- +short-description: Keyval module +authors: + - name: Mark Schulte, Paolo Bonzini + years: [2017, 2019] + has-copyright: false +... + +# keyval module + +This module parses files consisting of a series of `key=value` lines. +One use of this module is to load kconfig configurations in Meson +projects. + +**Note**: this does not provide kconfig frontend tooling to generate a +configuration. You still need something such as kconfig frontends (see +link below) to parse your Kconfig files, and then (after you've chosen +the configuration options), output a ".config" file. + + [kconfig-frontends]: http://ymorin.is-a-geek.org/projects/kconfig-frontends + +## Usage + +The module may be imported as follows: + +``` meson +keyval = import('keyval') +``` + +The following functions will then be available as methods on the object +with the name `keyval`. You can, of course, replace the name +`keyval` with anything else. + +### keyval.load() + +This function loads a file consisting of a series of `key=value` lines +and returns a dictionary object. + +`keyval.load()` makes no attempt at parsing the values in the file. In +particular boolean and integer values will be represented as strings, +and strings will keep any quoting that is present in the input file. +It can be useful to create a +[`configuration_data()`](#configuration_data) object from the +dictionary and use methods such as `get_unquoted()`. + +Kconfig frontends usually have ".config" as the default name for the +configuration file. However, placing the configuration file in the +source directory limits the user to one configuration per source +directory. In order to allow separate configurations for each build +directory, as is the Meson standard, `meson.build` should not hardcode +".config" as the argument to `kconfig.load()`, and should instead make +the argument to `kconfig.load()` a [project build +option](Build-options.md). + +* The first (and only) argument is the path to the configuration file to + load (usually ".config"). + +**Returns**: a [dictionary object](Reference-manual.md#dictionary-object). diff --git a/meson/docs/markdown/Localisation.md b/meson/docs/markdown/Localisation.md new file mode 100644 index 000000000..a826f8dfd --- /dev/null +++ b/meson/docs/markdown/Localisation.md @@ -0,0 +1,86 @@ +--- +short-description: Localization with GNU Gettext +... + +# Localisation + +Localising your application with GNU gettext takes a little effort but +is quite straightforward. We'll create a `po` subdirectory at your +project root directory for all the localisation info. + +## Generating .pot and .po files + +In your main meson.build file include the `po` subdirectory in the build process. + + subdir('po') + +In this `po` subdirectory we need: +- `LINGUAS`: Space separated list of languages +- `POTFILES`: List of source files to scan for translatable strings. +- `meson.build`: Localization specific Meson file + +### LINGUAS + +File with space separated list of languages. A sample LINGUAS might look like this. + + aa ab ae af + +### POTFILES + +File that lists all the source files that gettext should scan in order +to find strings to translate. The syntax of the file is one line per +source file and the line must contain the relative path from source +root. A sample POTFILES might look like this. + + src/file1.c + src/file2.c + src/subdir/file3.c + include/mything/somefile.h + +### meson.build + +Localization specific Meson file. It imports and uses the `i18n` +module. If not defined before it needs to define the `GETTEXT_PACKAGE` +global. + +```meson +i18n = import('i18n') +# define GETTEXT_PACKAGE +add_project_arguments('-DGETTEXT_PACKAGE="intltest"', language:'c') +i18n.gettext(meson.project_name(), + args: '--directory=' + meson.source_root() +) +``` + +The first command imports the `i18n` module that provides gettext +features. The fourth line does the actual invocation. The first +argument is the gettext package name. This causes two things to +happen. The first is that Meson will generate binary mo files and put +them to their proper locations when doing an install. The second is +that it creates a build rule to regenerate the main pot file. If you +are using the Ninja backend, this is how you would invoke the rebuild. + +### generate .pot file + +Then we need to generate the main pot file. The potfile can have any +name but is usually the name of the gettext package. Let's say the +project is called *intltest*. In this case the corresponding pot file +would be called `intltest.pot`. + +Run the following command from your build folder to generate the pot +file. It is recommended to inspect it manually afterwards and fill in +e.g. proper copyright and contact information. + +```console +$ meson compile intltest-pot +``` + +### generate .po files + +For each language listed in the array above we need a corresponding +`.po` file. Those can be generated by running the following command +from your build folder. + +```console +$ meson compile intltest-update-po +``` diff --git a/meson/docs/markdown/Machine-files.md b/meson/docs/markdown/Machine-files.md new file mode 100644 index 000000000..631408240 --- /dev/null +++ b/meson/docs/markdown/Machine-files.md @@ -0,0 +1,359 @@ +# Cross and Native File reference + +Cross and native files are nearly identical, but not completely. This +is the documentation on the common values used by both, for the +specific values of one or the other see the [cross +compilation](Cross-compilation.md) and [native +environments](Native-environments.md). + +*Changed in 0.56.0* Keys within sections are now case sensitive. This +is required to make project options work correctly. + +## Data Types + +There are four basic data types in a machine file: +- strings +- arrays +- booleans +- integers + +A string is specified single quoted: +```ini +[section] +option1 = 'false' +option2 = '2' +``` + +An array is enclosed in square brackets, and must consist of strings or booleans +```ini +[section] +option = ['value'] +``` + +A boolean must be either `true` or `false`, and unquoted. +```ini +option = false +``` + +An integer must be an unquoted numeric constant. +```ini +option = 42 +``` + +## Sections + +The following sections are allowed: +- constants +- binaries +- paths +- properties +- cmake +- project options +- built-in options + +### constants + +*Since 0.56.0* + +String and list concatenation is supported using the `+` operator, +joining paths is supported using the `/` operator. Entries defined in +the `[constants]` section can be used in any other section (they are +always parsed first), entries in any other section can be used only +within that same section and only after it has been defined. + +```ini +[constants] +toolchain = '/toolchain' +common_flags = ['--sysroot=' + toolchain / 'sysroot'] + +[properties] +c_args = common_flags + ['-DSOMETHING'] +cpp_args = c_args + ['-DSOMETHING_ELSE'] + +[binaries] +c = toolchain / 'gcc' +``` + +This can be useful with cross file composition as well. A generic +cross file could be composed with a platform specific file where +constants are defined: + +```ini +# aarch64.ini +[constants] +arch = 'aarch64-linux-gnu' +``` + +```ini +# cross.ini +[binaries] +c = arch + '-gcc' +cpp = arch + '-g++' +strip = arch + '-strip' +pkgconfig = arch + '-pkg-config' +... +``` + +This can be used as `meson setup --cross-file aarch64.ini --cross-file +cross.ini builddir`. + +Note that file composition happens before the parsing of values. The +example below results in `b` being `'HelloWorld'`: + +```ini +# file1.ini: +[constants] +a = 'Foo' +b = a + 'World' +``` + +```ini +#file2.ini: +[constants] +a = 'Hello' +``` + +The example below results in an error when file1.ini is included +before file2.ini because `b` would be defined before `a`: + +```ini +# file1.ini: +[constants] +b = a + 'World' +``` + +```ini +#file2.ini: +[constants] +a = 'Hello' +``` + +### Binaries + +The binaries section contains a list of binaries. These can be used +internally by Meson, or by the `find_program` function. + +These values must be either strings or an array of strings + +Compilers and linkers are defined here using `<lang>` and `<lang>_ld`. +`<lang>_ld` is special because it is compiler specific. For compilers +like gcc and clang which are used to invoke the linker this is a value +to pass to their "choose the linker" argument (-fuse-ld= in this +case). For compilers like MSVC and Clang-Cl, this is the path to a +linker for Meson to invoke, such as `link.exe` or `lld-link.exe`. +Support for `ld` is *new in 0.53.0* + +*changed in 0.53.1* the `ld` variable was replaced by `<lang>_ld`, +because it regressed a large number of projects. in 0.53.0 the `ld` +variable was used instead. + +Native example: + +```ini +c = '/usr/bin/clang' +c_ld = 'lld' +sed = 'C:\\program files\\gnu\\sed.exe' +llvm-config = '/usr/lib/llvm8/bin/llvm-config' +``` + +Cross example: + +```ini +c = ['ccache', '/usr/bin/i586-mingw32msvc-gcc'] +cpp = ['ccache', '/usr/bin/i586-mingw32msvc-g++'] +c_ld = 'gold' +cpp_ld = 'gold' +ar = '/usr/i586-mingw32msvc/bin/ar' +strip = '/usr/i586-mingw32msvc/bin/strip' +pkgconfig = '/usr/bin/i586-mingw32msvc-pkg-config' +``` + +An incomplete list of internally used programs that can be overridden +here is: + +- cmake +- cups-config +- gnustep-config +- gpgme-config +- libgcrypt-config +- libwmf-config +- llvm-config +- pcap-config +- pkgconfig +- sdl2-config +- wx-config (or wx-3.0-config or wx-config-gtk) + +### Paths and Directories + +*Deprecated in 0.56.0* use the built-in section instead. + +As of 0.50.0 paths and directories such as libdir can be defined in +the native and cross files in a paths section. These should be +strings. + +```ini +[paths] +libdir = 'mylibdir' +prefix = '/my prefix' +``` + +These values will only be loaded when not cross compiling. Any +arguments on the command line will override any options in the native +file. For example, passing `--libdir=otherlibdir` would result in a +prefix of `/my prefix` and a libdir of `otherlibdir`. + +### Properties + +*New in native files in 0.54.0*, always in cross files. + +In addition to special data that may be specified in cross files, this +section may contain random key value pairs accessed using the +`meson.get_external_property()`, or `meson.get_cross_property()`. + +*Changed in 0.56.0* putting `<lang>_args` and `<lang>_link_args` in +the properties section has been deprecated, and should be put in the +built-in options section. + +#### Supported properties + +This is a non exhaustive list of supported variables in the `[properties]` +section. + +- `cmake_toolchain_file` specifies an absolute path to an already existing + CMake toolchain file that will be loaded with `include()` as the last + instruction of the automatically generated CMake toolchain file from Meson. + (*new in 0.56.0*) +- `cmake_defaults` is a boolean that specifies whether Meson should automatically + generate default toolchain variables from other sections (`binaries`, + `host_machine`, etc.) in the machine file. Defaults are always overwritten + by variables set in the `[cmake]` section. The default is `true`. (*new in 0.56.0*) +- `cmake_skip_compiler_test` is an enum that specifies when Meson should + automatically generate toolchain variables to skip the CMake compiler + sanity checks. This only has an effect if `cmake_defaults` is `true`. + Supported values are `always`, `never`, `dep_only`. The default is `dep_only`. + (*new in 0.56.0*) +- `cmake_use_exe_wrapper` is a boolean that controls whether to use the + `exe_wrapper` specified in `[binaries]` to run generated executables in CMake + subprojects. This setting has no effect if the `exe_wrapper` was not specified. + The default value is `true`. (*new in 0.56.0*) +- `java_home` is an absolute path pointing to the root of a Java installation. + +### CMake variables + +*New in 0.56.0* + +All variables set in the `[cmake]` section will be added to the +generate CMake toolchain file used for both CMake dependencies and +CMake subprojects. The type of each entry must be either a string or a +list of strings. + +**Note:** All occurrences of `\` in the value of all keys will be replaced with + a `/` since CMake has a lot of issues with correctly escaping `\` when + dealing with variables (even in cases where a path in `CMAKE_C_COMPILER` + is correctly escaped, CMake will still trip up internaly for instance) + + A custom toolchain file should be used (via the `cmake_toolchain_file` + property) if `\` support is required. + +```ini +[cmake] + +CMAKE_C_COMPILER = '/usr/bin/gcc' +CMAKE_CXX_COMPILER = 'C:\\user\\bin\\g++' +CMAKE_SOME_VARIABLE = ['some', 'value with spaces'] +``` + +For instance, the `[cmake]` section from above will generate the +following code in the CMake toolchain file: + +```cmake +set(CMAKE_C_COMPILER "/usr/bin/gcc") +set(CMAKE_CXX_COMPILER "C:/usr/bin/g++") +set(CMAKE_SOME_VARIABLE "some" "value with spaces") +``` + +### Project specific options + +*New in 0.56.0* + +Path options are not allowed, those must be set in the `[paths]` +section. + +Being able to set project specific options in a cross or native file +can be done using the `[project options]` section of the specific file +(if doing a cross build the options from the native file will be +ignored) + +For setting options in subprojects use the `[<subproject>:project +options]` section instead. + +```ini +[project options] +build-tests = true + +[zlib:project options] +build-tests = false +``` + +### Meson built-in options + +Meson built-in options can be set the same way: + +```ini +[built-in options] +c_std = 'c99' +``` + +You can set some Meson built-in options on a per-subproject basis, +such as `default_library` and `werror`. The order of precedence is: + +1) Command line +2) Machine file +3) Build system definitions + +```ini +[zlib:built-in options] +default_library = 'static' +werror = false +``` + +Options set on a per-subproject basis will inherit the option from the +parent if the parent has a setting but the subproject doesn't, even +when there is a default set Meson language. + +```ini +[built-in options] +default_library = 'static' +``` + +will make subprojects use default_library as static. + +Some options can be set on a per-machine basis (in other words, the +value of the build machine can be different than the host machine in a +cross compile). In these cases the values from both a cross file and a +native file are used. + +An incomplete list of options is: +- pkg_config_path +- cmake_prefix_path + +## Loading multiple machine files + +Native files allow layering (cross files can be layered since Meson +0.52.0). More than one file can be loaded, with values from a previous +file being overridden by the next. The intention of this is not +overriding, but to allow composing files. This composition is done by +passing the command line argument multiple times: + +```console +meson setup builddir/ --cross-file first.ini --cross-file second.ini --cross-file thrid.ini +``` + +In this case `first.ini` will be loaded, then `second.ini`, with +values from `second.ini` replacing `first.ini`, and so on. + +For example, if there is a project using C and C++, python 3.4-3.7, +and LLVM 5-7, and it needs to build with clang 5, 6, and 7, and gcc +5.x, 6.x, and 7.x; expressing all of these configurations in +monolithic configurations would result in 81 different native files. +By layering them, it can be expressed by just 12 native files. diff --git a/meson/docs/markdown/Manual.md b/meson/docs/markdown/Manual.md new file mode 100644 index 000000000..988efa162 --- /dev/null +++ b/meson/docs/markdown/Manual.md @@ -0,0 +1,9 @@ +--- +short-description: User manual for Meson +... + +# Manual + +This is the user manual for Meson. It currently tracks the state of +Git head. If you are using an older version, some of the information +here might not work for you. diff --git a/meson/docs/markdown/Meson-sample.md b/meson/docs/markdown/Meson-sample.md new file mode 100644 index 000000000..f504cd989 --- /dev/null +++ b/meson/docs/markdown/Meson-sample.md @@ -0,0 +1,80 @@ +--- +short-description: Simple project step by step explanation +... + +# Meson sample + +A Meson file that builds an executable looks like this. + +```meson +project('simple', 'c') +executable('myexe', 'source.c') +``` + +All Meson build definitions begin with the `project` command. It +specifies the name of the project and what programming languages it +uses. Here the project is called *simple* and it uses only the C +programming language. All strings are single-quoted. + +On the next line we define a *build target*, in this case an +executable called *myexe*. It consists of one source file. This is all +the code that a user needs to write to compile an executable with +Meson. + +Variables are fully supported. The above code snippet could also have +been declared like this. + +```meson +project('simple', 'c') +src = 'source.c' +executable('myexe', src) +``` + +Most executables consist of more than one source file. The easiest way +to deal with this is to put them in an array. + +```meson +project('simple', 'c') +src = ['source1.c', 'source2.c', 'source3.c'] +executable('myexe', src) +``` + +Meson also supports the notion of *keyword arguments*. Indeed most +arguments to functions can only be passed using them. The above +snippet could be rewritten like this. + +```meson +project('simple', 'c') +src = ['source1.c', 'source2.c', 'source3.c'] +executable('myexe', sources : src) +``` + +These two formats are equivalent and choosing one over the other is +mostly a question of personal preference. + +The `executable` command actually returns an *executable object*, +which represents the given build target. It can be passed on to other +functions, like this. + +```meson +project('simple', 'c') +src = ['source1.c', 'source2.c', 'source3.c'] +exe = executable('myexe', src) +test('simple test', exe) +``` + +Here we create a unit test called *simple test*, and which uses the +built executable. When the tests are run with the `meson test` +command, the built executable is run. If it returns zero, the test +passes. A non-zero return value indicates an error, which Meson will +then report to the user. + +A note to Visual Studio users +----- + +There's a slight terminology difference between Meson and Visual +Studio. A Meson *project* is the equivalent to a Visual Studio +*solution*. That is, the topmost thing that encompasses all things to +be built. A Visual Studio *project* on the other hand is the +equivalent of a Meson top level build target, such as an executable or +a shared library. diff --git a/meson/docs/markdown/MesonCI.md b/meson/docs/markdown/MesonCI.md new file mode 100644 index 000000000..65175afee --- /dev/null +++ b/meson/docs/markdown/MesonCI.md @@ -0,0 +1,43 @@ +# Meson CI setup + +This document is aimed for Meson contributors and documents the CI +setup used for testing Meson itself. The Meson project uses multiple +CI platforms for covering a wide range of target systems. + +## GitHub actions + +The configuration files for GitHub actions are located in +`.github/workflows`. Here, all [images](#docker-images) are tested +with the full `run_tests.py` run. Additionally, some other, smaller, +tests are run. + +## Docker images + +The Linux docker images are automatically built and uploaded by GitHub +actions. An image rebuild is triggerd when any of the image definition +files are changed (in `ci/ciimage`) in the master branch. +Additionally, the images are also updated weekly. + +Each docker image has one corresponding dirctory in `ci/ciimage` with +an `image.json` and an `install.sh`. + +### Image generation + +There are no manual Dockerfiles. Instead the Dockerfile is +automatically generated by the `build.py` script. This is done to +ensure that all images have the same layout and can all be built and +tested automatically. + +The Dockerfile is generated from the `image.json` file and basically +only adds a few common files and runs the `install.sh` script which +should contain all distribution specific setup steps. The `common.sh` +can be sourced via `source /ci/common.sh` to access some shared +functionalety. + +To generate the image run `build.py -t build <image>`. A generated +image can be tested with `build.py -t test <image>`. + +### Common image setup + +Each docker image has a `/ci` directory with an `env_vars.sh` script. +This script has to be sourced before running the Meson test suite. diff --git a/meson/docs/markdown/Mixing-build-systems.md b/meson/docs/markdown/Mixing-build-systems.md new file mode 100644 index 000000000..683006410 --- /dev/null +++ b/meson/docs/markdown/Mixing-build-systems.md @@ -0,0 +1,55 @@ +# Meson's policy on mixing multiple build systems in one build directory + +Meson has been designed with the principle that all dependencies are +either provided by "the platform" via a mechanism such as Pkg-Config +or that they are built as Meson subprojects under the main project. +There are several projects that would like to mix build systems, that +is, build dependencies in the same build directory as the other build +system by having one build system call the other. The build +directories do not necessarily need to be inside each other, but that +is the common case. + +This page lists the Meson project's stance on mixing build systems. +The tl/dr version is that while we do provide some functionality for +this use case, it only works for simple cases. Anything more complex +can not be made reliable and trying to do that would burden Meson +developers with an effectively infinite maintenance burden. Thus these +use cases are not guaranteed to work, and even if a project using them +works today there are no guarantees that it will work in any future +version. + +## The definition of "build system mixing" + +For the purposes of this page, mixing build systems means any and all +mechanisms where one build system uses build artifacts from a +different build system's build directory in any way. + +Note that this definition does not specify what the dependencies are +and how they are built, only how they are consumed. For example +suppose you have a standalone dependency library that builds with +build system X. In this case having Meson call the build system to +build the dependency at build time would be interpreted as mixing +build systems. On the other hand a "Flatpak-like" approach of building +and installing the library with an external mechanism and consuming it +via a standard build-system agnostic method such as Pkg-Config would +not be considered build system mixing. Use of uninstalled-pkgconfig +files is considered mixing, though. + +## What does this mean for support and compatibility? + +The Meson project will not take on any maintenance burden to ensure +anything other than the simple builds setups as discussed above will +work. Nor will we make changes to support these use cases that would +worsen the user experience of users of plain Meson. This includes, but +is not limited to, the following: + +- Any changes in other build systems that cause mixed project breakage + will not be considered a bug in Meson. + +- Breakages in mixed build projects will not be considered regressions + and such problems will never be considered release blockers, + regardless of what the underlying issue is. + +- Any use case that would require major changes in Meson to work + around missing or broken functionality in the other build system is + not supported. These issues must be fixed upstream. diff --git a/meson/docs/markdown/Modules.md b/meson/docs/markdown/Modules.md new file mode 100644 index 000000000..a96668289 --- /dev/null +++ b/meson/docs/markdown/Modules.md @@ -0,0 +1,25 @@ +--- +short-description: Meson modules for common build operations +... + +# Modules + +In addition to core language features, Meson also provides a module +system aimed at providing helper methods for common build operations. +Using modules is simple, first you import them: + +```meson +mymod = import('somemodule') +``` + +After this you can use the returned object to use the functionality +provided: + +```meson +mymod.do_something('text argument') +``` + +Meson has a selection of modules to make common requirements easy to +use. Modules can be thought of like the standard library of a +programming language. Currently Meson provides the modules listed on +subpages. diff --git a/meson/docs/markdown/Native-environments.md b/meson/docs/markdown/Native-environments.md new file mode 100644 index 000000000..d79313224 --- /dev/null +++ b/meson/docs/markdown/Native-environments.md @@ -0,0 +1,50 @@ +--- +short-description: Setting up native compilation +... + +# Persistent native environments + +New in 0.49.0 + +Meson has [cross files for describing cross compilation +environments](Cross-compilation.md), for describing native +environments it has equivalent "native files". + +Natives describe the *build machine*, and can be used to override +properties of non-cross builds, as well as properties that are marked +as "native" in a cross build. + +There are a couple of reasons you might want to use a native file to +keep a persistent environment: + +* To build with a non-default native tool chain (such as clang instead of gcc) +* To use a non-default version of another binary, such as yacc, or llvm-config + +## Changing native file settings + +All of the rules about cross files and changed settings apply to native files +as well, see [here](Cross-compilation.md#changing-cross-file-settings) + +## Defining the environment + +See the [config-files section](Machine-files.md), for options shared by cross +and native files. + +## Native file locations + +Like cross files, native files may be installed to user or system wide +locations, defined as: + - $XDG_DATA_DIRS/meson/native + (/usr/local/share/meson/native:/usr/share/meson/native if $XDG_DATA_DIRS is + undefined) + - $XDG_DATA_HOME/meson/native ($HOME/.local/share/meson/native if + $XDG_DATA_HOME is undefined) + +The order of locations tried is as follows: + - A file relative to the local dir + - The user local location + - The system wide locations in order + +These files are not intended to be shipped by distributions, unless +they are specifically for distribution packaging, they are mainly +intended for developers. diff --git a/meson/docs/markdown/Overview.md b/meson/docs/markdown/Overview.md new file mode 100644 index 000000000..7bee93789 --- /dev/null +++ b/meson/docs/markdown/Overview.md @@ -0,0 +1,58 @@ +--- +short-description: Overview of the Meson build system +... + +# Overview + +Meson is a build system that is designed to be as user-friendly as +possible without sacrificing performance. The main tool for this is a +custom language that the user uses to describe the structure of his +build. The main design goals of this language has been simplicity, +clarity and conciseness. Much inspiration was drawn from the Python +programming language, which is considered very readable, even to +people who have not programmed in Python before. + +Another main idea has been to provide first class support for modern +programming tools and best practices. These include features as varied +as unit testing, code coverage reporting, precompiled headers and the +like. All of these features should be immediately available to any +project using Meson. The user should not need to hunt for third party +macros or write shell scripts to get these features. They should just +work out of the box. + +This power should not come at the expense of limited usability. Many +software builds require unorthodox steps. A common example is that you +first need to build a custom tool and then use that tool to generate +more source code to build. This functionality needs to be supported +and be as easy to use as other parts of the system. + +Terminology +-- + +Meson follows the overall structure of other popular build systems, +such as CMake and GNU Autotools. This means that the build is divided +into two discrete steps: *configure step* and *build step*. The first +step inspects the system, checks for dependencies and does all other +steps necessary to configure the build. It then generates the actual +build system. The second step is simply executing this generated build +system. The end result is a bunch of *build targets*, which are +usually executables and shared and static libraries. + +The directory that contains the source code is called the *source +directory*. Correspondingly the directory where the output is written +is called the *build directory*. In other build systems it is common +to have these two be the same directory. This is called an *in-source +build*. The case where the build directory is separate is called an +*out-of-source build*. + +What sets Meson apart from most build systems is that it enforces a +separate build directory. All files created by the build system are +put in the build directory. It is actually impossible to do an +in-source build. For people used to building inside their source tree, +this may seem like a needless complication. However there are several +benefits to doing only out-of-source builds. These will be explained +in the next chapter. + +When the source code is built, a set of *unit tests* is usually +run. They ensure that the program is working as it should. If it does, +the build result can be *installed* after which it is ready for use. diff --git a/meson/docs/markdown/Performance-comparison.md b/meson/docs/markdown/Performance-comparison.md new file mode 100644 index 000000000..2f47d114a --- /dev/null +++ b/meson/docs/markdown/Performance-comparison.md @@ -0,0 +1,7 @@ +# Performance comparison + +This page lists experiments comparing build performance between Meson +and other build systems. + +- [Simple comparison](Simple-comparison.md) +- [ARM performance test](ARM-performance-test.md) diff --git a/meson/docs/markdown/Pkg-config-files.md b/meson/docs/markdown/Pkg-config-files.md new file mode 100644 index 000000000..1fbef0bab --- /dev/null +++ b/meson/docs/markdown/Pkg-config-files.md @@ -0,0 +1,30 @@ +# Pkg config files + +[Pkg-config](https://en.wikipedia.org/wiki/Pkg-config) is a way for +shared libraries to declare the compiler flags needed to use them. +There are two different ways of generating Pkg-config files in Meson. +The first way is to build them manually with the `configure_file` +command. The second way is to use Meson's built in Pkg-config file +generator. The difference between the two is that the latter is very +simple and meant for basic use cases. The former should be used when +you need to provide a more customized solution. + +In this document we describe the simple generator approach. It is used in the following way. + +```meson +pkg = import('pkgconfig') +libs = ... # the library/libraries users need to link against +h = ['.', ...] # subdirectories of ${prefix}/${includedir} to add to header path +pkg.generate(libraries : libs, + subdirs : h, + version : '1.0', + name : 'libsimple', + filebase : 'simple', + description : 'A simple demo library.') +``` + +This causes a file called `simple.pc` to be created and placed into +the install directory during the install phase. + +More information on the pkg-config module and the parameters can be +found on the [pkgconfig-module](Pkgconfig-module.md) page. diff --git a/meson/docs/markdown/Pkgconfig-module.md b/meson/docs/markdown/Pkgconfig-module.md new file mode 100644 index 000000000..0d1e859eb --- /dev/null +++ b/meson/docs/markdown/Pkgconfig-module.md @@ -0,0 +1,127 @@ +# Pkgconfig module + +This module is a simple generator for +[pkg-config](https://pkg-config.freedesktop.org/) files. + +## Usage + +```meson +pkg = import('pkgconfig') +bar_dep = dependency('bar') +lib = library('foo', dependencies : [bar]) +pkg.generate(lib) +``` + +### pkg.generate() + +The generated file's properties are specified with the following +keyword arguments. + +- `description` a string describing the library, used to set the `Description:` field +- `extra_cflags` a list of extra compiler flags to be added to the + `Cflags` field after the header search path +- `filebase` the base name to use for the pkg-config file; as an + example, the value of `libfoo` would produce a pkg-config file called + `libfoo.pc` +- `install_dir` the directory to install to, defaults to the value of + option `libdir` followed by `/pkgconfig` +- `libraries` a list of built libraries (usually results of + shared_library) that the user needs to link against. Arbitrary strings can + also be provided and they will be added into the `Libs` field. Since 0.45.0 + dependencies of built libraries will be automatically added, see the + [Implicit dependencies](#implicit-dependencies) section below for the exact + rules. Since 0.58.0 custom_target() objects are supported as long as they are + linkable (has known extension such as `.a`, `.so`, etc). +- `libraries_private` list of built libraries or strings to put in the + `Libs.private` field. Since 0.45.0 dependencies of built libraries will be + automatically added, see the [Implicit dependencies](#implicit-dependencies) + section below for the exact rules. Since 0.58.0 custom_target() objects are + supported as long as they are linkable (has known extension such as `.a`, + `.so`, etc). +- `name` the name of this library, used to set the `Name:` field +- `subdirs` which subdirs of `include` should be added to the header + search path, for example if you install headers into + `${PREFIX}/include/foobar-1`, the correct value for this argument + would be `foobar-1` +- `requires` list of strings, pkgconfig-dependencies or libraries that + `pkgconfig.generate()` was used on to put in the `Requires` field +- `requires_private` same as `requires` but for `Requires.private` field + field +- `url` a string with a url for the library +- `variables` a list of strings with custom variables to add to the + generated file. The strings must be in the form `name=value` and may + reference other pkgconfig variables, + e.g. `datadir=${prefix}/share`. The names `prefix`, `libdir` and + `includedir` are reserved and may not be used. *Since 0.56.0* it can also be a + dictionary but ordering of Meson dictionaries are not guaranteed, which could + cause issues when some variables reference other variables. + Spaces in values are escaped with `\`, this is required in the case the value is + a path that and is used in `cflags` or `libs` arguments. *Since 0.59.0* if + escaping is not desired (e.g. space separate list of values) `unescaped_variables` + keyword argument should be used instead. +- `uninstalled_variables` used instead of the `variables` keyword argument, when + generating the uninstalled pkg-config file. Since *0.54.0* + Spaces in values are escaped with `\`, this is required in the case the value is + a path that and is used in `cflags` or `libs` arguments. *Since 0.59.0* if + escaping is not desired (e.g. space separate list of values) + `unescaped_uninstalled_variables` keyword argument should be used instead. +- `version` a string describing the version of this library, used to set the + `Version:` field. (*since 0.46.0*) Defaults to the project version if unspecified. +- `d_module_versions` a list of module version flags used when compiling + D sources referred to by this pkg-config file +- `dataonly` field. (*since 0.54.0*) this is used for architecture-independent + pkg-config files in projects which also have architecture-dependent outputs. +- `conflicts` (*since 0.36.0, incorrectly issued a warning prior to 0.54.0*) list of strings to be put in the `Conflicts` field. + +Since 0.46 a `StaticLibrary` or `SharedLibrary` object can optionally +be passed as first positional argument. If one is provided a default +value will be provided for all required fields of the pc file: +- `install_dir` is set to `pkgconfig` folder in the same location than the provided library. +- `description` is set to the project's name followed by the library's name. +- `name` is set to the library's name. + +Since 0.54.0 uninstalled pkg-config files are generated as well. They +are located in `<build dir>/meson-uninstalled/`. It is sometimes +useful to build projects against libraries built by Meson without +having to install them into a prefix. In order to do so, just set +`PKG_CONFIG_PATH=<builddir>/meson-uninstalled` before building your +application. That will cause pkg-config to prefer those +`-uninstalled.pc` files and find libraries and headers from the Meson +builddir. This is an experimental feature provided on a best-effort +basis, it might not work in all use-cases. + +### Implicit dependencies + +The exact rules followed to find dependencies that are implicitly +added into the pkg-config file have evolved over time. Here are the +rules as of Meson *0.49.0*, previous versions might have slightly +different behaviour. + +- Not found libraries or dependencies are ignored. +- Libraries and dependencies are private by default (i.e. added into + `Requires.private:` or `Libs.private:`) unless they are explicitly added in + `libraries` or `requires` keyword arguments, or is the main library (first + positional argument). +- Libraries and dependencies will be de-duplicated, if they are added in both + public and private (e.g `Requires:` and `Requires.private:`) it will be removed + from the private list. +- Shared libraries (i.e. `shared_library()` and **NOT** `library()`) add only + `-lfoo` into `Libs:` or `Libs.private:` but their dependencies are not pulled. + This is because dependencies are only needed for static link. +- Other libraries (i.e. `static_library()` or `library()`) add `-lfoo` into `Libs:` + or `Libs.private:` and recursively add their dependencies into `Libs.private:` or + `Requires.private:`. +- Dependencies provided by pkg-config are added into `Requires:` or + `Requires.private:`. If a version was specified when declaring that dependency + it will be written into the generated file too. +- The threads dependency (i.e. `dependency('threads')`) adds `-pthread` into + `Libs:` or `Libs.private:`. +- Internal dependencies (i.e. + `declare_dependency(compiler_args : '-DFOO', link_args : '-Wl,something', link_with : foo)`) + add `compiler_args` into `Cflags:` if public, `link_args` and `link_with` into + `Libs:` if public or `Libs.private:` if private. +- Other dependency types add their compiler arguments into `Cflags:` if public, + and linker arguments into `Libs:` if public or `Libs.private:` if private. +- Once a pkg-config file is generated for a library using `pkg.generate(mylib)`, + any subsequent call to `pkg.generate()` where mylib appears, will generate a + `Requires:` or `Requires.private` instead of a `Libs:` or `Libs.private:`. diff --git a/meson/docs/markdown/Playground.md b/meson/docs/markdown/Playground.md new file mode 100644 index 000000000..906197841 --- /dev/null +++ b/meson/docs/markdown/Playground.md @@ -0,0 +1,35 @@ +# playground + +This page is *not* part of official documentation. It exists merely +for testing new stuff for the wiki. + +## Ref manual reformat + +The current format is not very readable. We should have something more +like what +[glib](https://developer.gnome.org/glib/stable/glib-Hash-Tables.html) +or [Python](https://docs.python.org/3/library/os.html) do. + +Here's a first proposal. + + project(<project name>, + <languages to use, comma separated>, + version : <project version>, + subproject_dir : <alternative directory to store subprojects>, + meson_version : <required version of Meson>, + license : <string or array of licenses>, + default_options : <default values for project options>, + +Longer descriptions of arguments go here. + +Take two: + +## project + + <project name> + <languages to use, comma separated> + version : <project version> + subproject_dir : <alternative directory to store subprojects> + meson_version : <required version of Meson> + license : <string or array of licenses> + default_options : <default values for project options> diff --git a/meson/docs/markdown/Porting-from-autotools.md b/meson/docs/markdown/Porting-from-autotools.md new file mode 100644 index 000000000..34e1bbd3a --- /dev/null +++ b/meson/docs/markdown/Porting-from-autotools.md @@ -0,0 +1,700 @@ +# Porting from Autotools + +This page uses +[AppStream-glib](https://github.com/hughsie/appstream-glib/) as an +example project. AppStream-Glib contains some libraries, GObject +Introspection data, tests, man pages, i18n, bash-completion with +optional flags to build/not build support for some things. + +Meson comes with a helper script `ac_converter` that you can use to +convert the basic autoconf checks for your project. + +## Configure.ac + +First let's look at `configure.ac` and write the same in +`meson.build`. + +```autoconf +AC_PREREQ(2.63) +``` +Meson doesn't provide the same function, so just ignore this. + +### Defining variables +`configure.ac`: +```autoconf +m4_define([as_major_version], [0]) +m4_define([as_minor_version], [3]) +m4_define([as_micro_version], [6]) +m4_define([as_version], + [as_major_version.as_minor_version.as_micro_version]) +``` +`meson.build`: +```meson + +as_version = meson.project_version() # set in project() below +ver_arr = as_version.split('.') + +as_major_version = ver_arr[0] +as_minor_version = ver_arr[1] +as_micro_version = ver_arr[2] +``` + +### Initializing project and setting compilers +`configure.ac`: +```autoconf +AC_INIT([appstream-glib],[as_version]) +AC_PROG_CC +``` +`meson.build`: +```meson +project('appstream-glib', 'c', version : '0.3.6') +``` +Note that this must be the first line of your `meson.build` file. + +### AC_SUBST +`configure.ac`: +```autoconf +AC_SUBST(AS_MAJOR_VERSION) +AC_SUBST(AS_MINOR_VERSION) +AC_SUBST(AS_MICRO_VERSION) +AC_SUBST(AS_VERSION) +``` + +You don't need to do the same in Meson, because it does not have two +different types of files (Makefile, configure). + +### Auto headers + +`configure.ac`: + +```autoconf +AC_CONFIG_HEADERS([config.h]) +``` + +`meson.build`: + +```meson +conf = configuration_data() +# Surround the version in quotes to make it a C string +conf.set_quoted('VERSION', as_version) +configure_file(output : 'config.h', + configuration : conf) +``` + +Meson doesn't support autoheaders, you need to manually specify what +do you want to see in header file, write `configuration_data()` object +and use `configure_file()`. + +You can also substitute variables of type `@SOME_VAR@` with configure +data. The details are on the [configuration page](Configuration.md). + +### Finding programs + +`configure.ac`: + +```autoconf +AC_PATH_PROG(GPERF, [gperf], [no]) +if test x$GPERF != xno ; then + AC_DEFINE(HAVE_GPERF,[1], [Use gperf]) +fi +AM_CONDITIONAL(HAVE_GPERF, [test x$GPERF != xno]) +``` + +`meson.build`: + +```meson +gperf = find_program('gperf', required : false) +if gperf.found() + conf.set('HAVE_GPERF', 1) +endif +``` + +### Finding pkg-config modules + +`configure.ac`: + +```autoconf +PKG_CHECK_MODULES(SOUP, libsoup-2.4 >= 2.24) +``` + +`meson.build`: + +```meson +soup = dependency('libsoup-2.4', version : '>= 2.24') +``` + +### Arguments + +`configure.ac`: + +```autoconf +AC_ARG_ENABLE(dep11, AS_HELP_STRING([--enable-dep11],[enable DEP-11]), + enable_dep11=$enableval,enable_dep11=yes) +AM_CONDITIONAL(HAVE_DEP11, test x$enable_dep11 = xyes) +if test x$enable_dep11 = xyes; then + AC_CHECK_HEADER(yaml.h, [], [AC_MSG_ERROR([No yaml.h])]) + YAML_LIBS="-lyaml" + AC_SUBST(YAML_LIBS) + AC_DEFINE(AS_BUILD_DEP11,1,[Build DEP-11 code]) +fi +``` + +`meson.build`: + +```meson +if get_option('enable-dep11') + yaml = dependency('yaml-0.1') + conf.set('AS_BUILD_DEP11', 1) +else + yaml = dependency('yaml-0.1', required : false) +endif +``` + +`meson_options.txt`: + +```meson +option('enable-dep11', type : 'boolean', value : true, description : 'enable DEP-11') +``` + +## Makefile.am + +Next step is `Makefile.am`. In Meson you don't need to have other +file, you still use `meson.build`. + +### Sub directories + +`Makefile.am`: + +```make +SUBDIRS = \ + libappstream-glib +``` + +`meson.build`: + +```meson +subdir('libappstream-glib') +``` + +### *CLEANFILES, EXTRA_DIST, etc. + +`Makefile.am`: + +```make +DISTCLEANFILES = \ + appstream-glib-*.tar.xz + +MAINTAINERCLEANFILES = \ + *~ \ + ABOUT-NLS \ + aclocal.m4 \ + ChangeLog \ + compile \ + config.guess \ + config.h.* \ + config.rpath + +EXTRA_DIST = \ + COPYING \ + MAINTAINERS \ + AUTHORS \ + README.md \ + NEWS \ + autogen.sh \ + config.h +``` + +In Meson you don't need have `*CLEANFILES`, because in Meson you are +building in temporary directory (usually called `build`), you manually +removing it. You also not need to use `EXTRA_DIST`, because you will +make tarballs via `git archive` or something like this. + +### glib-compile-resources + +`Makefile.am`: +```make +as-resources.c: appstream-glib.gresource.xml \ + as-stock-icons.txt \ + as-license-ids.txt \ + as-blacklist-ids.txt \ + as-category-ids.txt \ + as-environment-ids.txt + $(AM_V_GEN) \ + glib-compile-resources \ + --sourcedir=$(srcdir) \ + --sourcedir=$(top_builddir)/data \ + --target=$@ \ + --generate-source \ + --c-name as \ + $(srcdir)/appstream-glib.gresource.xml +as-resources.h: appstream-glib.gresource.xml \ + as-stock-icons.txt \ + as-license-ids.txt \ + as-blacklist-ids.txt \ + as-category-ids.txt \ + as-environment-ids.txt + $(AM_V_GEN) \ + glib-compile-resources \ + --sourcedir=$(srcdir) \ + --sourcedir=$(top_builddir)/data \ + --target=$@ \ + --generate-header \ + --c-name as \ + $(srcdir)/appstream-glib.gresource.xml + +BUILT_SOURCES = \ + as-resources.c \ + as-resources.h +``` + +`meson.build`: + +```meson +asresources = gnome.compile_resources( + 'as-resources', 'appstream-glib.gresource.xml', + source_dir : '.', + c_name : 'as') +``` + +### Headers + +`Makefile.am`: + +```make +libappstream_glib_includedir = $(includedir)/libappstream-glib +libappstream_glib_include_HEADERS = \ + appstream-glib.h \ + as-app.h \ + as-bundle.h \ + as-enums.h \ + as-icon.h \ + as-image.h \ + as-inf.h \ + as-node.h \ + as-problem.h \ + as-provide.h \ + as-release.h \ + as-screenshot.h \ + as-store.h \ + as-tag.h \ + as-utils.h \ + as-version.h +``` + +`meson.build`: + +```meson +headers = [ + 'appstream-glib.h', + 'as-app.h', + 'as-bundle.h', + 'as-enums.h', + 'as-icon.h', + 'as-image.h', + 'as-inf.h', + 'as-node.h', + 'as-problem.h', + 'as-provide.h', + 'as-release.h', + 'as-screenshot.h', + 'as-store.h', + 'as-tag.h', + 'as-utils.h', + 'as-version.h'] +install_headers(headers, subdir : 'libappstream-glib') +``` + +### Libraries + +`Makefile.am`: +```make +lib_LTLIBRARIES = \ + libappstream-glib.la +libappstream_glib_la_SOURCES = \ + as-app.c \ + as-app-desktop.c \ + as-app-inf.c \ + as-app-private.h \ + as-app-validate.c \ + as-bundle.c \ + as-bundle-private.h \ + as-cleanup.h \ + as-enums.c \ + as-icon.c \ + as-icon-private.h \ + as-image.c \ + as-image-private.h \ + as-inf.c \ + as-inf.h \ + as-node.c \ + as-node-private.h \ + as-problem.c \ + as-problem.h \ + as-provide.c \ + as-provide-private.h \ + as-release.c \ + as-release-private.h \ + as-resources.c \ + as-resources.h \ + as-screenshot.c \ + as-screenshot-private.h \ + as-store.c \ + as-tag.c \ + as-utils.c \ + as-utils-private.h \ + as-version.h \ + as-yaml.c \ + as-yaml.h + +libappstream_glib_la_LIBADD = \ + $(GLIB_LIBS) \ + $(GDKPIXBUF_LIBS) \ + $(LIBARCHIVE_LIBS) \ + $(SOUP_LIBS) \ + $(YAML_LIBS) + +libappstream_glib_la_LDFLAGS = \ + -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ + -export-dynamic \ + -no-undefined \ + -export-symbols-regex '^as_.*' +``` + +`meson.build`: + +```meson +sources = [ + 'as-app.c', + 'as-app-desktop.c', + 'as-app-inf.c', + 'as-app-private.h', + 'as-app-validate.c', + 'as-bundle.c', + 'as-bundle-private.h', + 'as-cleanup.h', + 'as-enums.c', + 'as-icon.c', + 'as-icon-private.h', + 'as-image.c', + 'as-image-private.h', + 'as-inf.c', + 'as-inf.h', + 'as-node.c', + 'as-node-private.h', + 'as-problem.c', + 'as-problem.h', + 'as-provide.c', + 'as-provide-private.h', + 'as-release.c', + 'as-release-private.h', + asresources, + 'as-screenshot.c', + 'as-screenshot-private.h', + 'as-store.c', + 'as-tag.c', + 'as-utils.c', + 'as-utils-private.h', + 'as-version.h', + 'as-yaml.c', + 'as-yaml.h'] + +deps = [glib, gdkpixbuf, libarchive, soup, yaml] + +mapfile = 'appstream-glib.map' +vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile) +asglib = shared_library( + 'appstream-glib', sources, + soversion : lt_current, + version : lt_version, + dependencies : deps, + include_directories : include_directories('@0@/..'.format(meson.current_build_dir())), + link_args : ['-Wl,--no-undefined', vflag], + link_depends : mapfile, + install : true) +``` + +`appstream-glib.map`: + +``` +{ +global: + as_*; +local: + *; +}; +``` + +### Custom targets + +`Makefile.am`: + +```make +if HAVE_GPERF +as-tag-private.h: as-tag.gperf + $(AM_V_GEN) gperf < $< > $@ + +libappstream_glib_la_SOURCES += as-tag-private.h +BUILT_SOURCES += as-tag-private.h +endif +``` + +`meson.build`: + +```meson +if gperf.found() + astagpriv = custom_target('gperf as-tag', + output : 'as-tag-private.h', + input : 'as-tag.gperf', + command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@']) + sources = sources + [astagpriv] +endif +``` + +### Global CFLAGS + +`Makefile.am`: + +```make +AM_CPPFLAGS = \ + -DAS_COMPILATION \ + -DLOCALSTATEDIR=\""$(localstatedir)"\" \ + -DG_LOG_DOMAIN=\"As\" +``` + +`meson.build`: + +```meson +add_project_arguments('-DG_LOG_DOMAIN="As"', language : 'c') +add_project_arguments('-DAS_COMPILATION', language : 'c') +add_project_arguments('-DLOCALSTATEDIR="/var"', language : 'c') +``` + +### Tests + +`Makefile.am`: + +```make +check_PROGRAMS = \ + as-self-test +as_self_test_SOURCES = \ + as-self-test.c +as_self_test_LDADD = \ + $(GLIB_LIBS) \ + $(GDKPIXBUF_LIBS) \ + $(LIBARCHIVE_LIBS) \ + $(SOUP_LIBS) \ + $(YAML_LIBS) \ + $(lib_LTLIBRARIES) +as_self_test_CFLAGS = -DTESTDATADIR=\""$(top_srcdir)/data/tests"\" + +TESTS = as-self-test +``` + +`meson.build`: + +```meson +selftest = executable( + 'as-self-test', 'as-self-test.c', + include_directories : include_directories('@0@/..'.format(meson.current_build_dir())), + dependencies : deps, + c_args : '-DTESTDATADIR="@0@/../data/tests"'.format(meson.current_source_dir()), + link_with : asglib) +test('as-self-test', selftest) +``` + +### GObject Introspection + +`Makefile.am`: + +```make +introspection_sources = \ + as-app.c \ + as-app-validate.c \ + as-app.h \ + as-bundle.c \ + as-bundle.h \ + as-enums.c \ + as-enums.h \ + as-icon.c \ + as-icon.h \ + as-image.c \ + as-image.h \ + as-inf.c \ + as-inf.h \ + as-node.c \ + as-node.h \ + as-problem.c \ + as-problem.h \ + as-provide.c \ + as-provide.h \ + as-release.c \ + as-release.h \ + as-screenshot.c \ + as-screenshot.h \ + as-store.c \ + as-store.h \ + as-tag.c \ + as-tag.h \ + as-utils.c \ + as-utils.h \ + as-version.h + +AppStreamGlib-1.0.gir: libappstream-glib.la +AppStreamGlib_1_0_gir_INCLUDES = GObject-2.0 Gio-2.0 GdkPixbuf-2.0 +AppStreamGlib_1_0_gir_CFLAGS = $(AM_CPPFLAGS) +AppStreamGlib_1_0_gir_SCANNERFLAGS = --identifier-prefix=As \ + --symbol-prefix=as_ \ + --warn-all \ + --add-include-path=$(srcdir) +AppStreamGlib_1_0_gir_EXPORT_PACKAGES = appstream-glib +AppStreamGlib_1_0_gir_LIBS = libappstream-glib.la +AppStreamGlib_1_0_gir_FILES = $(introspection_sources) +INTROSPECTION_GIRS += AppStreamGlib-1.0.gir + +girdir = $(datadir)/gir-1.0 +gir_DATA = $(INTROSPECTION_GIRS) + +typelibdir = $(libdir)/girepository-1.0 +typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) + +CLEANFILES += $(gir_DATA) $(typelib_DATA) +``` + +`meson.build`: + +```meson +introspection_sources = [ + 'as-app.c', + 'as-app-validate.c', + 'as-app.h', + 'as-bundle.c', + 'as-bundle.h', + 'as-enums.c', + 'as-enums.h', + 'as-icon.c', + 'as-icon.h', + 'as-image.c', + 'as-image.h', + 'as-inf.c', + 'as-inf.h', + 'as-node.c', + 'as-node.h', + 'as-problem.c', + 'as-problem.h', + 'as-provide.c', + 'as-provide.h', + 'as-release.c', + 'as-release.h', + 'as-screenshot.c', + 'as-screenshot.h', + 'as-store.c', + 'as-store.h', + 'as-tag.c', + 'as-tag.h', + 'as-utils.c', + 'as-utils.h', + 'as-version.h'] + +gnome.generate_gir(asglib, + sources : introspection_sources, + nsversion : '1.0', + namespace : 'AppStreamGlib', + symbol_prefix : 'as_', + identifier_prefix : 'As', + export_packages : 'appstream-glib', + includes : ['GObject-2.0', 'Gio-2.0', 'GdkPixbuf-2.0'], + install : true +) +``` + +### GSettings + +`configure.ac`: +```sh +GLIB_GSETTINGS +``` + +`Makefile.am`: +```make +gsettings_SCHEMAS = foo.gschema.xml +@GSETTINGS_RULES@ +``` + +`meson.build`: +```meson +install_data('foo.gschema.xml', install_dir: get_option('datadir') / 'glib-2.0' / 'schemas') +meson.add_install_script('meson_post_install.py') +``` + +`meson_post_install.py`: +```python +#!/usr/bin/env python3 + +import os +import subprocess + +schemadir = os.path.join(os.environ['MESON_INSTALL_PREFIX'], 'share', 'glib-2.0', 'schemas') + +if not os.environ.get('DESTDIR'): + print('Compiling gsettings schemas...') + subprocess.call(['glib-compile-schemas', schemadir]) +``` + +### gettext + +Note this example does not include `intltool` usage. + +`configure.ac`: +```m4 +AM_GNU_GETTEXT([external]) +AM_GNU_GETTEXT_VERSION([0.19.7]) + +GETTEXT_PACKAGE=foo +AC_SUBST(GETTEXT_PACKAGE) +AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [The prefix for our gettext translation domains.]) +``` + +`po/Makevars`: +```make +XGETTEXT_OPTIONS = --from-code=UTF-8 --keyword=_ --keyword=N_ --keyword=C_:1c,2 --keyword=NC_:1c,2 --keyword=g_dngettext:2,3 --add-comments +``` + +`Makefile.am`: +```make +%.desktop: %.desktop.in + $(AM_V_GEN)$(MSGFMT) --desktop --template $< -d $(top_srcdir)/po -o $@ + +%.appdata.xml: %.appdata.xml.in + $(AM_V_GEN)$(MSGFMT) --xml --template $< -d $(top_srcdir)/po -o $@ +``` + +`meson.build`: +```meson +i18n = import('i18n') + +gettext_package = 'foo' +add_project_arguments('-DGETTEXT_PACKAGE=' + gettext_package, language: 'c') +subdir('po') + +i18n.merge_file( + input: 'foo.desktop.in', + output: 'foo.desktop', + type: 'desktop', + po_dir: 'po', + install: true, + install_dir: get_option('datadir') / 'applications' +) + +i18n.merge_file( + input: 'foo.appdata.xml.in', + output: 'foo.appdata.xml', + po_dir: 'po', + install: true, + install_dir: get_option('datadir') / 'appdata' +) +``` + +`po/meson.build`: +```meson +i18n.gettext(gettext_package, preset: 'glib') +``` diff --git a/meson/docs/markdown/Precompiled-headers.md b/meson/docs/markdown/Precompiled-headers.md new file mode 100644 index 000000000..e78dfe04e --- /dev/null +++ b/meson/docs/markdown/Precompiled-headers.md @@ -0,0 +1,119 @@ +--- +short-description: Using precompiled headers to reduce compilation time +... + +# Precompiled headers + +Parsing header files of system libraries is surprisingly expensive. A +typical source file has less than one thousand lines of code. In +contrast the headers of large libraries can be tens of thousands of +lines. This is especially problematic with C++, where header-only +libraries are common and they may contain extremely complex code. This +makes them slow to compile. + +Precompiled headers are a tool to mitigate this issue. Basically what +they do is parse the headers and then serialize the compiler's +internal state to disk. The downside of precompiled headers is that +they are tricky to set up. Meson has native support for precompiled +headers, but using them takes a little work. + +A precompiled header file is relatively simple. It is a header file +that contains `#include` directives for the system headers to +precompile. Here is a C++ example. + +```cpp + #include<vector> + #include<string> + #include<map> +``` + +In Meson, precompiled header files are always per-target. That is, the +given precompiled header is used when compiling every single file in +the target. Due to limitations of the underlying compilers, this +header file must not be in the same subdirectory as any of the source +files. It is strongly recommended that you create a subdirectory +called `pch` in the target directory and put the header files (and +nothing else) there. + +Toggling the usage of precompiled headers +-- + +If you wish to compile your project without precompiled headers, you +can change the value of the pch option by passing `-Db_pch=false` +argument to Meson at configure time or later with `meson configure`. +You can also toggle the use of pch in a configured build directory +with the GUI tool. You don't have to do any changes to the source +code. Typically this is done to test whether your project compiles +cleanly without pch (that is, checking that its #includes are in +order) and working around compiler bugs. + +Using precompiled headers with GCC and derivatives +-- + +Once you have a file to precompile, you can enable the use of pch for +a given target with a *pch* keyword argument. As an example, let's +assume you want to build a small C binary with precompiled headers. +Let's say the source files of the binary use the system headers +`stdio.h` and `string.h`. Then you create a header file +`pch/myexe_pch.h` with this content: + +```c +#include <stdio.h> +#include <string.h> +``` + +And add this to Meson: + +```meson +executable('myexe', sources : sourcelist, c_pch : 'pch/myexe_pch.h') +``` + +That's all. You should note that your source files must _not_ include +the file `myexe_pch.h` and you must _not_ add the pch subdirectory to +your search path. Any modification of the original program files is +not necessary. Meson will make the compiler include the pch with +compiler options. If you want to disable pch (because of, say, +compiler bugs), it can be done entirely on the build system side with +no changes to source code. + +You can use precompiled headers on any build target. If your target +has multiple languages, you can specify multiple pch files like this. + +```meson +executable('multilang', sources : srclist, + c_pch : 'pch/c_pch.h', cpp_pch : 'pch/cpp_pch.h') +``` + +Using precompiled headers with MSVC +-- +Since Meson version 0.50.0, precompiled headers with MSVC work just like +with GCC. Meson will automatically create the matching pch implementation +file for you. + +Before version 0.50.0, in addition to the header file, Meson +also requires a corresponding source file. If your header is called +`foo_pch.h`, the corresponding source file is usually called +`foo_pch.cpp` and it resides in the same `pch` subdirectory as the +header. Its contents are this: + +```cpp +#if !defined(_MSC_VER) +#error "This file is only for use with MSVC." +#endif + +#include "foo_pch.h" +``` + +To enable pch, simply list both files in the target definition: + +```meson +executable('myexe', sources : srclist, + cpp_pch : ['pch/foo_pch.h', 'pch/foo_pch.cpp']) +``` + +This form will work with both GCC and msvc, because Meson knows that +GCC does not need a `.cpp` file and thus just ignores it. + +It should be noted that due to implementation details of the MSVC +compiler, having precompiled headers for multiple languages in the +same target is not guaranteed to work. diff --git a/meson/docs/markdown/Project-templates.md b/meson/docs/markdown/Project-templates.md new file mode 100644 index 000000000..7ded318b7 --- /dev/null +++ b/meson/docs/markdown/Project-templates.md @@ -0,0 +1,49 @@ +--- +short-description: Project templates +... + +# Project templates + +To make it easier for new developers to start working, Meson ships a +tool to generate the basic setup of different kinds of projects. This +functionality can be accessed with the `meson init` command. A typical +project setup would go like this: + +```console +$ mkdir project_name +$ cd project_name +$ meson init --language=c --name=myproject --version=0.1 +``` + +This would create the build definitions for a helloworld type +project. The result can be compiled as usual. For example it +could be done like this: + +``` +$ meson setup builddir +$ meson compile -C builddir +``` + +The generator has many different projects and settings. They can all +be listed by invoking the command `meson init --help`. + +This feature is available since Meson version 0.45.0. + +# Generate a build script for an existing project + +With `meson init` you can generate a build script for an existing +project with existing project files by running the command in the +root directory of your project. Meson currently supports this +feature for `executable`, and `jar` projects. + +# Build after generation of template + +It is possible to have Meson generate a build directory from the +`meson init` command without running `meson setup`. This is done +by passing `-b` or `--build` switch. + +```console +$ mkdir project_name +$ cd project_name +$ meson init --language=c --name=myproject --version=0.1 --build +```
\ No newline at end of file diff --git a/meson/docs/markdown/Python-3-module.md b/meson/docs/markdown/Python-3-module.md new file mode 100644 index 000000000..b89ea3e2f --- /dev/null +++ b/meson/docs/markdown/Python-3-module.md @@ -0,0 +1,57 @@ +# Python 3 module + +This module provides support for dealing with Python 3. It has the +following methods. + +This module is deprecated and replaced by the +[python](Python-module.md) module. + +## find_python + +This is a cross platform way of finding the Python 3 executable, which +may have a different name on different operating systems. Returns an +[external program](Reference-manual.md#external-program-object) +object. + +*Added 0.38.0* + +Deprecated, replaced by +[`find_installation`](Python-module.md#find_installation) function +from `python` module. + +## extension_module + +Creates a `shared_module` target that is named according to the naming +conventions of the target platform. All positional and keyword +arguments are the same as for +[shared_module](Reference-manual.md#shared_module). + +`extension_module` does not add any dependencies to the library so user may +need to add `dependencies : dependency('python3')`, see +[Python3 dependency](Dependencies.md#python3). + +*Added 0.38.0* + +Deprecated, replaced by +[`extension_module`](Python-module.md#extension_module) method from +`python` module. + +## language_version + +Returns a string with the Python language version such as `3.5`. + +*Added 0.40.0* + +Deprecated, replaced by +[`language_version`](Python-module.md#language_version) method from +`python` module. + +## sysconfig_path + +Returns the Python sysconfig path without prefix, such as +`lib/python3.6/site-packages`. + +*Added 0.40.0* + +Deprecated, replaced by [`get_path`](Python-module.md#get_path) +method from `python` module. diff --git a/meson/docs/markdown/Python-module.md b/meson/docs/markdown/Python-module.md new file mode 100644 index 000000000..3b7b4f59c --- /dev/null +++ b/meson/docs/markdown/Python-module.md @@ -0,0 +1,248 @@ +--- +short-description: Generic python module +authors: + - name: Mathieu Duponchelle + email: mathieu@centricular.com + years: [2018] + has-copyright: false +... + +# Python module + +This module provides support for finding and building extensions against +python installations, be they python 2 or 3. + +*Added 0.46.0* + +## Functions + +### `find_installation()` + +``` meson +pymod.find_installation(name_or_path, ...) +``` + +Find a python installation matching `name_or_path`. + +That argument is optional, if not provided then the returned python +installation will be the one used to run Meson. + +If provided, it can be: + +- A simple name, eg `python-2.7`, Meson will look for an external program + named that way, using [find_program] + +- A path, eg `/usr/local/bin/python3.4m` + +- One of `python2` or `python3`: in either case, the module will try + some alternative names: `py -2` or `py -3` on Windows, and `python` + everywhere. In the latter case, it will check whether the version + provided by the sysconfig module matches the required major version + +Keyword arguments are the following: + +- `required`: by default, `required` is set to `true` and Meson will + abort if no python installation can be found. If `required` is set to `false`, + Meson will continue even if no python installation was found. You can + then use the `.found()` method on the returned object to check + whether it was found or not. Since *0.48.0* the value of a + [`feature`](Build-options.md#features) option can also be passed to the + `required` keyword argument. +- `disabler`: if `true` and no python installation can be found, return a + [disabler object](Reference-manual.md#disabler-object) instead of a not-found object. + *Since 0.49.0* +- `modules`: a list of module names that this python installation must have. + *Since 0.51.0* + +**Returns**: a [python installation][`python_installation` object] + +## `python_installation` object + +The `python_installation` object is an [external program], with several +added methods. + +### Methods + +#### `path()` + +```meson +str py_installation.path() +``` + +*Added 0.50.0* + +Works like the path method of other `ExternalProgram` objects. Was not +provided prior to 0.50.0 due to a bug. + +#### `extension_module()` + +``` meson +shared_module py_installation.extension_module(module_name, list_of_sources, ...) +``` + +Create a `shared_module` target that is named according to the naming +conventions of the target platform. + +All positional and keyword arguments are the same as for +[shared_module], excluding `name_suffix` and `name_prefix`, and with +the addition of the following: + +- `subdir`: By default, Meson will install the extension module in + the relevant top-level location for the python installation, eg + `/usr/lib/site-packages`. When subdir is passed to this method, + it will be appended to that location. This keyword argument is + mutually exclusive with `install_dir` + +`extension_module` does not add any dependencies to the library so +user may need to add `dependencies : py_installation.dependency()`, +see [][`dependency()`]. + +**Returns**: a [buildtarget object] + +#### `dependency()` + +``` meson +python_dependency py_installation.dependency(...) +``` + +This method accepts no positional arguments, and the same keyword +arguments as the standard [dependency] function. It also supports the +following keyword argument: + +- `embed`: *(since 0.53.0)* If true, Meson will try to find a python + dependency that can be used for embedding python into an + application. + +**Returns**: a [python dependency][`python_dependency` object] + +#### `install_sources()` + +``` meson +void py_installation.install_sources(list_of_files, ...) +``` + +Install actual python sources (`.py`). + +All positional and keyword arguments are the same as for +[install_data], with the addition of the following: + +- `pure`: On some platforms, architecture independent files are + expected to be placed in a separate directory. However, if the + python sources should be installed alongside an extension module + built with this module, this keyword argument can be used to + override that behaviour. Defaults to `true` + +- `subdir`: See documentation for the argument of the same name to + [][`extension_module()`] + +#### `get_install_dir()` + +``` meson +string py_installation.get_install_dir(...) +``` + +Retrieve the directory [][`install_sources()`] will install to. + +It can be useful in cases where `install_sources` cannot be used +directly, for example when using [configure_file]. + +This function accepts no arguments, its keyword arguments are the same +as [][`install_sources()`]. + +**Returns**: A string + +#### `language_version()` + +``` meson +string py_installation.language_version() +``` + +Get the major.minor python version, eg `2.7`. + +The version is obtained through the `sysconfig` module. + +This function expects no arguments or keyword arguments. + +**Returns**: A string + +#### `get_path()` + +``` meson +string py_installation.get_path(path_name, fallback) +``` + +Get a path as defined by the `sysconfig` module. + +For example: + +``` meson +purelib = py_installation.get_path('purelib') +``` + +This function requires at least one argument, `path_name`, +which is expected to be a non-empty string. + +If `fallback` is specified, it will be returned if no path +with the given name exists. Otherwise, attempting to read +a non-existing path will cause a fatal error. + +**Returns**: A string + +#### `has_path()` + +``` meson + bool py_installation.has_path(path_name) +``` + +**Returns**: true if a path named `path_name` can be retrieved with +[][`get_path()`], false otherwise. + +#### `get_variable()` + +``` meson +string py_installation.get_variable(variable_name, fallback) +``` + +Get a variable as defined by the `sysconfig` module. + +For example: + +``` meson +py_bindir = py_installation.get_variable('BINDIR', '') +``` + +This function requires at least one argument, `variable_name`, +which is expected to be a non-empty string. + +If `fallback` is specified, it will be returned if no variable +with the given name exists. Otherwise, attempting to read +a non-existing variable will cause a fatal error. + +**Returns**: A string + +#### `has_variable()` + +``` meson + bool py_installation.has_variable(variable_name) +``` + +**Returns**: true if a variable named `variable_name` can be retrieved +with [][`get_variable()`], false otherwise. + +## `python_dependency` object + +This [dependency object] subclass will try various methods to obtain +the compiler and linker arguments, starting with pkg-config then +potentially using information obtained from python's `sysconfig` +module. + +It exposes the same methods as its parent class. + +[find_program]: Reference-manual.md#find_program +[shared_module]: Reference-manual.md#shared_module +[external program]: Reference-manual.md#external-program-object +[dependency]: Reference-manual.md#dependency +[install_data]: Reference-manual.md#install_data +[configure_file]: Reference-manual.md#configure_file +[dependency object]: Reference-manual.md#dependency-object +[buildtarget object]: Reference-manual.md#build-target-object diff --git a/meson/docs/markdown/Qt4-module.md b/meson/docs/markdown/Qt4-module.md new file mode 100644 index 000000000..6b6241569 --- /dev/null +++ b/meson/docs/markdown/Qt4-module.md @@ -0,0 +1,6 @@ +# Qt4 module + +This module provides support for Qt4's `moc`, `uic` and `rcc` +tools. It is used identically to the [Qt 5 module](Qt5-module.md). + +{{ _include_qt_base.md }} diff --git a/meson/docs/markdown/Qt5-module.md b/meson/docs/markdown/Qt5-module.md new file mode 100644 index 000000000..8a5eb00a0 --- /dev/null +++ b/meson/docs/markdown/Qt5-module.md @@ -0,0 +1,6 @@ +# Qt5 module + +The Qt5 module provides tools to automatically deal with the various +tools and steps required for Qt. + +{{ _include_qt_base.md }} diff --git a/meson/docs/markdown/Qt6-module.md b/meson/docs/markdown/Qt6-module.md new file mode 100644 index 000000000..4d40423f9 --- /dev/null +++ b/meson/docs/markdown/Qt6-module.md @@ -0,0 +1,8 @@ +# Qt6 module + +*New in Meson 0.57.0* + +The Qt5 module provides tools to automatically deal with the various +tools and steps required for Qt. + +{{ _include_qt_base.md }} diff --git a/meson/docs/markdown/Quick-guide.md b/meson/docs/markdown/Quick-guide.md new file mode 100644 index 000000000..c1de82048 --- /dev/null +++ b/meson/docs/markdown/Quick-guide.md @@ -0,0 +1,158 @@ +--- +title: Quickstart Guide +short-description: Getting Started using Mesonbuild +... + +# Using Meson + +Meson has been designed to be as simple to use as possible. This page +outlines the initial steps needed for installation, troubleshooting, +and standard use. + +For more advanced configuration please refer to the command line help +`meson --help` or the Meson documentation located at the +[Mesonbuild](https://mesonbuild.com) website. + +Table of Contents: +* [Requirements](#requirements) +* [Installation using package manager](#installation-using-package-manager) +* [Installation using Python](#installation-using-python) +* [Installation from source](#installation-from-source) +* [Troubleshooting](#troubleshooting) +* [Compiling a Meson project](#compiling-a-meson-project) +* [Using Meson as a distro packager](#using-meson-as-a-distro-packager) + +Requirements +-- + +* [Python 3](https://python.org) +* [Ninja](https://github.com/ninja-build/ninja/) + +*Ninja is only needed if you use the Ninja backend. Meson can also +generate native VS and Xcode project files.* + + +Installation using package manager +-- + +Ubuntu: + +```console +$ sudo apt-get install python3 python3-pip python3-setuptools \ + python3-wheel ninja-build +``` +*Due to our frequent release cycle and development speed, distro packaged software may quickly become outdated.* + +Installation using Python +-- +Requirements: **pip3** + +The best way to receive the most up-to-date version of Mesonbuild. + +Install as a local user (recommended): +```console +$ pip3 install --user meson +``` +Install as root: +```console +$ pip3 install meson +``` + +*If you are unsure whether to install as root or a local user, install + as a local user.* + + +Installation from source +-- +Requirements: **git** + +Meson can be run directly from the cloned git repository. + +```console +$ git clone https://github.com/mesonbuild/meson.git /path/to/sourcedir +``` +Troubleshooting: +-- +Common Issues: +```console +$ meson builddir +$ bash: /usr/bin/meson: No such file or directory +``` + +Description: The default installation prefix for the python pip module +installation is not included in your shell environment PATH. The +default prefix for python pip installation modules is located under +``/usr/local``. + +**Resolution: +This issue can be resolved by altering the default shell environment +PATH to include ``/usr/local/bin``. ** + +*Note: There are other ways of fixing this issue such as using + symlinks or copying the binaries to a default path and these methods + are not recommended or supported as they may break package management + interoperability.* + + +Compiling a Meson project +-- + +The most common use case of Meson is compiling code on a code base you +are working on. The steps to take are very simple. + +```console +$ cd /path/to/source/root +$ meson builddir && cd builddir +$ meson compile +$ meson test +``` + +The only thing to note is that you need to create a separate build +directory. Meson will not allow you to build source code inside your +source tree. All build artifacts are stored in the build directory. +This allows you to have multiple build trees with different +configurations at the same time. This way generated files are not +added into revision control by accident. + +To recompile after code changes, just type `meson compile`. The build +command is always the same. You can do arbitrary changes to source +code and build system files and Meson will detect those and will do +the right thing. If you want to build optimized binaries, just use the +argument `--buildtype=debugoptimized` when running Meson. It is +recommended that you keep one build directory for unoptimized builds +and one for optimized ones. To compile any given configuration, just +go into the corresponding build directory and run `meson compile`. + +Meson will automatically add compiler flags to enable debug +information and compiler warnings (i.e. `-g` and `-Wall`). This means +the user does not have to deal with them and can instead focus on +coding. + +Using Meson as a distro packager +-- + +Distro packagers usually want total control on the build flags +used. Meson supports this use case natively. The commands needed to +build and install Meson projects are the following. + +```console +$ cd /path/to/source/root +$ meson --prefix /usr --buildtype=plain builddir -Dc_args=... -Dcpp_args=... -Dc_link_args=... -Dcpp_link_args=... +$ meson compile -C builddir +$ meson test -C builddir +$ DESTDIR=/path/to/staging/root meson install -C builddir +``` + +The command line switch `--buildtype=plain` tells Meson not to add its +own flags to the command line. This gives the packager total control +on used flags. + +This is very similar to other build systems. The only difference is +that the `DESTDIR` variable is passed as an environment variable +rather than as an argument to `meson install`. + +As distro builds happen always from scratch, you might consider +enabling [unity builds](Unity-builds.md) on your packages because they +are faster and produce better code. However there are many projects +that do not build with unity builds enabled so the decision to use +unity builds must be done by the packager on a case by case basis. diff --git a/meson/docs/markdown/RPM-module.md b/meson/docs/markdown/RPM-module.md new file mode 100644 index 000000000..cab6d968a --- /dev/null +++ b/meson/docs/markdown/RPM-module.md @@ -0,0 +1,16 @@ +# RPM module + +The RPM module can be used to create a sample rpm spec file for a +Meson project. It autodetects installed files, dependencies and so +on. Using it is very simple. At the very end of your Meson project +(that is, the end of your top level `meson.build` file) add these two +lines. + +```meson +rpm = import('rpm') +rpm.generate_spec_template() +``` + +Run Meson once on your code and the template will be written in your +build directory. Then remove the two lines above and manually edit the +template to add missing information. After this it is ready for use. diff --git a/meson/docs/markdown/Reference-manual.md b/meson/docs/markdown/Reference-manual.md new file mode 100644 index 000000000..e96a6fc41 --- /dev/null +++ b/meson/docs/markdown/Reference-manual.md @@ -0,0 +1,2923 @@ +# Reference manual + +## Functions + +The following functions are available in build files. Click on each to +see the description and usage. The objects returned by them are [list +afterwards](#returned-objects). + +### add_global_arguments() + +``` meson + void add_global_arguments(arg1, arg2, ...) +``` + +Adds the positional arguments to the compiler command line. This +function has two keyword arguments: + +- `language`: specifies the language(s) that the arguments should be +applied to. If a list 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` *(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. + +The arguments are used in all compiler invocations with the exception +of compile tests, because you might need to run a compile test with +and without the argument in question. For this reason only the +arguments explicitly specified are used during compile tests. + +**Note:** Usually you should use `add_project_arguments` instead, + because that works even when you project is used as a subproject. + +**Note:** You must pass always arguments individually `arg1, arg2, + ...` rather than as a string `'arg1 arg2', ...` + +### add_global_link_arguments() + +``` meson + void add_global_link_arguments(*arg1*, *arg2*, ...) +``` + +Like `add_global_arguments` but the arguments are passed to the linker. + +### add_languages() + +``` meson + bool add_languages(*langs*) +``` + +Add programming languages used by the project. Equivalent to having +them in the `project` declaration. This function is usually used to +add languages that are only used under some conditions, like this: + +```meson +project('foobar', 'c') +if compiling_for_osx + add_languages('objc') +endif +if add_languages('cpp', required : false) + executable('cpp-app', 'main.cpp') +endif +``` + +Takes the following keyword arguments: + +- `required`: defaults to `true`, which means that if any of the languages +specified is not found, Meson will halt. *(since 0.47.0)* The value of a +[`feature`](Build-options.md#features) option can also be passed. + +- `native` *(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. + +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. + +### add_project_arguments() + +``` meson + void add_project_arguments(arg1, arg2, ...) +``` + +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. + +### add_project_link_arguments() + +``` meson + void add_project_link_arguments(*arg1*, *arg2*, ...) +``` + +Like `add_project_arguments` but the arguments are passed to the linker. + +### add_test_setup() + +``` meson + void add_test_setup(*name*, ...) +``` + +Add a custom test setup that can be used to run the tests with a +custom setup, for example under Valgrind. The keyword arguments are +the following: + +- `env`: environment variables to set, such as `['NAME1=value1', + 'NAME2=value2']`, or an [`environment()` + object](#environment-object) which allows more sophisticated + environment juggling. *(since 0.52.0)* A dictionary is also accepted. +- `exe_wrapper`: a list containing the wrapper command or script followed by the arguments to it +- `gdb`: if `true`, the tests are also run under `gdb` +- `timeout_multiplier`: 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. +- `is_default` *(since 0.49.0)*: a bool to set whether this is the default test setup. + If `true`, the setup will be used whenever `meson test` is run + without the `--setup` option. +- `exclude_suites` *(since 0.57.0)*: a list 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. + +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. + +### alias_target + +``` meson +runtarget alias_target(target_name, dep1, ...) +``` + +*(since 0.52.0)* + +This function creates a new top-level target. Like all top-level +targets, this integrates with the selected backend. For instance, with +you can run it as `meson compile target_name`. This is a dummy target +that does not execute any command, but ensures that all dependencies +are built. Dependencies can be any build target (e.g. return value of +[executable()](#executable), custom_target(), etc) + +### assert() + +``` meson + void assert(*condition*, *message*) +``` + +Abort with an error message if `condition` evaluates to `false`. + +*(since 0.53.0)* `message` argument is optional and defaults to print the condition +statement instead. + +### benchmark() + +``` meson + void benchmark(name, executable, ...) +``` + +Creates a benchmark item that will be run when the benchmark target is +run. The behavior of this function is identical to [`test()`](#test) +except for: + +* benchmark() has no `is_parallel` keyword because benchmarks are not run in parallel +* benchmark() does not automatically add the `MALLOC_PERTURB_` environment variable + +*Note:* Prior to 0.52.0 benchmark would warn that `depends` and +`priority` were unsupported, this is incorrect. + +### both_libraries() + +``` meson + buildtarget = both_libraries(library_name, list_of_sources, ...) +``` + +*(since 0.46.0)* + +Builds both a static and shared library with the given sources. +Positional and keyword arguments are otherwise the same as for +[`library`](#library). Source files will be compiled only once and +object files will be reused to build both shared and static libraries, +unless `b_staticpic` user option or `pic` argument are set to false in +which case sources will be compiled twice. + +The returned [buildtarget](#build-target-object) always represents the +shared library. In addition it supports the following extra methods: + +- `get_shared_lib()` returns the shared library build target +- `get_static_lib()` returns the static library build target + +### build_target() + +Creates a build target whose type can be set dynamically with the +`target_type` keyword argument. + +`target_type` may be set to one of: + +- `executable` +- `shared_library` +- `shared_module` +- `static_library` +- `both_libraries` +- `library` +- `jar` + +This declaration: + +```meson +executable(<arguments and keyword arguments>) +``` + +is equivalent to this: + +```meson +build_target(<arguments and keyword arguments>, target_type : 'executable') +``` + +The object returned by `build_target` and all convenience wrappers for +`build_target` such as [`executable`](#executable) and +[`library`](#library) has methods that are documented in the [object +methods section](#build-target-object) below. + +### configuration_data() + +``` meson + configuration_data_object = configuration_data(...) +``` + +Creates an empty configuration object. You should add your +configuration with [its method calls](#configuration-data-object) and +finally use it in a call to `configure_file`. + +*(since 0.49.0)* Takes an optional dictionary as first argument. If +provided, each key/value pair is added into the `configuration_data` +as if `set()` method was called for each of them. + +### configure_file() + +``` meson + generated_file = configure_file(...) +``` + +This function can run in three modes depending on the keyword arguments +passed to it. + +When a [`configuration_data()`](#configuration_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](Configuration.md). *(since 0.49.0)* +A dictionary can be passed instead of a +[`configuration_data()`](#configuration_data) object. + +When a list 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. + +*(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 +build directory with the name `output:` in the current directory. + +These are all the supported keyword arguments: + +- `capture` *(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`. +- `command`: 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()`](#custom_target) for details about string + substitutions. +- `copy` *(since 0.47.0)*: as explained above, if specified Meson only + copies the file from input to output. +- `depfile` *(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. +- `format` *(since 0.46.0)*: the format of defines. It defaults to `meson`, and so substitutes +`#mesondefine` statements and variables surrounded by `@` characters, you can also use `cmake` +to replace `#cmakedefine` statements and variables with the `${variable}` syntax. Finally you can use +`cmake@` in which case substitutions will apply on `#cmakedefine` statements and variables with +the `@variable@` syntax. +- `input`: the input file name. If it's not specified in configuration + mode, all the variables in the `configuration:` object (see above) + are written to the `output:` file. +- `install` *(since 0.50.0)*: when true, this generated file is installed during +the install step, and `install_dir` must be set and not empty. When false, this +generated file is not installed regardless of the value of `install_dir`. +When omitted it defaults to true when `install_dir` is set and not empty, +false otherwise. +- `install_dir`: the subdirectory to install the generated file to + (e.g. `share/myproject`), if omitted or given the value of empty + string, the file is not installed. +- `install_mode` *(since 0.47.0)*: specify the file mode in symbolic format + and optionally the owner/uid and group/gid for the installed files. +- `output`: the output file name. *(since 0.41.0)* may contain + `@PLAINNAME@` or `@BASENAME@` substitutions. In configuration mode, + the permissions of the input file (if it is specified) are copied to + the output file. +- `output_format` *(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 + will be prefixed with `#`, you can also use `nasm`, in which case the + prefix will be `%`. +- `encoding` *(since 0.47.0)*: set the file encoding for the input and output file, + defaults to utf-8. The supported encodings are those of python3, see + [standard-encodings](https://docs.python.org/3/library/codecs.html#standard-encodings). + +### custom_target() + +``` meson + customtarget custom_target(*name*, ...) +``` + +Create a custom top level build target. The only positional argument +is the name of this target and the keyword arguments are the +following. + +- `build_by_default` *(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 `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. +- `build_always` **(deprecated)**: if `true` this target is always considered out of + date and is rebuilt every time. Equivalent to setting both + `build_always_stale` and `build_by_default` to true. +- `build_always_stale` *(since 0.47.0)*: if `true` the target is always considered out of date. + Useful for things such as build timestamps or revision control tags. + The associated command is run even if the outputs are up to date. +- `capture`: there are some compilers that can't be told to write + their output to a file but 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 list may not + contain `@OUTPUT@` when capture mode is active. +- `console` *(since 0.48.0)*: keyword argument conflicts with `capture`, and is meant + for commands that are resource-intensive and take a long time to + finish. With the Ninja backend, setting this will add this target + to [Ninja's `console` pool](https://ninja-build.org/manual.html#_the_literal_console_literal_pool), + which has special properties such as not buffering stdout and + serializing all targets in this pool. +- `command`: 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()`](#find_program), + [`executable()`](#executable), [`configure_file()`](#configure_file), + [`files()`](#files), [`custom_target()`](#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'` as the latter will *not* work. +- `depend_files`: files ([`string`](#string-object), + [`files()`](#files), or [`configure_file()`](#configure_file)) that + this target depends on but are not listed in the `command` keyword + argument. Useful for adding regen dependencies. +- `depends`: specifies that this target 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 you have a tool that + e.g. does globbing internally. Usually you should just put the + generated sources as inputs and Meson will set up all dependencies + automatically. +- `depfile`: a dependency file that the command 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 +- `input`: list of source files. *(since 0.41.0)* the list is flattened. +- `install`: when true, this target is installed during the install step +- `install_dir`: directory to install to +- `install_mode` *(since 0.47.0)*: the file mode and optionally the + owner/uid and group/gid +- `output`: list of output files +- `env` *(since 0.57.0)*: environment variables to set, such as + `{'NAME1': 'value1', 'NAME2': 'value2'}` or `['NAME1=value1', 'NAME2=value2']`, + or an [`environment()` object](#environment-object) which allows more + sophisticated environment juggling. +- `feed` *(since 0.59.0)*: there are some compilers that can't be told to read + their input from a file and instead read it from standard input. When this + argument is set to true, Meson feeds the input file to `stdin`. Note that + your argument list may not contain `@INPUT@` when feed mode is active. + +The list of strings passed to the `command` keyword argument accept +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@']`. +- `@OUTPUT@`: the full path to the output passed to `output`. If more + than one outputs are 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 +- `@BASENAME@`: the input filename, with extension removed +- `@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 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@`: 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. + +*(since 0.47.0)* The `depfile` keyword argument also accepts the + `@BASENAME@` and `@PLAINNAME@` substitutions. + +The returned object also has methods that are documented in the +[object methods section](#custom-target-object) below. + +**Note:** Assuming that `command:` is executed by a POSIX `sh` shell +is not portable, notably to Windows. Instead, consider using a +`native: true` [executable()](#executable), or a python script. + +### declare_dependency() + +``` meson + dependency_object declare_dependency(...) +``` + +This function returns a [dependency object](#dependency-object) that +behaves like the return value of [`dependency`](#dependency) but is +internal to the current build. The main use case for this is in +subprojects. This allows a subproject to easily specify how it should +be used. This makes it interchangeable with the same dependency that +is provided externally by the system. This function has the following +keyword arguments: + +- `compile_args`: compile arguments to use. +- `dependencies`: other dependencies needed to use this dependency. +- `include_directories`: the directories to add to header search path, + must be include_directories objects or *(since 0.50.0)* plain strings +- `link_args`: link arguments to use. +- `link_with`: libraries to link against. +- `link_whole` *(since 0.46.0)*: libraries to link fully, same as [`executable`](#executable). +- `sources`: sources to add to targets (or generated header files + that should be built before sources including them are built) +- `version`: the version of this dependency, such as `1.2.3`. Defaults to the + project version. +- `variables` *(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 a list of `'key=value'` strings. + +### dependency() + +``` meson + dependency_object dependency(*dependency_name*, ...) +``` + +Finds an external dependency (usually a library installed on your +system) with the given name with `pkg-config` and [with +CMake](Dependencies.md#cmake) if `pkg-config` fails. Additionally, +frameworks (OSX only) and [library-specific fallback detection +logic](Dependencies.md#dependencies-with-custom-lookup-functionality) +are also supported. + +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()`](#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](Wrap-dependency-system-manual.md#provide-section) 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](Wrap-dependency-system-manual.md#provide-section) + for more details. This automatic search can be controlled using the + `allow_fallback` keyword argument. + +This function supports the following keyword arguments: + +- `default_options` *(since 0.37.0)*: an array of default option values + that override those set in the subproject's `meson_options.txt` + (like `default_options` in [`project()`](#project), they only have + effect when Meson is run for the first time, and command line + arguments override any default options in build files) +- `allow_fallback` (boolean argument, *since 0.56.0*): specifies whether Meson + should automatically pick a fallback subproject in case the dependency + is not found in the system. If `true` and the dependency is not found + on the system, Meson will fallback to a subproject that provides this + dependency. If `false`, Meson will not fallback even if a subproject + provides this dependency. By default, Meson will do so if `required` + is `true` or [`enabled`](Build-options.md#features); see the [Wrap + documentation](Wrap-dependency-system-manual.md#provide-section) + for more details. +- `fallback` (string or array argument): manually specifies a subproject + fallback to use in case the dependency is not found in the system. + This is useful if the automatic search is not applicable or if you + want to support versions of Meson older than 0.55.0. If the value is an + array `['subproj_name', 'subproj_dep']`, the first value is the name + of the subproject and the second is the variable name in that + subproject that contains a dependency object such as the return + value of [`declare_dependency`](#declare_dependency) or + [`dependency()`](#dependency), etc. Note that this means the + fallback dependency may be a not-found dependency, in which + case the value of the `required:` kwarg will be obeyed. + *Since 0.54.0* the value can be a single string, the subproject name; + in this case the subproject must use + `meson.override_dependency('dependency_name', subproj_dep)` + to specify the dependency object used in the superproject. + If the value is an empty list, it has the same effect as + `allow_fallback: false`. +- `language` *(since 0.42.0)*: defines what language-specific + dependency to find if it's available for multiple languages. +- `method`: defines the way the dependency is detected, the default is + `auto` but can be overridden to be e.g. `qmake` for Qt development, + and [different dependencies support different values]( + Dependencies.md#dependencies-with-custom-lookup-functionality) + for this (though `auto` will work on all of them) +- `native`: if set to `true`, causes Meson to find the dependency on + the build machine system rather than the host system (i.e. where the + cross compiled binary will run on), usually only needed if you build + a tool to be used during compilation. +- `not_found_message` *(since 0.50.0)*: an optional string that will + be printed as a `message()` if the dependency was not found. +- `required`: when set to false, Meson will proceed with the build + even if the dependency is not found. *(since 0.47.0)* The value of a + [`feature`](Build-options.md#features) option can also be passed. +- `static`: tells the dependency provider to try to get static + libraries instead of dynamic ones (note that this is not supported + by all dependency backends) +- `version` *(since 0.37.0)*: specifies the required version, a string containing 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 specify multiple restrictions by passing a list to this + keyword argument, such as: `['>=3.14.0', '<=4.1.0']`. + These requirements are never met if the version is unknown. +- `include_type` *(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 set to `'preserve'`, no additional conversion will be + performed. The default value is `'preserve'`. +- other +[library-specific](Dependencies.md#dependencies-with-custom-lookup-functionality) +keywords may also be accepted (e.g. `modules` specifies submodules to use for +dependencies such as Qt5 or Boost. `components` allows the user to manually +add CMake `COMPONENTS` for the `find_package` lookup) +- `disabler` *(since 0.49.0)*: if `true` and the dependency couldn't be found, + returns a [disabler object](#disabler-object) instead of a not-found dependency. + +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 also has methods that are documented in the +[object methods section](#dependency-object) below. + +### disabler() + +*(since 0.44.0)* + +Returns a [disabler object](#disabler-object). + +### error() + +``` meson + void error(message) +``` + +Print the argument string and halts the build process. + +*(since 0.58.0)* Can take more than one argument that will be separated by +space. + +### environment() + +``` meson + environment_object environment(...) +``` + +*(since 0.35.0)* + +Returns an empty [environment variable object](#environment-object). + +*(since 0.52.0)* Takes an optional dictionary as first argument. If +provided, each key/value pair is added into the `environment_object` +as if `set()` method was called for each of them. + +### executable() + +``` meson + buildtarget executable(*exe_name*, *sources*, ...) +``` + +Creates a new executable. The first argument specifies its name and +the remaining positional arguments define the input files to use. They +can be of the following types: + +- Strings relative to the current source directory +- [`files()`](#files) objects defined in any preceding build file +- The return value of configure-time generators such as [`configure_file()`](#configure_file) +- The return value of build-time generators such as + [`custom_target()`](#custom_target) or + [`generator.process()`](#generator-object) + +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. + +With the Ninja backend, Meson will create a build-time [order-only +dependency](https://ninja-build.org/manual.html#ref_dependencies) on +all generated input files, including unknown files. This is needed to +bootstrap the generation of the real dependencies in the +[depfile](https://ninja-build.org/manual.html#ref_headers) 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. + +Executable supports the following keyword arguments. Note that just +like the positional arguments above, these keyword arguments can also +be passed to [shared and static libraries](#library). + +- `<languagename>_pch`: precompiled header file to use for the given language +- `<languagename>_args`: compiler flags to use for the given language; + eg: `cpp_args` for C++ +- `build_by_default` *(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. +- `build_rpath`: a string to add to target's rpath definition in the + build dir, but which will be removed on install +- `dependencies`: one or more objects created with + [`dependency`](#dependency) or [`find_library`](#compiler-object) + (for external deps) or [`declare_dependency`](#declare_dependency) + (for deps built by the project) +- `extra_files`: not used for the build itself but are shown as + source files in IDEs that group files by targets (such as Visual + Studio) +- `gui_app`: when set to true flags this target as a GUI application + on platforms where this makes a differerence, **deprecated** since + 0.56.0, use `win_subsystem` instead. +- `link_args`: flags to use during linking. You can use UNIX-style + flags here for all platforms. +- `link_depends`: strings, files, or custom targets the link step + depends on such as a symbol visibility map. The purpose is to + automatically trigger a re-link (but not a re-compile) of the target + when this file changes. +- `link_language` *(since 0.51.0)* *(broken until 0.55.0)*: makes the linker for this + target be for the specified language. It is generally unnecessary to set + this, as Meson will detect the right linker to use in most cases. There are + only two cases where this is needed. One, your main function in an + executable is not in the language Meson picked, or second you want to force + a library to use only one ABI. +- `link_whole` *(since 0.40.0)*: links all contents of the given static libraries + whether they are used by not, equivalent to the `-Wl,--whole-archive` argument flag of GCC. + *(since 0.41.0)* If passed a list that list 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. +- `link_with`: one or more shared or static libraries (built by this + project) that this target should be linked with. *(since 0.41.0)* If passed a + list this list 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 this is not sufficient, + then the build system writer must write all other steps manually. +- `export_dynamic` *(since 0.45.0)*: when set to true causes the target's symbols to be + dynamically exported, allowing modules built using the + [`shared_module`](#shared_module) function to refer to functions, + variables and other symbols defined in the executable itself. Implies + the `implib` argument. +- `implib` *(since 0.42.0)*: 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. Only has any + effect on platforms where that is meaningful (e.g. Windows). Implies + the `export_dynamic` argument. +- `implicit_include_directories` *(since 0.42.0)*: a boolean telling whether Meson + adds the current source and build directories to the include path, + defaults to `true`. +- `include_directories`: one or more objects created with the + `include_directories` function, or *(since 0.50.0)* strings, which + will be transparently expanded to include directory objects +- `install`: when set to true, this executable should be installed, defaults to `false` +- `install_dir`: override install directory for this file. The value is + relative to the `prefix` specified. F.ex, if you want to install + plugins into a subdir, you'd use something like this: `install_dir : + get_option('libdir') / 'projectname-1.0'`. +- `install_mode` *(since 0.47.0)*: specify the file mode in symbolic format + and optionally the owner/uid and group/gid for the installed files. +- `install_rpath`: a string to set the target's rpath to after install + (but *not* before that). On Windows, this argument has no effect. +- `objects`: list of prebuilt object files (usually for third party + products you don't have source to) that should be linked in this + target, **never** use this for object files that you build yourself. +- `name_suffix`: the string that will be used as the extension for the + target by overriding the default. By default on Windows this is + `exe` and on other platforms it is omitted. Set this to `[]`, or omit + the keyword argument for the default behaviour. +- `override_options` *(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. +- `gnu_symbol_visibility` *(since 0.48.0)*: specifies how symbols should be exported, see + e.g [the GCC Wiki](https://gcc.gnu.org/wiki/Visibility) for more + information. This 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 + do not support GNU visibility arguments. +- `d_import_dirs`: list of directories to look in for string imports used + in the D programming language +- `d_unittest`: when set to true, the D modules are compiled in debug mode +- `d_module_versions`: list of module version identifiers set when compiling D sources +- `d_debug`: list of module debug identifiers set when compiling D sources +- `pie` *(since 0.49.0)*: build a position-independent executable +- `native`: is a boolean controlling whether the target is compiled for the + build or host machines. Defaults to false, building for the host machine. +- `win_subsystem` *(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](https://docs.microsoft.com/en-us/cpp/build/reference/subsystem-specify-subsystem) + for the full list. The default value is `console`. + +The list of `sources`, `objects`, and `dependencies` is always +flattened, which means you can freely nest and add lists while +creating the final list. + +The returned object also has methods that are documented in the +[object methods section](#build-target-object) below. + +### find_library() + +*(since 0.31.0)* **(deprecated)** Use `find_library()` method of +[the compiler object](#compiler-object) as obtained from +`meson.get_compiler(lang)`. + +### find_program() + +``` meson + program find_program(program_name1, program_name2, ...) +``` + +`program_name1` 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()`](Reference-manual.md#meson-object) +1. [`[provide]` sections](Wrap-dependency-system-manual.md#provide-section) + in subproject wrap files, if [`wrap_mode`](Builtin-options.md#core-options) is + set to `forcefallback` +1. [`[binaries]` section](Machine-files.md#binaries) in your machine files +1. Directories provided using the `dirs:` kwarg (see below) +1. Project's source tree relative to the current subdir + - If you use the return value of [`configure_file()`](#configure_file), the + current subdir inside the build tree is used instead +1. `PATH` environment variable +1. [`[provide]` sections](Wrap-dependency-system-manual.md#provide-section) in + subproject wrap files, if [`wrap_mode`](Builtin-options.md#core-options) is + set to anything other than `nofallback` + +*(since 0.37.0)* `program_name2` and later positional arguments are used as fallback +strings 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. + +Keyword arguments are the following: + +- `required` By default, `required` is set to `true` and 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 object](#external-program-object) to check + whether it was found or not. *(since 0.47.0)* The value of a + [`feature`](Build-options.md#features) option can also be passed to the + `required` keyword argument. + +- `native` *(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. + +- `disabler` *(since 0.49.0)*: if `true` and the program couldn't be found, return a + [disabler object](#disabler-object) instead of a not-found object. + + +- `version` *(since 0.52.0)*: specifies the required version, see + [`dependency()`](#dependency) for argument format. 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()`](#run_command). + +- `dirs` *(since 0.53.0)*: extra list of absolute paths where to look for program + names. + +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 a list of commands. + +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. + +```meson +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: + +```meson +setcap = find_program(['setcap', '/usr/sbin/setcap', '/sbin/setcap'], required : false) +``` + +The returned object also has methods that are documented in the +[object methods section](#external-program-object) below. + +### files() + +``` meson + file_array files(list_of_filenames) +``` + +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. 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: + +```meson + foofile = files('foo.cpp') +``` + +Then you can use it in `bar2` like this: + +```meson + executable('myprog', 'myprog.cpp', foofile, ...) +``` + +Meson will then do the right thing. + +### generator() + +``` meson + generator_object generator(*executable*, ...) +``` + +See also: [`custom_target`](#custom_target) + +This function creates a [generator object](#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. Keyword arguments are the +following: + +- `arguments`: a list of template strings that will be the command line + arguments passed to the executable +- `depends` *(since 0.51.0)*: is 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. +- `depfile`: is 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`: a template string (or list of template strings) defining + how an output file name is (or multiple output names are) generated + from a single source file name +- `capture` *(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`. + +The returned object also has methods that are documented in the +[object methods section](#generator-object) below. + +The template strings passed to all the above 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 passed to the `output` keyword argument *must* be +constructed using one or both of these two substitutions. + +In addition to the above substitutions, the `arguments` keyword +argument also accepts the following: + +- `@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](#build_target) or a [custom +target](#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 such as for +generating headers to be used by several sources, or data that will be +installed, and so on, use a [`custom_target`](#custom_target) instead. + +### get_option() + +``` meson + value get_option(option_name) +``` + +Obtains the value of the [project build option](Build-options.md) +specified in the positional argument. + +Note that the value returned for built-in options that end in `dir` +such as `bindir` and `libdir` is always a path relative to (and +inside) the `prefix`. + +The only exceptions are: `sysconfdir`, `localstatedir`, and +`sharedstatedir` which will return the value passed during +configuration as-is, which may be absolute, or relative to `prefix`. +[`install_dir` arguments](Installing.md) handles that as expected, but +if you need the absolute path to one of these e.g. to use in a define +etc., you should use `get_option('prefix') / +get_option('localstatedir')` + +For options of type `feature` a +[feature option object](#feature-option-object) +is returned instead of a string. +See [`feature` options](Build-options.md#features) +documentation for more details. + +### get_variable() + +``` meson + value get_variable(variable_name, fallback) +``` + +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. If a fallback is not specified, then attempting to read +a non-existing variable will cause a fatal error. + +### import() + +``` + module_object import(string, required : bool | feature, disabler : bool) +``` + +Imports the given extension module. Returns an object that can be used to call +the methods of the module. Here's an example for a hypothetical `testmod` +module. + +```meson + tmod = import('testmod') + tmod.do_something() +``` + +*Since 0.59.0* the required and disabler keyword arguments + +### include_directories() + +``` meson + include_object include_directories(directory_names, ...) +``` + +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:` keyword argument when +building executables or libraries. You can use the returned object in +any subdirectory you want, Meson will make the paths work +automatically. + +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()`](#add_project_arguments). + +See also `implicit_include_directories` parameter of +[executable()](#executable), which adds current source and build +directories to 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. + +For example, with the following source tree layout in +`/home/user/project.git`: + +`meson.build`: +```meson +project(...) + +subdir('include') +subdir('src') + +... +``` + +`include/meson.build`: +```meson +inc = include_directories('.') + +... +``` + +`src/meson.build`: +```meson +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`. + +This function has one keyword argument `is_system` which, if set, +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). + +### install_data() + +``` meson + void install_data(list_of_files, ...) +``` + +Installs files from the source tree that are listed as positional +arguments. The following keyword arguments are supported: + +- `install_dir`: 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`: 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`. + +- `rename` *(since 0.46.0)*: if specified renames each source file into corresponding + file from `rename` list. Nested paths are allowed and they are + joined with `install_dir`. Length of `rename` list must be equal to + the number of sources. + +See [Installing](Installing.md) for more examples. + +### install_headers() + +``` meson + void install_headers(list_of_headers, ...) +``` + +Installs the specified header files from the source tree into the +system header directory (usually `/{prefix}/include`) during the +install step. This directory can be overridden by specifying it with +the `install_dir` keyword argument. If you just want to install into a +subdirectory of the system header directory, then use the `subdir` +argument. As an example if this has the value `myproj` then the +headers would be installed to `/{prefix}/include/myproj`. + +For example, this will install `common.h` and `kola.h` into +`/{prefix}/include`: + +```meson +install_headers('common.h', 'proj/kola.h') +``` + +This will install `common.h` and `kola.h` into `/{prefix}/include/myproj`: + +```meson +install_headers('common.h', 'proj/kola.h', subdir : 'myproj') +``` + +This will install `common.h` and `kola.h` into `/{prefix}/cust/myproj`: + +```meson +install_headers('common.h', 'proj/kola.h', install_dir : 'cust', subdir : 'myproj') +``` + +Accepts the following keywords: + +- `install_mode` *(since 0.47.0)*: can be used to specify the file mode in symbolic + format and optionally the owner/uid and group/gid for the installed files. + An example value could be `['rwxr-sr-x', 'root', 'root']`. + +### install_man() + +``` meson + void install_man(list_of_manpages, ...) +``` + +Installs the specified man files from the source tree into system's +man directory during the install step. This directory can be +overridden by specifying it with the `install_dir` keyword argument. + +Accepts the following keywords: + +- `install_mode` *(since 0.47.0)*: can be used to specify the file mode in symbolic + format and optionally the owner/uid and group/gid for the installed files. + An example value could be `['rwxr-sr-x', 'root', 'root']`. + +- `locale` *(since 0.58.0)*: can be used to specify the locale into which the + man page will be installed within the manual page directory tree. + An example manual might be `foo.fr.1` with a locale of `fr`, such + that `{mandir}/{locale}/man{num}/foo.1` becomes the installed file. + +*(since 0.49.0)* [manpages are no longer compressed + implicitly][install_man_49]. + +[install_man_49]: +https://mesonbuild.com/Release-notes-for-0-49-0.html#manpages-are-no-longer-compressed-implicitly + +### install_subdir() + +``` meson + void install_subdir(subdir_name, + install_dir : ..., + exclude_files : ..., + exclude_directories : ..., + strip_directory : ...) +``` + +Installs the entire given subdirectory and its contents from the +source tree to the location specified by the keyword argument +`install_dir`. + +If the subdirectory does not exist in the source tree, an empty directory is +created in the specified location. *(since 0.45.0)* A newly created +subdirectory may only be created in the keyword argument `install_dir`. + +The following keyword arguments are supported: + +- `exclude_files`: a list of file names that should not be installed. + Names are interpreted as paths relative to the `subdir_name` location. +- `exclude_directories`: a list of directory names that should not be installed. + Names are interpreted as paths relative to the `subdir_name` location. +- `install_dir`: the location to place the installed subdirectory. +- `install_mode` *(since 0.47.0)*: the file mode in symbolic format and optionally + the owner/uid and group/gid for the installed files. +- `strip_directory` *(since 0.45.0)*: install directory contents. `strip_directory=false` by default. + If `strip_directory=true` only the last component of the source path is used. + +For a given directory `foo`: +```text +foo/ + bar/ + file1 + file2 +``` +`install_subdir('foo', install_dir : 'share', strip_directory : false)` creates +```text +share/ + foo/ + bar/ + file1 + file2 +``` + +`install_subdir('foo', install_dir : 'share', strip_directory : true)` creates +```text +share/ + bar/ + file1 + file2 +``` + +`install_subdir('foo/bar', install_dir : 'share', strip_directory : false)` creates +```text +share/ + bar/ + file1 +``` + +`install_subdir('foo/bar', install_dir : 'share', strip_directory : true)` creates +```text +share/ + file1 +``` + +`install_subdir('new_directory', install_dir : 'share')` creates +```text +share/ + new_directory/ +``` + +### is_disabler() + +``` meson + bool is_disabler(var) +``` + +*(since 0.52.0)* + +Returns true if a variable is a disabler and false otherwise. + +### is_variable() + +``` meson + bool is_variable(varname) +``` + +Returns true if a variable of the given name exists and false otherwise. + +### jar() + +```meson + jar_object jar(name, list_of_sources, ...) +``` + +Build a jar from the specified Java source files. Keyword arguments +are the same as [`executable`](#executable)'s, with the addition of +`main_class` which specifies the main class to execute when running +the jar with `java -jar file.jar`. + +### join_paths() + +``` meson +string join_paths(string1, string2, ...) +``` + +*(since 0.36.0)* + +Joins the given strings into a file system path segment. For example +`join_paths('foo', 'bar')` results in `foo/bar`. If any one of the +individual segments is an absolute path, all segments before it are +dropped. That means that `join_paths('foo', '/bar')` returns `/bar`. + +**Warning** Don't use `join_paths()` for sources in [`library`](#library) and +[`executable`](#executable), you should use [`files`](#files) instead. + +*(since 0.49.0)* Using the`/` operator on strings is equivalent to calling +`join_paths`. + +```meson +# res1 and res2 will have identical values +res1 = join_paths(foo, bar) +res2 = foo / bar +``` + +### library() + +``` meson + buildtarget library(library_name, list_of_sources, ...) +``` + +Builds a library that is either static, shared or both depending on +the value of `default_library` +user [option](https://mesonbuild.com/Builtin-options.html). +You should use this instead of [`shared_library`](#shared_library), +[`static_library`](#static_library) or +[`both_libraries`](#both_libraries) most of the time. This allows you +to toggle your entire project (including subprojects) from shared to +static with only one option. This option applies to libraries being +built internal to the entire project. For external dependencies, the +default library type preferred is shared. This can be adapted on a per +library basis using the [dependency()](#dependency)) `static` keyword. + +The keyword arguments for this are the same as for +[`executable`](#executable) with the following additions: + +- `name_prefix`: 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`. +- `name_suffix`: the string that will be used as the suffix for the + target output filename by overriding the default (see also: + [executable()](#executable)). By default, for shared libraries this + 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. +- `rust_crate_type`: specifies the crate type for Rust + libraries. Defaults to `dylib` for shared libraries and `rlib` for + static libraries. + +`static_library`, `shared_library` and `both_libraries` also accept +these keyword arguments. + +Note: You can set `name_prefix` and `name_suffix` to `[]`, or omit +them for the default behaviour for each platform. + +### message() + +``` meson + void message(text) +``` + +This function prints its argument to stdout. + +*(since 0.54.0)* Can take more than one argument that will be +separated by space. + +### warning() + +``` meson + void warning(text) +``` + +*(since 0.44.0)* + +This function prints its argument to stdout prefixed with WARNING:. + +*(since 0.54.0)* Can take more than one argument that will be separated by +space. + +### summary() + +``` meson + void summary(key, value) + void summary(dictionary) +``` + +*(since 0.53.0)* + +This function is used to summarize build configuration at the end of the build +process. This function provides a way for projects (and subprojects) to report +this information in a clear way. + +The content is a series of key/value pairs grouped into sections. If +the section keyword argument is omitted, those key/value pairs are +implicitly grouped into a section with no title. key/value pairs can +optionally be grouped into a dictionary, but keep in mind that +dictionaries does not guarantee ordering. `key` must be string, +`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 +- a list of those. + +`summary()` can be called multiple times as long as the same +section/key pair doesn't appear twice. All sections will be collected +and printed at the end of the configuration in the same order as they +have been called. + +Keyword arguments: +- `section`: title to group a set of key/value pairs. +- `bool_yn`: if set to true, all boolean values will be replaced by green YES + or red NO. +- `list_sep` *(since 0.54.0)*: string used to separate list values (e.g. `', '`). + +Example: +```meson +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', + 'A list': ['string', 1, true], + }, section: 'Configuration') +``` + +Output: +``` +My Project 1.0 + + Directories + prefix : /opt/gnome + bindir : bin + libdir : lib/x86_64-linux-gnu + datadir : share + + Configuration + Some boolean : False + Another boolean: True + Some string : Hello World + A list : string + 1 + True +``` + +### project() + +``` meson + void project(project_name, list_of_languages, ...) +``` + +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 is written to +e.g. the dependency manifest is usually makes sense to have it be the +same as the project tarball or pkg-config name. So for example you +would probably want to use the name _libfoobar_ instead of _The Foobar +Library_. + +It may be followed by the list of programming languages that the project uses. + +*(since 0.40.0)* The list 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`, `d`, +`objc`, `objcpp`, `fortran`, `java`, `cs` (for `C#`), `vala` and `rust`. + +Project supports the following keyword arguments. + +- `default_options`: takes an array of strings. The strings are in the + form `key=value` and have the same format as options to + `meson configure`. For example to set the default project type you would + set this: `default_options : ['buildtype=debugoptimized']`. Note + that these settings are only used when running Meson for the first + time. Global options such as `buildtype` can only be specified in + the master project, settings in subprojects are ignored. Project + specific options are used normally even in subprojects. + + +- `license`: takes a string or array of strings describing the license(s) the + code is under. To avoid ambiguity it is recommended to use a standardized + license identifier from the [SPDX license list](https://spdx.org/licenses/). + Usually this would be something like `license : 'GPL-2.0-or-later'`, but if + the code has multiple licenses you can specify them as an array like this: + `license : ['proprietary', 'GPL-3.0-only']`. 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()`. + +- `meson_version`: takes a string describing which Meson version the + project requires. Usually something like `>=0.28.0`. + +- `subproject_dir`: specifies the top level directory name that holds + Meson subprojects. This is only meant as a compatibility option + for existing code bases that house their embedded source code in a + custom directory. All new projects should not set this but instead + use the default value. It should be noted that this keyword + argument is ignored inside subprojects. There can be only one + subproject dir and it is set in the top level Meson file. + +- `version`: which is a free form string describing the version of + this project. You can access the value in your Meson build files + with `meson.project_version()`. Since 0.57.0 this can also be a + `File` object pointing to a file that contains exactly one line of + text. + +### run_command() + +``` meson + runresult run_command(command, list_of_args, ...) +``` + +Runs the command specified in positional arguments. `command` can be a +string, or the output of [`find_program()`](#find_program), +[`files()`](#files) or [`configure_file()`](#configure_file), or [a +compiler object](#compiler-object). + +Returns [an opaque object](#run-result-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. + +This function supports the following keyword arguments: + + - `check` *(since 0.47.0)*: takes a boolean. If `true`, the exit status code of the command will + be checked, and the configuration will fail if it is non-zero. The default is + `false`. + - `env` *(since 0.50.0)*: environment variables to set, such as `['NAME1=value1', + 'NAME2=value2']`, or an [`environment()` + object](#environment-object) which allows more sophisticated + environment juggling. *(since 0.52.0)* A dictionary is also accepted. + +See also [External commands](External-commands.md). + +### run_target + +``` meson +runtarget run_target(target_name, ...) +``` + +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. + +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. + + - `command` is a list containing the command to run and the arguments + to pass to it. Each list item may be a string or a target. For + instance, passing the return value of [`executable()`](#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` is a list 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) +- `env` *(since 0.57.0)*: environment variables to set, such as + `{'NAME1': 'value1', 'NAME2': 'value2'}` or `['NAME1=value1', 'NAME2=value2']`, + or an [`environment()` object](#environment-object) which allows more + sophisticated environment juggling. + +*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. + +### set_variable() + +``` meson + void set_variable(variable_name, value) +``` + +Assigns a value to the given variable name. Calling +`set_variable('foo', bar)` is equivalent to `foo = bar`. + +*(since 0.46.1)* The `value` parameter can be an array type. + +### shared_library() + +``` meson + buildtarget shared_library(library_name, list_of_sources, ...) +``` + +Builds a shared library with the given sources. Positional and keyword +arguments are the same as for [`library`](#library) with the following +extra keyword arguments. + +- `soversion`: a string 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 is not 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 is set to `3`. +- `version`: 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 is not specified, `soversion` is used + instead (see above). +- `darwin_versions` *(since 0.48.0)*: an integer, string, or a list of + versions to use for setting dylib `compatibility version` and + `current version` on macOS. If a list is specified, it must be + either zero, one, or two elements. If only one element is specified + or if it's not a list, the specified value will be used for setting + both compatibility version and current version. If unspecified, the + `soversion` will be used as per the aforementioned rules. +- `vs_module_defs`: a string, a File object, or Custom Target for a + Microsoft module definition file for controlling symbol exports, + etc., on platforms where that is possible (e.g. Windows). + +### shared_module() + +``` meson + buildtarget shared_module(module_name, list_of_sources, ...) +``` + +*(since 0.37.0)* + +Builds a shared module with the given sources. Positional and keyword +arguments are the same as for [`library`](#library). + +This is useful for building modules that will be `dlopen()`ed and +hence may contain undefined symbols that will be provided by the +library that is loading it. + +If you want the shared module to be able to refer to functions and +variables defined in the [`executable`](#executable) it is loaded by, +you will need to set the `export_dynamic` argument of the executable to +`true`. + +Supports the following extra keyword arguments: + +- `vs_module_defs` *(since 0.52.0)*: a string, a File object, or + Custom Target for a Microsoft module definition file for controlling + symbol exports, etc., on platforms where that is possible + (e.g. Windows). + +**Note:** Linking to a shared module is not supported on some +platforms, notably OSX. Consider using a +[`shared_library`](#shared_library) instead, if you need to both +`dlopen()` and link with a library. + +### static_library() + +``` meson + buildtarget static_library(library_name, list_of_sources, ...) +``` + +Builds a static library with the given sources. Positional and keyword +arguments are as for [`library`](#library), as well as: + + - `pic` *(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. + +- `prelink` *since0.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. + +### subdir() + +``` meson + void subdir(dir_name, ...) +``` + +Enters the specified subdirectory and executes the `meson.build` file +in it. Once that is 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 that each `meson.build` file in a source tree can +and must only be executed once. + +This function has one keyword argument. + + - `if_found`: takes one or several dependency objects and will only + recurse in the subdir if they all return `true` when queried with + `.found()` + +### subdir_done() + +``` meson + subdir_done() +``` + +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. This means that all targets defined before +the call of `subdir_done` will be build. + +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. + +Example: +```meson +project('example exit', 'cpp') +executable('exe1', 'exe1.cpp') +subdir_done() +executable('exe2', 'exe2.cpp') +``` + +The executable `exe1` will be build, while the executable `exe2` is not +build. + +### subproject() + +``` meson + subproject_object subproject(subproject_name, ...) +``` + +Takes the project specified in the positional argument and brings that +in the current build specification by returning a [subproject +object](#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`. Supports the following keyword +arguments: + + - `default_options` *(since 0.37.0)*: an array of default option values + that override those set in the subproject's `meson_options.txt` + (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. + - `version`: works just like the same as in `dependency`. + It specifies what version the subproject should be, as an example `>=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 [returned + object](#subproject-object). You may also pass the value of a + [`feature`](Build-options.md#features) option, same as + [`dependency()`](#dependency). + +Note that you can use the returned [subproject +object](#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()`](#dependency). + +[See additional documentation](Subprojects.md). + +### test() + +``` meson + void test(name, executable, ...) +``` + +Defines a test to run with the test harness. Takes two positional +arguments, the first is the name of the test and the second is the +executable to run. The executable can be an [executable build target +object](#build-target-object) returned by +[`executable()`](#executable) or an [external program +object](#external-program-object) returned by +[`find_program()`](#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: using +`mesonlib.join_args`). Test scripts may 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, environment variable +[`MALLOC_PERTURB_`](http://man7.org/linux/man-pages/man3/mallopt.3.html) +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. However, this can have a performance +impact, and may fail a test due to external libraries whose internals +are out of the user's control. To check if this feature is causing an +expected runtime crash, disable the feature by temporarily setting +environment variable `MALLOC_PERTURB_=0`. While it's preferable to +only temporarily disable this check, if a project requires permanent +disabling of this check in meson.build do like: + +```meson +nomalloc = environment({'MALLOC_PERTURB_': '0'}) + +test(..., env: nomalloc, ...) +``` + +#### test() Keyword arguments + +- `args`: arguments to pass to the executable + +- `env`: environment variables to set, such as `['NAME1=value1', + 'NAME2=value2']`, or an [`environment()` + object](#environment-object) which allows more sophisticated + environment juggling. *(since 0.52.0)* A dictionary is also accepted. + +- `is_parallel`: when false, specifies that no other test must be + running at the same time as this test + +- `should_fail`: when true the test is considered passed if the + executable returns a non-zero return value (i.e. reports an error) + +- `suite`: `'label'` (or list 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 a list + of strings, the suite names will be `(sub)project_name:label1`, + `(sub)project_name:label2`, etc. + +- `timeout`: 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. + +- `workdir`: absolute path that will be used as the working directory + for the test + +- `depends` *(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 test is executed even if they have `build_by_default : false`. + +- `protocol` *(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](Unit-tests.md). 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](https://www.testanything.org/). + - `gtest` *(since 0.55.0)*: for Google Tests. + - `rust` *(since 0.56.0)*: for native rust tests + +- `priority` *(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, negative numbers are + permitted. + +Defined tests can be run in a backend-agnostic way by calling +`meson test` inside the build dir, or by using backend-specific +commands, such as `ninja test` or `msbuild RUN_TESTS.vcxproj`. + +### vcs_tag() + +``` meson + customtarget vcs_tag(...) +``` + +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. Keywords are similar to `custom_target`. + +- `command`: string list with the command to execute, see + [`custom_target`](#custom_target) for details on how this command + must be specified +- `fallback`: version number to use when no revision control + information is present, such as when building from a release tarball + (defaults to `meson.project_version()`) +- `input`: file to modify (e.g. `version.c.in`) (required) +- `output`: file to write the results to (e.g. `version.c`) (required) +- `replace_string`: string in the input file to substitute with the + commit information (defaults to `@VCS_TAG@`) + +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_target`](#custom_target) 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. + +If you desire more specific behavior than what this command provides, +you should use `custom_target`. + +### range() + +``` meson + rangeobject range(stop) + rangeobject range(start, stop[, step]) +``` + +*Since 0.58.0* + +Return an opaque object that can be only be used in `foreach` statements. +- `start` must be integer greater or equal to 0. Defaults to 0. +- `stop` must be integer greater or equal to `start`. +- `step` must be integer greater or equal to 1. Defaults to 1. + +It cause the `foreach` loop to be called with the value from `start` included +to `stop` excluded with an increment of `step` after each loop. + +```meson +# 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. +```meson +r = range(5, 10, 2) +assert(r[2] == 9) +``` + +## Built-in objects + +These are built-in objects that are always available. + +### `meson` object + +The `meson` object allows you to introspect various properties of the +system. This object is always mapped in the `meson` variable. It has +the following methods. + +- `add_dist_script(script_name, arg1, arg2, ...)` *(since 0.48.0)*: causes the script + given as argument to run during `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 can not be found in the staging directory, it is a hard + error. The `MESON_DIST_ROOT` environment variables is set when dist scripts is + run. + *(since 0.49.0)* Accepts multiple arguments for the script. + *(since 0.54.0)* The `MESON_SOURCE_ROOT` and `MESON_BUILD_ROOT` + environment variables are set when dist scripts are run. They are path to the + root source and build directory of the main project, even when the script + comes from a subproject. + *(since 0.55.0)* The output of `configure_file`, `files`, and `find_program` + as well as strings. + *(since 0.57.0)* `file` objects and the output of `configure_file` may be + used as the `script_name` parameter. + *(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 are 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>`. + +- `add_install_script(script_name, arg1, arg2, ...)`: causes the script + given as an argument to be run during the install step, this script + will have the environment variables `MESON_SOURCE_ROOT`, + `MESON_BUILD_ROOT`, `MESON_INSTALL_PREFIX`, + `MESON_INSTALL_DESTDIR_PREFIX`, and `MESONINTROSPECT` set. + All positional arguments are passed as parameters. + *since 0.57.0* `skip_if_destdir` boolean keyword argument (defaults to `false`) + can be specified. If `true` the script will not be run if DESTDIR is set during + installation. This is useful in the case the script updates system wide + cache that is only needed when copying files into final destination. + + *(since 0.54.0)* If `meson install` is called with the `--quiet` option, the + environment variable `MESON_INSTALL_QUIET` will be set. + + *(since 0.55.0)* The output of `configure_file`, `files`, `find_program`, + `custom_target`, indexes of `custom_target`, `executable`, `library`, and + other built targets as well as strings. + + *(since 0.57.0)* `file` objects and the output of `configure_file` may be + *used as the `script_name` parameter. + + Meson uses the `DESTDIR` environment variable as set by the + inherited environment to determine the (temporary) installation + location for files. Your install script must be aware of this while + manipulating and installing files. The correct way to handle this is + with the `MESON_INSTALL_DESTDIR_PREFIX` variable which is always set + and contains `DESTDIR` (if set) and `prefix` joined together. This + is useful because both are usually absolute paths and there are + platform-specific edge-cases in joining two absolute paths. + + In case it is needed, `MESON_INSTALL_PREFIX` is also always set and + has the value of the `prefix` option passed to Meson. + + `MESONINTROSPECT` contains the path to the introspect command that + corresponds to the `meson` executable that was used to configure the + build. (This 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. + +- `add_postconf_script(script_name, arg1, arg2, ...)`: runs the + executable given as an argument after all project files have been + generated. This script will have the environment variables + `MESON_SOURCE_ROOT` and `MESON_BUILD_ROOT` set. + + *(since 0.55.0)* The output of `configure_file`, `files`, and `find_program` + as well as strings. + + *(since 0.57.0)* `file` objects and the output of `configure_file` may be + *used as the `script_name` parameter. + +- `backend()` *(since 0.37.0)*: returns a string representing the + current backend: `ninja`, `vs2010`, `vs2012`, `vs2013`, `vs2015`, + `vs2017`, `vs2019`, or `xcode`. + +- `build_root()`: returns a string with the absolute path to the build + root directory. *(deprecated since 0.56.0)*: this function will return the + build root of the parent project if called from a subproject, which is usually + not what you want. Try using `current_build_dir()` or `project_build_root()`. + In the rare cases where the root of the main project is needed, + use `global_build_root()` that has the same behaviour but with a more explicit + name. + +- `source_root()`: returns a string with the absolute path to the + source root directory. Note: you should use the `files()` function + to refer to files in the root source directory instead of + constructing paths manually with `meson.source_root()`. + *(deprecated since 0.56.0)*: 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 `current_source_dir()` or `project_source_root()`. + In the rare cases where the root of the main project is needed, + use `global_source_root()` that has the same behaviour but with a more explicit + name. + +- `project_build_root()` *(since 0.56.0)*: returns a string with the absolute path + to the build root directory of the current (sub)project. + +- `project_source_root()` *(since 0.56.0)*: returns a string with the absolute path + to the source root directory of the current (sub)project. + +- `global_build_root()` *(since 0.58.0)*: 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 `current_build_dir()` or `project_build_root()`. + +- `global_source_root()` *(since 0.58.0)*: returns a string with the absolute path + to the source root directory. This function will return the source root of the + main project if called from a subproject, which is usually not what you want. + It is usually preferable to use `current_source_dir()` or `project_source_root()`. + +- `current_build_dir()`: returns a string with the absolute path to the + current build directory. + +- `current_source_dir()`: returns a string to the current source + directory. Note: **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()`. + +- `get_compiler(language)`: returns [an object describing a + compiler](#compiler-object), takes one positional argument which is + the language to use. It also accepts one keyword argument, `native` + which when set to true makes Meson return 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. + +- `get_cross_property(propname, fallback_value)`: + *Deprecated since 0.58.0, use `get_external_property()` instead*. + 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. + +- `get_external_property(propname, fallback_value, native: true/false)` + *(since 0.54.0)*: returns the given property from a native or cross file. + The optional fallback_value is returned if the given property is not found. + The optional `native: true` forces retrieving a variable from the + native file, even when cross-compiling. + If `native: false` or not specified, variable is retrieved from the + cross-file if cross-compiling, and from the native-file when not cross-compiling. + +- `has_external_property(propname, native: true/false)` + *(since 0.58.0)*: checks whether the given property exist in a native or + cross file. The optional `native: true` forces checking for the variable + in the native file, even when cross-compiling. + If `native: false` or not specified, the variable is checked for in the + cross-file if cross-compiling, and in the native-file when not cross-compiling. + +- `can_run_host_binaries()` *(since 0.55.0)*: returns true if the build machine can run + binaries compiled for the host. This returns true unless you are + 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. + +- `has_exe_wrapper()`: *(since 0.55.0)* **(deprecated)**. Use `can_run_host_binaries` instead. + +- `install_dependency_manifest(output_name)`: installs a manifest file + containing a list of all subprojects, their versions and license + files to the file name given as the argument. + +- `is_cross_build()`: returns `true` if the current build is a [cross + build](Cross-compilation.md) and `false` otherwise. + +- `is_subproject()`: returns `true` if the current project is being + built as a subproject of some other project and `false` otherwise. + +- `is_unity()`: returns `true` when doing a [unity + build](Unity-builds.md) (multiple sources are combined before + compilation to reduce build time) and `false` otherwise. + +- `override_find_program(progname, program)` *(since 0.46.0)*: + 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`. *(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. + + If `program` is an `executable`, it cannot be used during configure. + +- `override_dependency(name, dep_object)` *(since 0.54.0)*: + specifies that whenever `dependency(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()`. It takes optional + `native` keyword arguments. 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)`. + +- `project_version()`: returns the version string specified in + `project` function call. + +- `project_license()`: returns the array of licenses specified in + `project` function call. + +- `project_name()`: returns the project name specified in the `project` + function call. + +- `version()`: return a string with the version of Meson. + +- `add_devenv()`: *(Since 0.58.0)* add an [`environment()`](#environment) object + to the list of environments that will be applied when using [`meson devenv`](Commands.md#devenv) + command line. This is useful for developpers who wish to use the project without + installing it, it is often needed to set for example the path to plugins + directory, etc. Alternatively, a list or dictionary can be passed as first + argument. + ``` meson + 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: + ```sh + $ meson devenv -C <builddir> + $ echo $PLUGINS_PATH + /path/to/source/subdir + ``` + See [`meson devenv`](Commands.md#devenv) command documentation for a list of + environment variables that are set by default by Meson. + +### `build_machine` object + +Provides information about the build machine — the machine that is +doing the actual compilation. See +[Cross-compilation](Cross-compilation.md). It has the following +methods: + +- `cpu_family()`: returns the CPU family name. [This + table](Reference-tables.md#cpu-families) contains all known CPU + families. These are guaranteed to continue working. + +- `cpu()`: returns a more specific CPU name, such as `i686`, `amd64`, + etc. + +- `system()`: returns the operating system name. [This + table](Reference-tables.md#operating-system-names) Lists all of + the currently known Operating System names, these are guaranteed to + continue working. + +- `endian()`: returns `big` on big-endian systems and `little` on + little-endian systems. + +Currently, these values are populated using +[`platform.system()`](https://docs.python.org/3.4/library/platform.html#platform.system) +and +[`platform.machine()`](https://docs.python.org/3.4/library/platform.html#platform.machine). 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 report](https://github.com/mesonbuild/meson/issues/new) with +details and we'll look into it. + +### `host_machine` object + +Provides information about the host machine — the machine on which the +compiled binary will run. See +[Cross-compilation](Cross-compilation.md). + +It has the same methods as [`build_machine`](#build_machine-object). + +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. + +### `target_machine` object + +Provides information about the target machine — the machine on which +the compiled binary's output will run. Hence, this object should only +be used while cross-compiling a compiler. See +[Cross-compilation](Cross-compilation.md). + +It has the same methods as [`build_machine`](#build_machine-object). + +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. + +### `string` object + +All [strings](Syntax.md#strings) have the following methods. Strings +are immutable, all operations return their results as a new string. + +- `contains(string)`: returns true if string contains the string + specified as the argument. + +- `endswith(string)`: returns true if string ends with the string + specified as the argument. + +- `format()`: formats text, see the [Syntax + manual](Syntax.md#string-formatting) for usage info. + +- `join(list_of_strings)`: the opposite of split, for example + `'.'.join(['a', 'b', 'c']` yields `'a.b.c'`. + +- `replace('old_substr', 'new_str')` *(since 0.58.0)*: replaces instances of + `old_substr` in the string with `new_str` and returns a new string + +- `split(split_character)`: splits the string at the specified + character (or whitespace if not set) and returns the parts in an + array. + +- `startswith(string)`: returns true if string starts with the string + specified as the argument + +- `substring(start,end)` *(since 0.56.0)*: returns a substring specified from start to end. + Both `start` and `end` arguments are optional, so, for example, `'foobar'.substring()` will return `'foobar'`. + +- `strip()`: removes whitespace at the beginning and end of the string. + *(since 0.43.0)* Optionally can take one positional string argument, + and all characters in that string will be stripped. + +- `to_int()`: returns the string converted to an integer (error if string + is not a number). + +- `to_lower()`: creates a lower case version of the string. + +- `to_upper()`: creates an upper case version of the string. + +- `underscorify()`: creates a string where every non-alphabetical + non-number character is replaced with `_`. + +- `version_compare(comparison_string)`: does semantic version + comparison, if `x = '1.2.3'` then `x.version_compare('>1.0.0')` + returns `true`. + +### `Number` object + +[Numbers](Syntax.md#numbers) support these methods: + +- `is_even()`: returns true if the number is even +- `is_odd()`: returns true if the number is odd +- `to_string()`: returns the value of the number as a string. + +### `boolean` object + +A [boolean](Syntax.md#booleans) object has two simple methods: + +- `to_int()`: returns either `1` or `0`. + +- `to_string()`: 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. + +### `array` object + +The following methods are defined for all [arrays](Syntax.md#arrays): + +- `contains(item)`: returns `true` if the array contains the object + given as argument, `false` otherwise + +- `get(index, fallback)`: 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 + +- `length()`: the size of the array + +You can also iterate over arrays with the [`foreach` +statement](Syntax.md#foreach-statements). + +### `dictionary` object + +*(since 0.47.0)* + +The following methods are defined for all [dictionaries](Syntax.md#dictionaries): + +- `has_key(key)`: returns `true` if the dictionary contains the key + given as argument, `false` otherwise + +- `get(key, fallback)`: 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, causes a fatal error + +- `keys()`: returns an array of keys in the dictionary + +You can also iterate over dictionaries with the [`foreach` +statement](Syntax.md#foreach-statements). + +*(since 0.48.0)* Dictionaries can be added (e.g. `d1 = d2 + d3` and `d1 += d2`). +Values from the second dictionary overrides values from the first. + +## Returned objects + +These are objects returned by the [functions listed above](#functions). + +### `compiler` object + +This object is returned by +[`meson.get_compiler(lang)`](#meson-object). It represents a compiler +for a given language and allows you to query its properties. It has +the following methods: + +- `alignment(typename)`: returns the alignment of the type specified in + the positional argument, you can specify external dependencies to + use with `dependencies` keyword argument. + +- `cmd_array()`: returns an array containing the command(s) for the compiler. + +- `compiles(code)`: returns true if the code fragment given in the + positional argument compiles, you can specify external dependencies + to use with `dependencies` keyword argument, `code` can be either a + string containing source code or a `file` object pointing to the + source code. + +- `compute_int(expr, ...')`: computes the value of the given expression + (as an example `1 + 2`). When cross compiling this is evaluated with + an iterative algorithm, you can specify keyword arguments `low` + (defaults to -1024), `high` (defaults to 1024) and `guess` to + specify max and min values for the search and the value to try + first. + +- `find_library(lib_name, ...)`: tries to find the library specified in + the positional argument. The [result + object](#external-library-object) can be used just like the return + value of `dependency`. If the keyword argument `required` is false, + Meson will proceed even if the library is not found. By default the + library is searched for in the system library directory + (e.g. /usr/lib). This can be overridden with the `dirs` keyword + argument, which can be either a string or a list of strings. + *(since 0.47.0)* The value of a [`feature`](Build-options.md#features) + option can also be passed to the `required` keyword argument. + *(since 0.49.0)* If the keyword argument `disabler` is `true` and the + dependency couldn't be found, return a [disabler object](#disabler-object) + instead of a not-found dependency. *(since 0.50.0)* The `has_headers` keyword + argument can be a list of header files that must be found as well, using + `has_header()` method. All keyword arguments prefixed with `header_` will be + passed down to `has_header()` method with the prefix removed. *(since 0.51.0)* + The `static` keyword (boolean) can be set to `true` to limit the search to + static libraries and `false` for dynamic/shared. + +- `first_supported_argument(list_of_strings)`: given a list of + strings, returns the first argument that passes the `has_argument` + test or an empty array if none pass. + +- `first_supported_link_argument(list_of_strings)` *(since 0.46.0)*: + given a list of strings, returns the first argument that passes the + `has_link_argument` test or an empty array if none pass. + +- `get_define(definename)`: returns the given preprocessor symbol's + value as a string or empty string if it is not defined. + *(since 0.47.0)* This method will concatenate string literals as + the compiler would. E.g. `"a" "b"` will become `"ab"`. + +- `get_id()`: returns a string identifying the compiler. For example, + `gcc`, `msvc`, [and more](Reference-tables.md#compiler-ids). + +- `get_argument_syntax()` *(since 0.49.0)*: 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 compilers + such as clang or icc, especially when they use different syntax on different + operating systems. + +- `get_linker_id()` *(since 0.53.0)*: returns a string identifying the linker. + For example, `ld.bfd`, `link`, [and more](Reference-tables.md#linker-ids). + +- `get_supported_arguments(list_of_string)` *(since 0.43.0)*: returns + an array containing only the arguments supported by the compiler, + as if `has_argument` were called on them individually. + +- `get_supported_link_arguments(list_of_string)` *(since 0.46.0)*: returns + an array containing only the arguments supported by the linker, + as if `has_link_argument` were called on them individually. + +- `has_argument(argument_name)`: returns true if the compiler accepts + the specified command line argument, that is, can compile code + without erroring out or printing a warning about an unknown flag. + +- `has_link_argument(argument_name)` *(since 0.46.0)*: returns true if + the linker accepts the specified command line argument, that is, can + compile and link code without erroring out or printing a warning + about an unknown flag. Link arguments will be passed to the + compiler, so should usually have the `-Wl,` prefix. On VisualStudio + a `/link` argument will be prepended. + +- `has_function(funcname)`: returns true if the given function is + provided by the standard library or a library passed in with the + `args` keyword, you can specify external dependencies to use with + `dependencies` keyword argument. + +- `check_header(header_name)` *(since 0.47.0)*: returns true if the + specified header is *usable* with the specified prefix, + dependencies, and arguments. You can specify external dependencies + to use with `dependencies` keyword argument and extra code to put + above the header test with the `prefix` keyword. In order to look + for headers in a specific directory you can use `args : + '-I/extra/include/dir`, but this should only be used in exceptional + cases for includes that can't be detected via pkg-config and passed + via `dependencies`. *(since 0.50.0)* The `required` keyword argument + can be used to abort if the header cannot be found. + +- `has_header(header_name)`: returns true if the specified header + *exists*, and is faster than `check_header()` since it only does a + pre-processor check. You can specify external dependencies to use + with `dependencies` keyword argument and extra code to put above the + header test with the `prefix` keyword. In order to look for headers + in a specific directory you can use `args : '-I/extra/include/dir`, + but this should only be used in exceptional cases for includes that + can't be detected via pkg-config and passed via `dependencies`. + *(since 0.50.0)* The `required` keyword argument can be used to + abort if the header cannot be found. + +- `has_header_symbol(headername, symbolname)`: detects + whether a particular symbol (function, variable, #define, type + definition, etc) is declared in the specified header, you can + specify external dependencies to use with `dependencies` keyword + argument. *(since 0.50.0)* The `required` keyword argument can be + used to abort if the symbol cannot be found. + +- `has_member(typename, membername)`: takes two arguments, type name + and member name and returns true if the type has the specified + member, you can specify external dependencies to use with + `dependencies` keyword argument. + +- `has_members(typename, membername1, membername2, ...)`: takes at + least two arguments, type name and one or more member names, returns + true if the type has all the specified members, you can specify + external dependencies to use with `dependencies` keyword argument. + +- `has_multi_arguments(arg1, arg2, arg3, ...)` *(since 0.37.0)*: the same as + `has_argument` but takes multiple arguments and uses them all in a + single compiler invocation. + +- `has_multi_link_arguments(arg1, arg2, arg3, ...)` *(since 0.46.0)*: + the same as `has_link_argument` but takes multiple arguments and + uses them all in a single compiler invocation. + +- `has_type(typename)`: returns true if the specified token is a type, + you can specify external dependencies to use with `dependencies` + keyword argument. + +- `links(code)`: returns true if the code fragment given in the + positional argument compiles and links, you can specify external + dependencies to use with `dependencies` keyword argument, `code` can + be either a string containing source code or a `file` object + pointing to the source code. + +- `run(code)`: attempts to compile and execute the given code fragment, + returns a run result object, you can specify external dependencies + to use with `dependencies` keyword argument, `code` can be either a + string containing source code or a `file` object pointing to the + source code. + +- `symbols_have_underscore_prefix()` *(since 0.37.0)*: returns `true` + if the C symbol mangling is one underscore (`_`) prefixed to the symbol. + +- `sizeof(typename, ...)`: returns the size of the given type + (e.g. `'int'`) or -1 if the type is unknown, to add includes set + them in the `prefix` keyword argument, you can specify external + dependencies to use with `dependencies` keyword argument. + +- `version()`: returns the compiler's version number as a string. + +- `has_function_attribute(name)` *(since 0.48.0)*: returns `true` if the + compiler supports the GNU style (`__attribute__(...)`) `name`. This is + preferable to manual compile checks as it may be optimized for compilers that + do not support such attributes. + [This table](Reference-tables.md#gcc-__attribute__) lists all of the + supported attributes. + +- `get_supported_function_attributes(list_of_names)` *(since 0.48.0)*: + returns an array containing any names that are supported GCC style + attributes. Equivalent to `has_function_attribute` was called on each of them + individually. + +The following keyword arguments can be used: + +- `args`: used to pass a list of compiler arguments that are + required to find the header or symbol. For example, you might need + to pass the include path `-Isome/path/to/header` if a header is not + in the default include path. *(since 0.38.0)* you should use the + `include_directories` keyword described below. You may also want to + pass a library name `-lfoo` for `has_function` to check for a function. + Supported by all methods except `get_id`, `version`, and `find_library`. + +- `include_directories` *(since 0.38.0)*: specifies extra directories for + header searches. + +- `name`: the name to use for printing a message about the compiler + check. Supported by the methods `compiles()`, `links()`, and + `run()`. If this keyword argument is not passed to those methods, no + message will be printed about the check. + +- `no_builtin_args`: when set to true, the compiler arguments controlled + by built-in configuration options are not added. + +- `prefix`: adds #includes and other things that are + required for the symbol to be declared. 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, see below). Supported by the methods + `sizeof`, `has_type`, `has_function`, `has_member`, `has_members`, + `check_header`, `has_header`, `has_header_symbol`, `get_define` + +**Note:** 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. Hence, 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> + +### `build target` object + +A build target is either an [executable](#executable), [shared +library](#shared_library), [static library](#static_library), [both +shared and static library](#both_libraries) or [shared +module](#shared_module). + +- `extract_all_objects()`: is same as `extract_objects` but returns all + object files generated by this target. *(since 0.46.0)* keyword argument + `recursive` must be set to `true` to also return objects passed to + the `object` argument of this target. By default only objects built + for this target are returned to maintain backward compatibility with + previous versions. The default will eventually be changed to `true` + in a future version. + +- `extract_objects(source1, source2, ...)`: takes as its arguments + a number of source files as [`string`](#string-object) or + [`files()`](#files) and 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:`](#executable) keyword + argument or include them in the command line of a + [`custom_target`](#custom_target)`. + +- `full_path()`: 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. + +- `path()` *(since 0.59.0)* **(deprecated)**: does the exact same + as `full_path()`. **NOTE:** This function is solely kept for compatebility + with [`external program`](#external-program-object) objects. It will be + removed once the, also deprecated, corresponding `path()` function in the + `external program` object is removed. + +- `private_dir_include()`: returns a opaque value that works like + `include_directories` but points to the private directory of this + target, usually only needed if an another target needs to access + some generated internal headers of this target + +- `name()` *(since 0.54.0)*: returns the target name. + +- `found()` *(since 0.59.0)*: Always returns `true`. This function is meant + to make executables objects feature compatible with + [`external program`](#external-program-object) objects. This simplifies + use-cases where an executable is used instead of an external program. + + +### `configuration` data object + +This object is returned by +[`configuration_data()`](#configuration_data) and encapsulates +configuration values to be used for generating configuration files. A +more in-depth description can be found in the [the configuration wiki +page](Configuration.md) It has three methods: + +- `get(varname, default_value)`: returns the value of `varname`, if the + value has not been set returns `default_value` if it is defined + *(since 0.38.0)* and errors out if not + +- `get_unquoted(varname, default_value)` *(since 0.44.0)*: returns the value + of `varname` but without surrounding double quotes (`"`). If the value has + not been set returns `default_value` if it is defined and errors out if not. + +- `has(varname)`: returns `true` if the specified variable is set + +- `keys()`*(since 0.57.0)*: returns an array of keys of + the configuration data object. + + You can iterate over this array with the [`foreach` + statement](Syntax.md#foreach-statements). + +- `merge_from(other)` *(since 0.42.0)*: takes as argument a different + configuration data object and copies all entries from that object to + the current. + +- `set(varname, value)`, sets a variable to a given value + +- `set10(varname, boolean_value)` is the same as above but the value + is either `true` or `false` and will be written as 1 or 0, + respectively + +- `set_quoted(varname, value)` is same as `set` but quotes the value + in double quotes (`"`) + +They all take the `description` keyword 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. + +### `custom target` object + +This object is returned by [`custom_target`](#custom_target) and +contains a target with the following methods: + +- `full_path()`: 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. + *(since 0.54.0)* It can be also called on indexes objects: + `custom_targets[i].full_path()`. + +- `[index]`: returns an opaque object that references this target, and + can be used as a source in other targets. When it is used as such it + will make that target depend on this custom target, but the only + source added will be the one that corresponds to the index of the + custom target's output argument. + +- `to_list()` *(since 0.54.0)*: returns a list of opaque objects that references + this target, and can be used as a source in other targets. This can be used to + iterate outputs with `foreach` loop. + +### `dependency` object + +This object is returned by [`dependency()`](#dependency) and contains +an external dependency with the following methods: + + - `found()`: returns whether the dependency was found. + + - `name()` *(since 0.48.0)*: returns the name of the dependency that was + searched. Returns `internal` for dependencies created with + `declare_dependency()`. + + - `get_pkgconfig_variable(varname)` *(since 0.36.0)*: gets the + pkg-config variable specified, or, if invoked on a non pkg-config + dependency, error out. *(since 0.44.0)* You can also redefine a + variable by passing a list to the `define_variable` parameter + that can affect the retrieved variable: `['prefix', '/'])`. + *(since 0.45.0)* A warning is issued if the variable is not defined, + unless a `default` parameter is specified. + + *(Deprecated since 0.56.0*) use `get_variable(pkgconfig : ...)` instead + + - `get_configtool_variable(varname)` *(since 0.44.0)*: gets the + command line argument from the config tool (with `--` prepended), or, + if invoked on a non config-tool dependency, error out. + + *(Deprecated since 0.56.0*) use `get_variable(configtool : ...)` instead + + - `type_name()`: 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. + + - `version()`: the version number as a string, for example `1.2.8`. + `unknown` if the dependency provider doesn't support determining the + version. + + - `include_type()`: returns whether the value set by the `include_type` kwarg + + - `as_system(value)`: returns a copy of the dependency object, which has changed + the value of `include_type` to `value`. The `value` argument is optional and + defaults to `'preserve'`. + + - `as_link_whole()` *Since 0.56.0* Only dependencies created with + `declare_dependency()`, returns a copy of the dependency object with all + link_with arguments changed to link_whole. This is useful for example for + fallback dependency from a subproject built with `default_library=static`. + Note that all `link_with` objects must be static libraries otherwise an error + will be raised when trying to `link_whole` a shared library. + + - `partial_dependency(compile_args : false, link_args : false, links + : false, includes : false, sources : false)` *(since 0.46.0)*: 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: + + ```meson + 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. + + *Note*: A bug present until 0.50.1 results in the above behavior + not working correctly. + + 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 + + - `get_variable(varname, cmake : str, pkgconfig : str, configtool : str, + internal: str, default_value : str, pkgconfig_define : [str, str])` + *(since 0.51.0)*: a generic variable getter method, which replaces the + get_*type*_variable methods. This allows one to 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. + *(since 0.54.0)* added `internal` keyword. + *(since 0.58.0)* added `varname` as first positional argument. It is used as + default value for `cmake`, `pkgconfig`, `configtool` and `internal` 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')`. + +### `disabler` object + +A disabler object is an object that 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) they will cause the +statement evaluation to immediately short circuit to return a disabler +object. A disabler object has one method: + +- `found()`: always returns `false`. + +### `external program` object + +This object is returned by [`find_program()`](#find_program) and +contains an external (i.e. not built as part of this project) program +and has the following methods: + +- `found()`: returns whether the executable was found. + +- `path()`: *(since 0.55.0)* **(deprecated)** use `full_path()` instead. + Returns a string pointing to the script or executable + **NOTE:** You should not need to use this method. Passing the object + itself should work in all cases. For example: `run_command(obj, arg1, arg2)`. + +- `full_path()` (*since 0.55.0*): which returns a string pointing to the script or + executable **NOTE:** You should not need to use this method. Passing the object + itself should work in all cases. For example: `run_command(obj, arg1, arg2)`. + +### `environment` object + +This object is returned by [`environment()`](#environment) and stores +detailed information about how environment variables should be set +during tests. It should be passed as the `env` keyword argument to +tests and other functions. It has the following methods. + +- `append(varname, value1, value2, ...)`: 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. If + the separator is not specified explicitly, the default path + separator for the host operating system will be used, i.e. ';' for + Windows and ':' for UNIX/POSIX systems. + +- `prepend(varname, value1, value2, ...)`: same as `append` + except that it writes to the beginning of the variable. + +- `set(varname, value1, value2)`: sets the environment variable + specified in the first argument to the values in the second argument + joined by the separator, e.g. `env.set('FOO', 'BAR'),` sets envvar + `FOO` to value `BAR`. See `append()` above for how separators work. + +*Since 0.58.0* `append()` and `prepend()` methods can be called multiple times +on the same `varname`. Earlier Meson versions would warn and only the last +operation took effect. + +```meson +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') +``` + +### `external library` object + +This object is returned by [`find_library()`](#find_library) and +contains an external (i.e. not built as part of this project) +library. This object has the following methods: + +- `found()`: returns whether the library was found. + +- `type_name()` *(since 0.48.0)*: returns a string describing + the type of the dependency, which will be `library` in this case. + +- `partial_dependency(compile_args : false, link_args : false, links + : false, includes : false, source : false)` *(since 0.46.0)*: 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. + +### Feature option object + +*(since 0.47.0)* + +The following methods are defined for all [`feature` options](Build-options.md#features): + +- `enabled()`: returns whether the feature was set to `'enabled'` +- `disabled()`: returns whether the feature was set to `'disabled'` +- `auto()`: returns whether the feature was set to `'auto'` +- `allowed()` *(since 0.59.0)*: returns whether the feature was set to `'enabled'` or `'auto'` +- `disable_auto_if(value)` *(since 0.59.0)*: returns the feature, with + `'auto'` converted to `'disabled'` if value is true. + + | Feature / Condition | True | False | + | ------------------- | ---- | ----- | + | Enabled | Enabled | Enabled | + | Disabled | Disabled | Disabled | + | Auto | Disabled | Auto | + +- `require(value, error_message: '')` *(since 0.59.0)*: 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. + +`require` is useful to restrict 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() then + src += ['directx.c'] + config.set10('HAVE_DIRECTX', 1) +endif +``` + +### `generator` object + +This object is returned by [`generator()`](#generator) and contains a +generator that is used to transform files from one type to another by +an executable (e.g. `idl` files into source code and headers). + +- `process(list_of_files, ...)`: takes a list of files, causes them to + be processed and returns an object containing the result which can + then, for example, be passed into a build target definition. The + keyword argument `extra_args`, if specified, will be used to replace + an entry `@EXTRA_ARGS@` in the argument list. The keyword argument + `preserve_path_from`, 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`. + +### `subproject` object + +This object is returned by [`subproject()`](#subproject) and is an +opaque object representing it. + +- `found()` *(since 0.48.0)*: returns whether the subproject was + successfully setup + +- `get_variable(name, fallback)`: fetches the specified variable from + inside the subproject. This is useful to, for instance, get a + [declared dependency](#declare_dependency) from the + [subproject](Subprojects.md). + + 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. + +### `run result` object + +This object encapsulates the result of trying to compile and run a +sample piece of code with [`compiler.run()`](#compiler-object) or +[`run_command()`](#run_command). It has the following methods: + +- `compiled()`: 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. +- `returncode()`: the return code of executing the compiled binary +- `stderr()`: the standard error produced when the command was run +- `stdout()`: the standard out produced when the command was run + +### `module` object + +Modules provide their own specific implementation methods, but all modules +proivide the following methods: + +- `bool found()`: returns True if the module was successfully imported, + otherwise false. *Since 0.59.0* diff --git a/meson/docs/markdown/Reference-tables.md b/meson/docs/markdown/Reference-tables.md new file mode 100644 index 000000000..f2fc663eb --- /dev/null +++ b/meson/docs/markdown/Reference-tables.md @@ -0,0 +1,334 @@ +# Reference tables + +## Compiler ids + +These are return values of the `get_id` (Compiler family) and +`get_argument_syntax` (Argument syntax) method in a compiler object. + +| Value | Compiler family | Argument syntax | +| ----- | --------------- | --------------- | +| arm | ARM compiler | | +| armclang | ARMCLANG compiler | | +| c2000 | Texas Instruments C2000 compiler | | +| ccomp | The CompCert formally-verified C compiler | | +| ccrx | Renesas RX Family C/C++ compiler | | +| clang | The Clang compiler | gcc | +| clang-cl | The Clang compiler (MSVC compatible driver) | msvc | +| dmd | D lang reference compiler | | +| emscripten| Emscripten WASM compiler | | +| flang | Flang Fortran compiler | | +| g95 | The G95 Fortran compiler | | +| gcc | The GNU Compiler Collection | gcc | +| intel | Intel compiler (Linux and Mac) | gcc | +| intel-cl | Intel compiler (Windows) | msvc | +| lcc | Elbrus C/C++/Fortran Compiler | | +| llvm | LLVM-based compiler (Swift, D) | | +| mono | Xamarin C# compiler | | +| msvc | Microsoft Visual Studio | msvc | +| nagfor | The NAG Fortran compiler | | +| nvidia_hpc| NVidia HPC SDK compilers | | +| open64 | The Open64 Fortran Compiler | | +| pathscale | The Pathscale Fortran compiler | | +| pgi | Portland PGI C/C++/Fortran compilers | | +| rustc | Rust compiler | | +| sun | Sun Fortran compiler | | +| valac | Vala compiler | | +| xc16 | Microchip XC16 C compiler | | +| cython | The Cython compiler | | + +## Linker ids + +These are return values of the `get_linker_id` method in a compiler object. + +| Value | Linker family | +| ----- | --------------- | +| ld.bfd | The GNU linker | +| ld.gold | The GNU gold linker | +| ld.lld | The LLVM linker, with the GNU interface | +| ld.solaris | Solaris and illumos | +| ld.wasm | emscripten's wasm-ld linker | +| ld64 | Apple ld64 | +| link | MSVC linker | +| lld-link | The LLVM linker, with the MSVC interface | +| xilink | Used with Intel-cl only, MSVC like | +| optlink | optlink (used with DMD) | +| rlink | The Renesas linker, used with CCrx only | +| xc16-ar | The Microchip linker, used with XC16 only | +| ar2000 | The Texas Instruments linker, used with C2000 only | +| armlink | The ARM linker (arm and armclang compilers) | +| pgi | Portland/Nvidia PGI | +| nvlink | Nvidia Linker used with cuda | +| ccomp | CompCert used as the linker driver | + +For languages that don't have separate dynamic linkers such as C# and Java, the +`get_linker_id` will return the compiler name. + +## Script environment variables + +| Value | Comment | +| ----- | ------- | +| MESONINTROSPECT | Command to run to run the introspection command, may be of the form `python /path/to/meson introspect`, user is responsible for splitting the path if necessary. | +| MESON_BUILD_ROOT | Absolute path to the build dir | +| MESON_DIST_ROOT | Points to the root of the staging directory, only set when running `dist` scripts | +| MESON_SOURCE_ROOT | Absolute path to the source dir | +| MESON_SUBDIR | Current subdirectory, only set for `run_command` | + +## CPU families + +These are returned by the `cpu_family` method of `build_machine`, +`host_machine` and `target_machine`. For cross compilation they are +set in the cross file. + +| Value | Comment | +| ----- | ------- | +| aarch64 | 64 bit ARM processor | +| alpha | DEC Alpha processor | +| arc | 32 bit ARC processor | +| arm | 32 bit ARM processor | +| avr | Atmel AVR processor | +| c2000 | 32 bit C2000 processor | +| csky | 32 bit CSky processor | +| dspic | 16 bit Microchip dsPIC | +| e2k | MCST Elbrus processor | +| ia64 | Itanium processor | +| loongarch64 | 64 bit Loongson processor| +| m68k | Motorola 68000 processor | +| microblaze | MicroBlaze processor | +| mips | 32 bit MIPS processor | +| mips64 | 64 bit MIPS processor | +| parisc | HP PA-RISC processor | +| pic24 | 16 bit Microchip PIC24 | +| ppc | 32 bit PPC processors | +| ppc64 | 64 bit PPC processors | +| riscv32 | 32 bit RISC-V Open ISA | +| riscv64 | 64 bit RISC-V Open ISA | +| rl78 | Renesas RL78 | +| rx | Renesas RX 32 bit MCU | +| s390 | IBM zSystem s390 | +| s390x | IBM zSystem s390x | +| sh4 | SuperH SH-4 | +| sparc | 32 bit SPARC | +| sparc64 | SPARC v9 processor | +| wasm32 | 32 bit Webassembly | +| wasm64 | 64 bit Webassembly | +| x86 | 32 bit x86 processor | +| x86_64 | 64 bit x86 processor | + +Any cpu family not listed in the above list is not guaranteed to +remain stable in future releases. + +Those porting from autotools should note that Meson does not add +endianness to the name of the cpu_family. For example, autotools +will call little endian PPC64 "ppc64le", Meson will not, you must +also check the `.endian()` value of the machine for this information. + +## Operating system names + +These are provided by the `.system()` method call. + +| Value | Comment | +| ----- | ------- | +| android | By convention only, subject to change | +| cygwin | The Cygwin environment for Windows | +| darwin | Either OSX or iOS | +| dragonfly | DragonFly BSD | +| emscripten | Emscripten's Javascript environment | +| freebsd | FreeBSD and its derivatives | +| gnu | GNU Hurd | +| haiku | | +| linux | | +| netbsd | | +| openbsd | | +| windows | Any version of Windows | +| sunos | illumos and Solaris | + +Any string not listed above is not guaranteed to remain stable in +future releases. + +## Language arguments parameter names + +These are the parameter names for passing language specific arguments to your build target. + +| Language | compiler name | linker name | +| ------------- | ------------- | ----------------- | +| C | c_args | c_link_args | +| C++ | cpp_args | cpp_link_args | +| C# | cs_args | cs_link_args | +| D | d_args | d_link_args | +| Fortran | fortran_args | fortran_link_args | +| Java | java_args | java_link_args | +| Objective C | objc_args | objc_link_args | +| Objective C++ | objcpp_args | objcpp_link_args | +| Rust | rust_args | rust_link_args | +| Vala | vala_args | vala_link_args | +| Cython | cython_args | cython_link_args | + +All these `<lang>_*` options are specified per machine. See in +[specifying options per +machine](Builtin-options.md#Specifying-options-per-machine) for on how +to do this in cross builds. + +## Compiler and linker flag environment variables + +These environment variables will be used to modify the compiler and +linker flags. + +It is recommended that you **do not use these**. They are provided +purely to for backwards compatibility with other build systems. There +are many caveats to their use, especially when rebuilding the project. +It is **highly** recommended that you use [the command line +arguments](#language-arguments-parameter-names) instead. + +| Name | Comment | +| ----- | ------- | +| CFLAGS | Flags for the C compiler | +| CXXFLAGS | Flags for the C++ compiler | +| OBJCFLAGS | Flags for the Objective C compiler | +| FFLAGS | Flags for the Fortran compiler | +| DFLAGS | Flags for the D compiler | +| VALAFLAGS | Flags for the Vala compiler | +| RUSTFLAGS | Flags for the Rust compiler | +| CYTHONFLAGS | Flags for the Cython compiler | +| LDFLAGS | The linker flags, used for all languages | + +N.B. these settings are specified per machine, and so the environment +varibles actually come in pairs. See the [environment variables per +machine](#Environment-variables-per-machine) section for details. + +## Function Attributes + +These are the parameters names that are supported using +`compiler.has_function_attribute()` or +`compiler.get_supported_function_attributes()` + +### GCC `__attribute__` + +These values are supported using the GCC style `__attribute__` annotations, +which are supported by GCC, Clang, and other compilers. + + +| Name | +|--------------------------| +| alias | +| aligned | +| alloc_size | +| always_inline | +| artificial | +| cold | +| const | +| constructor | +| constructor_priority | +| deprecated | +| destructor | +| error | +| externally_visible | +| fallthrough | +| flatten | +| format | +| format_arg | +| force_align_arg_pointer³ | +| gnu_inline | +| hot | +| ifunc | +| malloc | +| noclone | +| noinline | +| nonnull | +| noreturn | +| nothrow | +| optimize | +| packed | +| pure | +| returns_nonnull | +| unused | +| used | +| visibility* | +| visibility:default† | +| visibility:hidden† | +| visibility:internal† | +| visibility:protected† | +| warning | +| warn_unused_result | +| weak | +| weakreaf | + +\* *Changed in 0.52.0* the "visibility" target no longer includes +"protected", which is not present in Apple's clang. + +† *New in 0.52.0* These split visibility attributes are preferred to the plain +"visibility" as they provide narrower checks. + +³ *New in 0.55.0* + +### MSVC __declspec + +These values are supported using the MSVC style `__declspec` annotation, +which are supported by MSVC, GCC, Clang, and other compilers. + +| Name | +|----------------------| +| dllexport | +| dllimport | + + +## Dependency lookup methods + +These are the values that can be passed to `dependency` function's +`method` keyword argument. + +| Name | Comment | +| ----- | ------- | +| auto | Automatic method selection | +| pkg-config | Use Pkg-Config | +| cmake | Look up as a CMake module | +| config-tool | Use a custom dep tool such as `cups-config` | +| system | System provided (e.g. OpenGL) | +| extraframework | A macOS/iOS framework | + + +## Compiler and Linker selection variables + +N.B. these settings are specified per machine, and so the environment +varibles actually come in pairs. See the [environment variables per +machine](#Environment-variables-per-machine) section for details. + +| Language | Compiler | Linker | Note | +|---------------|----------|-----------|---------------------------------------------| +| C | CC | CC_LD | | +| C++ | CXX | CXX_LD | | +| D | DC | DC_LD | Before 0.54 D_LD* | +| Fortran | FC | FC_LD | Before 0.54 F_LD* | +| Objective-C | OBJC | OBJC_LD | | +| Objective-C++ | OBJCXX | OBJCXX_LD | Before 0.54 OBJCPP_LD* | +| Rust | RUSTC | RUSTC_LD | Before 0.54 RUST_LD* | +| Vala | VALAC | | Use CC_LD. Vala transpiles to C | +| C# | CSC | CSC | The linker is the compiler | + +*The old environment variales are still supported, but are deprecated +and will be removed in a future version of Meson.* + +## Environment variables per machine + +Since *0.54.0*, Following Autotool and other legacy build systems, +environment variables that affect machine-specific settings come in +pairs: for every bare environment variable `FOO`, there is a suffixed +`FOO_FOR_BUILD`, where `FOO` just affects the host machine +configuration, while `FOO_FOR_BUILD` just affects the build machine +configuration. For example: + + - `PKG_CONFIG_PATH_FOR_BUILD` controls the paths pkg-config will search for + just `native: true` dependencies (build machine). + + - `PKG_CONFIG_PATH` controls the paths pkg-config will search for just + `native: false` dependencies (host machine). + +This mirrors the `build.` prefix used for (built-in) Meson options, +which has the same meaning. + +This is useful for cross builds. In the native builds, build = host, +and the unsuffixed environment variables alone will suffice. + +Prior to *0.54.0*, there was no `_FOR_BUILD`-suffixed variables, and +most environment variables only effected native machine +configurations, though this wasn't consistent (e.g. `PKG_CONFIG_PATH` +still affected cross builds). diff --git a/meson/docs/markdown/Release-notes-for-0.37.0.md b/meson/docs/markdown/Release-notes-for-0.37.0.md new file mode 100644 index 000000000..930c1d1f4 --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.37.0.md @@ -0,0 +1,173 @@ +--- +title: Release 0.37 +short-description: Release notes for 0.37 +... + +# New features + +## Mesontest + +Mesontest is a new testing tool that allows you to run your tests in +many different ways. As an example you can run tests multiple times: + + mesontest --repeat=1000 a_test + +or with an arbitrary wrapper executable: + + mesontest --wrap='valgrind --tool=helgrind' a_test + +or under `gdb`, 1000 times in a row. This is handy for tests that fail +spuriously, as when the crash happens you are given the full GDB +command line: + + mesontest --repeat=1000 --gdb a_test + +## Mesonrewriter + +Mesonrewriter is an experimental tool to manipulate your build +definitions programmatically. It is not installed by default yet but +those interested can run it from the source repository. + +As an example, here is how you would add a source file to a build target: + + mesonrewriter add --target=program --filename=new_source.c + +## Shared modules + +The new `shared_module` function allows the creation of shared +modules, that is, extension modules such as plugins that are meant to +be used solely with `dlopen` rather than linking them to targets. + +## Gnome module + +- Detect required programs and print useful errors if missing + +### gtkdoc + +- Allow passing a list of directories to `src_dir` keyword argument +- Add `namespace` keyword argument +- Add `mode` keyword argument +- Fix `gtkdoc-scangobj` finding local libraries + +### compile_resources + +- Add `gresource_bundle` keyword argument to output `.gresource` files +- Add `export` and `install_header` keyword arguments +- Use depfile support available in GLib >= 2.52.0 + +## i18n module + +- Add `merge_file()` function for creating translated files +- Add `preset` keyword argument to included common gettext flags +- Read languages from `LINGUAS` file + +## LLVM IR compilation + +Meson has long had support for compiling assembler (GAS) files. In +this release we add support for compiling LLVM IR files in a similar +way when building with the Clang compiler. Just add it to the list of +files when creating a `library` or `executable` target like any other +source file. No special handling is required: + +```meson +executable('some-exe', 'main.c', 'asm-file.S', 'ir-file.ll') +``` + +As always, you can also mix LLVM IR files with C++, C, and Assembly +(GAS) sources. + +## ViM indent and syntax files + +We now include filetype, indent, and syntax files for ViM [with the +source +tree](https://github.com/mesonbuild/meson/tree/master/data/syntax-highlighting/vim). +Please file issues (or pull requests!) for enhancements or if you face +any problems using them. + +## Push URLs in .wrap files + +[.wrap files](Using-the-WrapDB.md) for subprojects can now include a +separate push URL to allow developers to push changes directly from a +subproject git checkout. + +## pkg-config dependencies + +Meson now supports multiple version restrictions while searching for pkg-config dependencies. + +```meson +# Just want a lower limit +dependency('zlib', version : '>1.2.1') +# Want both a lower and an upper limit +dependency('opencv', version : ['>=2.3.0', '<=3.1.0']) +# Want to exclude one specific broken version +dependency('foolite', version : ['>=3.12.1', '!=3.13.99']) +``` + +## Overriding more binaries with environment variables + +You can now specify the binary to be used for the following tools by +setting the corresponding environment variable + +| Name | Environment variable | +| ---- | -------------------- | +| pkg-config | PKG_CONFIG | +| readelf | READELF | +| nm | NM | + +## Support for `localstatedir` + +Similar to other options such as `bindir` and `datadir`, you can now +specify the `localstatedir` for a project by passing +`--localstatedir=dir` to `meson` or `-Dlocalstatedir=dir` to +`mesonconf` after configuration. You can also access it from inside +the `meson.build` file with `get_option('localstatedir')`. + +## New compiler function `symbols_have_underscore_prefix` + +Checks if the compiler prefixes an underscore to C global symbols with +the default calling convention. This is useful when linking to +compiled assembly code, or other code that does not have its C symbol +mangling handled transparently by the compiler. + +```meson +cc = meson.get_compiler('c') +conf = configuration_data() +if cc.symbols_have_underscore_prefix() + conf.set('SYMBOLS_HAVE_UNDERSCORE', true) +endif +``` + +C symbol mangling is platform and architecture dependent, and a helper +function is needed to detect it. For example, Windows 32-bit prefixes +underscore, but 64-bit does not. Linux does not prefix an underscore +but OS X does. + +## Vala + +GLib Resources compiled with +[`gnome.compile_resources`](Gnome-module.md#compile_resources) that +are added to the sources of a Vala build target will now cause the +appropriate `--gresources` flag to be passed to the Vala compiler so +you don't need to add that yourself to `vala_args:`. + +## Improvements to install scripts + +You can now pass arguments to install scripts added with +[`meson.add_install_script()`](Reference-manual.md#meson-object). All +arguments after the script name will be passed to the script. + +The `MESON_INSTALL_DESTDIR_PREFIX` environment variable is now set +when install scripts are called. This contains the values of the +`DESTDIR` environment variable and the `prefix` option passed to Meson +joined together. This is useful because both those are usually +absolute paths, and joining absolute paths in a cross-platform way is +tricky. [`os.path.join` in +Python](https://docs.python.org/3/library/os.path.html#os.path.join) +will discard all previous path segments when it encounters an absolute +path, and simply concatenating them will not work on Windows where +absolute paths begin with the drive letter. + +## More install directories + +Added new options `sbindir` and `infodir` that can be used for +installation. diff --git a/meson/docs/markdown/Release-notes-for-0.38.0.md b/meson/docs/markdown/Release-notes-for-0.38.0.md new file mode 100644 index 000000000..152308d0e --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.38.0.md @@ -0,0 +1,123 @@ +--- +title: Release 0.38 +short-description: Release notes for 0.38 +... + +## Uninstall target + +Meson allows you to uninstall an install step by invoking the +uninstall target. This will remove all files installed as part of +install. Note that this does not restore the original files. This also +does not undo changes done by custom install scripts (because they can +do arbitrary install operations). + +## Support for arbitrary test setups + +Sometimes you need to run unit tests with special settings. For +example under Valgrind. Usually this requires extra command line +options for the tool. This is supported with the new *test setup* +feature. For example to set up a test run with Valgrind, you'd write +this in a `meson.build` file: + +```meson +add_test_setup('valgrind', + exe_wrapper : [vg, '--error-exitcode=1', '--leak-check=full'], + timeout_multiplier : 100) +``` + +This tells Meson to run tests with Valgrind using the given options +and multiplying the test timeout values by 100. To run this test setup +simply issue the following command: + +```console +$ mesontest --setup=valgrind +``` + +## Intel C/C++ compiler support + +As usual, just set `CC=icc CXX=icpc` and Meson will use it as the +C/C++ compiler. Currently only Linux is supported. + +## Get values from configuration data objects + +Now it is possible to query values stored in configuration data +objects. + +```meson +cdata.set('key', 'value') +cdata.get('key') # returns 'value' +cdata.get('nokey', 'default') # returns 'default' +cdata.get('nokey') # halts with an error +``` + +## Python 3 module support + +Building Python 3 extension modules has always been possible, but it +is now even easier: + +```meson +py3_mod = import('python3') +pylib = py3_mod.extension_module('modname', + 'modsource.c', + dependencies : py3_dep) +``` + +## Default options to subprojects + +Projects can specify overriding values for subprojects' +`default_options` when invoking a subproject: + +```meson +subproject('foo', default_options : ['optname=overridevalue']) +dependency('some-dep', fallback : ['some_subproject', 'some_dep'], default_options : ['optname=overridevalue']) +``` + +The effect is the same as if the default options were written in the +subproject's `project` call. + +## Set targets to be built (or not) by default + +Build targets got a new keyword `build_by_default` which tells whether +the target should be built by default when running e.g. `ninja`. +Custom targets are not built by default but other targets are. Any +target that is tagged as installed or to be built always is also built +by default, regardless of the value of this keyword. + +## Add option to mesonconf to wipe cached data. + +Meson caches the results of dependency lookups. Sometimes these may +get out of sync with the system state. Mesonconf now has a +`--clearcache` option to clear these values so they will be +re-searched from the system upon next compile. + +## Can specify file permissions and owner when installing data + +The new `install_mode` keyword argument can be used to specify file +permissions and uid/gid of files when doing the install. This allows +you to, for example, install suid root scripts. + +## `has_header()` checks are now faster + +When using compilers that implement the [`__has_include()` +preprocessor +macro](https://clang.llvm.org/docs/LanguageExtensions.html#include-file-checking-macros), +the check is now ~40% faster. + +## Array indexing now supports fallback values + +The second argument to the array +[`.get()`](Reference-manual.md#array-object) function is now returned +if the specified index could not be found + +```meson +array = [10, 11, 12, 13] +array.get(0) # this will return `10` +array.get(4) # this will give an error about invalid index +array.get(4, 0) # this will return `0` +``` + +## Silent mode for Mesontest + +The Meson test executor got a new argument `-q` (and `--quiet`) that +suppresses all output of successful tests. This makes interactive +usage nicer because only errors are printed. diff --git a/meson/docs/markdown/Release-notes-for-0.39.0.md b/meson/docs/markdown/Release-notes-for-0.39.0.md new file mode 100644 index 000000000..73b49ae8d --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.39.0.md @@ -0,0 +1,16 @@ +--- +title: Release 0.39 +short-description: Release notes for 0.39 +... + +The 0.39.0 release turned out to consist almost entirely of bug fixes +and minor polishes. + +# New features + +## Extra arguments for tests + +The Meson test executable allows specifying extra command line +arguments to pass to test executables. + + mesontest --test-args=--more-debug-info currenttest diff --git a/meson/docs/markdown/Release-notes-for-0.40.0.md b/meson/docs/markdown/Release-notes-for-0.40.0.md new file mode 100644 index 000000000..53bc9bad9 --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.40.0.md @@ -0,0 +1,152 @@ +--- +title: Release 0.40 +short-description: Release notes for 0.40 +... + +# New features + +## Outputs of generators can be used in custom targets in the VS backend + +This has been possible with the Ninja backend for a long time but now +the Visual Studio backend works too. + +## `compute_int` method in the compiler objects + +This method can be used to evaluate the value of an expression. As an +example: + +```meson +cc = meson.get_compiler('c') +two = cc.compute_int('1 + 1') # A very slow way of adding two numbers. +``` + +## Visual Studio 2017 support + +There is now a VS2017 backend (`--backend=vs2017`) as well as a +generic VS backend (`--backend=vs`) that autodetects the currently +active VS version. + +## Automatic initialization of subprojects that are git submodules + +If you have a directory inside your subprojects directory (usually +`subprojects/`) that is a git submodule, Meson will automatically +initialize it if your build files refer to it. This will be done +without needing a wrap file since git contains all the information +needed. + +## No download mode for wraps + +Added a new option `wrap-mode` that can be toggled to prevent Meson +from downloading dependency projects. Attempting to do so will cause +an error. This is useful for distro packagers and other cases where +you must explicitly enforce that nothing is downloaded from the net +during configuration or build. + +## Overriding options per target + +Build targets got a new keyword argument `override_options` that can +be used to override system options. As an example if you have a target +that you know can't be built with `-Werror` enabled you can override +the value of the option like this: + +```meson +executable('foo', 'foo.c', override_options : ['werror=false']) +``` + +Note that this does not affect project options, only those options +that come from Meson (language standards, unity builds etc). + +## Compiler object get define + +Compiler objects got a new method `get_define()` that returns the +given preprocessor symbol as a string. + +```meson +cc = meson.get_compiler('c') +one = cc.get_define('__linux__') # returns '1' on Linux hosts +``` + +## Cygwin support + +Meson now works under Cygwin and we have added it to our CI test +matrix. + +## Multiple install directories + +Custom targets can produce many output files. Previously it was only +possible to install all of them in the same directory, but now you can +install each output in its own directory like this: + +```meson +custom_target('two_out', + output : ['diff.h', 'diff.sh'], + command : [creator, '@OUTDIR@'], + install : true, + install_dir : ['dir1', 'dir2']) +``` + +For backwards compatibility and for conciseness, if you only specify +one directory all outputs will be installed into it. + +The same feature is also available for Vala build targets. For +instance, to install a shared library built by valac, the generated +header, and the generated VAPI (respectively) into the default +locations, you can do: + +```meson +shared_library('valalib', 'mylib.vala', + install : true, + install_dir : [true, true, true]) +``` + +To install any of the three in a custom directory, just pass it as a +string instead of `true`. To not install it, pass `false`. You can +also pass a single string (as before) and it will cause only the +library to be installed, so this is a backwards-compatible change. + +## Can specify method of obtaining dependencies + +Some dependencies have many ways of being provided. As an example Qt +can either be detected via `pkg-config` or `qmake`. Until now Meson +has had a heuristic for selecting which method to choose but sometimes +it does the wrong thing. This can now be overridden with the `method` +keyword like this: + +```meson +qt5_dep = dependency('qt5', modules : 'core', method : 'qmake') +``` + +## Link whole contents of static libraries + +The default behavior of static libraries is to discard all symbols +that are not not directly referenced. This may lead to exported +symbols being lost. Most compilers support "whole archive" linking +that includes all symbols and code of a given static library. This is +exposed with the `link_whole` keyword. + +```meson +shared_library('foo', 'foo.c', link_whole : some_static_library) +``` + +Note that Visual Studio compilers only support this functionality on +VS 2015 and newer. + +## Unity builds only for subprojects + +Up until now unity builds were either done for every target or none of +them. Now unity builds can be specified to be enabled only for +subprojects, which change seldom, and not for the master project, +which changes a lot. This is enabled by setting the `unity` option to +`subprojects`. + +## Running `mesonintrospect` from scripts + +Meson now sets the `MESONINTROSPECT` environment variable in addition +to `MESON_SOURCE_ROOT` and other variables when running scripts. It is +guaranteed to point to the correct `mesonintrospect` script, which is +important when running Meson uninstalled from git or when your `PATH`s +may not be set up correctly. + +Specifically, the following Meson functions will set it: +`meson.add_install_script()`, `meson.add_postconf_script()`, +`run_command()`, `run_target()`. diff --git a/meson/docs/markdown/Release-notes-for-0.41.0.md b/meson/docs/markdown/Release-notes-for-0.41.0.md new file mode 100644 index 000000000..8ce181a71 --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.41.0.md @@ -0,0 +1,84 @@ +--- +title: Release 0.41 +short-description: Release notes for 0.41 +... + +# New features + +## Dependency Handler for LLVM + +Native support for linking against LLVM using the `dependency` function. + +## vcs_tag keyword fallback is now optional + +The `fallback` keyword in `vcs_tag()` is now optional. If not given, +its value defaults to the return value of `meson.project_version()`. + +## Better quoting of special characters in ninja command invocations + +The ninja backend now quotes special characters that may be +interpreted by ninja itself, providing better interoperability with +custom commands. This support may not be perfect; please report any +issues found with special characters to the issue tracker. + +## Pkgconfig support for custom variables + +The Pkgconfig module object can add arbitrary variables to the generated .pc +file with the new `variables` keyword: +```meson +pkg.generate(libraries : libs, + subdirs : h, + version : '1.0', + name : 'libsimple', + filebase : 'simple', + description : 'A simple demo library.', + variables : ['datadir=${prefix}/data']) +``` + +## A target for creating tarballs + +Creating distribution tarballs is simple: + + ninja dist + +This will create a `.tar.xz` archive of the source code including +submodules without any revision control information. This command also +verifies that the resulting archive can be built, tested and +installed. This is roughly equivalent to the `distcheck` target in +other build systems. Currently this only works for projects using Git +and only with the Ninja backend. + +## Support for passing arguments to Rust compiler + +Targets for building rust now take a `rust_args` keyword. + +## Code coverage export for tests + +Code coverage can be generated for tests by passing the `--cov` argument to +the `run_tests.py` test runner. Note, since multiple processes are used, +coverage must be combined before producing a report (`coverage3 combine`). + +## Reproducible builds + +All known issues have been fixed and Meson can now build reproducible Debian +packages out of the box. + +## Extended template substitution in configure_file + +The output argument of `configure_file()` is parsed for @BASENAME@ and +@PLAINNAME@ substitutions. + +## Cross-config property for overriding whether an exe wrapper is needed + +The new `needs_exe_wrapper` property allows overriding auto-detection for +cases where `build_machine` appears to be compatible with `host_machine`, +but actually isn't. For example when: +- `build_machine` is macOS and `host_machine` is the iOS Simulator +- the `build_machine`'s libc is glibc but the `host_machine` libc is uClibc +- code relies on kernel features not available on the `build_machine` + +## Support for capturing stdout of a command in configure_file + +`configure_file()` now supports a new keyword - `capture`. When this argument +is set to true, Meson captures `stdout` of the `command` and writes it to +the target file specified as `output`. diff --git a/meson/docs/markdown/Release-notes-for-0.42.0.md b/meson/docs/markdown/Release-notes-for-0.42.0.md new file mode 100644 index 000000000..585380b1a --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.42.0.md @@ -0,0 +1,148 @@ +--- +title: Release 0.42 +short-description: Release notes for 0.42 +... + +# New features + +## Distribution tarballs from Mercurial repositories + +Creating distribution tarballs can now be made out of projects based +on Mercurial. As before, this remains possible only with the Ninja +backend. + +## Keyword argument verification + +Meson will now check the keyword arguments used when calling any +function and print a warning if any of the keyword arguments is not +known. In the future this will become a hard error. + +## Add support for Genie to Vala compiler + +The Vala compiler has an alternative syntax, Genie, that uses the +`.gs` file extension. Meson now recognises and uses Genie files. + +## Pkgconfig support for additional cflags + +The Pkgconfig module object can add arbitrary extra cflags to the Cflags +value in the .pc file, using the "extra_cflags" keyword: +```meson +pkg.generate(libraries : libs, + subdirs : h, + version : '1.0', + name : 'libsimple', + filebase : 'simple', + description : 'A simple demo library.', + extra_cflags : '-Dfoo' ) +``` + +## Base options accessible via get_option() + +Base options are now accessible via the get_option() function. +```meson +uses_lto = get_option('b_lto') +``` + +## Allow crate type configuration for Rust compiler + +Rust targets now take an optional `rust_crate_type` keyword, allowing +you to set the crate type of the resulting artifact. Valid crate types +are `dylib` or `cdylib` for shared libraries, and `rlib` or +`staticlib` for static libraries. For more, see Rust's [linkage +reference][rust-linkage]. + +[rust-linkage]: https://doc.rust-lang.org/reference/linkage.html + +## Simultaneous use of Address- and Undefined Behavior Sanitizers + +Both the address- and undefined behavior sanitizers can now be used +simultaneously by passing `-Db_sanitize=address,undefined` to Meson. + +## Unstable SIMD module + +A new experimental module to compile code with many different SIMD +instruction sets and selecting the best one at runtime. This module +is unstable, meaning its API is subject to change in later releases. +It might also be removed altogether. + + +## Import libraries for executables on Windows + +The new keyword `implib` to `executable()` allows generation of an import +library for the executable. + +## Added build_rpath keyword argument + +You can specify `build_rpath : '/foo/bar'` in build targets and the +given path will get added to the target's rpath in the build tree. It +is removed during the install step. + +Meson will print a warning when the user tries to add an rpath linker +flag manually, e.g. via `link_args` to a target. This is not +recommended because having multiple rpath causes them to stomp on each +other. This warning will become a hard error in some future release. + +## Vulkan dependency module + +Vulkan can now be used as native dependency. The dependency module +will detect the VULKAN_SDK environment variable or otherwise try to +receive the vulkan library and header via pkgconfig or from the +system. + +## Limiting the maximum number of linker processes + +With the Ninja backend it is now possible to limit the maximum number of +concurrent linker processes. This is usually only needed for projects +that have many large link steps that cause the system to run out of +memory if they are run in parallel. This limit can be set with the +new `backend_max_links` option. + +## Disable implicit include directories + +By default Meson adds the current source and build directories to the +header search path. On some rare occasions this is not desired. Setting +the `implicit_include_directories` keyword argument to `false` these +directories are not used. + +## Support for MPI dependency + +MPI is now supported as a dependency. Because dependencies are +language-specific, you must specify the requested language with the +`language` keyword, i.e., `dependency('mpi', language='c')` will +request the C MPI headers and libraries. See [the MPI +dependency](Dependencies.md#mpi) for more information. + +## Allow excluding files or directories from `install_subdir` + +The [`install_subdir`](Reference-manual.md#install_subdir) command +accepts the new `exclude_files` and `exclude_directories` keyword +arguments that allow specified files or directories to be excluded +from the installed subdirectory. + +## Make all Meson functionality invokable via the main executable + +Previously Meson had multiple executables such as `mesonintrospect` +and `mesontest`. They are now invokable via the main Meson executable +like this: + + meson configure <arguments> # equivalent to mesonconf <options> + meson test <arguments> # equivalent to mesontest <arguments> + +The old commands are still available but they are deprecated +and will be removed in some future release. + +## Pcap dependency detector + +Meson will automatically obtain dependency information for pcap +using the `pcap-config` tool. It is used like any other dependency: + +```meson +pcap_dep = dependency('pcap', version : '>=1.0') +``` + +## GNOME module mkenums_simple() addition + +Most libraries and applications use the same standard templates for +glib-mkenums. There is now a new `mkenums_simple()` convenience method +that passes those default templates to glib-mkenums and allows some tweaks +such as optional function decorators or leading underscores. diff --git a/meson/docs/markdown/Release-notes-for-0.43.0.md b/meson/docs/markdown/Release-notes-for-0.43.0.md new file mode 100644 index 000000000..1ce774dec --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.43.0.md @@ -0,0 +1,125 @@ +--- +title: Release 0.43 +short-description: Release notes for 0.43 +... + +## Portability improvements to Boost Dependency + +The Boost dependency has been improved to better detect the various +ways to install boost on multiple platforms. At the same time the +`modules` semantics for the dependency has been changed. Previously it +was allowed to specify header directories as `modules` but it wasn't +required. Now, modules are only used to specify libraries that require +linking. + +This is a breaking change and the fix is to remove all modules that aren't +found. + +## Generator learned capture + +Generators can now be configured to capture the standard output. See +`test cases/common/98 gen extra/meson.build` for an example. + +## Can index CustomTarget objects + +The `CustomTarget` object can now be indexed like an array. The +resulting object can be used as a source file for other Targets, this +will create a dependency on the original `CustomTarget`, but will only +insert the generated file corresponding to the index value of the +`CustomTarget`'s `output` keyword. + +```meson +c = custom_target( + ... + output : ['out.h', 'out.c'], +) +lib1 = static_library( + 'lib1', + [lib1_sources, c[0]], + ... +) +exec = executable( + 'executable', + c[1], + link_with : lib1, +) +``` + +## Can override executables in the cross file + +The cross file can now be used for overriding the result of +`find_program`. As an example if you want to find the `objdump` +command and have the following definition in your cross file: + +```ini +[binaries] +... +objdump = '/usr/bin/arm-linux-gnueabihf-objdump-6' +``` + +Then issuing the command `find_program('objdump')` will return the +version specified in the cross file. If you need the build machine's +objdump, you can specify the `native` keyword like this: + +```meson +native_objdump = find_program('objdump', native : true) +``` + +## Easier handling of supported compiler arguments + +A common pattern for handling multiple desired compiler arguments, was +to test their presence and add them to an array one-by-one, e.g.: + +```meson +warning_flags_maybe = [ + '-Wsomething', + '-Wanother-thing', + '-Wno-the-other-thing', +] +warning_flags = [] +foreach flag : warning_flags_maybe + if cc.has_argument(flag) + warning_flags += flag + endif +endforeach +cc.add_project_argument(warning_flags) +``` + +A helper has been added for the foreach/has_argument pattern, so you +can now simply do: + +```meson +warning_flags = [ ... ] +flags = cc.get_supported_arguments(warning_flags) +``` + +## Better support for shared libraries in non-system paths + +Meson has support for prebuilt object files and static libraries. This +release adds feature parity to shared libraries that are either in +non-standard system paths or shipped as part of your project. On +systems that support rpath, Meson automatically adds rpath entries to +built targets using manually found external libraries. + +This means that e.g. supporting prebuilt libraries shipped with your +source or provided by subprojects or wrap definitions by writing a +build file like this: + +```meson +project('myprebuiltlibrary', 'c') + +cc = meson.get_compiler('c') +prebuilt = cc.find_library('mylib', dirs : meson.current_source_dir()) +mydep = declare_dependency(include_directories : include_directories('.'), + dependencies : prebuilt) +``` + +Then you can use the dependency object in the same way as any other. + +## wrap-svn + +The [Wrap dependency system](Wrap-dependency-system-manual.md) now +supports [Subversion](https://subversion.apache.org/) (svn). This +support is rudimentary. The repository url has to point to a specific +(sub)directory containing the `meson.build` file (typically `trunk/`). +However, providing a `revision` is supported. diff --git a/meson/docs/markdown/Release-notes-for-0.44.0.md b/meson/docs/markdown/Release-notes-for-0.44.0.md new file mode 100644 index 000000000..8e5c09846 --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.44.0.md @@ -0,0 +1,154 @@ +--- +title: Release 0.44 +short-description: Release notes for 0.44 +... + +# New features + +## Added warning function + +This function prints its argument to the console prefixed by +"WARNING:" in yellow color. A simple example: + +warning('foo is deprecated, please use bar instead') + + +## Adds support for additional Qt5-Module keyword `moc_extra_arguments` + +When `moc`-ing sources, the `moc` tool does not know about any +preprocessor macros. The generated code might not match the input +files when the linking with the moc input sources happens. + +This amendment allows to specify a a list of additional arguments +passed to the `moc` tool. They are called `moc_extra_arguments`. + + +## Prefix-dependent defaults for sysconfdir, localstatedir and sharedstatedir + +These options now default in a way consistent with +[FHS](http://refspecs.linuxfoundation.org/fhs.shtml) and common usage. + +If prefix is `/usr`, default sysconfdir to `/etc`, localstatedir to `/var` and +sharedstatedir to `/var/lib`. + +If prefix is `/usr/local` (the default), default localstatedir to +`/var/local` and sharedstatedir to `/var/local/lib`. + + +## An array type for user options + +Previously to have an option that took more than one value a string +value would have to be created and split, but validating this was +difficult. A new array type has been added to the `meson_options.txt` +for this case. It works like a 'combo', but allows more than one +option to be passed. The values can optionally be validated against a +list of valid values. When used on the command line (with -D), values +are passed as a comma separated list. + +```meson +option('array_opt', type : 'array', choices : ['one', 'two', 'three'], value : ['one']) +``` + +These can be overwritten on the command line, + +```meson +meson _build -Darray_opt=two,three +``` + +## LLVM dependency supports both dynamic and static linking + +The LLVM dependency has been improved to consistently use dynamic +linking. Previously recent version (>= 3.9) would link dynamically +while older versions would link statically. + +Now LLVM also accepts the `static` keyword to enable statically +linking to LLVM modules instead of dynamically linking. + + +## Added `if_found` to subdir + +Added a new keyword argument to the `subdir` command. It is given a +list of dependency objects and the function will only recurse in the +subdirectory if they are all found. Typical usage goes like this. + +```meson +d1 = dependency('foo') # This is found +d2 = dependency('bar') # This is not found + +subdir('somedir', if_found : [d1, d2]) +``` + +In this case the subdirectory would not be entered since `d2` could +not be found. + +## `get_unquoted()` method for the `configuration` data object + +New convenience method that allows reusing a variable value +defined quoted. Useful in C for config.h strings for example. + + +## Added disabler object + +A disabler object is a new kind of object that has very specific +semantics. If it is used as part of any other operation such as an +argument to a function call, logical operations etc, it will cause the +operation to not be evaluated. Instead the return value of said +operation will also be the disabler object. + +For example if you have an setup like this: + +```meson +dep = dependency('foo') +lib = shared_library('mylib', 'mylib.c', + dependencies : dep) +exe = executable('mytest', 'mytest.c', + link_with : lib) +test('mytest', exe) +``` + +If you replace the dependency with a disabler object like this: + +```meson +dep = disabler() +lib = shared_library('mylib', 'mylib.c', + dependencies : dep) +exe = executable('mytest', 'mytest.c', + link_with : lib) +test('mytest', exe) +``` + +Then the shared library, executable and unit test are not +created. This is a handy mechanism to cut down on the number of `if` +statements. + + +## Config-Tool based dependencies gained a method to get arbitrary options + +A number of dependencies (CUPS, LLVM, pcap, WxWidgets, GnuStep) use a +config tool instead of pkg-config. As of this version they now have a +`get_configtool_variable` method, which is analogous to the +`get_pkgconfig_variable` for pkg config. + +```meson +dep_llvm = dependency('LLVM') +llvm_inc_dir = dep_llvm.get_configtool_variable('includedir') +``` + +## Embedded Python in Windows MSI packages + +Meson now ships an internal version of Python in the MSI installer +packages. This means that it can run Python scripts that are part of +your build transparently. That is, if you do the following: + +```meson +myprog = find_program('myscript.py') +``` + +Then Meson will run the script with its internal Python version if necessary. + +## Libwmf dependency now supports libwmf-config + +Earlier, `dependency('libwmf')` could only detect the library with +pkg-config files. Now, if pkg-config files are not found, Meson will +look for `libwmf-config` and if it's found, will use that to find the +library. diff --git a/meson/docs/markdown/Release-notes-for-0.45.0.md b/meson/docs/markdown/Release-notes-for-0.45.0.md new file mode 100644 index 000000000..9dd56e31a --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.45.0.md @@ -0,0 +1,203 @@ +--- +title: Release 0.45 +short-description: Release notes for 0.45 +... + +# New features + +## Python minimum version is now 3.5 + +Meson will from this version on require Python version 3.5 or newer. + +## Config-Tool based dependencies can be specified in a cross file + +Tools like LLVM and pcap use a config tool for dependencies, this is a +script or binary that is run to get configuration information (cflags, +ldflags, etc) from. + +These binaries may now be specified in the `binaries` section of a +cross file. + +```ini +[binaries] +cc = ... +llvm-config = '/usr/bin/llvm-config32' +``` + +## Visual Studio C# compiler support + +In addition to the Mono C# compiler we also support Visual Studio's C# +compiler. Currently this is only supported on the Ninja backend. + +## Removed two deprecated features + +The standalone `find_library` function has been a no-op for a long +time. Starting with this version it becomes a hard error. + +There used to be a keywordless version of `run_target` which looked +like this: + +```meson +run_target('targetname', 'command', 'arg1', 'arg2') +``` + +This is now an error. The correct format for this is now: + +```meson +run_target('targetname', + command : ['command', 'arg1', 'arg2']) +``` + +## Experimental FPGA support + +This version adds support for generating, analysing and uploading FPGA +programs using the [IceStorm +toolchain](http://www.clifford.at/icestorm/). This support is +experimental and is currently limited to the `iCE 40` series of FPGA +chips. + +FPGA generation integrates with other parts of Meson seamlessly. As an +example, [here](https://github.com/jpakkane/lm32) is an example +project that compiles a simple firmware into Verilog and combines that +with an lm32 softcore processor. + +## Generator outputs can preserve directory structure + +Normally when generating files with a generator, Meson flattens the +input files so they all go in the same directory. Some code +generators, such as Protocol Buffers, require that the generated files +have the same directory layout as the input files used to generate +them. This can now be achieved like this: + +```meson +g = generator(...) # Compiles protobuf sources +generated = gen.process('com/mesonbuild/one.proto', + 'com/mesonbuild/two.proto', + preserve_path_from : meson.current_source_dir()) +``` + +This would cause the following files to be generated inside the target +private directory: + + com/mesonbuild/one.pb.h + com/mesonbuild/one.pb.cc + com/mesonbuild/two.pb.h + com/mesonbuild/two.pb.cc + +## Hexadecimal string literals + +Hexadecimal integer literals can now be used in build and option files. + +```meson +int_255 = 0xFF +``` + +## b_ndebug : if-release + +The value `if-release` can be given for the `b_ndebug` project option. + +This will make the `NDEBUG` pre-compiler macro to be defined for +release type builds as if the `b_ndebug` project option had had the +value `true` defined for it. + +## `install_data()` defaults to `{datadir}/{projectname}` + +If `install_data()` is not given an `install_dir` keyword argument, the +target directory defaults to `{datadir}/{projectname}` (e.g. +`/usr/share/myproj`). + +## install_subdir() supports strip_directory + +If strip_directory=true install_subdir() installs directory contents +instead of directory itself, stripping basename of the source directory. + +## Integer options + +There is a new integer option type with optional minimum and maximum +values. It can be specified like this in the `meson_options.txt` file: + +```meson +option('integer_option', type : 'integer', min : 0, max : 5, value : 3) +``` + +## New method meson.project_license() + +The `meson` builtin object now has a `project_license()` method that +returns a list of all licenses for the project. + +## Rust cross-compilation + +Cross-compilation is now supported for Rust targets. Like other +cross-compilers, the Rust binary must be specified in your cross file. +It should specify a `--target` (as installed by `rustup target`) and a +custom linker pointing to your C cross-compiler. For example: + +```ini +[binaries] +c = '/usr/bin/arm-linux-gnueabihf-gcc-7' +rust = [ + 'rustc', + '--target', 'arm-unknown-linux-gnueabihf', + '-C', 'linker=/usr/bin/arm-linux-gnueabihf-gcc-7', +] +``` + +## Rust compiler-private library disambiguation + +When building a Rust target with Rust library dependencies, an +`--extern` argument is now specified to avoid ambiguity between the +dependency library, and any crates of the same name in `rustc`'s +private sysroot. + +## Project templates + +Meson ships with predefined project templates. To start a new project +from scratch, simply go to an empty directory and type: + + meson init --name=myproject --type=executable --language=c + +## Improve test setup selection + +Test setups are now identified (also) by the project they belong to +and it is possible to select the used test setup from a specific +project. E.g. to use a test setup `some_setup` from project +`some_project` for all executed tests one can use + + meson test --setup some_project:some_setup + +Should one rather want test setups to be used from the same project as +where the current test itself has been defined, one can use just + + meson test --setup some_setup + +In the latter case every (sub)project must have a test setup `some_setup` +defined in it. + +## Can use custom targets as Windows resource files + +The `compile_resources()` function of the `windows` module can now be +used on custom targets as well as regular files. + +## Can promote dependencies with wrap command + +The `promote` command makes it easy to copy nested dependencies to the +top level. + + meson wrap promote scommon + +This will search the project tree for a subproject called `scommon` +and copy it to the top level. + +If there are many embedded subprojects with the same name, you have to +specify which one to promote manually like this: + + meson wrap promote subprojects/s1/subprojects/scommon + +## Yielding subproject option to superproject + +Normally project options are specific to the current project. However +sometimes you want to have an option whose value is the same over all +projects. This can be achieved with the new `yield` keyword for +options. When set to `true`, getting the value of this option in +`meson.build` files gets the value from the option with the same name +in the master project (if such an option exists). diff --git a/meson/docs/markdown/Release-notes-for-0.46.0.md b/meson/docs/markdown/Release-notes-for-0.46.0.md new file mode 100644 index 000000000..64e237d0e --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.46.0.md @@ -0,0 +1,329 @@ +--- +title: Release 0.46 +short-description: Release notes for 0.46 +... + +# New features + +## Allow early return from a script + +Added the function `subdir_done()`. Its invocation exits the current +script at the point of invocation. All previously invoked build +targets and commands are build/executed. All following ones are +ignored. If the current script was invoked via `subdir()` the parent +script continues normally. + +## Log output slightly changed + +The format of some human-readable diagnostic messages has changed in +minor ways. In case you are parsing these messages, you may need to +adjust your code. + +## ARM compiler for C and CPP + +Cross-compilation is now supported for ARM targets using ARM compiler +- ARMCC. The current implementation does not support shareable +libraries. The default extension of the output is .axf. The +environment path should be set properly for the ARM compiler +executables. The '--cpu' option with the appropriate target type +should be mentioned in the cross file as shown in the snippet below. + +```ini +[properties] +c_args = ['--cpu=Cortex-M0plus'] +cpp_args = ['--cpu=Cortex-M0plus'] + +``` + +## Building both shared and static libraries + +A new function `both_libraries()` has been added to build both shared +and static libraries at the same time. Source files will be compiled +only once and object files will be reused to build both shared and +static libraries, unless `b_staticpic` user option or `pic:` keyword +argument are set to false in which case sources will be compiled +twice. + +The returned `buildtarget` object always represents the shared library. + +## Compiler object can now be passed to run_command() + +This can be used to run the current compiler with the specified +arguments to obtain additional information from it. One of the use +cases is to get the location of development files for the GCC plugins: + +```meson +cc = meson.get_compiler('c') +result = run_command(cc, '-print-file-name=plugin') +plugin_dev_path = result.stdout().strip() +``` + +## declare_dependency() now supports `link_whole:` + +`declare_dependency()` now supports the `link_whole:` keyword argument which +transparently works for build targets which use that dependency. + +## Old command names are now errors + +The old executable names `mesonintrospect`, `mesonconf`, +`mesonrewriter` and `mesontest` have been deprecated for a long time. +Starting from this version they no longer do anything but instead +always error out. All functionality is available as subcommands in the +main `meson` binary. + +## Meson and meson configure now accept the same arguments + +Previously Meson required that builtin arguments (like prefix) be +passed as `--prefix` to `meson` and `-Dprefix` to `meson configure`. +`meson` now accepts -D form like `meson configure` has. `meson +configure` also accepts the `--prefix` form, like `meson` has. + +## Recursively extract objects + +The `recursive:` keyword argument has been added to +`extract_all_objects()`. When set to `true` it will also return +objects passed to the `objects:` argument of this target. By default +only objects built for this target are returned to maintain backward +compatibility with previous versions. The default will eventually be +changed to `true` in a future version. + +```meson +lib1 = static_library('a', 'source.c', objects : 'prebuilt.o') +lib2 = static_library('b', objects : lib1.extract_all_objects(recursive : true)) +``` + +## Can override find_program() + +It is now possible to override the result of `find_program` to point +to a custom program you want. The overriding is global and applies to +every subproject from there on. Here is how you would use it. + +In master project + +```meson +subproject('mydep') +``` + +In the called subproject: + +```meson +prog = find_program('my_custom_script') +meson.override_find_program('mycodegen', prog) +``` + +In master project (or, in fact, any subproject): + +```meson +genprog = find_program('mycodegen') +``` + +Now `genprog` points to the custom script. If the dependency had come +from the system, then it would point to the system version. + +You can also use the return value of `configure_file()` to override +a program in the same way as above: + +```meson +prog_script = configure_file(input : 'script.sh.in', + output : 'script.sh', + configuration : cdata) +meson.override_find_program('mycodegen', prog_script) +``` + +## New functions: has_link_argument() and friends + +A new set of methods has been added to [compiler +objects](Reference-manual.md#compiler-object) to test if the linker +supports given arguments. + +- `has_link_argument()` +- `has_multi_link_arguments()` +- `get_supported_link_arguments()` +- `first_supported_link_argument()` + +## "meson help" now shows command line help + +Command line parsing is now less surprising. "meson help" is now +equivalent to "meson --help" and "meson help <subcommand>" is +equivalent to "meson <subcommand> --help", instead of creating a build +directory called "help" in these cases. + +## Autogeneration of simple meson.build files + +A feature to generate a meson.build file compiling given C/C++ source +files into a single executable has been added to "meson init". By +default, it will take all recognizable source files in the current +directory. You can also specify a list of dependencies with the -d +flag and automatically invoke a build with the -b flag to check if the +code builds with those dependencies. + +For example, + +```meson +meson init -fbd sdl2,gl +``` + +will look for C or C++ files in the current directory, generate a +meson.build for them with the dependencies of sdl2 and gl and +immediately try to build it, overwriting any previous meson.build and +build directory. + +## install_data() supports `rename:` + +The `rename:` keyword argument is used to change names of the installed +files. Here's how you install and rename the following files: + +- `file1.txt` into `share/myapp/dir1/data.txt` +- `file2.txt` into `share/myapp/dir2/data.txt` + +```meson +install_data(['file1.txt', 'file2.txt'], + rename : ['dir1/data.txt', 'dir2/data.txt'], + install_dir : 'share/myapp') +``` + +## Support for lcc compiler for e2k (Elbrus) architecture + +In this version, a support for lcc compiler for Elbrus processors +based on [e2k +microarchitecture](https://en.wikipedia.org/wiki/Elbrus_2000) has been +added. + +Examples of such CPUs: +* [Elbrus-8S](https://en.wikipedia.org/wiki/Elbrus-8S); +* Elbrus-4S; +* [Elbrus-2S+](https://en.wikipedia.org/wiki/Elbrus-2S%2B). + +Such compiler have a similar behavior as gcc (basic option compatibility), +but, in is not strictly compatible with gcc as of current version. + +Major differences as of version 1.21.22: +* it does not support LTO and PCH; +* it suffers from the same dependency file creation error as icc; +* it has minor differences in output, especially version output; +* it differently reacts to lchmod() detection; +* some backend messages are produced in ru_RU.KOI8-R even if LANG=C; +* its preprocessor treats some characters differently. + +So every noted difference is properly handled now in Meson. + +## String escape character sequence update + +Single-quoted strings in Meson have been taught the same set of escape +sequences as in Python. It is therefore now possible to use arbitrary +bytes in strings, like for example `NUL` (`\0`) and other ASCII +control characters. See the chapter about [*Strings* in +*Syntax*](Syntax.md#strings) for more details. + +Potential backwards compatibility issue: Any valid escape sequence +according to the new rules will be interpreted as an escape sequence +instead of the literal characters. Previously only the following +escape sequences were supported in single-quote strings: `\'`, `\\` +and `\n`. + +Note that the behaviour of triple-quoted (multiline) strings has not +changed. They behave like raw strings and do not support any escape +sequences. + +## New `forcefallback` wrap mode + +A new wrap mode was added, `--wrap-mode=forcefallback`. When this is +set, dependencies for which a fallback was provided will always use +it, even if an external dependency exists and satisfies the version +requirements. + +## Relaxing of target name requirements + +In earlier versions of Meson you could only have one target of a given +name for each type. For example you could not have two executables +named `foo`. This requirement is now relaxed so that you can have +multiple targets with the same name, as long as they are in different +subdirectories. + +Note that projects that have multiple targets with the same name can +not be built with the `flat` layout or any backend that writes outputs +in the same directory. + +## Addition of OpenMP dependency + +An OpenMP dependency (`openmp`) has been added that encapsulates the +various flags used by compilers to enable OpenMP and checks for the +existence of the `omp.h` header. The `language` keyword may be passed +to force the use of a specific compiler for the checks. + +## Added new partial_dependency method to dependencies and libraries + +It is now possible to use only part of a dependency in a target. This +allows, for example, to only use headers with convenience libraries to +avoid linking to the same library multiple times. + +```meson +dep = dependency('xcb') + +helper = static_library( + 'helper', + ['helper1.c', 'helper2.c'], + dependencies : dep.partial_dependency(includes : true), +] + +final = shared_library( + 'final', + ['final.c'], + dependencyes : dep, +) +``` + +A partial dependency will have the same name version as the full +dependency it is derived from, as well as any values requested. + +## Improved generation of pkg-config files for static only libraries. + +Previously pkg-config files generated by the pkgconfig modules for +static libraries with dependencies could only be used in a +dependencies with `static: true`. + +Now the generated file contains the needed dependencies libraries +directly within `Requires` and `Libs` for build static libraries +passed via the `libraries` keyword argument. + +Projects that install both a static and a shared version of a library +should use the result of +[`both_libraries()`](Reference-manual.md#both_libraries) to the +pkg-config file generator or use +[`configure_file()`](Reference-manual.md#configure_file) for more +complicated setups. + +## Improvements to pkgconfig module + +A `StaticLibrary` or `SharedLibrary` object can optionally be passed +as first positional argument of the `generate()` method. If one is provided a +default value will be provided for all required fields of the pc file: +- `install_dir` is set to `pkgconfig` folder in the same location than the provided library. +- `description` is set to the project's name followed by the library's name. +- `name` is set to the library's name. + +Generating a .pc file is now as simple as: + +```meson +pkgconfig.generate(mylib) +``` + +## pkgconfig.generate() requires parameters non-string arguments + +`pkgconfig.generate()` `requires:` and `requires_private:` keyword +arguments now accept pkgconfig-dependencies and libraries that +pkgconfig-files were generated for. + +## Generic python module + +Meson now has is a revamped and generic (python 2 and 3) version of +the python3 module. With [this new interface](Python-module.md), +projects can now fully specify the version of python they want to +build against / install sources to, and can do so against multiple +major or minor versions in parallel. + +## test() now supports the `depends:` keyword argument + +Build targets and custom targets can be listed in the `depends:` +keyword argument of test function. These targets will be built before +test is run even if they have `build_by_default : false`. diff --git a/meson/docs/markdown/Release-notes-for-0.47.0.md b/meson/docs/markdown/Release-notes-for-0.47.0.md new file mode 100644 index 000000000..175126ea9 --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.47.0.md @@ -0,0 +1,312 @@ +--- +title: Release 0.47 +short-description: Release notes for 0.47 +... + +# New features + +## Allow early return from a script + +Added the function `subdir_done()`. Its invocation exits the current +script at the point of invocation. All previously invoked build +targets and commands are build/executed. All following ones are +ignored. If the current script was invoked via `subdir()` the parent +script continues normally. + +## Concatenate string literals returned from `get_define()` + +After obtaining the value of a preprocessor symbol consecutive string +literals are merged into a single string literal. For example a +preprocessor symbol's value `"ab" "cd"` is returned as `"abcd"`. + +## ARM compiler(version 6) for C and CPP + +Cross-compilation is now supported for ARM targets using ARM compiler +version 6 - ARMCLANG. The required ARMCLANG compiler options for +building a shareable library are not included in the current Meson +implementation for ARMCLANG support, so it can not build shareable +libraries. This current Meson implementation for ARMCLANG support can +not build assembly files with arm syntax (we need to use armasm +instead of ARMCLANG for the `.s` files with this syntax) and only +supports GNU syntax. + +The default extension of the executable output is `.axf`. The +environment path should be set properly for the ARM compiler +executables. The `--target`, `-mcpu` options with the appropriate +values should be mentioned in the cross file as shown in the snippet +below. + +```ini +[properties] +c_args = ['--target=arm-arm-none-eabi', '-mcpu=cortex-m0plus'] +cpp_args = ['--target=arm-arm-none-eabi', '-mcpu=cortex-m0plus'] +``` + +Note: +- The current changes are tested on Windows only. +- PIC support is not enabled by default for ARM, + if users want to use it, they need to add the required arguments + explicitly from cross-file(`c_args`/`cpp_args`) or some other way. + +## New base build option for LLVM (Apple) bitcode support + +When building with clang on macOS, you can now build your static and +shared binaries with embedded bitcode by enabling the `b_bitcode` +[base option](Builtin-options.md#base-options) by passing +`-Db_bitcode=true` to Meson. + +This is better than passing the options manually in the environment +since Meson will automatically disable conflicting options such as +`b_asneeded`, and will disable bitcode support on targets that don't +support it such as `shared_module()`. + +Since this requires support in the linker, it is currently only +enabled when using Apple ld. In the future it can be extended to clang +on other platforms too. + +## New compiler check: `check_header()` + +The existing compiler check `has_header()` only checks if the header +exists, either with the `__has_include` C++11 builtin, or by running +the pre-processor. + +However, sometimes the header you are looking for is unusable on some +platforms or with some compilers in a way that is only detectable at +compile-time. For such cases, you should use `check_header()` which +will include the header and run a full compile. + +Note that `has_header()` is much faster than `check_header()`, so it +should be used whenever possible. + +## New action `copy:` for `configure_file()` + +In addition to the existing actions `configuration:` and `command:`, +[`configure_file()`](Reference-manual.md#configure_file) now accepts a +keyword argument `copy:` which specifies a new action to copy the file +specified with the `input:` keyword argument to a file in the build +directory with the name specified with the `output:` keyword argument. + +These three keyword arguments are, as before, mutually exclusive. You +can only do one action at a time. + +## New keyword argument `encoding:` for `configure_file()` + +Add a new keyword to +[`configure_file()`](Reference-manual.md#configure_file) that allows +the developer to specify the input and output file encoding. The +default value is the same as before: UTF-8. + +In the past, Meson would not handle non-UTF-8/ASCII files correctly, +and in the worst case would try to coerce it to UTF-8 and mangle the +data. UTF-8 is the standard encoding now, but sometimes it is +necessary to process files that use a different encoding. + +For additional details see [#3135](https://github.com/mesonbuild/meson/pull/3135). + +## New keyword argument `output_format:` for `configure_file()` + +When called without an input file, `configure_file` generates a C +header file by default. A keyword argument was added to allow +specifying the output format, for example for use with nasm or yasm: + +```meson +conf = configuration_data() +conf.set('FOO', 1) + +configure_file('config.asm', + configuration: conf, + output_format: 'nasm') +``` + +## Substitutions in `custom_target(depfile:)` + +The `depfile` keyword argument to `custom_target` now accepts the `@BASENAME@` +and `@PLAINNAME@` substitutions. + +## Deprecated `build_always:` for custom targets + +Setting `build_always` to `true` for a custom target not only marks +the target to be always considered out of date, but also adds it to +the set of default targets. This option is therefore deprecated and +the new option `build_always_stale` is introduced. + +`build_always_stale` *only* marks the target to be always considered +out of date, but does not add it to the set of default targets. The +old behaviour can be achieved by combining `build_always_stale` with +`build_by_default`. + +The documentation has been updated accordingly. + +## New built-in object type: dictionary + +Meson dictionaries use a syntax similar to python's dictionaries, but +have a narrower scope: they are immutable, keys can only be string +literals, and initializing a dictionary with duplicate keys causes a +fatal error. + +Example usage: + +```meson +d = {'foo': 42, 'bar': 'baz'} + +foo = d.get('foo') +foobar = d.get('foobar', 'fallback-value') + +foreach key, value : d + Do something with key and value +endforeach +``` + +## Array options treat `-Dopt=` and `-Dopt=[]` as equivalent + +Prior to this change passing -Dopt= to an array opt would be +interpreted as `['']` (an array with an empty string), now `-Dopt=` is +the same as `-Dopt=[]`, an empty list. + +## Feature detection based on `meson_version:` in `project()` + +Meson will now print a `WARNING:` message during configuration if you +use a function or a keyword argument that was added in a Meson version +that's newer than the version specified inside `project()`. For +example: + +```meson +project('featurenew', meson_version: '>=0.43') + +cdata = configuration_data() +cdata.set('FOO', 'bar') +message(cdata.get_unquoted('FOO')) +``` + +This will output: + +``` +The Meson build system +Version: 0.47.0.dev1 +Source dir: C:\path\to\srctree +Build dir: C:\path\to\buildtree +Build type: native build +Project name: featurenew +Project version: undefined +Build machine cpu family: x86_64 +Build machine cpu: x86_64 +WARNING: Project targeting '>=0.43' but tried to use feature introduced in '0.44.0': configuration_data.get_unquoted() +Message: bar +Build targets in project: 0 +WARNING: Project specifies a minimum meson_version '>=0.43' which conflicts with: + * 0.44.0: {'configuration_data.get_unquoted()'} +``` + +## New type of build option for features + +A new type of [option called `feature`](Build-options.md#features) can +be defined in `meson_options.txt` for the traditional `enabled / +disabled / auto` tristate. The value of this option can be passed to +the `required` keyword argument of functions `dependency()`, +`find_library()`, `find_program()` and `add_languages()`. + +A new global option `auto_features` has been added to override the +value of all `auto` features. It is intended to be used by packagers +to have full control on which feature must be enabled or disabled. + +## New options to `gnome.gdbus_codegen()` + +You can now pass additional arguments to gdbus-codegen using the +`extra_args` keyword. This is the same for the other gnome function +calls. + +Meson now automatically adds autocleanup support to the generated +code. This can be modified by setting the autocleanup keyword. + +For example: + +```meson +sources += gnome.gdbus_codegen('com.mesonbuild.Test', + 'com.mesonbuild.Test.xml', + autocleanup : 'none', + extra_args : ['--pragma-once']) +``` + +## Made 'install' a top level Meson command + +You can now run `meson install` in your build directory and it will do +the install. It has several command line options you can toggle the +behaviour that is not in the default `ninja install` invocation. This +is similar to how `meson test` already works. + +For example, to install only the files that have changed, you can do: + +```console +$ meson install --only-changed +``` + +## `install_mode:` keyword argument extended to all installable targets + +It is now possible to pass an `install_mode` argument to all +installable targets, such as `executable()`, libraries, headers, man +pages and custom/generated targets. + +The `install_mode` argument can be used to specify the file mode in +symbolic format and optionally the owner/uid and group/gid for the +installed files. + +## New built-in option `install_umask` with a default value 022 + +This umask is used to define the default permissions of files and +directories created in the install tree. Files will preserve their +executable mode, but the exact permissions will obey the +`install_umask`. + +The `install_umask` can be overridden in the Meson command-line: + +```console +$ meson --install-umask=027 builddir/ +``` + +A project can also override the default in the `project()` call: + +```meson +project('myproject', 'c', + default_options : ['install_umask=027']) +``` + +To disable the `install_umask`, set it to `preserve`, in which case +permissions are copied from the files in their origin. + +## Octal and binary string literals + +Octal and binary integer literals can now be used in build and option files. + +```meson +int_493 = 0o755 +int_1365 = 0b10101010101 +``` + +## New keyword arguments: 'check' and 'capture' for `run_command()` + +If `check:` is `true`, then the configuration will fail if the command +returns a non-zero exit status. The default value is `false` for +compatibility reasons. + +`run_command()` used to always capture the output and stored it for +use in build files. However, sometimes the stdout is in a binary +format which is meant to be discarded. For that case, you can now set +the `capture:` keyword argument to `false`. + +## Windows resource files dependencies + +The `compile_resources()` function of the `windows` module now takes +the `depend_files:` and `depends:` keywords. + +When using binutils's `windres`, dependencies on files `#include`'d by +the preprocessor are now automatically tracked. + +## Polkit support for privileged installation + +When running `install`, if installation fails with a permission error +and `pkexec` is available, Meson will attempt to use it to spawn a +permission dialog for privileged installation and retry the +installation. + +If `pkexec` is not available, the old behaviour is retained and you +will need to explicitly run the install step with `sudo`. diff --git a/meson/docs/markdown/Release-notes-for-0.48.0.md b/meson/docs/markdown/Release-notes-for-0.48.0.md new file mode 100644 index 000000000..4b68b6d7c --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.48.0.md @@ -0,0 +1,343 @@ +--- +title: Release 0.48 +short-description: Release notes for 0.48 +... + +# New features + +## Toggles for build type, optimization and vcrt type + +Since the very beginning Meson has provided different project types to +use, such as *debug* and *minsize*. There is also a *plain* type that +adds nothing by default but instead makes it the user's responsibility +to add everything by hand. This works but is a bit tedious. + +In this release we have added new new options to manually toggle e.g. +optimization levels and debug info so those can be changed +independently of other options. For example by default the debug +buildtype has no optmization enabled at all. If you wish to use GCC's +`-Og` instead, you could set it with the following command: + +``` +meson configure -Doptimization=g +``` + +Similarly we have added a toggle option to select the version of +Visual Studio C runtime to use. By default it uses the debug runtime +DLL debug builds and release DLL for release builds but this can be +manually changed with the new base option `b_vscrt`. + +## Meson warns if two calls to `configure_file()` write to the same file + +If two calls to +[`configure_file()`](Reference-manual.md#configure_file) write to the +same file Meson will print a `WARNING:` message during configuration. +For example: + +```meson +project('configure_file', 'cpp') + +configure_file( + input: 'a.in', + output: 'out', + command: ['./foo.sh'] +) +configure_file( + input: 'a.in', + output: 'out', + command: ['./foo.sh'] +) +``` + +This will output: + +``` +The Meson build system +Version: 0.47.0.dev1 +Source dir: /path/to/srctree +Build dir: /path/to/buildtree +Build type: native build +Project name: configure_file +Project version: undefined +Build machine cpu family: x86_64 +Build machine cpu: x86_64 +Configuring out with command +WARNING: Output file out for configure_file overwritten. First time written in line 3 now in line 8 +Configuring out with command +Build targets in project: 0 +Found ninja-1.8.2 at /usr/bin/ninja +``` + +## New kwarg `console` for `custom_target()` + +This keyword argument conflicts with `capture`, and is meant for +commands that are resource-intensive and take a long time to +finish. With the Ninja backend, setting this will add this target to +[Ninja's `console` +pool](https://ninja-build.org/manual.html#_the_literal_console_literal_pool), +which has special properties such as not buffering stdout and +serializing all targets in this pool. + +The primary use-case for this is to be able to run external commands +that take a long time to exeute. Without setting this, the user does +not receive any feedback about what the program is doing. + +## `dependency(version:)` now applies to all dependency types + +Previously, version constraints were only enforced for dependencies +found using the pkg-config dependency provider. These constraints now +apply to dependencies found using any dependency provider. + +Some combinations of dependency, host and method do not currently +support discovery of the version. In these cases, the dependency will +not be found if a version constraint is applied, otherwise the +`version()` method for the dependency object will return `'unknown'`. + +(If discovering the version in one of these combinations is important +to you, and a method exists to determine the version in that case, +please file an issue with as much information as possible.) + +## python3 module is deprecated + +A generic module `python` has been added in Meson `0.46.0` and has a superset of +the features implemented by the previous `python3` module. + +In most cases, it is a simple matter of renaming: +```meson +py3mod = import('python3') +python = py3mod.find_python() +``` + +becomes + +```meson +pymod = import('python') +python = pymod.find_installation() +``` + +## Dictionary addition + +Dictionaries can now be added, values from the second dictionary overrides values +from the first + +```meson +d1 = {'a' : 'b'} +d3 = d1 + {'a' : 'c'} +d3 += {'d' : 'e'} +``` + +## Dist scripts + +You can now specify scripts that are run as part of the `dist` +target. An example usage would go like this: + +```meson +project('foo', 'c') + +# other stuff here + +meson.add_dist_script('dist_cleanup.py') +``` + +## Fatal warnings + +A new command line option has been added: `--fatal-meson-warnings`. +When enabled, any warning message printed by Meson will be fatal and +raise an exception. It is intended to be used by developers and CIs to +easily catch deprecation warnings, or any other potential issues. + +## Helper methods added for checking GNU style attributes: `__attribute__(...)` + +A set of new helpers have been added to the C and C++ compiler objects +for checking GNU style function attributes. These are not just simpler +to use, they may be optimized to return fast on compilers that don't +support these attributes. Currently this is true for MSVC. + +```meson +cc = meson.get_compiler('c') +if cc.has_function_attribute('aligned') + add_project_arguments('-DHAVE_ALIGNED', language : 'c') +endif +``` + +Would replace code like: + +```meson +if cc.compiles('''into foo(void) __attribute__((aligned(32)))''') + add_project_arguments('-DHAVE_ALIGNED', language : 'c') +endif +``` + +Additionally, a multi argument version has been added: + +```meson +foreach s : cc.get_supported_function_attributes(['hidden', 'alias']) + add_project_arguments('-DHAVE_@0@'.format(s.to_upper()), language : 'c') +endforeach +``` + +## `gnome.generate_gir()` now optionally accepts multiple libraries + +The GNOME module can now generate a single gir for multiple libraries, +which is something `g-ir-scanner` supported, but had not been exposed +yet. + +gnome.generate_gir() will now accept multiple positional arguments, if +none of these arguments are an `Executable` instance. + +## Hotdoc module + +A new module has been written to ease generation of +[hotdoc](https://hotdoc.github.io/) based documentation. It supports +complex use cases such as hotdoc subprojects (to create documentation +portals) and makes it straight forward to leverage full capabilities +of hotdoc. + +Simple usage: + +``` meson +hotdoc = import('hotdoc') + +hotdoc.generate_doc( + 'foobar', + c_smart_index: true, + project_version: '0.1', + sitemap: 'sitemap.txt', + index: 'index.md', + c_sources: ['path/to/file.c'], + languages: ['c'], + install: true, +) +``` + +## `i18n.merge_file()` now fully supports variable substitutions defined in `custom_target()` + +Filename substitutions like @BASENAME@ and @PLAINNAME@ were previously +accepted but the name of the build target wasn't altered leading to +colliding target names when using the substitution twice. +i18n.merge_file() now behaves as custom_target() in this regard. + +## Projects args can be set separately for cross and native builds (potentially breaking change) + +It has been a longstanding bug (or let's call it a "delayed bug fix") +that if you do this: + +```meson +add_project_arguments('-DFOO', language : 'c') +``` + +Then the flag is used both in native and cross compilations. This is +very confusing and almost never what you want. To fix this a new +keyword `native` has been added to all functions that add arguments, +namely `add_global_arguments`, `add_global_link_arguments`, +`add_project_arguments` and `add_project_link_arguments` that behaves +like the following: + +```meson +# Added to native builds when compiling natively and to cross +# compilations when doing cross compiles. +add_project_arguments(...) + +# Added only to native compilations, not used in cross compilations. +add_project_arguments(..., native : true) + +# Added only to cross compilations, not used in native compilations. +add_project_arguments(..., native : false) +``` + +Also remember that cross compilation is a property of each target. +There can be target that are compiled with the native compiler and +some which are compiled with the cross compiler. + +Unfortunately this change is backwards incompatible and may cause some +projects to fail building. However this should be very rare in +practice. + +## More flexible `override_find_program()`. + +It is now possible to pass an `executable` to +`override_find_program()` if the overridden program is not used during +configure. + +This is particularly useful for fallback dependencies like Protobuf +that also provide a tool like protoc. + +## `shared_library()` now supports setting dylib compatibility and current version + +Now, by default `shared_library()` sets `-compatibility_version` and +`-current_version` of a macOS dylib using the `soversion`. + +This can be overridden by using the `darwin_versions:` kwarg to +[`shared_library()`](Reference-manual.md#shared_library). As usual, +you can also pass this kwarg to `library()` or `build_target()` and it +will be used in the appropriate circumstances. + +## Version comparison + +`dependency(version:)` and other version constraints now handle +versions containing non-numeric characters better, comparing versions +using the rpmvercmp algorithm (as using the `pkg-config` autoconf +macro `PKG_CHECK_MODULES` does). + +This is a breaking change for exact comparison constraints which rely +on the previous comparison behaviour of extending the compared +versions with `'0'` elements, up to the same length of `'.'`-separated +elements. + +For example, a version of `'0.11.0'` would previously match a version +constraint of `'==0.11'`, but no longer does, being instead considered +strictly greater. + +Instead, use a version constraint which exactly compares with the +precise version required, e.g. `'==0.11.0'`. + +## Keyword argument for GNU symbol visibility + +Build targets got a new keyword, `gnu_symbol_visibility` that controls +how symbols are exported from shared libraries. This is most commonly +used to hide implementation symbols like this: + +```meson +shared_library('mylib', ... + gnu_symbol_visibility: 'hidden') +``` + +In this case only symbols explicitly marked as visible in the source +files get exported. + +## Git wraps can now clone submodules automatically + +To enable this, the following needs to be added to the `.wrap` file: + +```ini +clone-recursive=true +``` + +## `subproject()` function now supports the `required:` kwarg + +This allows you to declare an optional subproject. You can now call +`found()` on the return value of the `subproject()` call to see if the +subproject is available before calling `get_variable()` to fetch +information from it. + +## `dependency()` objects now support the `.name()` method + +You can now fetch the name of the dependency that was searched like +so: + +```meson +glib_dep = dependency('glib-2.0') +... +message("dependency name is " + glib_dep.name()) +# This outputs `dependency name is glib-2.0` + +qt_dep = dependency('qt5') +... +message("dependency name is " + qt_dep.name()) +# This outputs `dependency name is qt5` + +decl_dep = declare_dependency() +... +message("dependency name is " + decl_dep.name()) +# This outputs `dependency name is internal` +``` diff --git a/meson/docs/markdown/Release-notes-for-0.49.0.md b/meson/docs/markdown/Release-notes-for-0.49.0.md new file mode 100644 index 000000000..6b84af19c --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.49.0.md @@ -0,0 +1,327 @@ +--- +title: Release 0.49 +short-description: Release notes for 0.49 +... + +# New features + +## Libgcrypt dependency now supports libgcrypt-config + +Earlier, `dependency('libgcrypt')` could only detect the library with +pkg-config files. Now, if pkg-config files are not found, Meson will +look for `libgcrypt-config` and if it's found, will use that to find +the library. + +## New `section` key for the buildoptions introspection + +Meson now has a new `section` key in each build option. This allows +IDEs to group these options similar to `meson configure`. + +The possible values for `section` are: + + - core + - backend + - base + - compiler + - directory + - user + - test + +## CC-RX compiler for C and CPP + +Cross-compilation is now supported for Renesas RX targets with the +CC-RX compiler. + +The environment path should be set properly for the CC-RX compiler +executables. The `-cpu` option with the appropriate value should be +mentioned in the cross-file as shown in the snippet below. + +```ini +[properties] +c_args = ['-cpu=rx600'] +cpp_args = ['-cpu=rx600'] +``` + +The default extension of the executable output is `.abs`. Other target +specific arguments to the compiler and linker will need to be added +explicitly from the +cross-file(`c_args`/`c_link_args`/`cpp_args`/`cpp_link_args`) or some +other way. Refer to the CC-RX User's manual for additional compiler +and linker options. + +## CMake `find_package` dependency backend + +Meson can now use the CMake `find_package` ecosystem to detect +dependencies. Both the old-style `<NAME>_LIBRARIES` variables as well +as imported targets are supported. Meson can automatically guess the +correct CMake target in most cases but it is also possible to manually +specify a target with the `modules` property. + +```meson +# Implicitly uses CMake as a fallback and guesses a target +dep1 = dependency('KF5TextEditor') + +# Manually specify one or more CMake targets to use +dep2 = dependency('ZLIB', method : 'cmake', modules : ['ZLIB::ZLIB']) +``` + +CMake is automatically used after `pkg-config` fails when +no `method` (or `auto`) was provided in the dependency options. + +## New compiler method `get_argument_syntax` + +The compiler object now has `get_argument_syntax` method, which +returns a string value of `gcc`, `msvc`, or an undefined value string +value. This can be used to determine if a compiler uses gcc syntax +(`-Wfoo`), msvc syntax (`/w1234`), or some other kind of arguments. + +```meson +cc = meson.get_compiler('c') + +if cc.get_argument_syntax() == 'msvc' + if cc.has_argument('/w1235') + add_project_arguments('/w1235', language : ['c']) + endif +elif cc.get_argument_syntax() == 'gcc' + if cc.has_argument('-Wfoo') + add_project_arguments('-Wfoo', language : ['c']) + endif +elif cc.get_id() == 'some other compiler' + add_project_arguments('--error-on-foo', language : ['c']) +endif +``` + +## Return `Disabler()` instead of not-found object + +Functions such as `dependency()`, `find_library()`, `find_program()`, +and `python.find_installation()` have a new keyword argument: +`disabler`. When set to `true` those functions return `Disabler()` +objects instead of not-found objects. + +## `introspect --projectinfo` can now be used without configured build directory + +This allows IDE integration to get information about the project +before the user has configured a build directory. + +Before you could use `meson.py introspect --projectinfo +build-directory`. Now you also can use `meson.py introspect +--projectinfo project-dir/meson.build`. + +The output is similar to the output with a build directory but +additionally also includes information from `introspect +--buildsystem-files`. + +For example `meson.py introspect --projectinfo test\ cases/common/47\ +subproject\ options/meson.build` This outputs (pretty printed for +readability): + +``` +{ + "buildsystem_files": [ + "meson_options.txt", + "meson.build" + ], + "name": "suboptions", + "version": null, + "descriptive_name": "suboptions", + "subprojects": [ + { + "buildsystem_files": [ + "subprojects/subproject/meson_options.txt", + "subprojects/subproject/meson.build" + ], + "name": "subproject", + "version": "undefined", + "descriptive_name": "subproject" + } + ] +} +``` + +Both usages now include a new `descriptive_name` property which always +shows the name set in the project. + +## Can specify keyword arguments with a dictionary + +You can now specify keyword arguments for any function and method call +with the `kwargs` keyword argument. This is perhaps best described +with an example: + +```meson +options = {'include_directories': include_directories('inc')} + +... + +executable(... + kwargs: options) +``` + +The above code is identical to this: + +```meson +executable(... + include_directories: include_directories('inc')) +``` + +That is, Meson will expand the dictionary given to `kwargs` as if the +entries in it had been given as keyword arguments directly. + +Note that any individual argument can be specified either directly or +with the `kwarg` dict but not both. If a key is specified twice, it +is a hard error. + +## Manpages are no longer compressed implicitly + +Earlier, the `install_man` command has automatically compressed +installed manpages into `.gz` format. This collided with manpage +compression hooks already used by various distributions. Now, manpages +are installed uncompressed and distributors are expected to handle +compressing them according to their own compression preferences. + +## Native config files + +Native files (`--native-file`) are the counterpart to cross files +(`--cross-file`), and allow specifying information about the build +machine, both when cross compiling and when not. + +Currently the native files only allow specifying the names of +binaries, similar to the cross file, for example: + +```ini +[binaries] +llvm-config = "/opt/llvm-custom/bin/llvm-config" +``` + +Will override the llvm-config used for *native* binaries. Targets for +the host machine will continue to use the cross file. + +## Foreach `break` and `continue` + +`break` and `continue` keywords can be used inside foreach loops. + +```meson +items = ['a', 'continue', 'b', 'break', 'c'] +result = [] +foreach i : items + if i == 'continue' + continue + elif i == 'break' + break + endif + result += i +endforeach +# result is ['a', 'b'] +``` + +You can check if an array contains an element like this: +```meson +my_array = [1, 2] +if 1 in my_array +# This condition is true +endif +if 1 not in my_array +# This condition is false +endif +``` + +You can check if a dictionary contains a key like this: +```meson +my_dict = {'foo': 42, 'foo': 43} +if 'foo' in my_dict +# This condition is true +endif +if 42 in my_dict +# This condition is false +endif +if 'foo' not in my_dict +# This condition is false +endif +``` + +## Joining paths with / + +For clarity and conciseness, we recommend using the `/` operator to separate +path elements: + +```meson +joined = 'foo' / 'bar' +``` + +Before Meson 0.49, joining path elements was done with the legacy +`join_paths` function, but the `/` syntax above is now recommended. + +```meson +joined = join_paths('foo', 'bar') +``` + +This only works for strings. + +## Position-independent executables + +When `b_pie` option, or `executable()`'s `pie` keyword argument is set +to `true`, position-independent executables are built. All their +objects are built with `-fPIE` and the executable is linked with +`-pie`. Any static library they link must be built with `pic` set to +`true` (see `b_staticpic` option). + +## Deprecation warning in pkg-config generator + +All libraries passed to the `libraries` keyword argument of the +`generate()` method used to be associated with that generated +pkg-config file. That means that any subsequent call to `generate()` +where those libraries appear would add the filebase of the +`generate()` that first contained them into `Requires:` or +`Requires.private:` field instead of adding an `-l` to `Libs:` or +`Libs.private:`. + +This behaviour is now deprecated. The library that should be +associated with the generated pkg-config file should be passed as +first positional argument instead of in the `libraries` keyword +argument. The previous behaviour is maintained but prints a +deprecation warning and support for this will be removed in a future +Meson release. If you can not create the needed pkg-config file +without this warning, please file an issue with as much details as +possible about the situation. + +For example this sample will write `Requires: liba` into `libb.pc` but +print a deprecation warning: + +```meson +liba = library(...) +pkg.generate(libraries : liba) + +libb = library(...) +pkg.generate(libraries : [liba, libb]) +``` + +It can be fixed by passing `liba` as first positional argument:: +```meson +liba = library(...) +pkg.generate(liba) + +libb = library(...) +pkg.generate(libb, libraries : [liba]) +``` + +## Subprojects download, checkout, update command-line + +New command-line tool has been added to manage subprojects: + +- `meson subprojects download` to download all subprojects that have a wrap file. +- `meson subprojects update` to update all subprojects to latest version. +- `meson subprojects checkout` to checkout or create a branch in all git subprojects. + +## New keyword argument `is_default` to `add_test_setup()` + +The keyword argument `is_default` may be used to set whether the test +setup should be used by default whenever `meson test` is run without +the `--setup` option. + +```meson +add_test_setup('default', is_default: true, env: 'G_SLICE=debug-blocks') +add_test_setup('valgrind', env: 'G_SLICE=always-malloc', ...) +test('mytest', exe) +``` + +For the example above, running `meson test` and `meson test +--setup=default` is now equivalent. diff --git a/meson/docs/markdown/Release-notes-for-0.50.0.md b/meson/docs/markdown/Release-notes-for-0.50.0.md new file mode 100644 index 000000000..0f7dbb878 --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.50.0.md @@ -0,0 +1,350 @@ +--- +title: Release 0.50.0 +short-description: Release notes for 0.50.0 +... + +# New features + +## Added `cmake_module_path` and `cmake_args` to dependency + +The CMake dependency backend can now make use of existing +`Find<name>.cmake` files by setting the `CMAKE_MODULE_PATH` with the +new `dependency()` property `cmake_module_path`. The paths given to +`cmake_module_path` should be relative to the project source +directory. + +Furthermore the property `cmake_args` was added to give CMake +additional parameters. + +## Added PGI compiler support + +Nvidia / PGI C, C++ and Fortran +[no-cost](https://www.pgroup.com/products/community.htm) compilers are +now supported. They have been tested on Linux so far. + + + +## Fortran Coarray + +Fortran 2008 / 2018 coarray support was added via `dependency('coarray')` + +## Libdir defaults to `lib` when cross compiling + +Previously `libdir` defaulted to the value of the build machine such +as `lib/x86_64-linux-gnu`, which is almost always incorrect when cross +compiling. It now defaults to plain `lib` when cross compiling. Native +builds remain unchanged and will point to the current system's library +dir. + +## Native and Cross File Paths and Directories + +A new `[paths]` section has been added to native and cross files. This +can be used to set paths such a prefix and libdir in a persistent way. + +## Add warning_level 0 option + +Adds support for a warning level 0 which does not enable any static +analysis checks from the compiler + +## A builtin target to run clang-format + +If you have `clang-format` installed and there is a `.clang-format` +file in the root of your master project, Meson will generate a run +target called `clang-format` so you can reformat all files with one +command: + +```meson +ninja clang-format +``` + + +## Added `.path()` method to object returned by `python.find_installation()` + +`ExternalProgram` objects as well as the object returned by the +`python3` module provide this method, but the new `python` module did +not. + +## Fix ninja console log from generators with multiple output nodes + +This resolves [issue +#4760](https://github.com/mesonbuild/meson/issues/4760) where a +generator with multiple output nodes printed an empty string to the +console + +## `introspect --buildoptions` can now be used without configured build directory + +It is now possible to run `meson introspect --buildoptions /path/to/meson.build` +without a configured build directory. + +Running `--buildoptions` without a build directory produces the same +output as running it with a freshly configured build directory. + +However, this behavior is not guaranteed if subprojects are +present. Due to internal limitations all subprojects are processed +even if they are never used in a real Meson run. Because of this +options for the subprojects can differ. + +## `include_directories` accepts a string + +The `include_directories` keyword argument now accepts plain strings +rather than an include directory object. Meson will transparently +expand it so that a declaration like this: + +```meson +executable(..., include_directories: 'foo') +``` + +Is equivalent to this: + +```meson +foo_inc = include_directories('foo') +executable(..., include_directories: foo_inc) +``` + +## Fortran submodule support + +Initial support for Fortran `submodule` was added, where the submodule +is in the same or different file than the parent `module`. The +submodule hierarchy specified in the source Fortran code `submodule` +statements are used by Meson to resolve source file dependencies. For +example: + +```fortran +submodule (ancestor:parent) child +``` + + +## Add `subproject_dir` to `--projectinfo` introspection output + +This allows applications interfacing with Meson (such as IDEs) to know +about an overridden subproject directory. + +## Find library with its headers + +The `find_library()` method can now also verify if the library's +headers are found in a single call, using the `has_header()` method +internally. + +```meson +# Aborts if the 'z' library is found but not its header file +zlib = find_library('z', has_headers : 'zlib.h') +# Returns not-found if the 'z' library is found but not its header file +zlib = find_library('z', has_headers : 'zlib.h', required : false) +``` + +Any keyword argument with the `header_` prefix passed to +`find_library()` will be passed to the `has_header()` method with the +prefix removed. + +```meson +libfoo = find_library('foo', + has_headers : ['foo.h', 'bar.h'], + header_prefix : '#include <baz.h>', + header_include_directories : include_directories('.')) +``` + +## NetCDF + +NetCDF support for C, C++ and Fortran is added via pkg-config. + +## Added the Flang compiler + +[Flang](https://github.com/flang-compiler/flang/releases) Fortran +compiler support was added. As with other Fortran compilers, flang is +specified using `FC=flang meson ..` or similar. + +## New `not_found_message` for `dependency()` + +You can now specify a `not_found_message` that will be printed if the +specified dependency was not found. The point is to convert constructs +that look like this: + +```meson +d = dependency('something', required: false) +if not d.found() + message('Will not be able to do something.') +endif +``` + +Into this: + +```meson +d = dependency('something', + required: false, + not_found_message: 'Will not be able to do something.') +``` + +Or constructs like this: + +```meson +d = dependency('something', required: false) +if not d.found() + error('Install something by doing XYZ.') +endif +``` + +into this: + +```meson +d = dependency('something', + not_found_message: 'Install something by doing XYZ.') +``` + +Which works, because the default value of `required` is `true`. + +## Cuda support + +Compiling Cuda source code is now supported, though only with the +Ninja backend. This has been tested only on Linux for now. + +Because NVidia's Cuda compiler does not produce `.d` dependency files, +dependency tracking does not work. + +## `run_command()` accepts `env` kwarg + +You can pass [`environment`](Reference-manual.md#environment-object) +object to [`run_command`](Reference-manual.md#run-command), just +like to `test`: + +```meson +env = environment() +env.set('FOO', 'bar') +run_command('command', 'arg1', 'arg2', env: env) +``` + +## `extract_objects:` accepts `File` arguments + +The `extract_objects` function now supports File objects to tell it +what to extract. Previously, file paths could only be passed as strings. + +## Changed the JSON format of the introspection + +All paths used in the Meson introspection JSON format are now +absolute. This affects the `filename` key in the targets introspection +and the output of `--buildsystem-files`. + +Furthermore, the `filename` and `install_filename` keys in the targets +introspection are now lists of strings with identical length. + +The `--target-files` option is now deprecated, since the same information +can be acquired from the `--tragets` introspection API. + +## Meson file rewriter + +This release adds the functionality to perform some basic modification +on the `meson.build` files from the command line. The currently +supported operations are: + +- For build targets: + - Add/Remove source files + - Add/Remove targets + - Modify a select set of kwargs + - Print some JSON information +- For dependencies: + - Modify a select set of kwargs +- For the project function: + - Modify a select set of kwargs + - Modify the default options list + +For more information see the rewriter documentation. + +## `introspect --scan-dependencies` can now be used to scan for dependencies used in a project + +It is now possible to run `meson introspect --scan-dependencies +/path/to/meson.build` without a configured build directory to scan for +dependencies. + +The output format is as follows: + +```json +[ + { + "name": "The name of the dependency", + "required": true, + "conditional": false, + "has_fallback": false + } +] +``` + +The `required` keyword specifies whether the dependency is marked as +required in the `meson.build` (all dependencies are required by +default). The `conditional` key indicates whether the `dependency()` +function was called inside a conditional block. In a real Meson run +these dependencies might not be used, thus they _may_ not be required, +even if the `required` key is set. The `has_fallback` key just +indicates whether a fallback was directly set in the `dependency()` +function. + +## `introspect --targets` can now be used without configured build directory + +It is now possible to run `meson introspect --targets +/path/to/meson.build` without a configured build directory. + +The generated output is similar to running the introspection with a +build directory. However, there are some key differences: + +- The paths in `filename` now are _relative_ to the future build directory +- The `install_filename` key is completely missing +- There is only one entry in `target_sources`: + - With the language set to `unknown` + - Empty lists for `compiler` and `parameters` and `generated_sources` + - The `sources` list _should_ contain all sources of the target + +There is no guarantee that the sources list in `target_sources` is +correct. There might be differences, due to internal limitations. It +is also not guaranteed that all targets will be listed in the output. +It might even be possible that targets are listed, which won't exist +when Meson is run normally. This can happen if a target is defined +inside an if statement. Use this feature with care. + +## Added option to introspect multiple parameters at once + +Meson introspect can now print the results of multiple introspection +commands in a single call. The results are then printed as a single +JSON object. + +The format for a single command was not changed to keep backward +compatibility. + +Furthermore the option `-a,--all`, `-i,--indent` and +`-f,--force-object-output` were added to print all introspection +information in one go, format the JSON output (the default is still +compact JSON) and force use the new output format, even if only one +introspection command was given. + +A complete introspection dump is also stored in the `meson-info` +directory. This dump will be (re)generated each time meson updates the +configuration of the build directory. + +Additionlly the format of `meson introspect target` was changed: + + - New: the `sources` key. It stores the source files of a target and their compiler parameters. + - New: the `defined_in` key. It stores the Meson file where a target is defined + - New: the `subproject` key. It stores the name of the subproject where a target is defined. + - Added new target types (`jar`, `shared module`). + +## `meson configure` can now print the default options of an unconfigured project + +With this release, it is also possible to get a list of all build +options by invoking `meson configure` with the project source +directory or the path to the root `meson.build`. In this case, Meson +will print the default values of all options. + +## HDF5 + +HDF5 support is added via pkg-config. + +## Added the `meson-info.json` introspection file + +Meson now generates a `meson-info.json` file in the `meson-info` +directory to provide introspection information about the latest Meson +run. This file is updated when the build configuration is changed and +the build files are (re)generated. + +## New kwarg `install:` for `configure_file()` + +Previously when using `configure_file()`, you could install the +outputted file by setting the `install_dir:` keyword argument. Now, +there is an explicit kwarg `install:` to enable/disable it. Omitting +it will maintain the old behaviour. diff --git a/meson/docs/markdown/Release-notes-for-0.51.0.md b/meson/docs/markdown/Release-notes-for-0.51.0.md new file mode 100644 index 000000000..cd94f6aff --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.51.0.md @@ -0,0 +1,337 @@ +--- +title: Release 0.51.0 +short-description: Release notes for 0.51.0 +... + +# New features + +## (C) Preprocessor flag handling + +Meson previously stored `CPPFLAGS` and per-language compilation flags +separately. (That latter would come from `CFLAGS`, `CXXFLAGS`, etc., +along with `<lang>_args` options whether specified no the command-line +interface (`-D..`), `meson.build` (`default_options`), or cross file +(`[properties]`).) This was mostly unobservable, except for certain +preprocessor-only checks like `check_header` would only use the +preprocessor flags, leading to confusion if some `-isystem` was in +`CFLAGS` but not `CPPFLAGS`. Now, they are lumped together, and +`CPPFLAGS`, for the languages which are deemed to care to about, is +just another source of compilation flags along with the others already +listed. + +## Sanity checking compilers with user flags + +Sanity checks previously only used user-specified flags for cross +compilers, but now do in all cases. + +All compilers Meson might decide to use for the build are "sanity +checked" before other tests are run. This usually involves building +simple executable and trying to run it. Previously user flags +(compilation and/or linking flags) were used for sanity checking cross +compilers, but not native compilers. This is because such flags might +be essential for a cross binary to succeed, but usually aren't for a +native compiler. + +In recent releases, there has been an effort to minimize the +special-casing of cross or native builds so as to make building more +predictable in less-tested cases. Since this the user flags are +necessary for cross, but not harmful for native, it makes more sense +to use them in all sanity checks than use them in no sanity checks, so +this is what we now do. + +## New `sourceset` module + +A new module, `sourceset`, was added to help building many binaries +from the same source files. Source sets associate source files and +dependencies to keys in a `configuration_data` object or a dictionary; +they then take multiple `configuration_data` objects or dictionaries, +and compute the set of source files and dependencies for each of those +configurations. + +## n_debug=if-release and buildtype=plain means no asserts + +Previously if this combination was used then assertions were enabled, +which is fairly surprising behavior. + +## `target_type` in `build_targets` accepts the value 'shared_module' + +The `target_type` keyword argument in `build_target()` now accepts the +value `'shared_module'`. + +The statement + +```meson +build_target(..., target_type: 'shared_module') +``` + +is equivalent to this: + +```meson +shared_module(...) +``` + +## New modules kwarg for python.find_installation + +This mirrors the modules argument that some kinds of dependencies +(such as qt, llvm, and cmake based dependencies) take, allowing you to +check that a particular module is available when getting a python +version. + +```meson +py = import('python').find_installation('python3', modules : ['numpy']) +``` + +## Support for the Intel Compiler on Windows (ICL) + +Support has been added for ICL.EXE and ifort on windows. The support +should be on part with ICC support on Linux/MacOS. The ICL C/C++ +compiler behaves like Microsoft's CL.EXE rather than GCC/Clang like +ICC does, and has a different id, `intel-cl` to differentiate it. + +```meson +cc = meson.get_compiler('c') +if cc.get_id == 'intel-cl' + add_project_argument('/Qfoobar:yes', language : 'c') +endif +``` + +## Added basic support for the Xtensa CPU toolchain + +You can now use `xt-xcc`, `xt-xc++`, `xt-nm`, etc... on your cross +compilation file and Meson won't complain about an unknown toolchain. + + +## Dependency objects now have a get_variable method + +This is a generic replacement for type specific variable getters such as +`ConfigToolDependency.get_configtool_variable` and +`PkgConfigDependency.get_pkgconfig_variable`, and is the only way to query +such variables from cmake dependencies. + +This method allows you to get variables without knowing the kind of +dependency you have. + +```meson +dep = dependency('could_be_cmake_or_pkgconfig') +# cmake returns 'YES', pkg-config returns 'ON' +if ['YES', 'ON'].contains(dep.get_variable(pkgconfig : 'var-name', cmake : 'COP_VAR_NAME', default_value : 'NO')) + error('Cannot build your project when dep is built with var-name support') +endif +``` + +## CMake prefix path overrides + +When using pkg-config as a dependency resolver we can pass +`-Dpkg_config_path=$somepath` to extend or overwrite where pkg-config +will search for dependencies. Now cmake can do the same, as long as +the dependency uses a ${Name}Config.cmake file (not a +Find{$Name}.cmake file), by passing +`-Dcmake_prefix_path=list,of,paths`. It is important that point this +at the prefix that the dependency is installed into, not the cmake +path. + +If you have installed something to `/tmp/dep`, which has a layout like: +``` +/tmp/dep/lib/cmake +/tmp/dep/bin +``` + +then invoke Meson as `meson builddir/ -Dcmake_prefix_path=/tmp/dep` + +## Tests that should fail but did not are now errors + +You can tag a test as needing to fail like this: + +```meson +test('shoulfail', exe, should_fail: true) +``` + +If the test passes the problem is reported in the error logs but due +to a bug it was not reported in the test runner's exit code. Starting +from this release the unexpected passes are properly reported in the +test runner's exit code. This means that test runs that were passing +in earlier versions of Meson will report failures with the current +version. This is a good thing, though, since it reveals an error in +your test suite that has, until now, gone unnoticed. + +## New target keyword argument: `link_language` + +There may be situations for which the user wishes to manually specify +the linking language. For example, a C++ target may link C, Fortran, +etc. and perhaps the automatic detection in Meson does not pick the +desired compiler. The user can manually choose the linker by language +per-target like this example of a target where one wishes to link with +the Fortran compiler: + +```meson +executable(..., link_language : 'fortran') +``` + +A specific case this option fixes is where for example the main +program is Fortran that calls C and/or C++ code. The automatic +language detection of Meson prioritizes C/C++, and so an compile-time +error results like `undefined reference to main`, because the linker +is C or C++ instead of Fortran, which is fixed by this per-target +override. + +## New module to parse kconfig output files + +The new module `unstable-kconfig` adds the ability to parse and use +kconfig output files from `meson.build`. + + +## Add new `meson subprojects foreach` command + +`meson subprojects` has learned a new `foreach` command which accepts +a command with arguments and executes it in each subproject directory. + +For example this can be useful to check the status of subprojects +(e.g. with `git status` or `git diff`) before performing other actions +on them. + + +## Added c17 and c18 as c_std values for recent GCC and Clang Versions + +For gcc version 8.0 and later, the values c17, c18, gnu17, and gnu18 +were added to the accepted values for built-in compiler option c_std. + +For Clang version 10.0 and later on Apple OSX (Darwin), and for +version 7.0 and later on other platforms, the values c17 and gnu17 +were added as c_std values. + +## gpgme dependency now supports gpgme-config + +Previously, we could only detect GPGME with custom invocations of +`gpgme-config` or when the GPGME version was recent enough (>=1.13.0) +to install pkg-config files. Now we added support to Meson allowing us +to use `dependency('gpgme')` and fall back on `gpgme-config` parsing. + +## Can link against custom targets + +The output of `custom_target` and `custom_target[i]` can be used in +`link_with` and `link_whole` keyword arguments. This is useful for +integrating custom code generator steps, but note that there are many +limitations: + + - Meson can not know about link dependencies of the custom target. If + the target requires further link libraries, you need to add them manually + + - The user is responsible for ensuring that the code produced by + different toolchains are compatible. + + - `custom_target` may only be used when it has a single output file. + Use `custom_target[i]` when dealing with multiple output files. + + - The output file must have the correct file name extension. + + +## Removed the deprecated `--target-files` API + +The `--target-files` introspection API is now no longer available. The same +information can be queried with the `--targets` API introduced in 0.50.0. + +## Generators have a new `depends` keyword argument + +Generators can now specify extra dependencies with the `depends` +keyword argument. It matches the behaviour of the same argument in +other functions and specifies that the given targets must be built +before the generator can be run. This is used in cases such as this +one where you need to tell a generator to indirectly invoke a +different program. + +```meson +exe = executable(...) +cg = generator(program_runner, + output: ['@BASENAME@.c'], + arguments: ['--use-tool=' + exe.full_path(), '@INPUT@', '@OUTPUT@'], + depends: exe) +``` + +## Specifying options per mer machine + +Previously, no cross builds were controllable from the command line. +Machine-specific options like the pkg-config path and compiler options +only affected native targets, that is to say all targets in native +builds, and `native: true` targets in cross builds. Now, prefix the +option with `build.` to affect build machine targets, and leave it +unprefixed to affect host machine targets. + +For those trying to ensure native and cross builds to the same +platform produced the same result, the old way was frustrating because +very different invocations were needed to affect the same targets, if +it was possible at all. Now, the same command line arguments affect +the same targets everywhere --- Meson is closer to ignoring whether +the "overall" build is native or cross, and just caring about whether +individual targets are for the build or host machines. + + +## subproject.get_variable() now accepts a `fallback` argument + +Similar to `get_variable`, a fallback argument can now be passed to +`subproject.get_variable()`, it will be returned if the requested +variable name did not exist. + +``` meson +var = subproject.get_variable('does-not-exist', 'fallback-value') +``` + +## Add keyword `static` to `find_library` + +`find_library` has learned the `static` keyword. They keyword must be +a boolean, where `true` only searches for static libraries and `false` +only searches for dynamic/shared. Leaving the keyword unset will keep +the old behavior of first searching for dynamic and then falling back +to static. + +## Fortran `include` statements recursively parsed + +While non-standard and generally not recommended, some legacy Fortran +programs use `include` directives to inject code inline. Since v0.51, +Meson can handle Fortran `include` directives recursively. + +DO NOT list `include` files as sources for a target, as in general +their syntax is not correct as a standalone target. In general +`include` files are meant to be injected inline as if they were copy +and pasted into the source file. + +`include` was never standard and was superceded by Fortran 90 `module`. + +The `include` file is only recognized by Meson if it has a Fortran +file suffix, such as `.f` `.F` `.f90` `.F90` or similar. This is to +avoid deeply nested scanning of large external legacy C libraries that +only interface to Fortran by `include biglib.h` or similar. + +## CMake subprojects + +Meson can now directly consume CMake based subprojects with the +CMake module. + +Using CMake subprojects is similar to using the "normal" Meson +subprojects. They also have to be located in the `subprojects` +directory. + +Example: + +```cmake +add_library(cm_lib SHARED ${SOURCES}) +``` + +```meson +cmake = import('cmake') + +# Configure the CMake project +sub_proj = cmake.subproject('libsimple_cmake') + +# Fetch the dependency object +cm_lib = sub_proj.dependency('cm_lib') + +executable(exe1, ['sources'], dependencies: [cm_lib]) +``` + +It should be noted that not all projects are guaranteed to work. The +safest approach would still be to create a `meson.build` for the +subprojects in question. + +## Multiple cross files can be specified + +`--cross-file` can be passed multiple times, with the configuration files overlaying the same way as `--native-file`. diff --git a/meson/docs/markdown/Release-notes-for-0.52.0.md b/meson/docs/markdown/Release-notes-for-0.52.0.md new file mode 100644 index 000000000..05e2dc27e --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.52.0.md @@ -0,0 +1,252 @@ +--- +title: Release 0.52.0 +short-description: Release notes for 0.52.0 +... + +# New features + +## Gettext targets are ignored if `gettext` is not installed + +Previously the `i18n` module has errored out when `gettext` tools are +not installed on the system. Starting with this version they will +become no-ops instead. This makes it easier to build projects on +minimal environments (such as when bootstrapping) that do not have +translation tools installed. + +## Support taking environment values from a dictionary + +`environment()` now accepts a dictionary as first argument. If +provided, each key/value pair is added into the `environment_object` +as if `set()` method was called for each of them. + +On the various functions that take an `env:` keyword argument, you may +now give a dictionary. + +## alias_target + +``` meson +runtarget alias_target(target_name, dep1, ...) +``` + +This function creates a new top-level target. Like all top-level +targets, this integrates with the selected backend. For instance, with +Ninja you can run it as `ninja target_name`. This is a dummy target +that does not execute any command, but ensures that all dependencies +are built. Dependencies can be any build target (e.g. return value of +executable(), custom_target(), etc) + + +## Enhancements to the pkg_config_path argument + +Setting sys_root in the [properties] section of your cross file will +now set PKG_CONFIG_SYSROOT_DIR automatically for host system +dependencies when cross compiling. + +## The Meson test program now accepts an additional "--gdb-path" argument to specify the GDB binary + +`meson test --gdb testname` invokes GDB with the specific test case. However, sometimes GDB is not in the path or a GDB replacement is wanted. +Therefore, a `--gdb-path` argument was added to specify which binary is executed (per default `gdb`): + +```console +$ meson test --gdb --gdb-path /my/special/location/for/gdb testname +$ meson test --gdb --gdb-path cgdb testname +``` + +## Better support for illumos and Solaris + +illumos (and hopefully Solaris) support has been dramatically +improved, and one can reasonably expect projects to compile. + +## Splitting of Compiler.get_function_attribute('visibility') + +On macOS there is no `protected` visibility, which results in the +visbility check always failing. 0.52.0 introduces two changes to +improve this situation: + +1. the "visibility" check no longer includes "protected" +2. a new set of "split" checks are introduced which check for a single + attribute instead of all attributes. + +These new attributes are: +* visibility:default +* visibility:hidden +* visibility:internal +* visibility:protected + +## Clang-tidy target + +If `clang-tidy` is installed and the project's source root contains a +`.clang-tidy` (or `_clang-tidy`) file, Meson will automatically define +a `clang-tidy` target that runs Clang-Tidy on all source files. + +If you have defined your own `clang-tidy` target, Meson will not +generate its own target. + +## Add blocks dependency + +Add `dependency('blocks')` to use the Clang blocks extension. + +## Meson's builtin b_lundef is now supported on macOS + +This has always been possible, but there are some additional +restrictions on macOS (mainly do to Apple only features). With the +linker internal re-architecture this has become possible + +## Compiler and dynamic linker representation split + +0.52.0 inclues a massive refactor of the representaitons of compilers to +tease apart the representations of compilers and dynamic linkers (ld). This +fixes a number of compiler/linker combinations. In particular this fixes +use GCC and vanilla clang on macOS. + +## Add `depth` option to `wrap-git` + +To allow shallow cloning, an option `depth` has been added to `wrap-git`. +This applies recursively to submodules when `clone-recursive` is set to `true`. + +Note that the git server may have to be configured to support shallow cloning +not only for branches but also for tags. + +## Enhancements to the source_set module + +`SourceSet` objects now provide the `all_dependencies()` method, that +complement the existing `all_sources()` method. + +## added `--only test(s)` option to run_project_tests.py + +Individual tests or a list of tests from run_project_tests.py can be selected like: +``` +python run_project_tests.py --only fortran + +python run_project_tests.py --only fortran python3 +``` + +This assists Meson development by only running the tests for the +portion of Meson being worked on during local development. + +## Experimental Webassembly support via Emscripten + +Meson now supports compiling code to Webassembly using the Emscripten +compiler. As with most things regarding Webassembly, this support is +subject to change. + +## Version check in `find_program()` + +A new `version` keyword argument has been added to `find_program` to +specify the required version. See [`dependency()`](#dependency) for +argument format. 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()`](#run_command). + +## Added `vs_module_defs` to `shared_module()` + +Like `shared_library()`, `shared_module()` now accepts +`vs_module_defs` argument for controlling symbol exports, etc. + +## Improved support for static libraries + +Static libraries had numerous shortcomings in the past, especially +when using uninstalled static libraries. This release brings many +internal changes in the way they are handled, including: + +- `link_whole:` of static libraries. In the example below, lib2 used to miss + symbols from lib1 and was unusable. +```meson +lib1 = static_library(sources) +lib2 = static_library(other_sources, link_whole : lib1, install : true) +``` +- `link_with:` of a static library with an uninstalled static library. In the +example below, lib2 now implicitly promote `link_with:` to `link_whole:` because +the installed lib2 would oterhwise be unusable. +```meson +lib1 = static_library(sources, install : false) +lib2 = static_library(sources, link_with : lib1, install : true) +``` +- pkg-config generator do not include uninstalled static libraries. In the example + below, the generated `.pc` file used to be unusable because it contained + `Libs.private: -llib1` and `lib1.a` is not installed. `lib1` is now omitted + from the `.pc` file because the `link_with:` has been promoted to + `link_whole:` (see above) and thus lib1 is not needed to use lib2. +```meson +lib1 = static_library(sources, install : false) +lib2 = both_libraries(sources, link_with : lib1, install : true) +pkg.generate(lib2) +``` + +Many projects have been using `extract_all_objects()` to work around +those issues, and hopefully those hacks could now be removed. Since +this is a pretty large change, please double check if your static +libraries behave correctly, and report any regression. + +## Enhancements to the kconfig module + +`kconfig.load()` may now accept a `configure_file()` as input file. + +## Added `include_type` kwarg to `dependency` + +The `dependency()` function now has a `include_type` kwarg. It can take the +values `'preserve'`, `'system'` and `'non-system'`. If it is set to `'system'`, +all include directories of the dependency are marked as system dependencies. + +The default value of `include_type` is `'preserve'`. + +Additionally, it is also possible to check and change the +`include_type` state of an existing dependency object with the new +`include_type()` and `as_system()` methods. + +## Enhancements to `configure_file()` + +`input:` now accepts multiple input file names for `command:`-configured file. + +`depfile:` keyword argument is now accepted. The dependency file can +list all the additional files the configure target depends on. + +## Projects args can be set separately for build and host machines (potentially breaking change) + +Simplify `native` flag behavior in `add_global_arguments`, +`add_global_link_arguments`, `add_project_arguments` and +`add_project_link_arguments`. The rules are now very simple: + + - `native: true` affects `native: true` targets + + - `native: false` affects `native: false` targets + + - No native flag is the same as `native: false` + +This further simplifies behavior to match the "build vs host" decision +done in last release with `c_args` vs `build_c_args`. The underlying +motivation in both cases is to execute the same commands whether the +overall build is native or cross. + +## Allow checking if a variable is a disabler + +Added the function `is_disabler(var)`. Returns true if a variable is a disabler +and false otherwise. + + +## gtkdoc-check support + +`gnome.gtkdoc()` now has a `check` keyword argument. If `true` runs it +will run `gtkdoc-check` when running unit tests. Note that this has +the downside of rebuilding the doc for each build, which is often very +slow. It usually should be enabled only in CI. + +## `gnome.gtkdoc()` returns target object + +`gnome.gtkdoc()` now returns a target object that can be passed as +dependency to other targets using generated doc files (e.g. in +`content_files` of another doc). + +## Dist is now a top level command + +Previously creating a source archive could only be done with `ninja +dist`. Starting with this release Meson provides a top level `dist` +that can be invoked directly. It also has a command line option to +determine which kinds of archives to create: + +```meson +meson dist --formats=xztar,zip +``` diff --git a/meson/docs/markdown/Release-notes-for-0.53.0.md b/meson/docs/markdown/Release-notes-for-0.53.0.md new file mode 100644 index 000000000..73a71db57 --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.53.0.md @@ -0,0 +1,219 @@ +--- +title: Release 0.53.0 +short-description: Release notes for 0.53.0 +... + +# New features + +## A new module for filesystem operations + +The new `fs` module can be used to examine the contents of the current +file system. + +```meson +fs = import('fs') +assert(fs.exists('important_file'), + 'The important file is missing.') +``` + +## meson dist --include-subprojects + +`meson dist` command line now gained `--include-subprojects` command +line option. When enabled, the source tree of all subprojects used by +the current build will also be included in the final tarball. This is +useful to distribute self contained tarball that can be built offline +(i.e. `--wrap-mode=nodownload`). + +## Added new Meson templates for `Dlang`, `Rust`, `Objective-C` + +Meson now ships with predefined project templates for `Dlang`, +`Fortran`, `Rust`, `Objective-C`, and by passing the associated flags `d`, +`fortran`, `rust`, `objc` to `meson init --language`. + +## Add a new summary() function + +A new function [`summary()`](Reference-manual.md#summary) has been +added to summarize build configuration at the end of the build +process. + +Example: +```meson +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', + 'A list': ['string', 1, true], + }, section: 'Configuration') +``` + +Output: +``` +My Project 1.0 + + Directories + prefix: /opt/gnome + bindir: bin + libdir: lib/x86_64-linux-gnu + datadir: share + + Configuration + Some boolean: False + Another boolean: True + Some string: Hello World + A list: string + 1 + True +``` + +## Generic Overrider for Dynamic Linker selection + +Previous to Meson 0.52.0 you set the dynamic linker using compiler +specific flags passed via language flags and hoped things worked out. +In version 0.52.0 Meson started detecting the linker and making +intelligent decisions about using it. Unfortunately this broke +choosing a non-default linker. + +Now there is a generic mechanism for doing this. In 0.53.0, you can +use the `LD` environment variable. **In 0.53.1** this was changed to +`<compiler_variable>_LD`, such as `CC_LD`, `CXX_LD`, `D_LD`, etc due +to regressions. The usual Meson [environment variable +rules](https://mesonbuild.com/Running-Meson.html#environment-variables) +apply. Alternatively, you can add the following to a cross or native +file: + +In 0.53.0: + +```ini +[binaries] +ld = 'gold' +``` + +**In 0.53.1 or newer**: + +```ini +[binaries] +c = 'gcc' +c_ld = 'gold' +``` + +```ini +[binaries] +c = 'clang' +c_ld = 'lld' +``` + +And Meson will select the linker if possible. + +## `fortran_std` option + +**new in 0.53.0** Akin to the `c_std` and `cpp_std` options, the +`fortran_std` option sets Fortran compilers to warn or error on +non-Fortran standard code. Only the Gfortran and Intel Fortran +compilers have support for this option. Other Fortran compilers ignore +the `fortran_std` option. + +Supported values for `fortran_std` include: + +* `legacy` for non-conforming code--this is especially important for Gfortran, which by default errors on old non-compliant Fortran code +* `f95` for Fortran 95 compliant code. +* `f2003` for Fortran 2003 compliant code. +* `f2008` for Fortran 2008 compliant code. +* `f2018` for Fortran 2018 compliant code. + +## python.dependency() embed kwarg + +Added the `embed` kwarg to the python module dependency function to +select the python library that can be used to embed python into an +application. + +## Scalapack + +added in **0.53.0**: + +```meson +scalapack = dependency('scalapack') +``` + +Historically and through today, typical Scalapack setups have broken +and incomplete pkg-config or FindScalapack.cmake. Meson handles +finding Scalapack on setups including: + +* Linux: Intel MKL or OpenMPI + Netlib +* MacOS: Intel MKL or OpenMPI + Netlib +* Windows: Intel MKL (OpenMPI not available on Windows) + +## Search directories for `find_program()` + +It is now possible to give a list of absolute paths where `find_program()` should +also search, using the `dirs` keyword argument. + +For example on Linux `/sbin` and `/usr/sbin` are not always in the `$PATH`: +```meson +prog = find_program('mytool', dirs : ['/usr/sbin', '/sbin']) +``` + +## Source tags targets + +When the respective tools are available, 'ctags', 'TAGS' and 'cscope' +targets will be generated by Meson, unless you have defined your own. + +## Dictionary entry using string variable as key + +Keys can now be any expression evaluating to a string value, not limited +to string literals any more. +```meson +d = {'a' + 'b' : 42} +k = 'cd' +d += {k : 43} +``` + +## Improved CMake subprojects support + +With this release even more CMake projects are supported via [CMake +subprojects](CMake-module.md#cmake-subprojects) due to these internal +improvements: + +- Use the CMake file API for CMake >=3.14 +- Handle the explicit dependencies via `add_dependency` +- Basic support for `add_custom_target` +- Improved `add_custom_command` support +- Object library support on Windows + +## compiler.get_linker_id() + +since 0.53.0, `compiler.get_linker_id()` allows retrieving a lowercase +name for the linker. Since each compiler family can typically use a +variety of linkers depending on operating system, this helps users +define logic for corner cases not otherwise easily handled. + +## CUDA dependency + +Native support for compiling and linking against the CUDA Toolkit +using the `dependency` function: + +```meson +project('CUDA test', 'cpp', meson_version: '>= 0.53.0') +exe = executable('prog', 'prog.cc', dependencies: dependency('cuda')) +``` + +See [the CUDA dependency](Dependencies.md#cuda) for more information. + +## Added global option to disable C++ RTTI + +The new boolean option is called `cpp_rtti`. + +## Introspection API changes + +dependencies (--dependencies, intro-dependencies.json): +- added the `version` key + +scanning dependencies (--scan-dependencies): +- added the `version` key containing the required dependency version + +tests and benchmarks (--tests, --benchmarks, intro-tests.json, +intro-benchmarks.json): +- added the `protocol` key diff --git a/meson/docs/markdown/Release-notes-for-0.54.0.md b/meson/docs/markdown/Release-notes-for-0.54.0.md new file mode 100644 index 000000000..7e9fbf225 --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.54.0.md @@ -0,0 +1,394 @@ +--- +title: Release 0.54.0 +short-description: Release notes for 0.54.0 +... + +# New features + +## Emscripten (emcc) now supports threads + +In addition to properly setting the compile and linker arguments, a +new Meson builtin has been added to control the PTHREAD_POOL_SIZE +option, `-D<lang>_thread_count`, which may be set to any integer value +greater than 0. If it set to 0 then the PTHREAD_POOL_SIZE option will +not be passed. + +## Introduce dataonly for the pkgconfig module + +This allows users to disable writing out the inbuilt variables to the +pkg-config file as they might actually not be required. + +One reason to have this is for architecture-independent pkg-config +files in projects which also have architecture-dependent outputs. + +``` +pkgg.generate( + name : 'libhello_nolib', + description : 'A minimalistic pkgconfig file.', + version : libver, + dataonly: true +) +``` + +## Consistently report file locations relative to cwd + +The paths for filenames in error and warning locations are now +consistently reported relative to the current working directory (when +possible), or as absolute paths (when a relative path does not exist, +e.g. a Windows path starting with a different drive letter to the +current working directory). + +(The previous behaviour was to report a path relative to the source +root for all warnings and most errors, and relative to cwd for certain +parser errors) + +## `dependency()` consistency + +The first time a dependency is found, using `dependency('foo', ...)`, +the return value is now cached. Any subsequent call will return the +same value as long as version requested match, otherwise not-found +dependency is returned. This means that if a system dependency is +first found, it won't fallback to a subproject in a subsequent call +any more and will rather return not-found instead if the system +version does not match. Similarly, if the first call returns the +subproject fallback dependency, it will also return the subproject +dependency in a subsequent call even if no fallback is provided. + +For example, if the system has `foo` version 1.0: +```meson +# d2 is set to foo_dep and not the system dependency, even without fallback argument. +d1 = dependency('foo', version : '>=2.0', required : false, + fallback : ['foo', 'foo_dep']) +d2 = dependency('foo', version : '>=1.0', required : false) +``` +```meson +# d2 is not-found because the first call returned the system dependency, but its version is too old for 2nd call. +d1 = dependency('foo', version : '>=1.0', required : false) +d2 = dependency('foo', version : '>=2.0', required : false, + fallback : ['foo', 'foo_dep']) +``` + +## Override `dependency()` + +It is now possible to override the result of `dependency()` to point +to any dependency object you want. The overriding is global and +applies to every subproject from there on. + +For example, this subproject provides 2 libraries with version 2.0: + +```meson +project(..., version : '2.0') + +libfoo = library('foo', ...) +foo_dep = declare_dependency(link_with : libfoo) +meson.override_dependency('foo', foo_dep) + +libbar = library('bar', ...) +bar_dep = declare_dependency(link_with : libbar) +meson.override_dependency('bar', bar_dep) +``` + +Assuming the system has `foo` and `bar` 1.0 installed, and master project does this: +```meson +foo_dep = dependency('foo', version : '>=2.0', fallback : ['foo', 'foo_dep']) +bar_dep = dependency('bar') +``` + +This used to mix system 1.0 version and subproject 2.0 dependencies, +but thanks to the override `bar_dep` is now set to the subproject's +version instead. + +Another case this can be useful is to force a subproject to use a +specific dependency. If the subproject does `dependency('foo')` but +the main project wants to provide its own implementation of `foo`, it +can for example call `meson.override_dependency('foo', +declare_dependency(...))` before configuring the subproject. + +## Simplified `dependency()` fallback + +In the case a subproject `foo` calls +`meson.override_dependency('foo-2.0', foo_dep)`, the parent project +can omit the dependency variable name in fallback keyword argument: +`dependency('foo-2.0', fallback : 'foo')`. + +## Backend agnostic compile command + +A new `meson compile` command has been added to support backend +agnostic compilation. It accepts two arguments, `-j` and `-l`, which +are used if possible (`-l` does nothing with msbuild). A `-j` or `-l` +value < 1 lets the backend decide how many threads to use. For msbuild +this means `-m`, for ninja it means passing no arguments. + +```console +meson builddir --backend vs +meson compile -C builddir -j0 # this is the same as `msbuild builddir/my.sln -m` +``` + +```console +meson builddir +meson compile -C builddir -j3 # this is the same as `ninja -C builddir -j3` +``` + +Additionally `meson compile` provides a `--clean` switch to clean the +project. + +A complete list of arguments is always documented via `meson compile --help` + +## Native (build machine) compilers not always required + +`add_languages()` gained a `native:` keyword, indicating if a native or cross +compiler is to be used. + +For the benefit of existing simple build definitions which don't +contain any `native: true` targets, without breaking backwards +compatibility for build definitions which assume that the native +compiler is available after `add_languages()`, if the `native:` +keyword is absent the languages may be used for either the build or +host machine, but are never required for the build machine. + +This changes the behaviour of the following Meson fragment (when +cross-compiling but a native compiler is not available) from reporting +an error at `add_language` to reporting an error at `executable`. + +``` +add_language('c') +executable('main', 'main.c', native: true) +``` + +## Summary improvements + +A new `list_sep` keyword argument has been added to `summary()` +function. If defined and the value is a list, elements will be +separated by the provided string instead of being aligned on a new +line. + +The automatic `subprojects` section now also print the number of +warnings encountered during that subproject configuration, or the +error message if the configuration failed. + +## Add a system type dependency for zlib + +This allows zlib to be detected on macOS and FreeBSD without the use +of pkg-config or cmake, neither of which are part of the base install +on those OSes (but zlib is). + +A side effect of this change is that `dependency('zlib')` also works +with cmake instead of requiring `dependency('ZLIB')`. + +## Added 'name' method + +Build target objects (as returned by executable(), library(), ...) now +have a name() method. + +## New option `--quiet` to `meson install` + +Now you can run `meson install --quiet` and Meson will not verbosely +print every file as it is being installed. As before, the full log is +always available inside the builddir in `meson-logs/install-log.txt`. + +When this option is passed, install scripts will have the environment +variable `MESON_INSTALL_QUIET` set. + +Numerous speed-ups were also made for the install step, especially on +Windows where it is now 300% to 1200% faster than before depending on +your workload. + +## Property support emscripten's wasm-ld + +Before 0.54.0 we treated emscripten as both compiler and linker, which +isn't really true. It does have a linker, called wasm-ld (Meson's name +is ld.wasm). This is a special version of clang's lld. This will now +be detected properly. + +## Skip sanity tests when cross compiling + +For certain cross compilation environments it is not possible to +compile a sanity check application. This can now be disabled by adding +the following entry to your cross file's `properties` section: + +``` +skip_sanity_check = true +``` + +## Support for overiding the linker with ldc and gdc + +LDC (the llvm D compiler) and GDC (The Gnu D Compiler) now honor D_LD +linker variable (or d_ld in the cross file) and is able to pick +different linkers. + +GDC supports all of the same values as GCC, LDC supports ld.bfd, +ld.gold, ld.lld, ld64, link, and lld-link. + +## Native file properties + +As of Meson 0.54.0, the `--native-file nativefile.ini` can contain: + +* binaries +* paths +* properties + +which are defined and used the same way as in cross files. The +`properties` are new for Meson 0.54.0, and are read like: + +```meson +x = meson.get_external_property('foobar', 'foo') +``` + +where `foobar` is the property name, and the optional `foo` is the +fallback string value. + +For cross-compiled projects, `get_external_property()` reads the +cross-file unless `native: true` is specified. + +## Changed the signal used to terminate a test process (group) + +A test process (group) is now terminated via SIGTERM instead of +SIGKILL allowing the signal to be handled. However, it is now the +responsibility of the custom signal handler (if any) to ensure that +any process spawned by the top-level test processes is correctly +killed. + +## Dynamic Linker environment variables actually match docs + +The docs have always claimed that the Dynamic Linker environment +variable should be `${COMPILER_VAR}_LD`, but that's only the case for +about half of the variables. The other half are different. In 0.54.0 +the variables match. The old variables are still supported, but are +deprecated and raise a deprecation warning. + +## Per subproject `default_library` and `werror` options + +The `default_library` and `werror` built-in options can now be defined +per subproject. This is useful for example when building shared +libraries in the main project, but static link a subproject, or when +the main project must build with no warnings but some subprojects +cannot. + +Most of the time this would be used either by the parent project by +setting subproject's default_options (e.g. `subproject('foo', +default_options: 'default_library=static')`), or by the user using the +command line `-Dfoo:default_library=static`. + +The value is overridden in this order: +- Value from parent project +- Value from subproject's default_options if set +- Value from subproject() default_options if set +- Value from command line if set + +## Environment Variables with Cross Builds + +Previously in Meson, variables like `CC` effected both the host and +build platforms for native builds, but the just the build platform for +cross builds. Now `CC_FOR_BUILD` is used for the build platform in +cross builds. + +This old behavior is inconsistent with the way Autotools works, which +undermines the purpose of distro-integration that is the only reason +environment variables are supported at all in Meson. The new behavior +is not quite the same, but doesn't conflict: Meson doesn't always +repond to an environment when Autoconf would, but when it does it +interprets it as Autotools would. + +## Added 'pkg_config_libdir' property + +Allows to define a list of folders used by pkg-config for a cross +build and avoid a system directories use. + +## More new sample Meson templates for (`Java`, `Cuda`, and more) + +Meson now ships with predefined project templates for `Java`, `Cuda`, +`Objective-C++`, and `C#`, we provided with associated values for +corresponding languages, available for both library, and executable. + +## Ninja version requirement bumped to 1.7 + +Meson now uses the [Implicit +outputs](https://ninja-build.org/manual.html#ref_outputs) feature of +Ninja for some types of targets that have multiple outputs which may +not be listed on the command-line. This feature requires Ninja 1.7+. + +Note that the latest version of [Ninja available in Ubuntu +16.04](https://packages.ubuntu.com/search?keywords=ninja-build&searchon=names&suite=xenial-backports§ion=all) +(the oldest Ubuntu LTS at the time of writing) is 1.7.1. If your +distro does not ship with a new-enough Ninja, you can download the +latest release from Ninja's GitHub page: +https://github.com/ninja-build/ninja/releases + +## Added `-C` argument to `meson init` command + +The Meson init assumes that it is run inside the project root +directory. If this isn't the case, you can now use `-C` to specify the +actual project source directory. + +## More than one argument to `message()` and `warning()` + +Arguments passed to `message()` and `warning()` will be printed +separated by space. + +## Added `has_tools` method to qt module + +It should be used to compile optional Qt code: +```meson +qt5 = import('qt5') +if qt5.has_tools(required: get_option('qt_feature')) + moc_files = qt5.preprocess(...) + ... +endif +``` + +## The MSI installer is only available in 64 bit version + +Microsoft ended support for Windows 7, so only 64 bit Windows OSs are +officially supported. Thus only a 64 bit MSI installer will be +provided going forward. People needing a 32 bit version can build +their own with the `msi/createmsi.py` script in Meson's source +repository. + +## Uninstalled pkg-config files + +**Note**: the functionality of this module is governed by [Meson's + rules on mixing build systems](Mixing-build-systems.md). + +The `pkgconfig` module now generates uninstalled pc files as well. For +any generated `foo.pc` file, an extra `foo-uninstalled.pc` file is +placed into `<builddir>/meson-uninstalled`. They can be used to build +applications against libraries built by Meson without installing them, +by pointing `PKG_CONFIG_PATH` to that directory. This is an +experimental feature provided on a best-effort basis, it might not +work in all use-cases. + +## CMake find_package COMPONENTS support + +It is now possible to pass components to the CMake dependency backend +via the new `components` kwarg in the `dependency` function. + +## Added Microchip XC16 C compiler support + +Make sure compiler executables are setup correctly in your path +Compiler is available from the Microchip website for free + + +## Added Texas Instruments C2000 C/C++ compiler support + +Make sure compiler executables are setup correctly in your path +Compiler is available from Texas Instruments website for free + +## Unity file block size is configurable + +Traditionally the unity files that Meson autogenerates contain all +source files that belong to a single target. This is the most +efficient setting for full builds but makes incremental builds slow. +This release adds a new option `unity_size` which specifies how many +source files should be put in each unity file. + +The default value for block size is 4. This means that if you have a +target that has eight source files, Meson will generate two unity +files each of which includes four source files. The old behaviour can +be replicated by setting `unity_size` to a large value, such as 10000. + +## Verbose mode for `meson compile` + +The new option `--verbose` has been added to `meson compile` that will +enable more verbose compilation logs. Note that for VS backend it +means that logs will be less verbose by default (without `--verbose` +option). diff --git a/meson/docs/markdown/Release-notes-for-0.55.0.md b/meson/docs/markdown/Release-notes-for-0.55.0.md new file mode 100644 index 000000000..110dd1d71 --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.55.0.md @@ -0,0 +1,332 @@ +--- +title: Release 0.55.0 +short-description: Release notes for 0.55.0 +... + +# New features + +## rpath removal now more careful + +On Linux-like systems, Meson adds rpath entries to allow running apps +in the build tree, and then removes those build-time-only rpath +entries when installing. Rpath entries may also come in via LDFLAGS +and via .pc files. Meson used to remove those latter rpath entries by +accident, but is now more careful. + +## Added ability to specify targets in `meson compile` + +It's now possible to specify targets in `meson compile`, which will +result in building only the requested targets. + +Usage: `meson compile [TARGET [TARGET...]]` +`TARGET` has the following syntax: `[PATH/]NAME[:TYPE]`. +`NAME`: name of the target from `meson.build` (e.g. `foo` from `executable('foo', ...)`). +`PATH`: path to the target relative to the root `meson.build` file. Note: relative path for a target specified in the root `meson.build` is `./`. +`TYPE`: type of the target (e.g. `shared_library`, `executable` and etc) + +`PATH` and/or `TYPE` can be omitted if the resulting `TARGET` can be used to uniquely identify the target in `meson.build`. + +For example targets from the following code: +```meson +shared_library('foo', ...) +static_library('foo', ...) +executable('bar', ...) +``` +can be invoked with `meson compile foo:shared_library foo:static_library bar`. + +## Test protocol for gtest + +Due to the popularity of Gtest (google test) among C and C++ +developers Meson now supports a special protocol for gtest. With this +protocol Meson injects arguments to gtests to output JUnit, reads that +JUnit, and adds the output to the JUnit it generates. + +## meson.add_*_script methods accept new types + +All three (`add_install_script`, `add_dist_script`, and +`add_postconf_script`) now accept ExternalPrograms (as returned by +`find_program`), Files, and the output of `configure_file`. The dist and +postconf methods cannot accept other types because of when they are run. +While dist could, in theory, take other dependencies, it would require more +extensive changes, particularly to the backend. + +```meson +meson.add_install_script(find_program('foo'), files('bar')) +meson.add_dist_script(find_program('foo'), files('bar')) +meson.add_postconf_script(find_program('foo'), files('bar')) +``` + +The install script variant is also able to accept custom_targets, +custom_target indexes, and build targets (executables, libraries), and +can use built executables a the script to run + +```meson +installer = executable('installer', ...) +meson.add_install_script(installer, ...) +meson.add_install_script('foo.py', installer) +``` + +## Machine file constants + +Native and cross files now support string and list concatenation using +the `+` operator, and joining paths using the `/` operator. Entries +defined in the `[constants]` section can be used in any other section. +An entry defined in any other section can be used only within that +same section and only after it has been defined. + +```ini +[constants] +toolchain = '/toolchain' +common_flags = ['--sysroot=' + toolchain + '/sysroot'] + +[properties] +c_args = common_flags + ['-DSOMETHING'] +cpp_args = c_args + ['-DSOMETHING_ELSE'] + +[binaries] +c = toolchain + '/gcc' +``` + +## Configure CMake subprojects with Meson.subproject_options + +Meson now supports passing configuration options to CMake and +overriding certain build details extracted from the CMake subproject. + +The new CMake configuration options object is very similar to the +[configuration data +object](Reference-manual.md#configuration-data-object) object returned +by [`configuration_data`](Reference-manual.md#configuration_data). It +is generated by the `subproject_options` function + +All configuration options have to be set *before* the subproject is +configured and must be passed to the `subproject` method via the +`options` key. Altering the configuration object won't have any effect +on previous `cmake.subproject` calls. + +**Note:** The `cmake_options` kwarg for the `subproject` function is +now deprecated since it is replaced by the new `options` system. + +## find_program: Fixes when the program has been overridden by executable + +When a program has been overridden by an executable, the returned +object of find_program() had some issues: + +```meson +# In a subproject: +exe = executable('foo', ...) +meson.override_find_program('foo', exe) + +# In main project: +# The version check was crashing Meson. +prog = find_program('foo', version : '>=1.0') + +# This was crashing Meson. +message(prog.path()) + +# New method to be consistent with built objects. +message(prog.full_path()) +``` + +## Response files enabled on Linux, reined in on Windows + +Meson used to always use response files on Windows, +but never on Linux. + +It now strikes a happier balance, using them on both platforms, +but only when needed to avoid command line length limits. + +## `unstable-kconfig` module renamed to `unstable-keyval` + +The `unstable-kconfig` module is now renamed to `unstable-keyval`. We +expect this module to become stable once it has some usage experience, +specifically in the next or the following release + + +## Fatal warnings in `gnome.generate_gir()` + +`gnome.generate_gir()` now has `fatal_warnings` keyword argument to +abort when a warning is produced. This is useful for example in CI +environment where it's important to catch potential issues. + +## b_ndebug support for D language compilers + +D Language compilers will now set -release/--release/-frelease (depending on +the compiler) when the b_ndebug flag is set. + +## Meson test now produces JUnit xml from results + +Meson will now generate a JUnit compatible XML file from test results. +it will be in the `meson-logs` directory and is called +`testlog.junit.xml`. + +## Config tool based dependencies no longer search PATH for cross compiling + +Before 0.55.0 config tool based dependencies (llvm-config, +cups-config, etc), would search system $PATH if they weren't defined +in the cross file. This has been a source of bugs and has been +deprecated. It is now removed, config tool binaries must be specified +in the cross file now or the dependency will not be found. + +## Rename has_exe_wrapper -> can_run_host_binaries + +The old name was confusing as it didn't really match the behavior of +the function. The old name remains as an alias (the behavior hasn't +changed), but is now deprecated. + +## String concatenation in meson_options.txt + +It is now possible to use string concatenation (with the `+` +opperator) in the `meson_options.txt` file. This allows splitting long +option descriptions. + +```meson +option( + 'testoption', + type : 'string', + value : 'optval', + description : 'An option with a very long description' + + 'that does something in a specific context' +) +``` + +## Wrap fallback URL + +Wrap files can now define `source_fallback_url` and +`patch_fallback_url` to be used in case the main server is temporaly +down. + +## Clang coverage support + +llvm-cov is now used to generate coverage information when clang is +used as the compiler. + +## Local wrap source and patch files + +It is now possible to use the `patch_filename` and `source_filename` +value in a `.wrap` file without `*_url` to specify a local source / +patch file. All local files must be located in the +`subprojects/packagefiles` directory. The `*_hash` entries are +optional with this setup. + +## Local wrap patch directory + +Wrap files can now specify `patch_directory` instead of +`patch_filename` in the case overlay files are local. Every files in +that directory, and subdirectories, will be copied to the subproject +directory. This can be used for example to add `meson.build` files to +a project not using Meson build system upstream. The patch directory +must be placed in `subprojects/packagefiles` directory. + +## Patch on all wrap types + +`patch_*` keys are not limited to `wrap-file` any more, they can be +specified for all wrap types. + +## link_language argument added to all targets + +Previously the `link_language` argument was only supposed to be +allowed in executables, because the linker used needs to be the linker +for the language that implements the main function. Unfortunately it +didn't work in that case, and, even worse, if it had been implemented +properly it would have worked for *all* targets. In 0.55.0 this +restriction has been removed, and the bug fixed. It now is valid for +`executable` and all derivative of `library`. + +## meson dist --no-tests + +`meson dist` has a new option `--no-tests` to skip build and tests of +generated packages. It can be used to not waste time for example when +done in CI that already does its own testing. + +## Force fallback for + +A newly-added `--force-fallback-for` command line option can now be +used to force fallback for specific subprojects. + +Example: + +``` +meson builddir/ --force-fallback-for=foo,bar +``` + +## Implicit dependency fallback + +`dependency('foo')` now automatically fallback if the dependency is +not found on the system but a subproject wrap file or directory exists +with the same name. + +That means that simply adding `subprojects/foo.wrap` is enough to add +fallback to any `dependency('foo')` call. It is however requires that +the subproject call `meson.override_dependency('foo', foo_dep)` to +specify which dependency object should be used for `foo`. + +## Wrap file `provide` section + +Wrap files can define the dependencies it provides in the `[provide]` +section. When `foo.wrap` provides the dependency `foo-1.0` any call do +`dependency('foo-1.0')` will automatically fallback to that subproject +even if no `fallback` keyword argument is given. See [Wrap +documentation](Wrap-dependency-system-manual.md#provide_section). + +## `find_program()` fallback + +When a program cannot be found on the system but a wrap file has its +name in the `[provide]` section, that subproject will be used as +fallback. + +## Test scripts are given the exe wrapper if needed + +Meson will now set the `MESON_EXE_WRAPPER` as the properly wrapped and +joined representation. For Unix-like OSes this means python's +shelx.join, on Windows an implementation that attempts to properly +quote windows argument is used. This allow wrapper scripts to run test +binaries, instead of just skipping. + +for example, if the wrapper is `['emulator', '--script']`, it will be passed +as `MESON_EXE_WRAPPER="emulator --script"`. + +## Added ability to specify backend arguments in `meson compile` + +It's now possible to specify backend specific arguments in `meson compile`. + +Usage: `meson compile [--vs-args=args] [--ninja-args=args]` + +``` + --ninja-args NINJA_ARGS Arguments to pass to `ninja` (applied only on `ninja` backend). + --vs-args VS_ARGS Arguments to pass to `msbuild` (applied only on `vs` backend). +``` + +These arguments use the following syntax: + +If you only pass a single string, then it is considered to have all +values separated by commas. Thus invoking the following command: + +``` +$ meson compile --ninja-args=-n,-d,explain +``` + +would add `-n`, `-d` and `explain` arguments to ninja invocation. + +If you need to have commas or spaces in your string values, then you +need to pass the value with proper shell quoting like this: + +``` +$ meson compile "--ninja-args=['a,b', 'c d']" +``` + +## Introspection API changes + +dumping the AST (--ast): **new in 0.55.0** +- prints the AST of a meson.build as JSON + +## `--backend=vs` now matches `-Db_vscrt=from_buildtype` behaviour in the Ninja backend + +When `--buildtype=debugoptimized` is used with the Ninja backend, the +VS CRT option used is `/MD`, which is the [behaviour documented for +all +backends](https://mesonbuild.com/Builtin-options.html#b_vscrt-from_buildtype). +However, the Visual Studio backend was pass `/MT` in that case, which +is inconsistent. + +If you need to use the MultiThreaded CRT, you should explicitly pass +`-Db_vscrt=mt` diff --git a/meson/docs/markdown/Release-notes-for-0.56.0.md b/meson/docs/markdown/Release-notes-for-0.56.0.md new file mode 100644 index 000000000..c196fded9 --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.56.0.md @@ -0,0 +1,375 @@ +--- +title: Release 0.56.0 +short-description: Release notes for 0.56.0 +... + +# New features + +## Python 3.5 support will be dropped in the next release + +The final [Python 3.5 release was 3.5.10 in +September](https://www.python.org/dev/peps/pep-0478/#id4). This +release series is now End-of-Life (EOL). The only LTS distribution +that still only ships Python 3.5 is Ubuntu 16.04, which will be [EOL +in April 2021](https://ubuntu.com/about/release-cycle). + +Python 3.6 has numerous features that we find useful such as improved +support for the `typing` module, f-string support, and better +integration with the `pathlib` module. + +As a result, we will begin requiring Python 3.6 or newer in Meson +0.57, which is the next release. Starting with Meson 0.56, we now +print a `NOTICE:` when a `meson` command is run on Python 3.5 to +inform users about this. This notice has also been backported into the +0.55.2 stable release. + +## `meson test` can now filter tests by subproject + +You could always specify a list of tests to run by passing the names +as arguments to `meson test`. If there were multiple tests with that +name (in the same project or different subprojects), all of them would +be run. Now you can: + +1. Run all tests with the specified name from a specific subproject: `meson test subprojname:testname` +1. Run all tests defined in a specific subproject: `meson test subprojectname:` + +As before, these can all be specified multiple times and mixed: + +```sh +# Run: +# * All tests called 'name1' or 'name2' and +# * All tests called 'name3' in subproject 'bar' and +# * All tests in subproject 'foo' +$ meson test name1 name2 bar:name3 foo: +``` + +## Native (build machine) compilers not always required by `project()` + +When cross-compiling, native (build machine) compilers for the +languages specified in `project()` are not required, if no targets use +them. + +## New `extra_files` key in target introspection + +The target introspection (`meson introspect --targets`, +`intro-targets.json`) now has the new `extra_files` key which lists +all files specified via the `extra_files` kwarg of a build target (see +`executable()`, etc.) + + +## Preliminary AIX support + +AIX is now supported when compiling with gcc. A number of features are +not supported yet. For example, only gcc is supported (not xlC). +Archives with both 32-bit and 64-bit dynamic libraries are not +generated automatically. The rpath includes both the build and install +rpath, no attempt is made to change the rpath at install time. Most +advanced features (eg. link\_whole) are not supported yet. + +## Wraps from subprojects are automatically promoted + +It is not required to promote wrap files for subprojects into the main +project any more. When configuring a subproject, Meson will look for +any wrap file or directory in the subproject's `subprojects/` +directory and add them into the global list of available subprojects, +to be used by any future `subproject()` call or `dependency()` +fallback. If a subproject with the same name already exists, the new +wrap file or directory is ignored. That means that the main project +can always override any subproject's wrap files by providing their +own, it also means the ordering in which subprojects are configured +matters, if 2 subprojects provide foo.wrap only the one from the first +subproject to be configured will be used. + +This new behavior can be disabled by passing `--wrap-mode=nopromote`. + +## `meson.build_root()` and `meson.source_root()` are deprecated + +Those function are common source of issue when used in a subproject +because they point to the parent project root which is rarely what is +expected and is a violation of subproject isolation. + +`meson.current_source_dir()` and `meson.current_build_dir()` should be +used instead and have been available in all Meson versions. New +functions `meson.project_source_root()` and +`meson.project_build_root()` have been added in Meson 0.56.0 to get +the root of the current (sub)project. + +## `dep.as_link_whole()` + +Dependencies created with `declare_dependency()` now has new method +`as_link_whole()`. It returns a copy of the dependency object with all +link_with arguments changed to link_whole. This is useful for example +for fallback dependency from a subproject built with +`default_library=static`. + +```meson +somelib = static_library('somelib', ...) +dep = declare_dependency(..., link_with: somelib) +library('someotherlib', ..., dependencies: dep.as_link_whole()) +``` + +## Add support for all Windows subsystem types + +It is now possible to build things like Windows kernel drivers with +the new `win_subsystem` keyword argument. This replaces the old +`gui_app` keyword argument, which is now deprecated. You should update +your project to use the new style like this: + +```meson +# Old way +executable(..., gui_app: 'true') +# New way +executable(..., win_subsystem: 'windows') +``` + +The argument supports versioning [as described on MSDN +documentation](https://docs.microsoft.com/en-us/cpp/build/reference/subsystem-specify-subsystem). +Thus to build a Windows kernel driver with a specific version you'd +write something like this: + +```meson +executable(..., win_subsystem: 'native,6.02') +``` + +## Added NVidia HPC SDK compilers + +Added support for `nvidia_hpc` NVidia HPC SDK compilers, which are currently in public beta testing. + +## Project and built-in options can be set in native or cross files + +A new set of sections has been added to the cross and native files, +`[project options]` and `[<subproject_name>:project options]`, where +`subproject_name` is the name of a subproject. Any options that are +allowed in the project can be set from this section. They have the +lowest precedent, and will be overwritten by command line arguments. + + +```meson +option('foo', type : 'string', value : 'foo') +``` + +```ini +[project options] +foo = 'other val' +``` + +```console +meson builddir/ --native-file my.ini +``` + +Will result in the option foo having the value `other val`, + +```console +meson builddir/ --native-file my.ini -Dfoo='different val' +``` + +Will result in the option foo having the value `different val`, + + +Subproject options are assigned like this: + +```ini +[zlib:project options] +foo = 'some val' +``` + +Additionally Meson level options can be set in the same way, using the +`[built-in options]` section. + +```ini +[built-in options] +c_std = 'c99' +``` + +These options can also be set on a per-subproject basis, although only +`default_library` and `werror` can currently be set: +```ini +[zlib:built-in options] +default_library = 'static' +``` + +## `unstable-keyval` is now stable `keyval` + +The `unstable-keyval` has been renamed to `keyval` and now promises stability +guarantees. + +Meson will print a warning when you load an `unstable-` module that has been +stabilised (so `unstable-keyval` is still accepted for example). + +## CMake subproject cross compilation support + +Meson now supports cross compilation for CMake subprojects. Meson will +try to automatically guess most of the required CMake toolchain +variables from existing entries in the cross and native files. These +variables will be stored in an automatically generate CMake toolchain +file in the build directory. The remaining variables that can't be +guessed can be added by the user in the new `[cmake]` cross/native +file section. + +## Machine file keys are stored case sensitive + +Previous the keys were always lowered, which worked fine for the +values that were allowed in the machine files. With the addition of +per-project options we need to make these sensitive to case, as the +options in meson_options.txt are sensitive to case already. + +## Consistency between `declare_dependency()` and `pkgconfig.generate()` variables + +The `variables` keyword argument in `declare_dependency()` used to +only support dictionary and `pkgconfig.generate()` only list of +strings. They now both support dictionary and list of strings in the +format `'name=value'`. This makes easier to share a common set of +variables for both: + +```meson +vars = {'foo': 'bar'} +dep = declare_dependency(..., variables: vars) +pkg.generate(..., variables: vars) +``` + +## Qt5 compile_translations now supports qresource preprocessing + +When using qtmod.preprocess() in combination with +qtmod.compile_translations() to embed translations using rcc, it is no +longer required to do this: + +```meson +ts_files = ['list', 'of', 'files'] +qtmod.compile_translations(ts_files) +# lang.qrc also contains the duplicated list of files +lang_cpp = qtmod.preprocess(qresources: 'lang.qrc') +``` + +Instead, use: +```meson +lang_cpp = qtmod.compile_translations(qresource: 'lang.qrc') +``` + +which will automatically detect and generate the needed +compile_translations targets. + +## Controlling subproject dependencies with `dependency(allow_fallback: ...)` + +As an alternative to the `fallback` keyword argument to `dependency`, +you may use `allow_fallback`, which accepts a boolean value. If `true` +and the dependency is not found on the system, Meson will fallback to +a subproject that provides this dependency, even if the dependency is +optional. If `false`, Meson will not fallback even if a subproject +provides this dependency. + +## Custom standard library + +- It is not limited to cross builds any more, `<lang>_stdlib` property can be + set in native files. +- The variable name parameter is no longer required as long as the subproject + calls `meson.override_dependency('c_stdlib', mylibc_dep)`. + +## Improvements for the builtin curses dependency + +This method has been extended to use config-tools, and a fallback to +find_library for lookup as well as pkg-config. + +## HDF5 dependency improvements + +HDF5 has been improved so that the internal representations have been +split. This allows selecting pkg-config and config-tool dependencies +separately. Both work as proper dependencies of their type, so +`get_variable` and similar now work correctly. + +It has also been fixed to use the selected compiler for the build instead of +the default compiler. + +## External projects + +A new experimental module `unstable_external_project` has been added +to build code using other build systems than Meson. Currently only +supporting projects with a configure script that generates Makefiles. + +```meson +project('My Autotools Project', 'c', + meson_version : '>=0.56.0', +) + +mod = import('unstable_external_project') + +p = mod.add_project('configure', + configure_options : ['--prefix=@PREFIX@', + '--libdir=@LIBDIR@', + '--incdir=@INCLUDEDIR@', + '--enable-foo', + ], +) + +mylib_dep = p.dependency('mylib') +``` + + +## Per subproject `warning_level` option + +`warning_level` can now be defined per subproject, in the same way as +`default_library` and `werror`. + +## `meson subprojects` command + +A new `--types` argument has been added to all subcommands to run the +command only on wraps with the specified types. For example this +command will only print `Hello` for each git subproject: `meson +subprojects foreach --types git echo "Hello"`. Multiple types can be +set as comma separated list e.g. `--types git,file`. + +Subprojects with no wrap file are now taken into account as well. This +happens for example for subprojects configured as git submodule, or +downloaded manually by the user and placed into the `subprojects/` +directory. + +The `checkout` subcommand now always stash any pending changes before +switching branch. Note that `update` subcommand was already stashing +changes before updating the branch. + +If the command fails on any subproject the execution continues with +other subprojects, but at the end an error code is now returned. + +The `update` subcommand has been reworked: +- In the case the URL of `origin` is different as the `url` set in wrap file, + the subproject will not be updated unless `--reset` is specified (see below). +- In the case a subproject directory exists and is not a git repository but has + a `[wrap-git]`, Meson used to run git commands that would wrongly apply to the + main project. It now skip the subproject unless `--reset` is specified (see below). +- The `--rebase` behaviour is now the default for consistency: it was + already rebasing when current branch and revision are the same, it is + less confusing to rebase when they are different too. +- Add `--reset` mode that checkout the new branch and hard reset that + branch to remote commit. This new mode guarantees that every + subproject are exactly at the wrap's revision. In addition the URL of `origin` + is updated in case it changed in the wrap file. If the subproject directory is + not a git repository but has a `[wrap-git]` the directory is deleted and the + new repository is cloned. +- Local changes are always stashed first to avoid any data loss. In the + worst case scenario the user can always check reflog and stash list to + rollback. + +## Added CompCert C compiler + +Added experimental support for the [CompCert formally-verified C +compiler](https://github.com/AbsInt/CompCert). The current state of +the implementation is good enough to build the [picolibc +project](https://github.com/picolibc/picolibc) with CompCert, but +might still need additional adjustments for other projects. + +## Dependencies listed in test and benchmark introspection + +The introspection data for tests and benchmarks now includes the +target ids for executables and built files that are needed by the +test. IDEs can use this feature to update the build more quickly +before running a test. + +## `include_type` support for the CMake subproject object dependency method + +The `dependency()` method of the CMake subproject object now also +supports the `include_type` kwarg which is similar to the sane kwarg +in the `dependency()` function. + +## Deprecate Dependency.get_pkgconfig_variable and Dependency.get_configtool_variable + +These have been replaced with the more versatile `get_variable()` method +already, and shouldn't be used anymore. diff --git a/meson/docs/markdown/Release-notes-for-0.57.0.md b/meson/docs/markdown/Release-notes-for-0.57.0.md new file mode 100644 index 000000000..595ebec01 --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.57.0.md @@ -0,0 +1,360 @@ +--- +title: Release 0.57.0 +short-description: Release notes for 0.57.0 +... + +# New features + +## Project version can be specified with a file + +Meson can be instructed to load a project's version string from an +external file like this: + +```meson +project('foo', 'c', version: files('VERSION')) +``` + +The version file must contain exactly one line of text which will +be used as the project's version. If the line ends in a newline +character, it is removed. + +## Support for reading files at configuration time with the `fs` module + +Reading text files during configuration is now supported. This can be done at +any time after `project` has been called + +```meson +project('myproject', 'c') +license_text = run_command( + find_program('python3'), '-c', 'print(open("COPYING").read())' +).stdout().strip() +about_header = configuration_data() +about_header.add('COPYRIGHT', license_text) +about_header.add('ABOUT_STRING', meson.project_name()) +... +``` + +There are several problems with the above approach: +1. It's ugly and confusing +2. If `COPYING` changes after configuration, Meson won't correctly rebuild when + configuration data is based on the data in COPYING +3. It has extra overhead + +`fs.read` replaces the above idiom thus: +```meson +project('myproject', 'c') +fs = import('fs') +license_text = fs.read('COPYING').strip() +about_header = configuration_data() +about_header.add('COPYRIGHT', license_text) +about_header.add('ABOUT_STRING', meson.project_name()) +... +``` + +They are not equivalent, though. Files read with `fs.read` create a +configuration dependency on the file, and so if the `COPYING` file is modified, +Meson will automatically reconfigure, guaranteeing the build is consistent. It +can be used for any properly encoded text files. It supports specification of +non utf-8 encodings too, so if you're stuck with text files in a different +encoding, it can be passed as an argument. See the [`meson` +object](Reference-manual.md#meson-object) documentation for details. + +## meson install --dry-run + +New option to meson install command that does not actually install files, but +only prints messages. + +## Experimental support for C++ modules in Visual Studio + +Modules are a new C++ 20 feature for organising source code aiming to +increase compilation speed and reliability. This support is +experimental and may change in future releases. It only works with the +latest preview release of Visual Studio. + +## Qt6 module + +A module for Qt6 is now available with the same functionality as the Qt5 +module. + +Currently finding Qt6 is only available via `qmake` as pkg-config files aren't +generated (see [QTBUG-86080](https://bugreports.qt.io/browse/QTBUG-86080)) and +CMake support is not available for this module yet. + +## Unstable Rust module + +A new unstable module has been added to make using Rust with Meson easier. +Currently, it adds a single function to ease defining Rust tests, as well as a +wrapper around bindgen, making it easier to use. + +## Meson test() now accepts `protocol : 'rust'` + +This allows native Rust tests to be run and parsed by Meson; simply set the +protocol to `rust` and Meson takes care of the rest. + +## MSVC/Clang-Cl Argument Changes/Cleanup + +* "Disable Debug" (`/Od`) is no longer manually specified for optimization levels {`0`,`g`} (it is already the default for MSVC). +* "Run Time Checking" (`/RTC1`) removed from `debug` buildtype by default +* Clang-CL `debug` buildtype arguments now match MSVC arguments +* There is now no difference between `buildtype` flags and `debug` + `optimization` flags + +The /Od flag has been removed, as it is already the default in the MSVC compilers, and conflicts with other user options. + +/RTC1 conflicts with other RTC argument types as there are many different options, and has been removed by default. +Run Time Checking can be enabled by manually adding `/RTC1` or other RTC flags of your choice. + +The `debug` buildtype for clang-cl added additional arguments compared to MSVC, which had more to do with optimization than debug. The arguments removed are `/Ob0`, `/Od`, `/RTC1`. (`/Zi` was also removed, but it is already added by default when debug is enabled.) + +If these are important issues for you and would like builtin toggle options, +please file an issue in the Meson bug tracker. + +## Buildtype remains even if dependent options are changed + +Setting the `buildtype` option to a value sets the `debug` and +`optimization` options to predefined values. Traditionally setting the +options to other values would then change the buildtype to `custom`. +This is confusing and means that you can't use, for example, debug +level `g` in `debug` buildtype even though it would make sense under +many circumstances. + +Starting with this release, the buildtype is only changed when the user +explicitly sets it; setting the build type modifies the `debug` and +`optimization` options as before. + +## Passing internal dependencies to the compiler object + +Methods on the compiler object (such as `compiles`, `links`, `has_header`) +can be passed dependencies returned by `declare_dependency`, as long as they +only specify compiler/linker arguments or other dependencies that satisfy +the same requirements. + +## `unstable_external_project` improvements + +- Default arguments are added to `add_project()` in case some tags are not found + in `configure_options`: `'--prefix=@PREFIX@'`, `'--libdir=@PREFIX@/@LIBDIR@'`, + and `'--includedir=@PREFIX@/@INCLUDEDIR@'`. It was previously considered a fatal + error to not specify them. + +- When the `verbose` keyword argument is not specified, or is false, command outputs + are written on file in `<builddir>/meson-logs/`. + +- The `LD` environment variable is not passed any more when running the configure + script. It caused issues because Meson sets `LD` to the `CC` linker wrapper but + autotools expects it to be a real linker (e.g. `/usr/bin/ld`). + +## `gnome.post_install()` + +Post-install update of various system wide caches. Each script will be executed +only once even if `gnome.post_install()` is called multiple times from multiple +subprojects. If `DESTDIR` is specified during installation all scripts will be +skipped. + +Currently supports `glib-compile-schemas`, `gio-querymodules`, and +`gtk-update-icon-cache`. + +## "Edit and continue" (/ZI) is no longer used by default for Visual Studio + +Meson was adding the `/ZI` compiler argument as an argument for Visual Studio +in debug mode. This enables the `edit-and-continue` debugging in +Visual Studio IDE's. + +Unfortunately, it is also extremely expensive and breaks certain use cases such +as link time code generation. Edit and continue can be enabled by manually by +adding `/ZI` to compiler arguments. + +The `/ZI` argument has now been replaced by the `/Zi` argument for debug builds. + +If this is an important issue for you and would like a builtin toggle option, +please file an issue in the Meson bug tracker. + +## Minimum required Python version updated to 3.6 + +Meson now requires at least Python version 3.6 to run as Python 3.5 +reaches EOL on September 2020. In practice this should only affect +people developing on Ubuntu Xenial, which will similarly reach EOL in +April 2021. + +## Packaging a subproject + +The `meson dist` command can now create a distribution tarball for a subproject +in the same git repository as the main project. This can be useful if parts of +the project (e.g. libraries) can be built and distributed separately. In that +case they can be moved into `subprojects/mysub` and running `meson dist` in that +directory will now create a tarball containing only the source code from that +subdir and not the rest of the main project or other subprojects. + +For example: +```sh +git clone https://github.com/myproject +cd myproject/subprojects/mysubproject +meson builddir +meson dist -C builddir +``` + +## `custom_target()` and `run_target()` now accepts an `env` keyword argument + +Environment variables can now be passed to the `custom_target()` command. + +```meson +env = environment() +env.append('PATH', '/foo') +custom_target(..., env: env) +custom_target(..., env: {'MY_ENV': 'value'}) +custom_target(..., env: ['MY_ENV=value']) +``` + +## `summary()` accepts external programs or dependencies + +External program objects and dependency objects can be passed to +`summary()` as the value to be printed. + +## CMake `find_package` version support + +It is now possible to specify a requested package version for the CMake +dependency backend via the new `cmake_package_version` kwarg in the +`dependency` function. + +## `meson test` only rebuilds test dependencies + +Until now, `meson test` rebuilt the whole project independent of the +requested tests and their dependencies. With this release, `meson test` +will only rebuild what is needed for the tests or suites that will be run. +This feature can be used, for example, to speed up bisecting regressions +using commands like the following: + + git bisect start <broken commit> <working commit> + git bisect run meson test <failing test name> + +This would find the broken commit automatically while at each step +rebuilding only those pieces of code needed to run the test. + +However, this change could cause failures when upgrading to 0.57, if the +dependencies are not specified correctly in `meson.build`. + +## The `add_*_script` methods now accept a File as the first argument + +Meson now accepts `file` objects, including those produced by +`configure_file`, as the first parameter of the various +`add_*_script` methods + +```meson +install_script = configure_file( + configuration : conf, + input : 'myscript.py.in', + output : 'myscript.py', +) + +meson.add_install_script(install_script, other, params) +``` + +## Unity build with Vala disabled + +The approach that meson has used for Vala unity builds is incorrect, we +combine the generated C files like we would any other C file. This is very +fragile however, as the Vala compiler generates helper functions and macros +which work fine when each file is a separate translation unit, but fail when +they are combined. + +## New logging format for `meson test` + +The console output format for `meson test` has changed in several ways. +The major changes are: + +* if stdout is a tty, `meson` includes a progress report. + +* if `--print-errorlogs` is specified, the logs are printed as tests run +rather than afterwards. All the error logs are printed rather than only +the first ten. + +* if `--verbose` is specified and `--num-processes` specifies more than +one concurrent test, test output is buffered and printed after the +test finishes. + +* the console logs include a reproducer command. If `--verbose` is +specified, the command is printed for all tests at the time they start; +otherwise, it is printed for failing tests at the time the test finishes. + +* for TAP and Rust tests, Meson is able to report individual subtests. If +`--verbose` is specified, all tests are reported. If `--print-errorlogs` +is specified, only failures are. + +In addition, if `--verbose` was specified, Meson used not to generate +logs. This limitation has now been removed. + +These changes make the default `ninja test` output more readable, while +`--verbose` output provides detailed, human-readable logs that +are well suited to CI environments. + +## Specify DESTDIR on command line + +`meson install` command now has a `--destdir` argument that overrides `DESTDIR` +from environment. + +## Skip install scripts if DESTDIR is set + +`meson.add_install_script()` now has `skip_if_destdir` keyword argument. If set +to `true` the script won't be run if `DESTDIR` is set during installation. This is +useful in the case the script updates system wide caches, or performs other tasks +that are only needed when copying files into final destination. + +## Add support for prelinked static libraries + +The static library gains a new `prelink` keyword argument that can be +used to prelink object files in that target. This is currently only +supported for the GNU toolchain, patches to add it to other compilers +are most welcome. + +## Rust now has an `std` option + +Rust calls these `editions`, however, Meson generally refers to such language +versions as "standards", or `std` for short. Therefore, Meson's Rust support +uses `std` for consistency with other languages. + +## Ctrl-C behavior in `meson test` + +Starting from this version, sending a `SIGINT` signal (or pressing `Ctrl-C`) +to `meson test` will interrupt the longest running test. Pressing `Ctrl-C` +three times within a second will exit `meson test`. + +## Support added for LLVM's thinLTO + +A new `b_lto_mode` option has been added, which may be set to `default` or +`thin`. Thin only works for clang, and only with gnu gold, lld variants, or +ld64. + +## `test()` timeout and timeout_multiplier value <= 0 + +`test(..., timeout: 0)`, or negative value, used to abort the test immediately +but now instead allow infinite duration. Note that omitting the `timeout` +keyword argument still defaults to 30s timeout. + +Likewise, `add_test_setup(..., timeout_multiplier: 0)`, or +`meson test --timeout-multiplier 0`, or negative value, disable tests timeout. + + +## Knob to control LTO thread + +Both the gnu linker and lld support using threads for speeding up LTO, meson +now provides a knob for this: `-Db_lto_threads`. Currently this is only +supported for clang and gcc. Any positive integer is supported, `0` means +`auto`. If the compiler or linker implements it's on `auto` we use that, +otherwise the number of threads on the machine is used. + +## `summary()` now uses left alignment for both keys and values + +Previously it aligned keys toward the center, but this was deemed harder +to read than having everything left aligned. + +## `//` is now allowed as a function id for `meson rewrite`. + +msys bash may expand `/` to a path, breaking +`meson rewrite kwargs set project / ...`. Passing `//` will be converted to +`/` by msys bash but in order to keep usage shell-agnostic, this release +also allows `//` as the id. This way, `meson rewrite kwargs set project +// ...` will work in both msys bash and other shells. + +## Get keys of configuration data object + +All keys of the `configuration_data` object can be obtained with the `keys()` +method as an alphabetically sorted array. + diff --git a/meson/docs/markdown/Release-notes-for-0.58.0.md b/meson/docs/markdown/Release-notes-for-0.58.0.md new file mode 100644 index 000000000..9a23abb7f --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.58.0.md @@ -0,0 +1,357 @@ +--- +title: Release 0.58.0 +short-description: Release notes for 0.58.0 +... + +# New features + +## New `meson.global_build_root()` and `meson.global_source_root()` methods + +Returns the root source and build directory of the main project. + +Those are direct replacement for `meson.build_root()` and `meson.source_root()` +that have been deprecated since 0.56.0. In some rare occasions they could not be +replaced by `meson.project_source_root()` or `meson.current_source_dir()`, in +which case the new methods can now be used instead. Old methods are still +deprecated because their names are not explicit enough and created many issues +when a project is being used as a subproject. + +## Developer environment + +New method `meson.add_devenv()` adds an [`environment()`](#environment) object +to the list of environments that will be applied when using `meson devenv` +command line. This is useful for developpers who wish to use the project without +installing it, it is often needed to set for example the path to plugins +directory, etc. Alternatively, a list or dictionary can be passed as first +argument. + +``` meson +devenv = environment() +devenv.set('PLUGINS_PATH', meson.current_build_dir()) +... +meson.add_devenv(devenv) +``` + +New command line has been added: `meson devenv -C builddir [<command>]`. +It runs a command, or open interactive shell if no command is provided, with +environment setup to run project from the build directory, without installation. + +These variables are set in environment in addition to those set using `meson.add_devenv()`: +- `MESON_DEVENV` is defined to `'1'`. +- `MESON_PROJECT_NAME` is defined to the main project's name. +- `PKG_CONFIG_PATH` includes the directory where Meson generates `-uninstalled.pc` + files. +- `PATH` includes every directory where there is an executable that would be + installed into `bindir`. On windows it also includes every directory where there + is a DLL needed to run those executables. +- `LD_LIBRARY_PATH` includes every directory where there is a shared library that + would be installed into `libdir`. This allows to run system application using + custom build of some libraries. For example running system GEdit when building + GTK from git. On OSX the environment variable is `DYLD_LIBRARY_PATH` and + `PATH` on Windows. +- `GI_TYPELIB_PATH` includes every directory where a GObject Introspection + typelib is built. This is automatically set when using `gnome.generate_gir()`. + +## `-pipe` no longer used by default + +Meson used to add the `-pipe` command line argument to all compilers +that supported it, but no longer does. If you need this, then you can +add it manually. However note that you should not do this unless you +have actually measured that it provides performance improvements. In +our tests we could not find a case where adding `-pipe` made +compilation faster and using `-pipe` [can cause sporadic build +failures in certain +cases](https://github.com/mesonbuild/meson/issues/8508). + +## `meson.add_dist_script()` allowd in subprojects + +`meson.add_dist_script()` can now 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 are 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>`. + +Note that existing dist scripts likely need to be modified to use those new +environment variables instead of `MESON_DIST_ROOT` to work properly when used +from a subproject. + +## Do not add custom target dir to header path if `implicit_include_directories` is `false` + +If you do the following: + +```meson +# in some subdirectory +gen_h = custom_target(...) +# in some other directory +executable('foo', 'foo.c', gen_h) +``` + +then the output directory of the custom target is automatically added +to the header search path. This is convenient, but sometimes it can +lead to problems. Starting with this version, the directory will no +longer be put in the search path if the target has +`implicit_include_directories: false`. In these cases you need to set +up the path manually with `include_directories`. + +## Multiple append() and prepend() in `environment()` object + +`append()` and `prepend()` methods can now be called multiple times +on the same `varname`. Earlier Meson versions would warn and only the last +opperation was taking effect. + +```meson +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') +``` + + +## `dep.get_variable(varname)` + +`dep.get_variable()` now has `varname` as first positional argument. +It is used as default value for `cmake`, `pkgconfig`, `configtool` and `internal` +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')`. + + +## clang-format include and ignore lists + +When clang-format is installed and a `.clang-format` file is found at the main +project's root source directory, Meson automatically adds a `clang-format` target +that reformat all C and C++ files. + +It is now possible to restrict files to be reformatted with optional +`.clang-format-include` and `.clang-format-ignore` files. + +The file `.clang-format-include` contains a list of patterns matching the files +that will be reformatted. The `**` pattern matches this directory and all +subdirectories recursively. Empty lines and lines starting with `#` are ignored. +If `.clang-format-include` is not found, the pattern defaults to `**/*` which +means all files recursively in the source directory but has the disadvantage to +walk the whole source tree which could be slow in the case it contains lots of +files. + +Example of `.clang-format-include` file: +``` +# All files in src/ and its subdirectories +src/**/* + +# All files in include/ but not its subdirectories +include/* +``` + +The file `.clang-format-ignore` contains a list of patterns matching the files +that will be excluded. Files matching the include list (see above) that match +one of the ignore pattern will not be reformatted. Unlike include patters, ignore +patterns does not support `**` and a single `*` match any characters including +path separators. Empty lines and lines starting with `#` are ignored. + +The build directory and file without a well known C or C++ suffix are always +ignored. + +Example of `.clang-format-ignore` file: +``` +# Skip C++ files in src/ directory +src/*.cpp +``` + +A new target `clang-format-check` has been added. It returns an error code if +any file needs to be reformatted. This is intended to be used by CI. + +## Introducing format strings to the Meson language + +In addition to the conventional `'A string @0@ to be formatted @1@'.format(n, m)` +method of formatting strings in the Meson language, there's now the additional +`f'A string @n@ to be formatted @m@'` notation that provides a non-positional +and clearer alternative. Meson's format strings are currently restricted to +identity-expressions, meaning `f'format @'m' + 'e'@'` will not parse. + +## Skip subprojects installation + +It is now possible to skip installation of some or all subprojects. This is +useful when subprojects are internal dependencies static linked into the main +project. + +By default all subprojects are still installed. +- `meson install -C builddir --skip-subprojects` installs only the main project. +- `meson install -C builddir --skip-subprojects foo,bar` installs the main project + and all subprojects except for subprojects `foo` and `bar` if they are used. + +## String `.replace()` + +String objects now have a method called replace for replacing all instances of a +substring in a string with another. + +```meson +s = 'aaabbb' +s = s.replace('aaa', 'bbb') +# 's' is now 'bbbbbb' +``` + +## `meson.get_cross_property()` has been deprecated + +It's a pure subset of `meson.get_external_property`, and works strangely in +host == build configurations, since it would be more accurately described as +`get_host_property`. + +## New `range()` function + +``` meson + rangeobject range(stop) + rangeobject range(start, stop[, step]) +``` + +Return an opaque object that can be only be used in `foreach` statements. +- `start` must be integer greater or equal to 0. Defaults to 0. +- `stop` must be integer greater or equal to `start`. +- `step` must be integer greater or equal to 1. Defaults to 1. + +It cause the `foreach` loop to be called with the value from `start` included +to `stop` excluded with an increment of `step` after each loop. + +```meson +# 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. +```meson +r = range(5, 10, 2) +assert(r[2] == 9) +``` + + +## Xcode improvements + +The Xcode backend has been much improved and should now we usable +enough for day to day development. + +## Use fallback from wrap file when force fallback + +Optional dependency like below will now fallback to the subproject +defined in the wrap file in the case `wrap_mode` is set to `forcefallback` +or `force_fallback_for` contains the subproject. + +```meson +# required is false because we could fallback to cc.find_library(), but in the +# forcefallback case this now configure the subproject. +dep = dependency('foo-1.0', required: false) +if not dep.found() + dep = cc.find_library('foo', has_headers: 'foo.h') +endif +``` + +```ini +[wrap-file] +... +[provide] +dependency_names = foo-1.0 +``` + +## `error()` with multiple arguments + +Just like `warning()` and `message()`, `error()` can now take more than one +argument that will be separated by space. + +## Specify man page locale during installation + +Locale directories can now be passed to `install_man`: + +```meson +# instead of +# install_data('foo.fr.1', install_dir: join_paths(get_option('mandir'), 'fr', 'man1'), rename: 'foo.1')` +install_man('foo.fr.1', locale: 'fr') +``` + +## Passing `custom_target()` output to `pkg.generate()` + +It is now allowed to pass libraries generated by a `custom_target()` to +pkg-config file generator. The output filename must have a known library extension +such as `.a`, `.so`, etc. + +## JDK System Dependency + +When building projects such as those interacting with the JNI, you need access +to a few header files located in a Java installation. This system dependency +will add the correct include paths to your target. It assumes that either +`JAVA_HOME` will be set to a valid Java installation, or the default `javac` on +your system is a located in the `bin` directory of a Java installation. Note: +symlinks are resolved. + +```meson +jdk = dependency('jdk', version : '>=1.8') +``` + +Currently this system dependency only works on `linux`, `win32`, and `darwin`. +This can easily be extended given the correct information about your compiler +and platform in an issue. + +## `meson subprojects update --reset` now re-extract tarballs + +When using `--reset` option, the source tree of `[wrap-file]` subprojects is now +deleted and re-extracted from cached tarballs, or re-downloaded. This is because +Meson has no way to know if the source tree or the wrap file has been modified, +and `--reset` should guarantee that latest code is being used on next reconfigure. + +Use `--reset` with caution if you do local changes on non-git subprojects. + +## Allow using generator with CustomTaget or Index of CustomTarget. + +Calling `generator.process()` with either a CustomTaget or Index of CustomTarget +as files is now permitted. + +## Qt Dependency uses a Factory + +This separates the Pkg-config and QMake based discovery methods into two +distinct classes in the backend. This allows using +`dependency.get_variable()` and `dependency.get_pkg_config_variable()`, as +well as being a cleaner implementation. + +## Purge subprojects folder + +It is now possible to purge a subprojects folder of artifacts created +from wrap-based subprojects including anything in `packagecache`. This is useful +when you want to return to a completely clean source tree or busting caches with +stale patch directories or caches. By default the command will only print out +what it is removing. You need to pass `--confirm` to the command for actual +artifacts to be purged. + +By default all wrap-based subprojects will be purged. + +- `meson subprojects purge` prints non-cache wrap artifacts which will be +purged. +- `meson subprojects purge --confirm` purges non-cache wrap artifacts. +- `meson subprojects purge --confirm --include-cache` also removes the cache +artifacts. +- `meson subprojects purge --confirm subproj1 subproj2` removes non-cache wrap +artifacts associated with the listed subprojects. + +## Check if native or cross-file properties exist + +It is now possible to check whether a native property or a cross-file property +exists with `meson.has_external_property('foo')`. This is useful if the +property in question is a boolean and one wants to distinguish between +"set" and "not provided" which can't be done the usual way by passing a +fallback parameter to `meson.get_external_property()` in this particular case. + +## `summary()` accepts features + +Build feature options can be passed to `summary()` as the value to be printed. + +## Address sanitizer support for Visual Studio + +The `b_sanitize` option for enabling Address sanitizer now works with +the Visual Studio compilers. This requires [a sufficiently new version +of Visual +Studio](https://devblogs.microsoft.com/cppblog/address-sanitizer-for-msvc-now-generally-available/). + diff --git a/meson/docs/markdown/Release-notes-for-0.59.0.md b/meson/docs/markdown/Release-notes-for-0.59.0.md new file mode 100644 index 000000000..b6ce6541c --- /dev/null +++ b/meson/docs/markdown/Release-notes-for-0.59.0.md @@ -0,0 +1,235 @@ +--- +title: Release 0.59.0 +short-description: Release notes for 0.59.0 +... + +# New features + +## Unescaped variables in pkgconfig files + +Spaces in variable values are escaped with `\`, this is required in the case the +value is a path that and is used in `cflags` or `libs` arguments. This was an +undocumented behaviour that caused issues in the case the variable is a space +separated list of items. + +For backward compatibility reasons this behaviour could not be changed, new +keyword arguments have thus been added: `unescaped_variables` and +`unescaped_uninstalled_variables`. + +```meson +pkg = import('pkgconfig') +... +pkg.generate(lib, + variables: { + 'mypath': '/path/with spaces/are/escaped', + }, + unescaped_variables: { + 'mylist': 'Hello World Is Not Escaped', + }, +) +``` + +## The custom_target() function now accepts a feed argument + +It is now possible to provide a `feed: true` argument to `custom_target()` to +pipe the target's input file to the program's standard input. + +## Separate functions for qt preprocess + +`qt.preprocess` is a large, complicated function that does a lot of things, +a new set of `compile_*` functions have been provided as well. These are +conceptually simpler, as they do a single thing. + +## Cython as as first class language + +Meson now supports Cython as a first class language. This means you can write: + +```meson +project('my project', 'cython') + +py = import('python').find_installation() +dep_py = py.dependency() + +py.extension_module( + 'foo', + 'foo.pyx', + dependencies : dep_py, +) +``` + +And avoid the step through a generator that was previously required. + +## Support for the Wine Resource Compiler + +Users can now choose `wrc` as the `windres` binary in their cross files and +`windows.compile_resources` will handle it correctly. Together with `winegcc` +patches in Wine 6.12 this enables basic support for compiling projects as a +winelib by specifying `winegcc`/`wineg++` as the compiler and `wrc` as the +resource compiler in a cross file. + +## New `vs2012` and `vs2013` backend options + +Adds the ability to generate Visual Studio 2012 and 2013 projects. This is an +extension to the existing Visual Studio 2010 projects so that it is no longer +required to manually upgrade the generated Visual Studio 2010 projects. + +Generating Visual Studio 2010 projects has also been fixed since its developer +command prompt does not provide a `%VisualStudioVersion%` envvar. + +## Developer environment + +Expand the support for the `link_whole:` project option for pre-Visual Studio 2015 +Update 2, where previously Visual Studio 2015 Update 2 or later was required for +this, for the Ninja backend as well as the vs2010 (as well as the newly-added +vs2012 and vs2013 backends). + +## Fs Module now accepts files objects + +It is now possible to define a `files()` object and run most Fs module +functions on the file, rather than passing a string and hoping it is in the +same directory. + + +## Compiler argument checking for `get_supported_arguments` + +The compiler method `get_supported_arguments` now supports +a new keyword argument named `checked` that can be set to +one of `warn`, `require` or `off` (defaults to `off`) to +enforce argument checks. + +## New custom dependency for libintl + +Meson can now find the library needed for translating messages via gettext. +This works both on systems where libc provides gettext, such as GNU or musl, +and on systems where the gettext project's standalone intl support library is +required, such as macOS. + +Rather than doing something such as: + +``` +intl_dep = dependency('', required: false) + +if cc.has_function('ngettext') + intl_found = true +else + intl_dep = cc.find_library('intl', required: false) + intl_found = intl_dep.found() +endif + +if intl_found + # build options that need gettext + conf.set('ENABLE_NLS', 1) +endif +``` + +one may simply use: + +``` +intl_dep = dependency('intl') + +if intl_dep.found() + # build options that need gettext + conf.set('ENABLE_NLS', 1) +endif +``` + +## Parallelized `meson subprojects` commands + +All `meson subprojects` commands are now run on each subproject in parallel by +default. The number of processes can be controlled with `--num-processes` +argument. + +This speeds up considerably IO-bound operations such as downloads and git fetch. + +## Using Vala no longer requires C in the project languages + +Meson will now add C automatically. Since the use of C is an implementation +detail of Vala, Meson shouldn't require users to add it. + +## The `import()` function gains `required` and `disabler` arguments + +In addition, modules now have a `found()` method, like programs and +dependencies. This allows them to be conditionally required, and used in most +places that an object with a `found()` method can be. + +## Objective C/C++ standard versions + +Objective C and C++ compilations will from now on use the language +versions set in `c_std` and `cpp_std`, respectively. It is not +possible to set the language version separately for Objective C and +plain C. + +## Qt.preprocess source arguments deprecated + +The `qt.preprocess` method currently has this signature: +`qt.preprocess(name: str | None, *srcs: str)`, this is not a nice signature +because it's confusing, and there's a `sources` keyword argument as well. +Both of these pass sources through unmodified, this is a bit of a historical +accident, and not the way that any other module works. These have been +deprecated, so instead of: +```meson +sources = qt.preprocess( + name, + list, of, sources, + sources : [more, sources], + ... # things to process, +) + +executable( + 'foo', + sources, +) +``` +use +```meson +processed = qt.preprocess( + name, + ... # thins to process +) + +executable( + 'foo', + 'list', 'of', 'sources', 'more', 'sources', processed, +) +``` + +## New `build target` methods + +The [`build target` object](Reference-manual.md#build-target-object) now supports +the following two functions, to ensure feature compatebility with +[`external program` objects](Reference-manual.html#external-program-object): + +- `found()`: Always returns `true`. This function is meant + to make executables objects feature compatible with + `external program` objects. This simplifies + use-cases where an executable is used instead of an external program. + +- `path()`: **(deprecated)** does the exact same as `full_path()`. + **NOTE:** This function is solely kept for compatebility + with `external program` objects. It will be + removed once the, also deprecated, corresponding `path()` function in the + `external program` object is removed. + +## Automatically set up Visual Studio environment + +When Meson is run on Windows it will automatically set up the +environment to use Visual Studio if no other compiler toolchain +can be detected. This means that you can run Meson commands from +any command prompt or directly from any IDE. This sets up the +64 bit native environment. If you need any other, then you +need to set it up manually as before. + +## `gnome.compile_schemas()` sets `GSETTINGS_SCHEMA_DIR` into devenv + +When using `gnome.compile_schemas()` the location of the compiled schema is +added to `GSETTINGS_SCHEMA_DIR` environment variable when using +[`meson devenv`](Commands.md#devenv) command. + +## `update_desktop_database` added to `gnome.post_install()` + +Applications that install a `.desktop` file containing a `MimeType` need to update +the cache upon installation. Most applications do that using a custom script, +but it can now be done by Meson directly. + +See [`gnome.post_install()`](Gnome-module.md#gnomepost_install). + diff --git a/meson/docs/markdown/Release-notes.md b/meson/docs/markdown/Release-notes.md new file mode 100644 index 000000000..d7de275fc --- /dev/null +++ b/meson/docs/markdown/Release-notes.md @@ -0,0 +1 @@ +# Release notes diff --git a/meson/docs/markdown/Release-procedure.md b/meson/docs/markdown/Release-procedure.md new file mode 100644 index 000000000..a7ef689c6 --- /dev/null +++ b/meson/docs/markdown/Release-procedure.md @@ -0,0 +1,69 @@ +# Release procedure + +**This page is WIP. The following procedure is not yet approved for use** + +# Trunk + +Meson operates under the principle that trunk should (in theory) be +always good enough for release. That is, all code merged in trunk must +pass all unit tests. Any broken code should either be fixed or +reverted immediately. + +People who are willing to tolerate the occasional glitch should be +able to use Meson trunk for their day to day development if they so +choose. + +# Major releases + +Major releases are currently in the form 0.X.0, where X is an +increasing number. We aim to do a major release roughly once a month, +though the schedule is not set in stone. + +Before a major release is made a stable branch will be made, and +0.X.0-rc1 release candidate will be made. A new milestone for 0.X.0 +will be made, and all bugs effecting the RC will be assigned to this +milestone. Patches fixing bugs in the milestone will be picked to the +stable branch, and normal development will continue on the master +branch. Every week after after this a new release candidate will be +made until all bugs are resolved in that milestone. When all of the +bugs are fixed the 0.X.0 release will be made. + +# Bugfix releases + +Bugfix releases contain only minor fixes to major releases and are +designated by incrementing the last digit of the version number. The +criteria for a bug fix release is one of the following: + + - release has a major regression compared to the previous release (making + existing projects unbuildable) + - the release has a serious bug causing data loss or equivalent + - other unforeseen major issue + +In these cases a bug fix release can be made. It shall contain _only_ +the fix for the issue (or issues) in question and other minor bug +fixes. Only changes that have already landed in trunk will be +considered for inclusion. No new functionality shall be added. + +# Requesting a bug fix release + +The process for requesting that a bug fix release be made goes roughly +as follows: + + - file a bug about the core issue + - file a patch fixing it if possible + - contact the development team and request a bug fix release (IRC is the + preferred contact medium) + +The request should contain the following information: + + - the issue in question + - whether it has already caused problems for real projects + - an estimate of how many people and projects will be affected + +There is no need to write a long and complicated request report. +Something like the following is sufficient: + +> The latest release has a regression where trying to do Foo using Bar +breaks. This breaks all projects that use both, which includes at +least [list of affected projects]. This causes problems for X amount +of people and because of this we should do a bugfix release. diff --git a/meson/docs/markdown/Reproducible-builds.md b/meson/docs/markdown/Reproducible-builds.md new file mode 100644 index 000000000..1e00feae8 --- /dev/null +++ b/meson/docs/markdown/Reproducible-builds.md @@ -0,0 +1,20 @@ +# Reproducible builds + +A reproducible build means the following (as quoted from [the +reproducible builds project site](https://reproducible-builds.org/)): + +> Reproducible builds are a set of software development practices that + create a verifiable path from human readable source code to the + binary code used by computers. + +Roughly what this means is that if two different people compile the +project from source, their outputs are bitwise identical to each +other. This allows people to verify that binaries downloadable from +the net actually come from the corresponding sources and have not, for +example, had malware added to them. + +Meson aims to support reproducible builds out of the box with zero +additional work (assuming the rest of the build environment is set up +for reproducibility). If you ever find a case where this is not +happening, it is a bug. Please file an issue with as much information +as possible and we'll get it fixed. diff --git a/meson/docs/markdown/Rewriter.md b/meson/docs/markdown/Rewriter.md new file mode 100644 index 000000000..018434f2b --- /dev/null +++ b/meson/docs/markdown/Rewriter.md @@ -0,0 +1,247 @@ +--- +short-description: Automatic modification of the build system files +... + +# Meson file rewriter + +Since version 0.50.0, Meson has the functionality to perform some +basic modification on the `meson.build` files from the command line. +The currently supported operations are: + +- For build targets: + - Add/Remove source files + - Add/Remove targets + - Modify a select set of kwargs + - Print some JSON information +- For dependencies: + - Modify a select set of kwargs +- For the project function: + - Modify a select set of kwargs + - Modify the default options list + +The rewriter has both, a normal command line interface and a "script +mode". The normal CLI is mostly designed for everyday use. The "script +mode", on the other hand, is meant to be used by external programs +(IDEs, graphical frontends, etc.) + +The rewriter itself is considered stable, however the user interface +and the "script mode" API might change in the future. These changes +may also break backwards comaptibility to older releases. + +We are also open to suggestions for API improvements. + +## Using the rewriter + +All rewriter functions are accessed via `meson rewrite`. The Meson +rewriter assumes that it is run inside the project root directory. If +this isn't the case, use `--sourcedir` to specify the actual project +source directory. + +### Adding and removing sources + +The most common operations will probably be the adding and removing of source +files to a build target. This can be easily done with: + +```bash +meson rewrite target <target name/id> {add/rm} [list of sources] +``` + +For instance, given the following example + +```meson +src = ['main.cpp', 'fileA.cpp'] + +exe1 = executable('testExe', src) +``` + +the source `fileB.cpp` can be added with: + +```bash +meson rewrite target testExe add fileB.cpp +``` + +After executing this command, the new `meson.build` will look like this: + +```meson +src = ['main.cpp', 'fileA.cpp', 'fileB.cpp'] + +exe1 = executable('testExe', src) +``` + +In this case, `exe1` could also have been used for the target name. +This is possible because the rewriter also searches for assignments +and unique Meson IDs, which can be acquired with introspection. If +there are multiple targets with the same name, Meson will do nothing +and print an error message. + +For more information see the help output of the rewriter target +command. + +### Setting the project version + +It is also possible to set kwargs of specific functions with the +rewriter. The general command for setting or removing kwargs is: + +```bash +meson rewrite kwargs {set/delete} <function type> <function ID> <key1> <value1> <key2> <value2> ... +``` + +For instance, setting the project version can be achieved with this command: + +```bash +meson rewrite kwargs set project / version 1.0.0 +``` + +Currently, only the following function types are supported: + +- dependency +- target (any build target, the function ID is the target name/ID) +- project (the function ID must be `/` since project() can only be called once) + +For more information see the help output of the rewrite kwargs command. + +Note msys bash may expand `/` to a path. Passing `//` will be +converted to `/` by msys bash but in order to keep usage +shell-agnostic, the rewrite command also allows `//` as the function +ID such that it will work in both msys bash and other shells. + +### Setting the project default options + +For setting and deleting default options, use the following command: + +```bash +meson rewrite default-options {set/delete} <opt1> <value1> <opt2> <value2> ... +``` + +## Limitations + +Rewriting a Meson file is not guaranteed to keep the indentation of +the modified functions. Additionally, comments inside a modified +statement will be removed. Furthermore, all source files will be +sorted alphabetically. + +For instance adding `e.c` to srcs in the following code + +```meson +# Important comment + +srcs = [ +'a.c', 'c.c', 'f.c', +# something important about b + 'b.c', 'd.c', 'g.c' +] + +# COMMENT +``` + +would result in the following code: + +```meson +# Important comment + +srcs = [ + 'a.c', + 'b.c', + 'c.c', + 'd.c', + 'e.c', + 'f.c', + 'g.c' +] + +# COMMENT +``` + +## Using the "script mode" + +The "script mode" should be the preferred API for third party +programs, since it offers more flexibility and higher API stability. +The "scripts" are stored in JSON format and executed with `meson +rewrite command <JSON file or string>`. + +The JSON format is defined as follows: + +```json +[ + { + "type": "function to execute", + ... + }, { + "type": "other function", + ... + }, + ... +] +``` + +Each object in the main array must have a `type` entry which specifies which +function should be executed. + +Currently, the following functions are supported: + +- target +- kwargs +- default_options + +### Target modification format + +The format for the type `target` is defined as follows: + +```json +{ + "type": "target", + "target": "target ID/name/assignment variable", + "operation": "one of ['src_add', 'src_rm', 'target_rm', 'target_add', 'info']", + "sources": ["list", "of", "source", "files", "to", "add, remove"], + "subdir": "subdir where the new target should be added (only has an effect for operation 'tgt_add')", + "target_type": "function name of the new target -- same as in the CLI (only has an effect for operation 'tgt_add')" +} +``` + +The keys `sources`, `subdir` and `target_type` are optional. + +### kwargs modification format + +The format for the type `target` is defined as follows: + +```json +{ + "type": "kwargs", + "function": "one of ['dependency', 'target', 'project']", + "id": "function ID", + "operation": "one of ['set', 'delete', 'add', 'remove', 'remove_regex', 'info']", + "kwargs": { + "key1": "value1", + "key2": "value2", + ... + } +} +``` + +### Default options modification format + +The format for the type `default_options` is defined as follows: + +```json +{ + "type": "default_options", + "operation": "one of ['set', 'delete']", + "options": { + "opt1": "value1", + "opt2": "value2", + ... + } +} +``` + +For operation `delete`, the values of the `options` can be anything +(including `null`) + +## Extracting information + +The rewriter also offers operation `info` for the types `target` and +`kwargs`. When this operation is used, Meson will print a JSON dump to +stderr, containing all available information to the rewriter about the +build target / function kwargs in question. + +The output format is currently experimental and may change in the future. diff --git a/meson/docs/markdown/Run-targets.md b/meson/docs/markdown/Run-targets.md new file mode 100644 index 000000000..04959ab3b --- /dev/null +++ b/meson/docs/markdown/Run-targets.md @@ -0,0 +1,55 @@ +--- +short-description: Targets to run external commands +... + +# Run targets + +Sometimes you need to have a target that just runs an external +command. As an example you might have a build target that reformats +your source code, runs `cppcheck` or something similar. In Meson this +is accomplished with a so called *run target*. + +The recommended way of doing this is writing the command(s) you want +to run to a script file. Here's an example script. + +```bash +#!/bin/sh + +cd "${MESON_SOURCE_ROOT}" +inspector_command -o "${MESON_BUILD_ROOT}/inspection_result.txt" +``` + +Note the two environment variables `MESON_SOURCE_ROOT` and +`MESON_BUILD_ROOT`. These are absolute paths to your project's source +and build directories and they are automatically set up by Meson. In +addition to these Meson also sets up the variable `MESON_SUBDIR`, +which points to the subdirectory where the run command was specified. +Most commands don't need to set up this. + +Note how the script starts by cd'ing into the source dir. Meson does +not guarantee that the script is run in any specific directory. +Whether you need to do the same depends on what your custom target +wants to do. + +To make this a run target we write it to a script file called +`scripts/inspect.sh` and specify it in the top level Meson file like +this. + +```meson +run_target('inspector', + command : 'scripts/inspect.sh') +``` + +Run targets are not run by default. To run it run the following command. + +```console +$ meson compile inspector +``` + +All additional entries in `run_target`'s `command` array are passed +unchanged to the inspector script, so you can do things like this: + +```meson +run_target('inspector', + command : ['scripts/inspect.sh', '--exclude', 'tests']) +``` diff --git a/meson/docs/markdown/Running-Meson.md b/meson/docs/markdown/Running-Meson.md new file mode 100644 index 000000000..2873cbc1b --- /dev/null +++ b/meson/docs/markdown/Running-Meson.md @@ -0,0 +1,210 @@ +--- +short-description: Building a project with Meson +... + +# Running Meson + +There are two different ways of invoking Meson. First, you can run it +directly from the source tree with the command +`/path/to/source/meson.py`. Second, Meson may also be installed in which case +the command is simply `meson`. In this manual we only use the latter +format for simplicity. + +At the time of writing only a command line version of Meson is +available. This means that Meson must be invoked using the terminal. +If you wish to use the MSVC compiler, you need to run Meson under +"Visual Studio command prompt". + +All available Meson commands are listed on the [commands reference +page](Commands.md). + +## Configuring the build directory + +Let us assume that we have a source tree that has a Meson build +system. This means that at the topmost directory has a file called +`meson.build`. We run the following commands to get the build started. + +```sh +cd /path/to/source/root +meson setup builddir +``` + +We invoke Meson with the `setup` command, giving it the location of the build +directory. Meson uses [out of source +builds](http://voices.canonical.com/jussi.pakkanen/2013/04/16/why-you-should-consider-using-separate-build-directories/). + +Hint: The syntax of Meson is `meson [command] [arguments] [options]`. +The `setup` command takes a `builddir` and a `srcdir` argument. If no +`srcdir` is given Meson will deduce the `srcdir` based on `pwd` and +the location of `meson.build`. + +Meson then loads the build configuration file and writes the +corresponding build backend in the build directory. By default Meson +generates a *debug build*, which turns on basic warnings and debug +information and disables compiler optimizations. + +Additionally, the invocation can pass options to Meson. The list of +options is documented [here](Builtin-options.md). + +You can specify a different type of build with the `--buildtype` command line +argument. It can have one of the following values. + +| value | meaning | +| ------ | -------- | +| `plain` | no extra build flags are used, even for compiler warnings, useful for distro packagers and other cases where you need to specify all arguments by yourself | +| `debug` | debug info is generated but the result is not optimized, this is the default | +| `debugoptimized` | debug info is generated and the code is optimized (on most compilers this means `-g -O2`) | +| `release` | full optimization, no debug info | + +The build directory is mandatory. The reason for this is that it +simplifies the build process immensely. Meson will not, under any +circumstances, write files inside the source directory (if it does, it +is a bug and should be fixed). This means that the user does not need +to add a bunch of files to their revision control's ignore list. It +also means that you can create arbitrarily many build directories for +any given source tree. + +For example, if we wanted to test building the source code with the +Clang compiler instead of the system default, we could just type the +following commands: + +```sh +cd /path/to/source/root +CC=clang CXX=clang++ meson setup buildclang +``` + +This separation is even more powerful if your code has multiple +configuration options (such as multiple data backends). You can create +a separate subdirectory for each of them. You can also have build +directories for optimized builds, code coverage, static analysis and +so on. They are all neatly separated and use the same source tree. +Changing between different configurations is just a question of +changing to the corresponding directory. + +Unless otherwise mentioned, all following command line invocations are +meant to be run in the source directory. + +By default, Meson will use the Ninja backend to build your project. If +you wish to use any of the other backends, you need to pass the +corresponding argument during configuration time. As an example, here +is how you would use Meson to generate a Visual Studio solution. + +```sh +meson setup <build dir> --backend=vs +``` + +You can then open the generated solution with Visual Studio and +compile it in the usual way. A list of backends can be obtained with +`meson setup --help`. + +## Environment variables + +Sometimes you want to add extra compiler flags, this can be done by +passing them in environment variables when calling Meson. See [the +reference +tables](Reference-tables.md#compiler-and-linker-flag-environment-variables) +for a list of all the environment variables. Be aware however these +environment variables are only used for the native compiler and will +not affect the compiler used for cross-compiling, where the flags +specified in the cross file will be used. + +Furthermore it is possible to stop Meson from adding flags itself by +using the `--buildtype=plain` option, in this case you must provide +the full compiler and linker arguments needed. + +## Building from the source + +To start the build, simply type the following command. + +```sh +meson compile -C builddir +``` + +See [`meson compile` description](Commands.md#compile) for more info. + +### Building directly with ninja + +By default Meson uses the [Ninja build +system](https://ninja-build.org/) to actually build the code. To start +the build, simply type the following command. + +```sh +ninja -C builddir +``` + +The main usability difference between Ninja and Make is that Ninja +will automatically detect the number of CPUs in your computer and +parallelize itself accordingly. You can override the amount of +parallel processes used with the command line argument `-j <num +processes>`. + +It should be noted that after the initial configure step `ninja` is +the only command you ever need to type to compile. No matter how you +alter your source tree (short of moving it to a completely new +location), Meson will detect the changes and regenerate itself +accordingly. This is especially handy if you have multiple build +directories. Often one of them is used for development (the "debug" +build) and others only every now and then (such as a "static analysis" +build). Any configuration can be built just by `cd`'ing to the +corresponding directory and running Ninja. + +## Running tests + +Meson provides native support for running tests. The command to do +that is simple. + +```sh +meson test -C builddir +``` + +See [`meson test` description](Commands.md#test) for more info. + +Meson does not force the use of any particular testing framework. You +are free to use GTest, Boost Test, Check or even custom executables. + +Note: it can be also invoked directly with ninja with the following command: +```sh +ninja -C builddir test +``` + +## Installing + +Installing the built software is just as simple. + +```sh +meson install -C builddir +``` + +See [`meson install` description](Commands.md#install) for more info. + +Note that Meson will only install build targets explicitly tagged as +installable, as detailed in the [installing targets +documentation](Installing.md). + +By default Meson installs to `/usr/local`. This can be changed by +passing the command line argument `--prefix /your/prefix` to Meson +during configure time. Meson also supports the `DESTDIR` variable used +in e.g. building packages. It is used like this: + +```sh +DESTDIR=/path/to/staging meson install -C builddir +``` + +Note: it can be also invoked directly with ninja with the following +command: + +```sh +ninja -C builddir install +``` + +## Command line help + +Meson has a standard command line help feature. It can be accessed +with the following command. + + meson --help + +## Exit status + +Meson exits with status 0 if successful, 1 for problems with the +command line or meson.build file, and 2 for internal errors. diff --git a/meson/docs/markdown/Rust-module.md b/meson/docs/markdown/Rust-module.md new file mode 100644 index 000000000..b89c052c5 --- /dev/null +++ b/meson/docs/markdown/Rust-module.md @@ -0,0 +1,83 @@ +--- +short-description: Rust language integration module +authors: + - name: Dylan Baker + email: dylan@pnwbakers.com + years: [2020, 2021] +... + +# Unstable Rust module + +*(new in 0.57.0)* + +**Note** Unstable modules make no backwards compatible API guarantees. + +The rust module provides helper to integrate rust code into Meson. The +goal is to make using rust in Meson more pleasant, while still +remaining mesonic, this means that it attempts to make Rust work more +like Meson, rather than Meson work more like rust. + +## Functions + +### test(name: string, target: library | executable, dependencies: []Dependency) + +This function creates a new rust unittest target from an existing rust +based target, which may be a library or executable. It does this by +copying the sources and arguments passed to the original target and +adding the `--test` argument to the compilation, then creates a new +test target which calls that executable, using the rust test protocol. + +This accepts all of the keyword arguments as the +[`test`](Reference-manual.md#test) function except `protocol`, it will set +that automatically. + +Additional, test only dependencies may be passed via the dependencies +argument. + +### bindgen(*, input: string | BuildTarget | []string | []BuildTarget, output: strng, include_directories: []include_directories, c_args: []string, args: []string) + +This function wraps bindgen to simplify creating rust bindings around C +libraries. This has two advantages over hand-rolling ones own with a +`generator` or `custom_target`: + +- It handles `include_directories`, so one doesn't have to manually convert them to `-I...` +- It automatically sets up a depfile, making the results more reliable + + +It takes the following keyword arguments + +- input — A list of Files, Strings, or CustomTargets. The first element is + the header bindgen will parse, additional elements are dependencies. +- output — the name of the output rust file +- include_directories — A list of `include_directories` objects, these are + passed to clang as `-I` arguments +- c_args — A list of string arguments to pass to clang untouched +- args — A list of string arguments to pass to `bindgen` untouched. + +```meson +rust = import('unstable-rust') + +inc = include_directories('..'¸ '../../foo') + +generated = rust.bindgen( + 'myheader.h', + 'generated.rs', + include_directories : [inc, include_directories('foo')], + args : ['--no-rustfmt-bindings'], + c_args : ['-DFOO=1'], +) +``` + +If the header depeneds on generated headers, those headers must be passed to +`bindgen` as well to ensure proper dependency ordering, static headers do not +need to be passed, as a proper depfile is generated: + +```meson +h1 = custom_target(...) +h2 = custom_target(...) + +r1 = rust.bindgen( + [h1, h2], # h1 includes h2, + 'out.rs', +) +``` diff --git a/meson/docs/markdown/Shipping-prebuilt-binaries-as-wraps.md b/meson/docs/markdown/Shipping-prebuilt-binaries-as-wraps.md new file mode 100644 index 000000000..73cf48b08 --- /dev/null +++ b/meson/docs/markdown/Shipping-prebuilt-binaries-as-wraps.md @@ -0,0 +1,36 @@ +# Shipping prebuilt binaries as wraps + +A common dependency case, especially on Windows, is the need to +provide dependencies as prebuilt binaries rather than Meson projects +that you build from scratch. Common reasons include not having access +to source code, not having the time and effort to rewrite a legacy +system's build definitions to Meson or just the fact that compiling +the dependency projects takes too long. + +Packaging a project is straightforward. As an example let's look at a +case where the project consists of one static library called `bob` and +some headers. To create a binary dependency project we put the static +library at the top level and headers in a subdirectory called +`include`. The Meson build definition would look like the following. + +```meson +project('binary dep', 'c') + +cc = meson.get_compiler('c') +bin_dep = declare_dependency( + dependencies : cc.find_library('bob', dirs : meson.current_source_dir()), + include_directories : include_directories('include')) +``` + +Now you can use this subproject as if it was a Meson project: + +```meson +project('using dep', 'c') +bob_dep = subproject('bob').get_variable('bin_dep') +executable('prog', 'prog.c', dependencies : bob_dep) +``` + +Note that often libraries compiled with different compilers (or even +compiler flags) might not be compatible. If you do this, then you are +responsible for verifying that your libraries are compatible, Meson +will not check things for you. diff --git a/meson/docs/markdown/Simd-module.md b/meson/docs/markdown/Simd-module.md new file mode 100644 index 000000000..29f3e952d --- /dev/null +++ b/meson/docs/markdown/Simd-module.md @@ -0,0 +1,72 @@ +# Unstable SIMD module + +This module provides helper functionality to build code with SIMD instructions. +Available since 0.42.0. + +**Note**: this module is unstable. It is only provided as a technology +preview. Its API may change in arbitrary ways between releases or it +might be removed from Meson altogether. + +## Usage + +This module is designed for the use case where you have an algorithm +with one or more SIMD implementation and you choose which one to use +at runtime. + +The module provides one method, `check`, which is used like this: + + rval = simd.check('mysimds', + mmx : 'simd_mmx.c', + sse : 'simd_sse.c', + sse2 : 'simd_sse2.c', + sse3 : 'simd_sse3.c', + ssse3 : 'simd_ssse3.c', + sse41 : 'simd_sse41.c', + sse42 : 'simd_sse42.c', + avx : 'simd_avx.c', + avx2 : 'simd_avx2.c', + neon : 'simd_neon.c', + compiler : cc) + +Here the individual files contain the accelerated versions of the +functions in question. The `compiler` keyword argument takes the +compiler you are going to use to compile them. The function returns an +array with two values. The first value is a bunch of libraries that +contain the compiled code. Any SIMD code that the compiler can't +compile (for example, Neon instructions on an x86 machine) are +ignored. You should pass this value to the desired target using +`link_with`. The second value is a `configuration_data` object that +contains true for all the values that were supported. For example if +the compiler did support sse2 instructions, then the object would have +`HAVE_SSE2` set to 1. + +Generating code to detect the proper instruction set at runtime is +straightforward. First you create a header with the configuration +object and then a chooser function that looks like this: + + void (*fptr)(type_of_function_here) = NULL; + + #if HAVE_NEON + if(fptr == NULL && neon_available()) { + fptr = neon_accelerated_function; + } + #endif + #if HAVE_AVX2 + if(fptr == NULL && avx2_available()) { + fptr = avx_accelerated_function; + } + #endif + + ... + + if(fptr == NULL) { + fptr = default_function; + } + +Each source file provides two functions, the `xxx_available` function +to query whether the CPU currently in use supports the instruction set +and `xxx_accelerated_function` that is the corresponding accelerated +implementation. + +At the end of this function the function pointer points to the fastest +available implementation and can be invoked to do the computation. diff --git a/meson/docs/markdown/Simple-comparison.md b/meson/docs/markdown/Simple-comparison.md new file mode 100644 index 000000000..a8ce17bd8 --- /dev/null +++ b/meson/docs/markdown/Simple-comparison.md @@ -0,0 +1,88 @@ +# A simple comparison + +In this experiment we generated one thousand C files with contents +that looked like this. + +```c +#include<stdio.h> +#include"header.h" + +int func23() { return 0; } +``` + +The function number was different in each file. In addition there was +a main C file that just called each function in turn. We then +generated build system files for *Meson*, *CMake*, *SCons*, *Premake* +and *Autotools* that compiled these files into a single executable. + +With this we measured three different things. The first is +configuration time, that is, the time the build system takes to +generate necessary build files. This is usually called the *configure +step*. The time was measured in seconds. + +The second thing to measure was the build time. This should be limited +by the compiler and in the optimal case should be the same for every +build system. Four parallel processes were used in this test. + +The third thing we measured was the empty build time. This measures +how much time the build system takes to check the states of all source +files because if any of them could potentially cause a rebuild. + +Since CMake has two different backends, Make and Ninja, we ran the +tests on both of them. All tests were run on a 2011 era Macbook Pro +running Ubuntu 13/04. The tests were run multiple times and we always +took the fastest time. + +Here are the results for configuration time. + +![Configuration times](images/conftime.png) + +The reason SCons got zero seconds on this test is because you cannot +separate configure and build steps. They run as one unit. Autotools is +the clear loser of this test as it is over an order of magnitude +slower than the second slowest one. This configuration time includes +both autogen and configure. All other systems take less than one +second to do this setup, which is fast enough for a human being to +interpret as instantaneous. + +![Build times](https://raw.githubusercontent.com/wiki/jpakkane/meson/buildtime.png) + +Build times are a bit more even. SCons is the slowest, being almost +ten seconds slower than the second slowest. Some of it is work from +the configure step but it still has the worst performance. Premake is +the fastest Make-based build system narrowly beating out Autotools. +Both Ninja-based build systems are faster than all non-Ninja ones with +Meson being slightly faster. In practice the difference is minimal. +The advantages of Ninja can be seen by comparing CMake's times when +using Make or Ninja. It is possible to shave off 3.5 seconds (over +20%) of the total build time just by changing the backend. The +project's CMake configuration files don't need any changes. + +![No-op time](https://raw.githubusercontent.com/wiki/jpakkane/meson/emptytime.png) + +Empty build times reflect the performance of regular build times. +SCons is again the slowest taking over three seconds compared to +Meson, which takes only 0.03 seconds, a difference of two orders of +magnitude. Even Autotools, the fastest Make-based system, is almost +one order of magnitude slower. Ninja holds the top spots just like in +the previous test. + +Conclusions +----- + +Build system performance matters. Even with this extremely simple +example we can find differences between various popular build systems. +As the project size increases, these differences grow even larger. +(The author has witnessed no-op build times of 30 seconds for Make +versus less than one second for Ninja when compiling the Clang +compiler.) Keeping incremental build times low is one of the major +keys of programmer productivity as it allows developers to iterate +faster and stay in the creative zone. + +Original scripts +----- + +Those who want to run these experiments themselves can download the scripts here: + +* [Generator script](https://raw.githubusercontent.com/wiki/jpakkane/meson/gen_src.py) +* [Measurement script](https://raw.githubusercontent.com/wiki/jpakkane/meson/measure.py) diff --git a/meson/docs/markdown/SimpleStart.md b/meson/docs/markdown/SimpleStart.md new file mode 100644 index 000000000..bf0d7aefb --- /dev/null +++ b/meson/docs/markdown/SimpleStart.md @@ -0,0 +1,150 @@ +--- +short-description: Simple getting started guide +... + +# The Absolute Beginner's Guide to Installing and Using Meson + +This page is meant for people who are new to using Meson and possibly +even to compiling C and/or C++ code in general. It is meant to contain +one simple way of getting your build environment up and running. If +you are more experienced and have your own preferred way of installing +and using development software, feel free to use that instead. This +guide only deals with Linux, Windows and macOS platforms. If you use +some other platform, such as one of the BSDs, you probably already +know how to install development tools on it (probably better than we +do, even). + +There are three phases to getting a development environment running. + +1. Installing a compiler toolchain +2. Installing Meson +3. Creating a project and building it + +## Installing a compiler toolchain + +### Linux + +All Linux distributions provide easy access to development tools. +Typically you need to open a terminal and execute one command, which +depends on your distro. + + - Debian, Ubuntu and derivatives: `sudo apt install build-essential` + - Fedora, Centos, RHEL and derivatives: `sudo dnf install gcc-c++` + - Arch: `sudo pacman -S gcc` + +### Windows + +The most common development toolchain on Windows is Visual Studio, +which can be downloaded from [the Visual Studio web +site](https://visualstudio.microsoft.com/). Select the Community +version unless you have bought a license. + +![Download page of Visual Studio](images/win_dlvs.png) + +Download the installer and run it. When you are given a list of things +to install, select *Desktop development with C++*. This installs both +a C and a C++ compiler. + +![Installing the Visual Studio compilers](images/win_installvs.png) + +Once the installer finishes the compiler toolchain is ready to use. + +### macOS + +On macOS the development toolchain must be installed via the Mac app +store. Search for an app called XCode and install it. + +![App store page for XCode](images/osx_xcode.png) + +*Note:* Installing XCode is not sufficient by itself. You also need to +start XCode' GUI application once. This will make XCode download and +install more files that are needed for compilation. + +## Installing Meson + +### Linux + +Installing Meson is just as simple as installing the compiler toolchain. + + - Debian, Ubuntu and derivatives: `sudo apt install meson ninja-build` + - Fedora, Centos, RHEL and derivatives: `sudo dnf install meson ninja-build` + - Arch: `sudo pacman -S meson` + +### Windows + +Meson provides a standard Windows `.msi` installer that can be +downloaded from [the Releases +page](https://github.com/mesonbuild/meson/releases). + +![Meson installed download](images/win_downloadmeson.png) + +Download and run it to install all the necessary bits. You can verify +that your installation is working by running the Visual Studio +developer tools command prompt that can be found in the start menu. + +![Devtool prompt](images/win_vstoolsprompt.png) + +You should be able to run both `meson` and `ninja` and query their +versions. + +![A working Windows install](images/win_working.png) + +### macOS + +Start by downloading the installation package from [the Releases +page](https://github.com/mesonbuild/meson/releases). + +![Downloading the macOS installer](images/meson_mac1.png) + +Double click the downloaded installer to start. If you are running a +new macOS version, it might refuse to run the application with the +following error message: + +![A macOS signing warning](images/meson_mac2.png) + +This can be fixed by starting System Preferences, selecting the +Security and Privacy entry. At the bottom it shows the blocked app and +you can enable it by clicking on the "Open anyway" button. + +![Security settings](images/meson_mac3.png) + +Now the installer should start. If not, double click on the downloaded +installer file again. + +![Installer running](images/meson_mac4.png) + +Once the installation is finished you can verify that the system is working via the terminal app. + +![A successful install](images/meson_mac5.png) + +## Running Meson + +Start a terminal application. On Windows you have to use the Visual +Studio Developer Tools Command Prompt as discussed above, because the +compilers are only available in that terminal. You also need to change +into your home directory (Linux and macOS terminals start in the home +directory by default). + + cd \users\username + +Create a new directory to hold your project. + + mkdir testproject + cd testproject + +Use Meson to create and build a new sample project. + + meson init --name testproject --build + +This will create a project skeleton for you and compile it. The result +is put in the `build` subdirectory and can be run directly from there. + + build/testproject + +![All finished and ready to go](images/linux_alldone.png) + +The project is now ready for development. You can edit the code with +any editor and it is rebuilt by going in the `build` subdirectory and +executing the `meson compile` command. If your version of Meson is too +old, you can compile the project by running the command `ninja` +instead. diff --git a/meson/docs/markdown/SourceSet-module.md b/meson/docs/markdown/SourceSet-module.md new file mode 100644 index 000000000..26c199552 --- /dev/null +++ b/meson/docs/markdown/SourceSet-module.md @@ -0,0 +1,212 @@ +--- +short-description: Source set module +authors: + - name: Paolo Bonzini + email: pbonzini@redhat.com + years: [2019] +... + +# Source set module + +This module provides support for building many targets against a +single set of files; the choice of which files to include in each +target depends on the contents of a dictionary or a +`configuration_data` object. The module can be loaded with: + +```meson +ssmod = import('sourceset') +``` + +A simple example of using the module looks like this: + +```meson +ss = ssmod.source_set() +# Include main.c unconditionally +ss.add(files('main.c')) +# Include a.c if configuration key FEATURE1 is true +ss.add(when: 'FEATURE1', if_true: files('a.c')) +# Include zlib.c if the zlib dependency was found, and link zlib +# in the executable +ss.add(when: zlib, if_true: files('zlib.c')) +# many more rules here... +ssconfig = ss.apply(config) +executable('exe', sources: ssconfig.sources(), + dependencies: ssconfig.dependencies()) +``` + +and it would be equivalent to + +```meson +sources = files('main.c') +dependencies = [] +if config['FEATURE1'] then + sources += [files('a.c')] +endif +if zlib.found() then + sources += [files('zlib.c')] + dependencies += [zlib] +endif +# many more "if"s here... +executable('exe', sources: sources, dependencies: dependencies()) +``` + +Sourcesets can be used with a single invocation of the `apply` method, +similar to the example above, but the module is especially useful when +multiple executables are generated by applying the same rules to many +different configurations. + +*Added 0.51.0* + +## Functions + +### `source_set()` + +```meson +ssmod.source_set() +``` + +Create and return a new source set object. + +**Returns**: a [source set][`source_set` object] + +## `source_set` object + +The `source_set` object provides methods to add files to a source set +and to query it. The source set becomes immutable after any method but +`add` is called. + +### Methods + +#### `add()` + +```meson +source_set.add([when: varnames_and_deps], + [if_true: sources_and_deps], + [if_false: list_of_alt_sources]) +source_set.add(sources_and_deps) +``` + +Add a *rule* to a source set. A rule determines the conditions under +which some source files or dependency objects are included in a build +configuration. All source files must be present in the source tree or +they can be created in the build tree via `configure_file`, +`custom_target` or `generator`. + +`varnames_and_deps` is a list of conditions for the rule, which can be +either strings or dependency objects (a dependency object is anything +that has a `found()` method). If *all* the strings evaluate to true +and all dependencies are found, the rule will evaluate to true; +`apply()` will then include the contents of the `if_true` keyword +argument in its result. Otherwise, that is if any of the strings in +the positional arguments evaluate to false or any dependency is not +found, `apply()` will instead use the contents of the `if_false` +keyword argument. + +Dependencies can also appear in `sources_and_deps`. In this case, a +missing dependency will simply be ignored and will *not* disable the +rule, similar to how the `dependencies` keyword argument works in +build targets. + +**Note**: It is generally better to avoid mixing source sets and +disablers. This is because disablers will cause the rule to be dropped +altogether, and the `list_of_alt_sources` would not be taken into +account anymore. + +#### `add_all()` + +```meson +source_set.add_all(when: varnames_and_deps, + if_true: [source_set1, source_set2, ...]) +source_set.add_all(source_set1, source_set2, ...) +``` + +Add one or more source sets to another. + +For each source set listed in the arguments, `apply()` will consider +their rules only if the conditions in `varnames_and_deps` are +evaluated positively. For example, the following: + +```meson +sources_b = ssmod.source_set() +sources_b.add(when: 'HAVE_A', if_true: 'file.c') +sources = ssmod.source_set() +sources.add_all(when: 'HAVE_B', if_true: sources_b) +``` + +is equivalent to: + +```meson +sources = ssmod.source_set() +sources.add(when: ['HAVE_A', 'HAVE_B'], if_true: 'file.c') +``` + +#### `all_sources()` + +```meson +list source_set.all_sources(...) +``` + +Returns a list of all sources that were placed in the source set using +`add` (including nested source sets) and that do not have a not-found +dependency. If a rule has a not-found dependency, only the `if_false` +sources are included (if any). + +**Returns**: a list of file objects + +#### `all_dependencies()` *(since 0.52.0)* + +```meson +list source_set.all_dependencies(...) +``` + +Returns a list of all dependencies that were placed in the source set +using `add` (including nested source sets) and that were found. + +**Returns**: a list of dependencies + +#### `apply()` + +```meson +source_files source_set.apply(conf_data[, strict: false]) +``` + +Match the source set against a dictionary or a `configuration_data` +object and return a *source configuration* object. A source +configuration object allows you to retrieve the sources and +dependencies for a specific configuration. + +By default, all the variables that were specified in the rules have to +be present in `conf_data`. However, in some cases the convention is +that `false` configuration symbols are absent in `conf_data`; this is +the case for example when the configuration was loaded from a Kconfig +file. In that case you can specify the `strict: false` keyword +argument, which will treat absent variables as false. + +**Returns**: a [source configuration][`source_configuration` object] + +## `source_configuration` object + +The `source_configuration` object provides methods to query the result of an +`apply` operation on a source set. + +### Methods + +#### `sources()` + +```meson +source_config.sources() +``` + +Return the source files corresponding to the applied configuration. + +**Returns**: a list of file objects + +#### `dependencies()` + +```meson +source_config.dependencies() +``` + +Return the dependencies corresponding to the applied configuration. + +**Returns**: a list of dependency objects diff --git a/meson/docs/markdown/Style-guide.md b/meson/docs/markdown/Style-guide.md new file mode 100644 index 000000000..f204a9a70 --- /dev/null +++ b/meson/docs/markdown/Style-guide.md @@ -0,0 +1,87 @@ +--- +short-description: Style recommendations for Meson files +... + +# Style recommendations + +This page lists some recommendations on organizing and formatting your +Meson build files. + +## Tabs or spaces? + +Always spaces. + +## Naming Variable + +Snake case (stylized as `snake_case`) refers to the style of writing in which +each space is replaced by an underscore (`_`) character, and the first letter of +each word written in lowercase. It is the most common naming convention used +in Meson build scripts as identifiers for variable. + +Let say you would like to refer to your executable so something like `my_exe`. + +## Dependency usage + +The `dependency` function is the recommended way to handle +dependencies. If your wrap files have the necessary `[provide]` +entries, everything will work automatically both when compiling your +own and when using system dependencies. + +You should only need `subproject` when you need to extract non dependencies/programs. + +## Naming options + +There are two ways of naming project options. As an example for +booleans the first one is `foo` and the second one is `enable-foo`. +The former style is recommended, because in Meson options have strong +type, rather than being just strings. + +You should try to name options the same as is common in other +projects. This is especially important for yielding options, because +they require that both the parent and subproject options have the same +name. + +# Global arguments + +Prefer `add_project_arguments` to `add_global_arguments` because using +the latter prevents using the project as a subproject. + +# Cross compilation arguments + +Try to keep cross compilation arguments away from your build files as +much as possible. Keep them in the cross file instead. This adds +portability, since all changes needed to compile to a different +platform are isolated in one place. + +# Sorting source paths + +The source file arrays should all be sorted. This makes it easier to +spot errors and often reduces merge conflicts. Furthermore, the paths +should be sorted with a natural sorting algorithm, so that numbers are +sorted in an intuitive way (`1, 2, 3, 10, 20` instead of `1, 10, 2, +20, 3`). + +Numbers should also be sorted before characters (`a111` before `ab0`). +Furthermore, strings should be sorted case insensitive. + +Additionally, if a path contains a directory it should be sorted before +normal files. This rule also applies recursively for subdirectories. + +The following example shows correct source list definition: + +```meson +sources = files([ + 'aaa/a1.c', + 'aaa/a2.c', + 'bbb/subdir1/b1.c', + 'bbb/subdir2/b2.c', + 'bbb/subdir10/b3.c', + 'bbb/subdir20/b4.c', + 'bbb/b5.c', + 'bbb/b6.c', + 'f1.c', + 'f2.c', + 'f10.c', + 'f20.c' +]) +``` diff --git a/meson/docs/markdown/Subprojects.md b/meson/docs/markdown/Subprojects.md new file mode 100644 index 000000000..7cb04e0eb --- /dev/null +++ b/meson/docs/markdown/Subprojects.md @@ -0,0 +1,382 @@ +--- +short-description: Using Meson projects as subprojects within other Meson projects +... + +# Subprojects + +Some platforms do not provide a native packaging system. In these +cases it is common to bundle all third party libraries in your source +tree. This is usually frowned upon because it makes it hard to add +these kinds of projects into e.g. those Linux distributions that +forbid bundled libraries. + +Meson tries to solve this problem by making it extremely easy to +provide both at the same time. The way this is done is that Meson +allows you to take any other Meson project and make it a part of your +build without (in the best case) any changes to its Meson setup. It +becomes a transparent part of the project. + +It should be noted that this is only guaranteed to work for subprojects +that are built with Meson. The reason is the simple fact that there is +no possible way to do this reliably with mixed build systems. Because of +this, only Meson subprojects are described here. +[CMake based subprojects](CMake-module.md#cmake-subprojects) are also +supported but not guaranteed to work. + +## A subproject example + +Usually dependencies consist of some header files plus a library to +link against. To declare this internal dependency use +`declare_dependency` function. + +As an example, suppose we have a simple project that provides a shared +library. Its `meson.build` would look like this. + +```meson +project('libsimple', 'c') + +inc = include_directories('include') +libsimple = shared_library('simple', + 'simple.c', + include_directories : inc, + install : true) + +libsimple_dep = declare_dependency(include_directories : inc, + link_with : libsimple) +``` + +### Naming convention for dependency variables + +Ideally the dependency variable name should be of `<project_name>_dep` +form. This way one can just use it without even looking inside build +definitions of that subproject. + +In cases where there are multiple dependencies need to be declared, +the default one should be named as `<project_name>_dep` (e.g. +`gtest_dep`), and others can have `<project_name>_<other>_<name>_dep` +form (e.g. `gtest_main_dep` - gtest with main function). + +There may be exceptions to these rules where common sense should be applied. + +### Adding variables to the dependency + +*New in 0.54.0* + +In some cases a project may define special variables via pkg-config or +cmake that a caller needs to know about. Meson provides a +`dependency.get_variable` method to hide what kind of dependency is +provided, and this is available to subprojects as well. Use the +`variables` keyword to add a dict of strings: + +```meson +my_dep = declare_dependency(..., variables : {'var': 'value', 'number': '3'}) +``` + +Which another project can access via: + +```meson +var = my_dep.get_variable(internal : 'var', cmake : 'CMAKE_VAR') +``` + +The values of the dict must be strings, as pkg-config and cmake will +return variables as strings. + +### Build options in subproject + +All Meson features of the subproject, such as project options keep +working and can be set in the master project. There are a few +limitations, the most important being that global compiler arguments +must be set in the main project before calling subproject. Subprojects +must not set global arguments because there is no way to do that +reliably over multiple subprojects. To check whether you are running +as a subproject, use the `is_subproject` function. + +## Using a subproject + +All subprojects must be inside `subprojects` directory. The +`subprojects` directory must be at the top level of your project. +Subproject declaration must be in your top level `meson.build`. + +### A simple example + +Let's use `libsimple` as a subproject. + +At the top level of your project create `subprojects` directory. +Then copy `libsimple` into `subprojects` directory. + +Your project's `meson.build` should look like this. + +```meson +project('my_project', 'cpp') + +libsimple_proj = subproject('libsimple') +libsimple_dep = libsimple_proj.get_variable('libsimple_dep') + +executable('my_project', + 'my_project.cpp', + dependencies : libsimple_dep, + install : true) +``` + +Note that the subproject object is *not* used as the dependency, but +rather you need to get the declared dependency from it with +`get_variable` because a subproject may have multiple declared +dependencies. + +### Toggling between system libraries and embedded sources + +When building distro packages it is very important that you do not +embed any sources. Some distros have a rule forbidding embedded +dependencies so your project must be buildable without them or +otherwise the packager will hate you. + +Here's how you would use system libraries and fall back to embedding sources +if the dependency is not available. + +```meson +project('my_project', 'cpp') + +libsimple_dep = dependency('libsimple', required : false) + +if not libsimple_dep.found() + libsimple_proj = subproject('libsimple') + libsimple_dep = libsimple_proj.get_variable('libsimple_dep') +endif + +executable('my_project', + 'my_project.cpp', + dependencies : libsimple_dep, + install : true) +``` + +Because this is such a common operation, Meson provides a shortcut for +this use case. + +```meson +dep = dependency('foo', fallback : [subproject_name, variable_name]) +``` + +The `fallback` keyword argument takes two items, the name of the +subproject and the name of the variable that holds the dependency. If +you need to do something more complicated, such as extract several +different variables, then you need to do it yourself with the manual +method described above. + +Using this shortcut the build definition would look like this. + +```meson +project('my_project', 'cpp') + +libsimple_dep = dependency('libsimple', fallback : ['libsimple', 'libsimple_dep']) + +executable('my_project', + 'my_project.cpp', + dependencies : libsimple_dep, + install : true) +``` + +With this setup when libsimple is provided by the system, we use it. +When that is not the case we use the embedded version (the one from +subprojects). + +Note that `libsimple_dep` can point to an external or an internal +dependency but you don't have to worry about their differences. Meson +will take care of the details for you. + +### Subprojects depending on other subprojects + +Subprojects can use other subprojects, but all subprojects must reside +in the top level `subprojects` directory. Recursive use of subprojects +is not allowed, though, so you can't have subproject `a` that uses +subproject `b` and have `b` also use `a`. + +## Obtaining subprojects + +Meson ships with a dependency system to automatically obtain +dependency subprojects. It is documented in the [Wrap dependency +system manual](Wrap-dependency-system-manual.md). + +## Command-line options + +The usage of subprojects can be controlled by users and distros with +the following command-line options: + +* **--wrap-mode=nodownload** + + Meson will not use the network to download any subprojects or + fetch any wrap information. Only pre-existing sources will be used. + This is useful (mostly for distros) when you want to only use the + sources provided by a software release, and want to manually handle + or provide missing dependencies. + +* **--wrap-mode=nofallback** + + Meson will not use subproject fallbacks for any dependency + declarations in the build files, and will only look for them in the + system. Note that this does not apply to unconditional subproject() + calls, and those are meant to be used for sources that cannot be + provided by the system, such as copylibs. + + This option may be overridden by `--force-fallback-for` for specific + dependencies. + +* **--wrap-mode=forcefallback** + + Meson will not look at the system for any dependencies which have + subproject fallbacks available, and will *only* use subprojects for + them. This is useful when you want to test your fallback setup, or + want to specifically build against the library sources provided by + your subprojects. + +* **--force-fallback-for=list,of,dependencies** + + Meson will not look at the system for any dependencies listed there, + provided a fallback was supplied when the dependency was declared. + + This option takes precedence over `--wrap-mode=nofallback`, and when + used in combination with `--wrap-mode=nodownload` will only work + if the dependency has already been downloaded. + + This is useful when your project has many fallback dependencies, + but you only want to build against the library sources for a few + of them. + + **Warning**: This could lead to mixing system and subproject version of the + same library in the same process. Take this case as example: + - Libraries `glib-2.0` and `gstreamer-1.0` are installed on your system. + - `gstreamer-1.0` depends on `glib-2.0`, pkg-config file `gstreamer-1.0.pc` + has `Requires: glib-2.0`. + - In your application build definition you do: + ```meson + executable('app', ..., + dependencies: [ + dependency('glib-2.0', fallback: 'glib'), + dependency('gstreamer-1.0', fallback: 'gstreamer')], + ) + ``` + - You configure with `--force-fallback-for=glib`. + This result in linking to two different versions of library `glib-2.0` + because `dependency('glib-2.0', fallback: 'glib')` will return the + subproject dependency, but `dependency('gstreamer-1.0', fallback: 'gstreamer')` + will not fallback and return the system dependency, including `glib-2.0` + library. To avoid that situation, every dependency that itself depend on + `glib-2.0` must also be forced to fallback, in this case with + `--force-fallback-for=glib,gsteamer`. + +* **--wrap-mode=nopromote** + + *Since 0.56.0* Meson will automatically use wrap files found in subprojects + and copy them into the main project. That new behavior can be disabled by + passing `--wrap-mode=nopromote`. In that case only wraps found in the main + project will be used. + +## `meson subprojects` command + +*Since 0.49.0* + +`meson subprojects` has various subcommands to manage all subprojects. +If the subcommand fails on any subproject the execution continues with +other subprojects. All subcommands accept `--sourcedir` argument +pointing to the root source dir of the main project. + +*Since 0.56.0* all subcommands accept `--types <file|git|hg|svn>` +argument to run the subcommands only on subprojects of the given +types. Multiple types can be set as comma separated list e.g. `--types +git,file`. + +*Since 0.56.0* If the subcommand fails on any subproject an error code +is returned at the end instead of retuning success. + +### Download subprojects + +*Since 0.49.0* + +Meson will automatically download needed subprojects during configure, +unless **--wrap-mode=nodownload** option is passed. It is sometimes +preferable to download all subprojects in advance, so the Meson +configure can be performed offline. The command-line `meson +subprojects download` can be used for that, it will download all +missing subprojects, but will not update already fetched subprojects. + +### Update subprojects + +*Since 0.49.0* + +Once a subproject has been fetched, Meson will not update it automatically. +For example if the wrap file tracks a git branch, it won't pull latest commits. + +To pull latest version of all your subprojects at once, just run the command: +`meson subprojects update`. +- If the wrap file comes from wrapdb, the latest version of the wrap file will + be pulled and used next time meson reconfigure the project. This can be + triggered using `meson --reconfigure`. Previous source tree is not deleted, to + prevent from any loss of local changes. *Since 0.58.0* If `--reset` is + specified, the source tree is deleted and new source is extracted. +- If subproject is currently in detached mode, a checkout of the revision from + wrap file is performed. *Since 0.56.0* a rebase is also performed in case the + revision already existed locally but was outdated. If `--reset` is specified, + a hard reset is performed instead of rebase. +- If subproject is currently at the same branch as specified by the wrap file, + a rebase on `origin` commit is performed. *Since 0.56.0* If `--reset` is + specified, a hard reset is performed instead of rebase. +- If subproject is currently in a different branch as specified by the wrap file, + it is skipped unless `--rebase` option is passed in which case a rebase on + `origin` commit is performed. *Since 0.56.0* the `--rebase` argument is + deprecated and has no effect. Instead, a checkout of the revision from wrap file + file is performed and a rebase is also performed in case the revision already + existed locally by was outdated. If `--reset` is specified, a hard reset is + performed instead of rebase. +- *Since 0.56.0* if the `url` specified in wrap file is different to the URL set + on `origin` for a git repository it will not be updated, unless `--reset` is + specified in which case the URL of `origin` will be reset first. +- *Since 0.56.0* If the subproject directory is not a git repository but has a + `[wrap-git]` the subproject is ignored, unless `--reset` is specified in which + case the directory is deleted and the new repository is cloned. + +### Start a topic branch across all git subprojects + +*Since 0.49.0* + +The command-line `meson subprojects checkout <branch_name>` will +checkout a branch, or create one with `-b` argument, in every git +subprojects. This is useful when starting local changes across +multiple subprojects. It is still your responsibility to commit and +push in each repository where you made local changes. + +To come back to the revision set in wrap file (i.e. master), just run +`meson subprojects checkout` with no branch name. + +*Since 0.56.0* any pending changes are now stashed before checkout a new branch. + +### Execute a command on all subprojects + +*Since 0.51.0* + +The command-line `meson subprojects foreach <command> [...]` will +execute a command in each subproject directory. For example this can +be useful to check the status of subprojects (e.g. with `git status` +or `git diff`) before performing other actions on them. + +## Why must all subprojects be inside a single directory? + +There are several reasons. + +First of all, to maintain any sort of sanity, the system must prevent going +inside other subprojects with `subdir()` or variations thereof. Having the +subprojects in well defined places makes this easy. If subprojects could be +anywhere at all, it would be a lot harder. + +Second of all it is extremely important that end users can easily see what +subprojects any project has. Because they are in one, and only one, place, +reviewing them becomes easy. + +This is also a question of convention. Since all Meson projects have the same +layout w.r.t subprojects, switching between projects becomes easier. You don't +have to spend time on a new project traipsing through the source tree looking +for subprojects. They are always in the same place. + +Finally if you can have subprojects anywhere, this increases the possibility of +having many different (possibly incompatible) versions of a dependency in your +source tree. Then changing some code (such as changing the order you traverse +directories) may cause a completely different version of the subproject to be +used by accident. diff --git a/meson/docs/markdown/Syntax.md b/meson/docs/markdown/Syntax.md new file mode 100644 index 000000000..be3292f98 --- /dev/null +++ b/meson/docs/markdown/Syntax.md @@ -0,0 +1,746 @@ +--- +short-description: Syntax and structure of Meson files +... + +# Syntax + +The syntax of Meson's specification language has been kept as simple +as possible. It is *strongly typed* so no object is ever converted to +another under the covers. Variables have no visible type which makes +Meson *dynamically typed* (also known as *duck typed*). + +The main building blocks of the language are *variables*, *numbers*, +*booleans*, *strings*, *arrays*, *function calls*, *method calls*, *if +statements* and *includes*. + +Usually one Meson statement takes just one line. There is no way to +have multiple statements on one line as in e.g. *C*. Function and +method calls' argument lists can be split over multiple lines. Meson +will autodetect this case and do the right thing. + +In other cases, *(added 0.50)* you can get multi-line statements by +ending the line with a `\`. Apart from line ending whitespace has no +syntactic meaning. + +## Variables + +Variables in Meson work just like in other high level programming +languages. A variable can contain a value of any type, such as an +integer or a string. Variables don't need to be predeclared, you can +just assign to them and they appear. Here's how you would assign +values to two different variables. + +```meson +var1 = 'hello' +var2 = 102 +``` + +One important difference in how variables work in Meson 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. This is different from, for example, how Python works for +objects, but similar to e.g. Python strings. + +```meson +var1 = [1, 2, 3] +var2 = var1 +var2 += [4] +# var2 is now [1, 2, 3, 4] +# var1 is still [1, 2, 3] +``` + +## Numbers + +Meson supports only integer numbers. They are declared simply by +writing them out. Basic arithmetic operations are supported. + +```meson +x = 1 + 2 +y = 3 * 4 +d = 5 % 3 # Yields 2. +``` + +Hexadecimal literals are supported since version 0.45.0: + +```meson +int_255 = 0xFF +``` + +Octal and binary literals are supported since version 0.47.0: + +```meson +int_493 = 0o755 +int_1365 = 0b10101010101 +``` + +Strings can be converted to a number like this: + +```meson +string_var = '42' +num = string_var.to_int() +``` + +Numbers can be converted to a string: + +```meson +int_var = 42 +string_var = int_var.to_string() +``` + +## Booleans + +A boolean is either `true` or `false`. + +```meson +truth = true +``` + +Booleans can be converted to a string or to a number: + +```meson +bool_var = true +string_var = bool_var.to_string() +int_var = bool_var.to_int() +``` + +## Strings + +Strings in Meson are declared with single quotes. To enter a literal +single quote do it like this: + +```meson +single quote = 'contains a \' character' +``` + +The full list of escape sequences is: + +* `\\` 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 +* `\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 + +As in python and C, up to three octal digits are accepted in `\ooo`. + +Unrecognized escape sequences are left in the string unchanged, i.e., the +backslash is left in the string. + +### String concatenation + +Strings can be concatenated to form a new string using the `+` symbol. + +```meson +str1 = 'abc' +str2 = 'xyz' +combined = str1 + '_' + str2 # combined is now abc_xyz +``` + +### String path building + +*(Added 0.49)* + +You can concatenate any two strings using `/` as an operator to build paths. +This will always use `/` as the path separator on all platforms. + +```meson +joined = '/usr/share' / 'projectname' # => /usr/share/projectname +joined = '/usr/local' / '/etc/name' # => /etc/name + +joined = 'C:\\foo\\bar' / 'builddir' # => C:/foo/bar/builddir +joined = 'C:\\foo\\bar' / 'D:\\builddir' # => D:/builddir +``` + +Note that this is equivalent to using [`join_paths()`](Reference-manual.md#join_paths), +which was obsoleted by this operator. + +### Strings running over multiple lines + +Strings running over multiple lines can be declared with three single +quotes, like this: + +```meson +multiline_string = '''#include <foo.h> +int main (int argc, char ** argv) { + return FOO_SUCCESS; +}''' +``` + +These are raw strings that do not support the escape sequences listed +above. These strings can also be combined with the string formatting +functionality described below. + +### String formatting + +#### .format() + +Strings can be built using the string formatting functionality. + +```meson +template = 'string: @0@, number: @1@, bool: @2@' +res = template.format('text', 1, true) +# res now has value 'string: text, number: 1, bool: true' +``` + +As can be seen, the formatting works by replacing placeholders of type +`@number@` with the corresponding argument. + +#### Format strings +*(Added 0.58)* + +Format strings can be used as a non-positional alternative to the +string formatting functionality described above. + +```meson +n = 10 +m = 'hi' + +s = f'int: @n@, string: @m@' +# s now has the value 'int: 10, string: hi' +``` + +Currently only identity-expressions are supported inside of format +strings, meaning you cannot use arbitrary Meson expressions inside of them. + +```meson +n = 10 +m = 5 + +# The following is not a valid format string +s = f'result: @n + m@' +``` + +### String methods + +Strings also support a number of other methods that return transformed +copies. + +#### .replace() + +Since 0.58.0, you can replace a substring from a string. + +```meson +# 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' +``` + +#### .strip() + +```meson +# 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' +``` + +#### .to_upper(), .to_lower() + +```meson +target = 'x86_FreeBSD' +upper = target.to_upper() # t now has the value 'X86_FREEBSD' +lower = target.to_lower() # t now has the value 'x86_freebsd' +``` + +#### .to_int() + +```meson +version = '1' +# Converts the string to an int and throws an error if it can't be +ver_int = version.to_int() +``` + +#### .contains(), .startswith(), .endswith() + +```meson +target = 'x86_FreeBSD' +is_fbsd = target.to_lower().contains('freebsd') +# is_fbsd now has the boolean value 'true' +is_x86 = target.startswith('x86') # boolean value 'true' +is_bsd = target.to_lower().endswith('bsd') # boolean value 'true' +``` + +#### .substring() + +Since 0.56.0, you can extract a substring from a string. + +```meson +# 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' +``` + +The method accepts negative values where negative `start` is relative to the end of +string `len(string) - start` as well as negative `end`. + +```meson +string = 'foobar' +string.substring(-5, -3) # => 'oo' +string.substring(1, -1) # => 'ooba' +``` + +#### .split(), .join() + +```meson +# 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', ''] + +# 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' + +# For joining path elements, you should use path1 / path2 +# This has the advantage of being cross-platform +path = '/usr' / 'local' / 'bin' +# path now has the value '/usr/local/bin' + +# For sources files, use files(): +my_sources = files('foo.c') +... +my_sources += files('bar.c') +# This has the advantage of always calculating the correct relative path, even +# if you add files in another directory or use them in a different directory +# than they're defined in + +# Example to set an API version for use in library(), install_header(), etc +project('project', 'c', version: '0.2.3') +version_array = meson.project_version().split('.') +# version_array now has the value ['0', '2', '3'] +api_version = '.'.join([version_array[0], version_array[1]]) +# api_version now has the value '0.2' + +# We can do the same with .format() too: +api_version = '@0@.@1@'.format(version_array[0], version_array[1]) +# api_version now (again) has the value '0.2' +``` + +#### .underscorify() + +```meson +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' +``` + +#### .version_compare() + +```meson +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: + +```meson +'3.6'.version_compare('>=3.6.0') == false +``` + +It is best to be unambiguous and specify the full revision level to compare. + +## Arrays + +Arrays are delimited by brackets. An array can contain an arbitrary number of objects of any type. + +```meson +my_array = [1, 2, 'string', some_obj] +``` + +Accessing elements of an array can be done via array indexing: + +```meson +my_array = [1, 2, 'string', some_obj] +second_element = my_array[1] +last_element = my_array[-1] +``` + +You can add more items to an array like this: + +```meson +my_array += ['foo', 3, 4, another_obj] +``` + +When adding a single item, you do not need to enclose it in an array: + +```meson +my_array += ['something'] +# This also works +my_array += 'else' +``` + +Note appending to an array will always create a new array object and +assign it to `my_array` instead of modifying the original since all +objects in Meson are immutable. + +Since 0.49.0, you can check if an array contains an element like this: + +```meson +my_array = [1, 2] +if 1 in my_array +# This condition is true +endif +if 1 not in my_array +# This condition is false +endif +``` + +### Array methods + +The following methods are defined for all arrays: + + - `length`, the size of the array + - `contains`, returns `true` if the array contains the object given as argument, `false` otherwise + - `get`, returns the object at the given index, negative indices count from the back of the array, indexing out of bounds is a fatal error. Provided for backwards-compatibility, it is identical to array indexing. + +## 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. Prior to *0.53.0* keys +were required to be literal strings, i.e., you could not use a +variable containing a string value as a key. + +```meson +my_dict = {'foo': 42, 'bar': 'baz'} +``` + +Keys must be unique: + +```meson +# This will fail +my_dict = {'foo': 42, 'foo': 43} +``` + +Dictionaries are immutable and do not have a guaranteed order. + +Dictionaries are available since 0.47.0. + +Visit the [Reference Manual](Reference-manual.md#dictionary-object) to read +about the methods exposed by dictionaries. + +Since 0.49.0, you can check if a dictionary contains a key like this: + +```meson +my_dict = {'foo': 42, 'bar': 43} +if 'foo' in my_dict +# This condition is true +endif +if 42 in my_dict +# This condition is false +endif +if 'foo' not in my_dict +# This condition is false +endif +``` + +*Since 0.53.0* Keys can be any expression evaluating to a string +value, not limited to string literals any more. + +```meson +d = {'a' + 'b' : 42} +k = 'cd' +d += {k : 43} +``` + +## Function calls + +Meson provides a set of usable functions. The most common use case is +creating build objects. + +```meson +executable('progname', 'prog.c') +``` + +Most functions take only few positional arguments but several keyword +arguments, which are specified like this: + +```meson +executable('progname', + sources: 'prog.c', + c_args: '-DFOO=1') +``` + +Starting with version 0.49.0 keyword arguments can be specified +dynamically. This is done by passing dictionary representing the +keywords to set in the `kwargs` keyword. The previous example would be +specified like this: + +```meson +d = {'sources': 'prog.c', + 'c_args': '-DFOO=1'} + +executable('progname', + kwargs: d) +``` + +A single function can take keyword argumets both directly in the +function call and indirectly via the `kwargs` keyword argument. The +only limitation is that it is a hard error to pass any particular key +both as a direct and indirect argument. + +```meson +d = {'c_args': '-DFOO'} +executable('progname', 'prog.c', + c_args: '-DBAZ=1', + kwargs: d) # This is an error! +``` + +Attempting to do this causes Meson to immediately exit with an error. + +## Method calls + +Objects can have methods, which are called with the dot operator. The +exact methods it provides depends on the object. + +```meson +myobj = some_function() +myobj.do_something('now') +``` + +## If statements + +If statements work just like in other languages. + +```meson +var1 = 1 +var2 = 2 +if var1 == var2 # Evaluates to false + something_broke() +elif var3 == var2 + something_else_broke() +else + everything_ok() +endif + +opt = get_option('someoption') +if opt != 'foo' + do_something() +endif +``` + +## Logical operations + +Meson has the standard range of logical operations which can be used in +`if` statements. + +```meson +if a and b + # do something +endif +if c or d + # do something +endif +if not e + # do something +endif +if not (f or g) + # do something +endif +``` + +Logical operations work only on boolean values. + +## Foreach statements + +To do an operation on all elements of an iterable, use the `foreach` +command. + +> Note that Meson variables are immutable. Trying to assign a new value +> to the iterated object inside a foreach loop will not affect foreach's +> control flow. + +### Foreach with an array + +Here's an example of how you could define two executables +with corresponding tests using arrays and foreach. + +```meson +progs = [['prog1', ['prog1.c', 'foo.c']], + ['prog2', ['prog2.c', 'bar.c']]] + +foreach p : progs + exe = executable(p[0], p[1]) + test(p[0], exe) +endforeach +``` + +### Foreach with a dictionary + +Here's an example of you could iterate a set of components that +should be compiled in according to some configuration. This uses +a [dictionary][dictionaries], which is available since 0.47.0. + +```meson +components = { + 'foo': ['foo.c'], + 'bar': ['bar.c'], + 'baz': ['baz.c'], +} + +# compute a configuration based on system dependencies, custom logic +conf = configuration_data() +conf.set('USE_FOO', 1) + +# Determine the sources to compile +sources_to_compile = [] +foreach name, sources : components + if conf.get('USE_@0@'.format(name.to_upper()), 0) == 1 + sources_to_compile += sources + endif +endforeach +``` + +### Foreach `break` and `continue` + +Since 0.49.0 `break` and `continue` keywords can be used inside foreach loops. + +```meson +items = ['a', 'continue', 'b', 'break', 'c'] +result = [] +foreach i : items + if i == 'continue' + continue + elif i == 'break' + break + endif + result += i +endforeach +# result is ['a', 'b'] +``` + +## Comments + +A comment starts with the `#` character and extends until the end of the line. + +```meson +some_function() # This is a comment +some_other_function() +``` + +## Ternary operator + +The ternary operator works just like in other languages. + +```meson +x = condition ? true_value : false_value +``` + +The only exception is that nested ternary operators are forbidden to +improve legibility. If your branching needs are more complex than this +you need to write an `if/else` construct. + +## Includes + +Most source trees have multiple subdirectories to process. These can +be handled by Meson's `subdir` command. It changes to the given +subdirectory and executes the contents of `meson.build` in that +subdirectory. All state (variables etc) are passed to and from the +subdirectory. The effect is roughly the same as if the contents of the +subdirectory's Meson file would have been written where the include +command is. + +```meson +test_data_dir = 'data' +subdir('tests') +``` + +## User-defined functions and methods + +Meson does not currently support user-defined functions or methods. +The addition of user-defined functions would make Meson +Turing-complete which would make it harder to reason about and more +difficult to integrate with tools like IDEs. More details about this +are [in the +FAQ](FAQ.md#why-is-meson-not-just-a-python-module-so-i-could-code-my-build-setup-in-python). +If because of this limitation you find yourself copying and pasting +code a lot you may be able to use a [`foreach` loop +instead](#foreach-statements). + +## Stability Promises + +Meson is very actively developed and continuously improved. There is a +possibility that future enhancements to the Meson build system will +require changes to the syntax. Such changes might be the addition of +new reserved keywords, changing the meaning of existing keywords or +additions around the basic building blocks like statements and +fundamental types. It is planned to stabilize the syntax with the 1.0 +release. + +## Grammar + +This is the full Meson grammar, as it is used to parse Meson build definition files: + +``` +additive_expression: multiplicative_expression | (additive_expression additive_operator multiplicative_expression) +additive_operator: "+" | "-" +argument_list: positional_arguments ["," keyword_arguments] | keyword_arguments +array_literal: "[" [expression_list] "]" +assignment_expression: conditional_expression | (logical_or_expression assignment_operator assignment_expression) +assignment_operator: "=" | "*=" | "/=" | "%=" | "+=" | "-=" +boolean_literal: "true" | "false" +build_definition: (NEWLINE | statement)* +condition: expression +conditional_expression: logical_or_expression | (logical_or_expression "?" expression ":" assignment_expression +decimal_literal: DECIMAL_NUMBER +DECIMAL_NUMBER: /[1-9][0-9]*/ +dictionary_literal: "{" [key_value_list] "}" +equality_expression: relational_expression | (equality_expression equality_operator relational_expression) +equality_operator: "==" | "!=" +expression: assignment_expression +expression_list: expression ("," expression)* +expression_statement: expression +function_expression: id_expression "(" [argument_list] ")" +hex_literal: "0x" HEX_NUMBER +HEX_NUMBER: /[a-fA-F0-9]+/ +id_expression: IDENTIFIER +IDENTIFIER: /[a-zA-Z_][a-zA-Z_0-9]*/ +identifier_list: id_expression ("," id_expression)* +integer_literal: decimal_literal | octal_literal | hex_literal +iteration_statement: "foreach" identifier_list ":" id_expression NEWLINE (statement | jump_statement)* "endforeach" +jump_statement: ("break" | "continue") NEWLINE +key_value_item: expression ":" expression +key_value_list: key_value_item ("," key_value_item)* +keyword_item: id_expression ":" expression +keyword_arguments: keyword_item ("," keyword_item)* +literal: integer_literal | string_literal | boolean_literal | array_literal | dictionary_literal +logical_and_expression: equality_expression | (logical_and_expression "and" equality_expression) +logical_or_expression: logical_and_expression | (logical_or_expression "or" logical_and_expression) +method_expression: postfix_expression "." function_expression +multiplicative_expression: unary_expression | (multiplicative_expression multiplicative_operator unary_expression) +multiplicative_operator: "*" | "/" | "%" +octal_literal: "0o" OCTAL_NUMBER +OCTAL_NUMBER: /[0-7]+/ +positional_arguments: expression ("," expression)* +postfix_expression: primary_expression | subscript_expression | function_expression | method_expression +primary_expression: literal | ("(" expression ")") | id_expression +relational_expression: additive_expression | (relational_expression relational_operator additive_expression) +relational_operator: ">" | "<" | ">=" | "<=" | "in" | ("not" "in") +selection_statement: "if" condition NEWLINE (statement)* ("elif" condition NEWLINE (statement)*)* ["else" (statement)*] "endif" +statement: (expression_statement | selection_statement | iteration_statement) NEWLINE +string_literal: ("'" STRING_SIMPLE_VALUE "'") | ("'''" STRING_MULTILINE_VALUE "'''") +STRING_MULTILINE_VALUE: \.*?(''')\ +STRING_SIMPLE_VALUE: \.*?(?<!\\)(\\\\)*?'\ +subscript_expression: postfix_expression "[" expression "]" +unary_expression: postfix_expression | (unary_operator unary_expression) +unary_operator: "not" | "+" | "-" +``` diff --git a/meson/docs/markdown/Threads.md b/meson/docs/markdown/Threads.md new file mode 100644 index 000000000..b12d4c513 --- /dev/null +++ b/meson/docs/markdown/Threads.md @@ -0,0 +1,20 @@ +--- +short-description: Enabling thread support +... + +# Threads + +Meson has a very simple notational shorthand for enabling thread +support on your build targets. First you obtain the thread dependency +object like this: + +```meson +thread_dep = dependency('threads') +``` + +And then you just use it in a target like this: + +```meson +executable('threadedprogram', ... + dependencies : thread_dep) +``` diff --git a/meson/docs/markdown/Tutorial.md b/meson/docs/markdown/Tutorial.md new file mode 100644 index 000000000..c1942c2fd --- /dev/null +++ b/meson/docs/markdown/Tutorial.md @@ -0,0 +1,209 @@ +--- +short-description: Simplest tutorial +... + +# Tutorial + +This page shows from the ground up how to create a Meson build +definition for a simple project. Then we expand it to use external +dependencies to show how easily they can be integrated into your +project. + +This tutorial has been written mostly for Linux usage. It assumes that +you have GTK development libraries available on the system. On +Debian-derived systems such as Ubuntu they can be installed with the +following command: + +``` +sudo apt install libgtk-3-dev +``` + +It is possible to build the GUI application on other platforms, such +as Windows and macOS, but you need to install the needed dependencies. + +The humble beginning +----- + +Let's start with the most basic of programs, the classic hello +example. First we create a file `main.c` which holds the source. It +looks like this. + +```c +#include <stdio.h> + +// +// main is where all program execution starts +// +int main(int argc, char **argv) { + printf("Hello there.\n"); + return 0; +} +``` + +Then we create a Meson build description and put it in a file called +`meson.build` in the same directory. Its contents are the following. + +```meson +project('tutorial', 'c') +executable('demo', 'main.c') +``` + +That is all. Note that unlike Autotools you [do not need to add any +source headers to the list of +sources](FAQ.md#do-i-need-to-add-my-headers-to-the-sources-list-like-in-autotools). + +We are now ready to build our application. First we need +to initialize the build by going into the source directory and issuing +the following commands. + +```console +$ meson setup builddir +``` + +We create a separate build directory to hold all of the compiler +output. Meson is different from some other build systems in that it +does not permit in-source builds. You must always create a separate +build directory. Common convention is to put the default build +directory in a subdirectory of your top level source directory. + +When Meson is run it prints the following output. + + The Meson build system + version: 0.13.0-research + Source dir: /home/jpakkane/mesontutorial + Build dir: /home/jpakkane/mesontutorial/builddir + Build type: native build + Project name is "tutorial". + Using native c compiler "ccache cc". (gcc 4.8.2) + Creating build target "demo" with 1 files. + +Now we are ready to build our code. + + +```console +$ cd builddir +$ ninja +``` + +If your Meson version is newer than 0.55.0, you can use the new +backend-agnostic build command: + +```console +$ cd builddir +$ meson compile +``` + +For the rest of this document we are going to use the latter form. + +Once the executable is built we can run it. + +```console +$ ./demo +``` + +This produces the expected output. + + Hello there. + +Adding dependencies +----- + +Just printing text is a bit old fashioned. Let's update our program to +create a graphical window instead. We'll use the +[GTK+](https://gtk.org) widget toolkit. First we edit the main file to +use GTK+. The new version looks like this. + +```c + +#include <gtk/gtk.h> + +// +// Should provided the active view for a GTK application +// +static void activate(GtkApplication* app, gpointer user_data) +{ + GtkWidget *window; + GtkWidget *label; + + window = gtk_application_window_new (app); + label = gtk_label_new("Hello GNOME!"); + gtk_container_add (GTK_CONTAINER (window), label); + gtk_window_set_title(GTK_WINDOW (window), "Welcome to GNOME"); + gtk_window_set_default_size(GTK_WINDOW (window), 200, 100); + gtk_widget_show_all(window); +} // end of function activate + +// +// main is where all program execution starts +// +int main(int argc, char **argv) +{ + GtkApplication *app; + int status; + + app = gtk_application_new(NULL, G_APPLICATION_FLAGS_NONE); + g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); + status = g_application_run(G_APPLICATION(app), argc, argv); + g_object_unref(app); + + return status; +} // end of function main +``` + +Then we edit the Meson file, instructing it to find and use the GTK+ +libraries. + +```meson +project('tutorial', 'c') +gtkdep = dependency('gtk+-3.0') +executable('demo', 'main.c', dependencies : gtkdep) +``` + +If your app needs to use multiple libraries, you need to use separate +[`dependency()`](Reference-manual.md#dependency) calls for each, like so: + +```meson +gtkdeps = [dependency('gtk+-3.0'), dependency('gtksourceview-3.0')] +``` + +We don't need it for the current example. + +Now we are ready to build. The thing to notice is that we do *not* +need to recreate our build directory, run any sort of magical commands +or the like. Instead we just type the exact same command as if we were +rebuilding our code without any build system changes. + +```console +$ meson compile +``` + +Once you have set up your build directory the first time, you don't +ever need to run the `meson` command again. You always just run `meson +compile`. Meson will automatically detect when you have done changes +to build definitions and will take care of everything so users don't +have to care. In this case the following output is produced. + + [1/1] Regenerating build files + The Meson build system + version: 0.13.0-research + Source dir: /home/jpakkane/mesontutorial + Build dir: /home/jpakkane/mesontutorial/builddir + Build type: native build + Project name is "tutorial". + Using native c compiler "ccache cc". (gcc 4.8.2) + Found pkg-config version 0.26. + Dependency gtk+-3.0 found: YES + Creating build target "demo" with 1 files. + [1/2] Compiling c object demo.dir/main.c.o + [2/2] Linking target demo + +Note how Meson noticed that the build definition has changed and reran +itself automatically. The program is now ready to be run: + +``` +$ ./demo +``` + +This creates the following GUI application. + +![GTK+ sample application screenshot](images/gtksample.png) diff --git a/meson/docs/markdown/Unit-tests.md b/meson/docs/markdown/Unit-tests.md new file mode 100644 index 000000000..5233a4fe8 --- /dev/null +++ b/meson/docs/markdown/Unit-tests.md @@ -0,0 +1,270 @@ +--- +short-description: Meson's own unit-test system +... + +# Unit tests + +Meson comes with a fully functional unit test system. To use it simply +build an executable and then use it in a test. + +```meson +e = executable('prog', 'testprog.c') +test('name of test', e) +``` + +You can add as many tests as you want. They are run with the command `meson +test`. + +Meson captures the output of all tests and writes it in the log file +`meson-logs/testlog.txt`. + +## Test parameters + +Some tests require the use of command line arguments or environment +variables. These are simple to define. + +```meson +test('command line test', exe, args : ['first', 'second']) +test('envvar test', exe2, env : ['key1=value1', 'key2=value2']) +``` + +Note how you need to specify multiple values as an array. + +### MALLOC_PERTURB_ + +By default, environment variable +[`MALLOC_PERTURB_`](http://man7.org/linux/man-pages/man3/mallopt.3.html) is +set to a random value between 1..255. This can help find memory leaks on +configurations using glibc, including with non-GCC compilers. This feature +can be disabled as discussed in [test()](Reference-manual.md#test). + +## Coverage + +If you enable coverage measurements by giving Meson the command line +flag `-Db_coverage=true`, you can generate coverage reports after +running the tests (running the tests is required to gather the list of +functions that get called). Meson will autodetect what coverage +generator tools you have installed and will generate the corresponding +targets. These targets are `coverage-xml` and `coverage-text` which +are both provided by [Gcovr](http://gcovr.com) (version 3.3 or higher) +and `coverage-html`, which requires +[Lcov](https://ltp.sourceforge.io/coverage/lcov.php) and +[GenHTML](https://linux.die.net/man/1/genhtml) or +[Gcovr](http://gcovr.com). As a convenience, a high-level `coverage` +target is also generated which will produce all 3 coverage report +types, if possible. + +The output of these commands is written to the log directory `meson-logs` in +your build directory. + +## Parallelism + +To reduce test times, Meson will by default run multiple unit tests in +parallel. It is common to have some tests which can not be run in +parallel because they require unique hold on some resource such as a +file or a D-Bus name. You have to specify these tests with a keyword +argument. + +```meson +test('unique test', t, is_parallel : false) +``` + +Meson will then make sure that no other unit test is running at the +same time. Non-parallel tests take longer to run so it is recommended +that you write your unit tests to be parallel executable whenever +possible. + +By default Meson uses as many concurrent processes as there are cores +on the test machine. You can override this with the environment +variable `MESON_TESTTHREADS` like this. + +```console +$ MESON_TESTTHREADS=5 meson test +``` + +## Priorities + +*(added in version 0.52.0)* + +Tests can be assigned a priority that determines when a test is +*started*. Tests with higher priority are started first, tests with +lower priority started later. The default priority is 0, Meson makes +no guarantee on the ordering of tests with identical priority. + +```meson +test('started second', t, priority : 0) +test('started third', t, priority : -50) +test('started first', t, priority : 1000) +``` + +Note that the test priority only affects the starting order of tests +and subsequent tests are affected by how long it takes previous tests +to complete. It is thus possible that a higher-priority test is still +running when lower-priority tests with a shorter runtime have +completed. + +## Skipped tests and hard errors + +Sometimes a test can only determine at runtime that it can not be run. + +For the default `exitcode` testing protocol, the GNU standard approach +in this case is to exit the program with error code 77. Meson will +detect this and report these tests as skipped rather than failed. This +behavior was added in version 0.37.0. + +For TAP-based tests, skipped tests should print a single line starting +with `1..0 # SKIP`. + +In addition, sometimes a test fails set up so that it should fail even +if it is marked as an expected failure. The GNU standard approach in +this case is to exit the program with error code 99. Again, Meson will +detect this and report these tests as `ERROR`, ignoring the setting of +`should_fail`. This behavior was added in version 0.50.0. + +## Testing tool + +The goal of the Meson test tool is to provide a simple way to run +tests in a variety of different ways. The tool is designed to be run +in the build directory. + +The simplest thing to do is just to run all tests. + +```console +$ meson test +``` + +### Run subsets of tests + +For clarity, consider the meson.build containing: + +```meson + +test('A', ..., suite: 'foo') +test('B', ..., suite: ['foo', 'bar']) +test('C', ..., suite: 'bar') +test('D', ..., suite: 'baz') + +``` + +Specify test(s) by name like: + +```console +$ meson test A D +``` + +Tests belonging to a suite `suite` can be run as follows + +```console +$ meson test --suite (sub)project_name:suite +``` + +Since version *0.46*, `(sub)project_name` can be omitted if it is the +top-level project. + +Multiple suites are specified like: + +```console +$ meson test --suite foo --suite bar +``` + +NOTE: If you choose to specify both suite(s) and specific test +name(s), the test name(s) must be contained in the suite(s). This +however is redundant-- it would be more useful to specify either +specific test names or suite(s). + +### Other test options + +Sometimes you need to run the tests multiple times, which is done like this: + +```console +$ meson test --repeat=10 +``` + +Invoking tests via a helper executable such as Valgrind can be done with the +`--wrap` argument + +```console +$ meson test --wrap=valgrind testname +``` + +Arguments to the wrapper binary can be given like this: + +```console +$ meson test --wrap='valgrind --tool=helgrind' testname +``` + +Meson also supports running the tests under GDB. Just doing this: + +```console +$ meson test --gdb testname +``` + +Meson will launch `gdb` all set up to run the test. Just type `run` in +the GDB command prompt to start the program. + +The second use case is a test that segfaults only rarely. In this case +you can invoke the following command: + +```console +$ meson test --gdb --repeat=10000 testname +``` + +This runs the test up to 10 000 times under GDB automatically. If the +program crashes, GDB will halt and the user can debug the application. +Note that testing timeouts are disabled in this case so `meson test` +will not kill `gdb` while the developer is still debugging it. The +downside is that if the test binary freezes, the test runner will wait +forever. + +Sometimes, the GDB binary is not in the PATH variable or the user +wants to use a GDB replacement. Therefore, the invoked GDB program can +be specified *(added 0.52.0)*: + +```console +$ meson test --gdb --gdb-path /path/to/gdb testname +``` + +```console +$ meson test --print-errorlogs +``` + +Meson will report the output produced by the failing tests along with +other useful information as the environmental variables. This is +useful, for example, when you run the tests on Travis-CI, Jenkins and +the like. + +For further information see the command line help of Meson by running +`meson test -h`. + +## Legacy notes + +If `meson test` does not work for you, you likely have a old version +of Meson. In that case you should call `mesontest` instead. If +`mesontest` doesn't work either you have a very old version prior to +0.37.0 and should upgrade. + +## Test outputs + +Meson will write several different files with detailed results of +running tests. These will be written into $builddir/meson-logs/ + +### testlog.json + +This is not a proper json file, but a file containing one valid json +object per line. This is file is designed so each line is streamed out +as each test is run, so it can be read as a stream while the test +harness is running + +### testlog.junit.xml + +This is a valid JUnit XML description of all tests run. It is not +streamed out, and is written only once all tests complete running. + +When tests use the `tap` protocol each test will be recorded as a +testsuite container, with each case named by the number of the result. + +When tests use the `gtest` protocol Meson will inject arguments to the +test to generate it's own JUnit XML, which Meson will include as part +of this XML file. + +*New in 0.55.0* diff --git a/meson/docs/markdown/Unity-builds.md b/meson/docs/markdown/Unity-builds.md new file mode 100644 index 000000000..833383d88 --- /dev/null +++ b/meson/docs/markdown/Unity-builds.md @@ -0,0 +1,39 @@ +--- +short-description: Unity builds are a technique for reducing build times +... + +# Unity builds + +Unity builds are a technique for cutting down build times. The way it +works is relatively straightforward. Suppose we have source files +`src1.c`, `src2.c` and `src3.c`. Normally we would run the compiler +three times, once for each file. In a unity build we instead compile +all these sources in a single unit. The simplest approach is to create +a new source file that looks like this. + +```c +#include<src1.c> +#include<src2.c> +#include<src3.c> +``` + +This is then compiled rather than the individual files. The exact +speedup depends on the code base, of course, but it is not uncommon to +obtain more than 50% speedup in compile times. This happens even +though the Unity build uses only one CPU whereas individual compiles +can be run in parallel. Unity builds can also lead to faster code, +because the compiler can do more aggressive optimizations (e.g. +inlining). + +The downside is that incremental builds are as slow as full rebuilds +(because that is what they are). Unity compiles also use more memory, +which may become an issue in certain scenarios. There may also be some +bugs in the source that need to be fixed before Unity compiles work. +As an example, if both `src1.c` and `src2.c` contain a static function +or variable of the same name, there will be a clash. + +Meson has built-in support for unity builds. To enable them, just pass +`--unity on` on the command line or enable unity builds with the GUI. +No code changes are necessary apart from the potential clash issue +discussed above. Meson will automatically generate all the necessary +inclusion files for you. diff --git a/meson/docs/markdown/Use-of-Python.md b/meson/docs/markdown/Use-of-Python.md new file mode 100644 index 000000000..e69a39791 --- /dev/null +++ b/meson/docs/markdown/Use-of-Python.md @@ -0,0 +1,48 @@ +# Use of Python + +Meson is implemented in Python. This has both positive and negative +sides. The main thing people seem to be mindful about is the +dependency on Python to build source code. This page discusses various +aspects of this problem. + +# Dependency hell + +There have been many Python programs that are difficult to maintain on +multiple platforms. The reasons come mostly from dependencies. The +program may use dependencies that are hard to compile on certain +platforms, are outdated, conflict with other dependencies, not +available on a given Python version and so on. + +Meson avoids dependency problems with one simple rule: Meson is not +allowed to have any dependencies outside the Python basic library. The +only thing you need is Python 3 (and possibly Ninja). + +## Reimplementability + +Meson has been designed in such a way that the implementation language +is never exposed in the build definitions. This makes it possible (and +maybe even easy) to reimplement Meson in any other programming +language. There are currently no plans to reimplement Meson, but we +will make sure that Python is not exposed inside the build +definitions. + +## Cross platform tooling + +There is no one technical solution or programming language that works +natively on all operating systems currently in use. When Autotools was +designed in the late 80s, Unix shell was available pretty much +anywhere. This is no longer the case. + +It is also the case that as any project gets larger, sooner or later +it requires code generation, scripting or other tooling. This seems to +be inevitable. Because there is no scripting language that would be +available everywhere, these tools either need to be rewritten for each +platform (which is a lot of work and is prone to errors) or the +project needs to take a dependency on _something_. + +Any project that uses Meson (at least the current version) can rely on +the fact that Python 3 will always be available, because you can't +compile the project without it. All tooling can then be done in Python +3 with the knowledge that it will run on any platform without any +extra dependencies (modulo the usual porting work). This reduces +maintenance effort on multiplatform projects by a fair margin. diff --git a/meson/docs/markdown/Users.md b/meson/docs/markdown/Users.md new file mode 100644 index 000000000..032ec1ed3 --- /dev/null +++ b/meson/docs/markdown/Users.md @@ -0,0 +1,158 @@ +--- +title: Users +... + +# List of projects using Meson + +If you have a project that uses Meson that you want to add to this +list, please [file a +pull-request](https://github.com/mesonbuild/meson/edit/master/docs/markdown/Users.md) +for it. All the software on this list is tested for regressions before +release, so it's highly recommended that projects add themselves +here. Some additional projects are listed in the [`meson` GitHub +topic](https://github.com/topics/meson). + + - [2048.cpp](https://github.com/plibither8/2048.cpp), a fully featured terminal version of the game "2048" written in C++ + - [Aravis](https://github.com/AravisProject/aravis), a glib/gobject based library for video acquisition using Genicam cameras + - [Akira](https://github.com/akiraux/Akira), a native Linux app for UI and UX design built in Vala and Gtk + - [AQEMU](https://github.com/tobimensch/aqemu), a Qt GUI for QEMU virtual machines, since version 0.9.3 + - [Arduino sample project](https://github.com/jpakkane/mesonarduino) + - [bolt](https://gitlab.freedesktop.org/bolt/bolt), userspace daemon to enable security levels for Thunderbolt™ 3 on Linux + - [Budgie Desktop](https://github.com/budgie-desktop/budgie-desktop), a desktop environment built on GNOME technologies + - [Bzip2](https://gitlab.com/federicomenaquintero/bzip2), the bzip2 compressor/decompressor + - [Cage](https://github.com/Hjdskes/cage), a Wayland kiosk + - [canfigger](https://github.com/andy5995/canfigger), simple configuration file parser library + - [casync](https://github.com/systemd/casync), Content-Addressable Data Synchronization Tool + - [cinnamon-desktop](https://github.com/linuxmint/cinnamon-desktop), the cinnamon desktop library + - [Cozy](https://github.com/geigi/cozy), a modern audio book player for Linux and macOS using GTK+ 3 + - [dav1d](https://code.videolan.org/videolan/dav1d), an AV1 decoder + - [dbus-broker](https://github.com/bus1/dbus-broker), Linux D-Bus Message Broker + - [DOSBox Staging](https://github.com/dosbox-staging/dosbox-staging), DOS/x86 emulator + - [DPDK](http://dpdk.org/browse/dpdk), Data Plane Development Kit, a set of libraries and drivers for fast packet processing + - [DXVK](https://github.com/doitsujin/dxvk), a Vulkan-based Direct3D 11 implementation for Linux using Wine + - [elementary OS](https://github.com/elementary/), Linux desktop oriented distribution + - [Emeus](https://github.com/ebassi/emeus), constraint based layout manager for GTK+ + - [Entangle](https://entangle-photo.org/), tethered camera control and capture desktop application + - [ESP8266 Arduino sample project](https://github.com/trilader/arduino-esp8266-meson), sample project for using the ESP8266 Arduino port with Meson + - [FeedReader](https://github.com/jangernert/FeedReader), a modern desktop application designed to complement existing web-based RSS accounts + - [Flecs](https://github.com/SanderMertens/flecs), a Fast and Lightweight ECS (Entity Component System) C library + - [Foliate](https://github.com/johnfactotum/foliate), a simple and modern GTK eBook reader, built with GJS and Epub.js + - [Fractal](https://wiki.gnome.org/Apps/Fractal/), a Matrix messaging client for GNOME + - [Frida](https://github.com/frida/frida-core), a dynamic binary instrumentation toolkit + - [fwupd](https://github.com/hughsie/fwupd), a simple daemon to allow session software to update firmware + - [GameMode](https://github.com/FeralInteractive/gamemode), a daemon/lib combo for Linux that allows games to request a set of optimisations be temporarily applied to the host OS + - [Geary](https://wiki.gnome.org/Apps/Geary), an email application built around conversations, for the GNOME 3 desktop. + - [GLib](https://gitlab.gnome.org/GNOME/glib), cross-platform C library used by GTK+ and GStreamer + - [Glorytun](https://github.com/angt/glorytun), a multipath UDP tunnel + - [GNOME Boxes](https://gitlab.gnome.org/GNOME/gnome-boxes), a GNOME hypervisor + - [GNOME Builder](https://gitlab.gnome.org/GNOME/gnome-builder), an IDE for the GNOME platform + - [GNOME MPV](https://github.com/gnome-mpv/gnome-mpv), GNOME frontend to the mpv video player + - [GNOME Recipes](https://gitlab.gnome.org/GNOME/recipes), application for cooking recipes + - [GNOME Software](https://gitlab.gnome.org/GNOME/gnome-software), an app store for GNOME + - [GNOME Twitch](https://github.com/vinszent/gnome-twitch), an app for viewing Twitch streams on GNOME desktop + - [GNOME Usage](https://gitlab.gnome.org/GNOME/gnome-usage), a GNOME application for visualizing system resources + - [GNU FriBidi](https://github.com/fribidi/fribidi), the open source implementation of the Unicode Bidirectional Algorithm + - [Graphene](https://ebassi.github.io/graphene/), a thin type library for graphics + - [Grilo](https://git.gnome.org/browse/grilo) and [Grilo plugins](https://git.gnome.org/browse/grilo-plugins), the Grilo multimedia framework + - [GStreamer](https://gitlab.freedesktop.org/gstreamer/gstreamer), multimedia framework + - [GTK+](https://gitlab.gnome.org/GNOME/gtk), the multi-platform toolkit used by GNOME + - [GtkDApp](https://gitlab.com/csoriano/GtkDApp), an application template for developing Flatpak apps with Gtk+ and D + - [GVfs](https://git.gnome.org/browse/gvfs/), a userspace virtual filesystem designed to work with the I/O abstraction of GIO + - [Hardcode-Tray](https://github.com/bil-elmoussaoui/Hardcode-Tray), fixes hardcoded tray icons in Linux + - [HarfBuzz](https://github.com/harfbuzz/harfbuzz), a text shaping engine + - [HelenOS](http://helenos.org), a portable microkernel-based multiserver operating system + - [HexChat](https://github.com/hexchat/hexchat), a cross-platform IRC client in C + - [IGT](https://gitlab.freedesktop.org/drm/igt-gpu-tools), Linux kernel graphics driver test suite + - [inih](https://github.com/benhoyt/inih) (INI Not Invented Here), a small and simple .INI file parser written in C + - [Irssi](https://github.com/irssi/irssi), a terminal chat client in C + - [iSH](https://github.com/tbodt/ish), Linux shell for iOS + - [Janet](https://github.com/janet-lang/janet), a functional and imperative programming language and bytecode interpreter + - [json](https://github.com/nlohmann/json), JSON for Modern C++ + - [JsonCpp](https://github.com/open-source-parsers/jsoncpp), a C++ library for interacting with JSON + - [Json-glib](https://gitlab.gnome.org/GNOME/json-glib), GLib-based JSON manipulation library + - [Kiwix libraries](https://github.com/kiwix/kiwix-lib) + - [Knot Resolver](https://gitlab.labs.nic.cz/knot/knot-resolver), Full caching DNS resolver implementation + - [Ksh](https://github.com/att/ast), a Korn Shell + - [Lc0](https://github.com/LeelaChessZero/lc0), LeelaChessZero is a UCI-compliant chess engine designed to play chess via neural network + - [Le](https://github.com/kirushyk/le), machine learning framework + - [libcamera](https://git.linuxtv.org/libcamera.git/), a library to handle complex cameras on Linux, ChromeOS and Android + - [Libdrm](https://gitlab.freedesktop.org/mesa/drm), a library for abstracting DRM kernel interfaces + - [libeconf](https://github.com/openSUSE/libeconf), Enhanced config file parsing library, which merges config files placed in several locations into one + - [Libepoxy](https://github.com/anholt/libepoxy/), a library for handling OpenGL function pointer management + - [libfuse](https://github.com/libfuse/libfuse), the reference implementation of the Linux FUSE (Filesystem in Userspace) interface + - [Libgit2-glib](https://git.gnome.org/browse/libgit2-glib), a GLib wrapper for libgit2 + - [libglvnd](https://gitlab.freedesktop.org/glvnd/libglvnd), Vendor neutral OpenGL dispatch library for Unix-like OSes + - [Libhttpseverywhere](https://git.gnome.org/browse/libhttpseverywhere), a library to enable httpseverywhere on any desktop app + - [libmodulemd](https://github.com/fedora-modularity/libmodulemd), a GObject Introspected library for managing [Fedora Project](https://getfedora.org/) module metadata. + - [Libosmscout](https://github.com/Framstag/libosmscout), a C++ library for offline map rendering, routing and location +lookup based on OpenStreetMap data + - [libratbag](https://github.com/libratbag/libratbag), provides a DBus daemon to configure input devices, mainly gaming mice. + - [libspng](https://github.com/randy408/libspng), a C library for reading and writing Portable Network Graphics (PNG) +format files + - [libui](https://github.com/andlabs/libui), a simple and portable (but not inflexible) GUI library in C that uses the native GUI technologies of each platform it supports + - [Libva](https://github.com/intel/libva), an implementation for the VA (VIdeo Acceleration) API + - [Libvirt](https://libvirt.org), a toolkit to manage virtualization platforms + - [Libzim](https://github.com/openzim/libzim), the reference implementation for the ZIM file format + - [Marker](https://github.com/fabiocolacio/Marker), a GTK-3 markdown editor + - [Mesa](https://gitlab.freedesktop.org/mesa/mesa/), an open source graphics driver project + - [MiracleCast](https://github.com/albfan/miraclecast), connect external monitors to your system via Wifi-Display specification aka Miracast + - [mrsh](https://github.com/emersion/mrsh), a minimal POSIX shell + - [Nautilus](https://gitlab.gnome.org/GNOME/nautilus), the GNOME file manager + - [Nemo](https://github.com/linuxmint/nemo), the file manager for the Cinnamon desktop environment + - [OcherBook](https://github.com/ccoffing/OcherBook), an open source book reader for Kobo devices + - [oomd](https://github.com/facebookincubator/oomd), a userspace Out-Of-Memory (OOM) killer for Linux systems + - [OpenH264](https://github.com/cisco/openh264), open source H.264 codec + - [OpenHMD](https://github.com/OpenHMD/OpenHMD), a free and open source API and drivers for immersive technology, such as head mounted displays with built in head tracking + - [OpenTitan](https://github.com/lowRISC/opentitan), an open source silicon Root of Trust (RoT) project. + - [Orc](https://gitlab.freedesktop.org/gstreamer/orc), the Optimized Inner Loop Runtime Compiler + - [OTS](https://github.com/khaledhosny/ots), the OpenType Sanitizer, parses and serializes OpenType files (OTF, TTF) and WOFF and WOFF2 font files, validating and sanitizing them as it goes. Used by Chromium and Firefox + - [Outlier](https://github.com/kerolasa/outlier), a small Hello World style Meson example project + - [p11-kit](https://github.com/p11-glue/p11-kit), PKCS#11 module aggregator + - [Pacman](https://gitlab.archlinux.org/pacman/pacman.git), a package manager for Arch Linux + - [Pango](https://git.gnome.org/browse/pango/), an Internationalized text layout and rendering library + - [Parzip](https://github.com/jpakkane/parzip), a multithreaded reimplementation of Zip + - [Peek](https://github.com/phw/peek), simple animated GIF screen recorder with an easy to use interface + - [PicoLibc](https://github.com/keith-packard/picolibc), a standard C library for small embedded systems with limited RAM + - [PipeWire](https://github.com/PipeWire/pipewire), a framework for video and audio for containerized applications + - [Paper Rock Scissors](https://github.com/michaelbrockus/paper_rock_scissors), a game with weapons themed at home paper rock scissors style. + - [Pithos](https://github.com/pithos/pithos), a Pandora Radio client + - [Pitivi](https://github.com/pitivi/pitivi/), a nonlinear video editor + - [Playerctl](https://github.com/acrisci/playerctl), mpris command-line controller and library for spotify, vlc, audacious, bmp, cmus, and others + - [Polari](https://gitlab.gnome.org/GNOME/polari), an IRC client + - [qboot](https://github.com/bonzini/qboot), a minimal x86 firmware for booting Linux kernels + - [radare2](https://github.com/radare/radare2), unix-like reverse engineering framework and commandline tools (not the default) + - [rmw](https://remove-to-waste.info), safe-remove utility for the command line + - [Rizin](https://rizin.re), Free and Open Source Reverse Engineering Framework + - [QEMU](https://qemu.org), a processor emulator and virtualizer + - [RxDock](https://gitlab.com/rxdock/rxdock), a protein-ligand docking software designed for high throughput virtual screening (fork of rDock) + - [scrcpy](https://github.com/Genymobile/scrcpy), a cross platform application that provides display and control of Android devices connected on USB or over TCP/IP + - [Sequeler](https://github.com/Alecaddd/sequeler), a friendly SQL client for Linux, built with Vala and Gtk + - [Siril](https://gitlab.com/free-astro/siril), an image processing software for amateur astronomy + - [SSHFS](https://github.com/libfuse/sshfs), allows you to mount a remote filesystem using SFTP + - [sway](https://github.com/swaywm/sway), i3-compatible Wayland compositor + - [Sysprof](https://git.gnome.org/browse/sysprof), a profiling tool + - [systemd](https://github.com/systemd/systemd), the init system + - [szl](https://github.com/dimkr/szl), a lightweight, embeddable scripting language + - [Taisei Project](https://taisei-project.org/), an open-source Touhou Project clone and fangame + - [Terminology](https://github.com/billiob/terminology), a terminal emulator based on the Enlightenment Foundation Libraries + - [Tilix](https://github.com/gnunn1/tilix), a tiling terminal emulator for Linux using GTK+ 3 + - [Tizonia](https://github.com/tizonia/tizonia-openmax-il), a command-line cloud music player for Linux with support for Spotify, Google Play Music, YouTube, SoundCloud, TuneIn, Plex servers and Chromecast devices + - [UFJF-MLTK](https://github.com/mateus558/UFJF-Machine-Learning-Toolkit), A C++ cross-platform framework for machine learning algorithms development and testing + - [Vala Language Server](https://github.com/benwaffle/vala-language-server), code intelligence engine for the Vala and Genie programming languages + - [Valum](https://github.com/valum-framework/valum), a micro web framework written in Vala + - [Venom](https://github.com/naxuroqa/Venom), a modern Tox client for the GNU/Linux desktop + - [VMAF](https://github.com/Netflix/vmaf) (by Netflix), a perceptual video quality assessment based on multi-method fusion + - [Wayland](https://github.com/wayland-project/wayland) and [Weston](https://github.com/wayland-project/weston), a next generation display server + - [wlroots](https://github.com/swaywm/wlroots), a modular Wayland compositor library + - [wxFormBuilder](https://github.com/wxFormBuilder/wxFormBuilder), RAD tool for wxWidgets GUI design + - [xi-gtk](https://github.com/eyelash/xi-gtk), a GTK+ front-end for the Xi editor + - [Xorg](https://gitlab.freedesktop.org/xorg/xserver), the X.org display server (not the default yet) + - [X Test Suite](https://gitlab.freedesktop.org/xorg/test/xts), The X.org test suite + - [zathura](https://github.com/pwmt/zathura), a highly customizable and functional document viewer based on the +girara user interface library and several document libraries + - [Zrythm](https://git.zrythm.org/cgit/zrythm), a cross-platform digital audio workstation using GTK+ 3 + - [ZStandard](https://github.com/facebook/zstd/commit/4dca56ed832c6a88108a2484a8f8ff63d8d76d91), a compression algorithm developed at Facebook (not used by default) + +Note that a more up-to-date list of GNOME projects that use Meson can +be found +[here](https://wiki.gnome.org/Initiatives/GnomeGoals/MesonPorting). diff --git a/meson/docs/markdown/Using-multiple-build-directories.md b/meson/docs/markdown/Using-multiple-build-directories.md new file mode 100644 index 000000000..557f3444d --- /dev/null +++ b/meson/docs/markdown/Using-multiple-build-directories.md @@ -0,0 +1,93 @@ +# Using multiple build directories + +One of the main design goals of Meson has been to build all projects +out-of-source. This means that *all* files generated during the build +are placed in a separate subdirectory. This goes against common Unix +tradition where you build your projects in-source. Building out of +source gives two major advantages. + +First of all this makes for very simple `.gitignore` files. In +classical build systems you may need to have tens of lines of +definitions, most of which contain wildcards. When doing out of source +builds all of this busywork goes away. A common ignore file for a +Meson project only contains a few lines that are the build directory +and IDE project files. + +Secondly this makes it very easy to clean your projects: just delete +the build subdirectory and you are done. There is no need to guess +whether you need to run `make clean`, `make distclean`, `make +mrproper` or something else. When you delete a build subdirectory +there is no possible way to have any lingering state from your old +builds. + +The true benefit comes from somewhere else, though. + +## Multiple build directories for the same source tree + +Since a build directory is fully self contained and treats the source +tree as a read-only piece of data, it follows that you can have +arbitrarily many build trees for any source tree at the same time. +Since all build trees can have different configuration, this is +extremely powerful. Now you might be wondering why one would want to +have multiple build setups at the same time. Let's examine this by +setting up a hypothetical project. + +The first thing to do is to set up the default build, that is, the one +we are going to use over 90% of the time. In this we use the system +compiler and build with debug enabled and no optimizations so it +builds as fast as possible. This is the default project type for +Meson, so setting it up is simple. + + mkdir builddir + meson builddir + +Another common setup is to build with debug and optimizations to, for +example, run performance tests. Setting this up is just as simple. + + mkdir buildopt + meson --buildtype=debugoptimized buildopt + +For systems where the default compiler is GCC, we would like to +compile with Clang, too. So let's do that. + + mkdir buildclang + CC=clang CXX=clang++ meson buildclang + +You can add cross builds, too. As an example, let's set up a Linux -> +Windows cross compilation build using MinGW. + + mkdir buildwine + meson --cross-file=mingw-cross.txt buildwine + +The cross compilation file sets up Wine so that not only can you +compile your application, you can also run the unit test suite just by +issuing the command `meson test`. + +To compile any of these build types, just cd into the corresponding +build directory and run `meson compile` or instruct your IDE to do the +same. Note that once you have set up your build directory once, you +can just run Ninja and Meson will ensure that the resulting build is +fully up to date according to the source. Even if you have not touched +one of the directories in weeks and have done major changes to your +build configuration, Meson will detect this and bring the build +directory up to date (or print an error if it can't do that). This +allows you to do most of your work in the default directory and use +the others every now and then without having to babysit your build +directories. + +## Specialized uses + +Separate build directories allows easy integration for various +different kinds of tools. As an example, Clang comes with a static +analyzer. It is meant to be run from scratch on a given source tree. +The steps to run it with Meson are very simple. + + rm -rf buildscan + mkdir buildscan + scan-build meson buildscan + cd buildscan + scan-build ninja + +These commands are the same for every single Meson project, so they +could even be put in a script turning static analysis into a single +command. diff --git a/meson/docs/markdown/Using-the-WrapDB.md b/meson/docs/markdown/Using-the-WrapDB.md new file mode 100644 index 000000000..baccfdc17 --- /dev/null +++ b/meson/docs/markdown/Using-the-WrapDB.md @@ -0,0 +1,47 @@ +# Using the WrapDB + +The Wrap database is a web service that provides Meson build +definitions to projects that do not have it natively. Using it is +simple. The service can be found +[here](https://wrapdb.mesonbuild.com). + +The front page lists all projects that are on the service. Select the +one you want and click it. The detail page lists available versions by +branch and revision id. The branch names come from upstream releases +and revision ids are version numbers internal to the database. +Whenever the packaging is updated a new revision is released to the +service a new revision with a bigger revision id is added. Usually you +want to select the newest branch with the highest revision id. + +You can get the actual wrap file which tells Meson how to fetch the +project by clicking on the download link on the page. As an example, +the wrap file for [zlib-1.2.8, revision +4](https://wrapdb.mesonbuild.com/v1/projects/zlib/1.2.8/4/get_wrap) +looks like this. You can find detailed documentation about it in [the +Wrap manual](Wrap-dependency-system-manual.md). + + [wrap-file] + directory = zlib-1.2.8 + + source_url = http://zlib.net/zlib-1.2.8.tar.gz + source_filename = zlib-1.2.8.tar.gz + source_hash = 36658cb768a54c1d4dec43c3116c27ed893e88b02ecfcb44f2166f9c0b7f2a0d + + patch_url = https://wrapdb.mesonbuild.com/v1/projects/zlib/1.2.8/4/get_zip + patch_filename = zlib-1.2.8-4-wrap.zip + patch_hash = 2327a42c8f73a4289ee8c9cd4abc43b324d0decc28d6e609e927f0a50321af4a + +Add this file to your project with the name `subprojects/zlib.wrap`. +Then you can use it in your `meson.build` file with this directive: + + zproj = subproject('zlib') + +When Meson encounters this it will automatically download, unpack and +patch the source files. + +## Contributing build definitions + +The contents of the Wrap database are tracked in git repos of the +[Mesonbuild project](https://github.com/mesonbuild). The actual +process is simple and described in [submission +documentation](Adding-new-projects-to-wrapdb.md). diff --git a/meson/docs/markdown/Using-with-Visual-Studio.md b/meson/docs/markdown/Using-with-Visual-Studio.md new file mode 100644 index 000000000..2680e8baf --- /dev/null +++ b/meson/docs/markdown/Using-with-Visual-Studio.md @@ -0,0 +1,47 @@ +--- +short-description: How to use Meson in Visual Studio +... + +# Using with Visual Studio + +In order to generate Visual Studio projects, Meson needs to know the +settings of your installed version of Visual Studio. The only way to +get this information is to run Meson under the Visual Studio Command +Prompt. + +You can always find the Visual Studio Command Prompt by searching from +the Start Menu. However, the name is different for each Visual Studio +version. With Visual Studio 2019, look for "x64 Native Tools Command +Prompt for VS 2019". The next steps are [the same as +always](https://mesonbuild.com/Running-Meson.html#configuring-the-build-directory): + +1. `cd` into your source directory +1. `meson setup builddir`, which will create and setup the build directory +1. `meson compile -C builddir`, to compile your code. You can also use `ninja -C builddir` here if you are using the default Ninja backend. + +If you wish to generate Visual Studio project files, pass `--backend +vs`. At the time of writing the Ninja backend is more mature than the +VS backend so you might want to use it for serious work. + +# Using Clang-CL with Visual Studio + +*(new in 0.52.0)* + +You will first need to get a copy of llvm+clang for Windows, such versions +are available from a number of sources, including the llvm website. Then you +will need the [llvm toolset extension for visual +studio](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.llvm-toolchain). +You then need to either use a [native file](Native-environments.md#binaries) +or `set CC=clang-cl`, and `set CXX=clang-cl` to use those compilers, Meson +will do the rest. + +This only works with visual studio 2017 and 2019. + +There is currently no support in Meson for clang/c2. + +# Using Intel-CL (ICL) with Visual Studio + +*(new in 0.52.0)* + +To use ICL you need only have ICL installed and launch an ICL development +shell like you would for the ninja backend and Meson will take care of it. diff --git a/meson/docs/markdown/Using-wraptool.md b/meson/docs/markdown/Using-wraptool.md new file mode 100644 index 000000000..ffa8309cf --- /dev/null +++ b/meson/docs/markdown/Using-wraptool.md @@ -0,0 +1,78 @@ +# Using wraptool + +Wraptool is a subcommand of Meson that allows you to manage your +source dependencies using the WrapDB database. It gives you all things +you would expect, such as installing and updating dependencies. The +wrap tool works on all platforms, the only limitation is that the wrap +definition works on your target platform. If you find some Wraps that +don't work, please file bugs or, even better, patches. + +All code examples here assume that you are running the commands in +your top level source directory. Lines that start with the `$` mark +are commands to type. + +## Simple querying + +The simplest operation to do is to query the list of packages +available. To list them all issue the following command: + + $ meson wrap list + box2d + enet + gtest + libjpeg + liblzma + libpng + libxml2 + lua + ogg + sqlite + vorbis + zlib + +Usually you want to search for a specific package. This can be done +with the `search` command: + + $ meson wrap search jpeg + libjpeg + +To determine which versions of libjpeg are available to install, issue +the `info` command: + + $ meson wrap info libjpeg + Available versions of libjpeg: + 9a 2 + +The first number is the upstream release version, in this case +`9a`. The second number is the Wrap revision number. They don't relate +to anything in particular, but larger numbers imply newer +releases. You should always use the newest available release. + +## Installing dependencies + +Installing dependencies is just as straightforward. First just create +the `subprojects` directory at the top of your source tree and issue +the install command. + + $ meson wrap install libjpeg + Installed libjpeg branch 9a revision 2 + +Now you can issue a `subproject('libjpeg')` in your `meson.build` file +to use it. + +To check if your projects are up to date you can issue the `status` command. + + $ meson wrap status + Subproject status + libjpeg up to date. Branch 9a, revision 2. + zlib not up to date. Have 1.2.8 2, but 1.2.8 4 is available. + +In this case `zlib` has a newer release available. Updating it is +straightforward: + + $ meson wrap update zlib + Updated zlib to branch 1.2.8 revision 4 + +Wraptool can do other things besides these. Documentation for these +can be found in the command line help, which can be accessed by +`meson wrap --help`. diff --git a/meson/docs/markdown/Vala.md b/meson/docs/markdown/Vala.md new file mode 100644 index 000000000..d3edce0e2 --- /dev/null +++ b/meson/docs/markdown/Vala.md @@ -0,0 +1,350 @@ +--- +title: Vala +short-description: Compiling Vala and Genie programs +... + +# Compiling Vala applications and libraries +Meson supports compiling applications and libraries written in +[Vala](https://vala-project.org/) and +[Genie](https://wiki.gnome.org/Projects/Genie) . A skeleton `meson.build` file: + +```meson +project('vala app', 'vala', 'c') + +dependencies = [ + dependency('glib-2.0'), + dependency('gobject-2.0'), +] + +sources = files('app.vala') + +executable('app_name', sources, dependencies: dependencies) +``` + +You must always specify the `glib-2.0` and `gobject-2.0` libraries as +dependencies, because all current Vala applications use them. +[GLib](https://developer.gnome.org/glib/stable/) is used for basic data types +and [GObject](https://developer.gnome.org/gobject/stable/) is used for the +runtime type system. + + +## Using libraries + +Meson uses the [`dependency()`](Reference-manual.md#dependency) +function to find the relevant VAPI, C headers and linker flags when it +encounters a Vala source file in a build target. Vala needs a VAPI +file and a C header or headers to use a library. The VAPI file helps +map Vala code to the library's C programming interface. It is the +[`pkg-config`](https://www.freedesktop.org/wiki/Software/pkg-config/) +tool that makes finding these installed files all work seamlessly +behind the scenes. When a `pkg-config` file doesn't exist for the +library then the [`find_library()`](Reference-manual.md#find_library) +method of the [compiler object](Reference-manual.md#compiler-object) +needs to be used. Examples are given later. + +Note Vala uses libraries that follow the C Application Binary Interface (C ABI). +The library, however, could be written in C, Vala, Rust, Go, C++ or any other +language that can generate a binary compatible with the C ABI and so provides C +headers. + + +### The simplest case +This first example is a simple addition to the `meson.build` file because: + + * the library has a `pkg-config` file, `gtk+-3.0.pc` + * the VAPI is distributed with Vala and so installed with the Vala compiler + * the VAPI is installed in Vala's standard search path + * the VAPI, `gtk+-3.0.vapi`, has the same name as the `pkg-config` file + +Everything works seamlessly in the background and only a single extra line is +needed: + +```meson +project('vala app', 'vala', 'c') + +dependencies = [ + dependency('glib-2.0'), + dependency('gobject-2.0'), + dependency('gtk+-3.0'), +] + +sources = files('app.vala') + +executable('app_name', sources, dependencies: dependencies) +``` + +GTK+ is the graphical toolkit used by GNOME, elementary OS and other +desktop environments. The binding to the library, the VAPI file, is +distributed with Vala. + +Other libraries may have a VAPI that is distributed with the library +itself. Such libraries will have their VAPI file installed along with +their other development files. The VAPI is installed in Vala's +standard search path and so works just as seamlessly using the +`dependency()` function. + + +### Targeting a version of GLib + +Meson's [`dependency()`](Reference-manual.md#dependency) function +allows a version check of a library. This is often used to check a +minimum version is installed. When setting a minimum version of GLib, +Meson will also pass this to the Vala compiler using the +`--target-glib` option. + +This is needed when using GTK+'s user interface definition files with +Vala's `[GtkTemplate]`, `[GtkChild]` and `[GtkCallback]` attributes. +This requires `--target-glib 2.38`, or a newer version, to be passed +to Vala. With Meson this is simply done with: + +```meson +project('vala app', 'vala', 'c') + +dependencies = [ + dependency('glib-2.0', version: '>=2.38'), + dependency('gobject-2.0'), + dependency('gtk+-3.0'), +] + +sources = files('app.vala') + +executable('app_name', sources, dependencies: dependencies) +``` + +Using `[GtkTemplate]` also requires the GTK+ user interface definition +files to be built in to the binary as GResources. For completeness, +the next example shows this: + +```meson +project('vala app', 'vala', 'c') + +dependencies = [ + dependency('glib-2.0', version: '>=2.38'), + dependency('gobject-2.0'), + dependency('gtk+-3.0'), +] + +sources = files('app.vala') + +sources += import( 'gnome' ).compile_resources( + 'project-resources', + 'src/resources/resources.gresource.xml', + source_dir: 'src/resources', +) + +executable('app_name', sources, dependencies: dependencies) +``` + + +### Adding to Vala's search path + +So far we have covered the cases where the VAPI file is either +distributed with Vala or the library. A VAPI can also be included in +the source files of your project. The convention is to put it in the +`vapi` directory of your project. + +This is needed when a library does not have a VAPI or your project +needs to link to another component in the project that uses the C ABI. +For example if part of the project is written in C. + +The Vala compiler's `--vapidir` option is used to add the project +directory to the VAPI search path. In Meson this is done with the +`add_project_arguments()` function: + +```meson +project('vala app', 'vala', 'c') + +vapi_dir = meson.current_source_dir() / 'vapi' + +add_project_arguments(['--vapidir', vapi_dir], language: 'vala') + +dependencies = [ + dependency('glib-2.0'), + dependency('gobject-2.0'), + dependency('foo'), # 'foo.vapi' will be resolved as './vapi/foo.vapi' +] + +sources = files('app.vala') + +executable('app_name', sources, dependencies: dependencies) +``` + +If the VAPI is for an external library then make sure that the VAPI +name corresponds to the pkg-config file name. + +The [`vala-extra-vapis` +repository](https://gitlab.gnome.org/GNOME/vala-extra-vapis) is a +community maintained repository of VAPIs that are not distributed. +Developers use the repository to share early work on new bindings and +improvements to existing bindings. So the VAPIs can frequently change. +It is recommended VAPIs from this repository are copied in to your +project's source files. + +This also works well for starting to write new bindings before they +are shared with the `vala-extra-vapis` repository. + + +### Libraries without pkg-config files + +A library that does not have a corresponding pkg-config file may mean +`dependency()` is unsuitable for finding the C and Vala interface +files. In this case it is necessary to use the `find_library()` method +of the compiler object. + +The first example uses Vala's POSIX binding. There is no pkg-config +file because POSIX includes the standard C library on Unix systems. +All that is needed is the VAPI file, `posix.vapi`. This is included +with Vala and installed in Vala's standard search path. Meson just +needs to be told to only find the library for the Vala compiler: + +```meson +project('vala app', 'vala', 'c') + +dependencies = [ + dependency('glib-2.0'), + dependency('gobject-2.0'), + meson.get_compiler('vala').find_library('posix'), +] + +sources = files('app.vala') + +executable('app_name', sources, dependencies: dependencies) +``` + +The next example shows how to link with a C library where no +additional VAPI is needed. The standard maths functions are already +bound in `glib-2.0.vapi`, but the GNU C library requires linking to +the maths library separately. In this example Meson is told to find +the library only for the C compiler: + +```meson +project('vala app', 'vala', 'c') + +dependencies = [ + dependency('glib-2.0'), + dependency('gobject-2.0'), + meson.get_compiler('c').find_library('m', required: false), +] + +sources = files('app.vala') + +executable('app_name', sources, dependencies: dependencies) +``` + +The `required: false` means the build will continue when using another +C library that does not separate the maths library. See [Add math +library (-lm) portably](howtox.md#add-math-library-lm-portably). + +The final example shows how to use a library that does not have a +pkg-config file and the VAPI is in the `vapi` directory of your +project source files: + +```meson +project('vala app', 'vala', 'c') + +vapi_dir = meson.current_source_dir() / 'vapi' + +add_project_arguments(['--vapidir', vapi_dir], language: 'vala') + +dependencies = [ + dependency('glib-2.0'), + dependency('gobject-2.0'), + meson.get_compiler('c').find_library('foo'), + meson.get_compiler('vala').find_library('foo', dirs: vapi_dir), +] + +sources = files('app.vala') + +executable('app_name', sources, dependencies: dependencies) +``` +The `find_library()` method of the C compiler object will try to find the C +header files and the library to link with. + +The `find_library()` method of the Vala compiler object needs to have the `dir` +keyword added to include the project VAPI directory. This is not added +automatically by `add_project_arguments()`. + +### Working with the Vala Preprocessor + +Passing arguments to [Vala's +preprocessor](https://wiki.gnome.org/Projects/Vala/Manual/Preprocessor) +requires specifying the language as `vala`. For example, the following +statement sets the preprocessor symbol `USE_FUSE`: + +```meson +add_project_arguments('-D', 'USE_FUSE', language: 'vala') +``` + +If you need to pass an argument to the C pre-processor then specify +the language as c. For example to set FUSE_USE_VERSION to 26 use: + +```meson +add_project_arguments('-DFUSE_USE_VERSION=26', language: 'c') +``` + +## Building libraries + + +### Changing C header and VAPI names + +Meson's [`library`](Reference-manual.md#library) target automatically +outputs the C header and the VAPI. They can be renamed by setting the +`vala_header` and `vala_vapi` arguments respectively: + +```meson +foo_lib = shared_library('foo', 'foo.vala', + vala_header: 'foo.h', + vala_vapi: 'foo-1.0.vapi', + dependencies: [glib_dep, gobject_dep], + install: true, + install_dir: [true, true, true]) +``` + +In this example, the second and third elements of the `install_dir` +array indicate the destination with `true` to use default directories +(i.e. `include` and `share/vala/vapi`). + + +### GObject Introspection and language bindings + +A 'binding' allows another programming language to use a library +written in Vala. Because Vala uses the GObject type system as its +runtime type system it is very easy to use introspection to generate a +binding. A Meson build of a Vala library can generate the GObject +introspection metadata. The metadata is then used in separate projects +with [language specific +tools](https://wiki.gnome.org/Projects/Vala/LibraryWritingBindings) to +generate a binding. + +The main form of metadata is a GObject Introspection Repository (GIR) +XML file. GIRs are mostly used by languages that generate bindings at +compile time. Languages that generate bindings at runtime mostly use a +typelib file, which is generated from the GIR. + +Meson can generate a GIR as part of the build. For a Vala library the +`vala_gir` option has to be set for the `library`: + +```meson +foo_lib = shared_library('foo', 'foo.vala', + vala_gir: 'Foo-1.0.gir', + dependencies: [glib_dep, gobject_dep], + install: true, + install_dir: [true, true, true, true]) +``` + +The `true` value in `install_dir` tells Meson to use the default +directory (i.e. `share/gir-1.0` for GIRs). The fourth element in the +`install_dir` array indicates where the GIR file will be installed. + +To then generate a typelib file use a custom target with the +`g-ir-compiler` program and a dependency on the library: + +```meson +g_ir_compiler = find_program('g-ir-compiler') +custom_target('foo typelib', command: [g_ir_compiler, '--output', '@OUTPUT@', '@INPUT@'], + input: meson.current_build_dir() / 'Foo-1.0.gir', + output: 'Foo-1.0.typelib', + depends: foo_lib, + install: true, + install_dir: get_option('libdir') / 'girepository-1.0') +``` diff --git a/meson/docs/markdown/Videos.md b/meson/docs/markdown/Videos.md new file mode 100644 index 000000000..fb600382e --- /dev/null +++ b/meson/docs/markdown/Videos.md @@ -0,0 +1,45 @@ +--- +short-description: Videos about Meson +... + +# Videos + + - [Behind (and under) the scenes of the Meson build + system](https://www.youtube.com/watch?v=iLN6wL7ExHU), Linux.conf.au + 2020 + + - [Behind the Scenes of a C++ Build + System](https://www.youtube.com/watch?v=34KzT2yvQuM), CppCon 2019 + + - [Compiling Multi-Million Line C++ Code Bases Effortlessly with the + Meson Build system](https://www.youtube.com/watch?v=SCZLnopmYBM), + CppCon 2018 + + - [The Meson Build System, 4+ years of work to become an overnight + success](https://www.youtube.com/watch?v=gHdTzdXkhRY), Linux.conf.au 2018 + + - [Power through simplicity, using Python in the Meson Build + System](https://youtu.be/3jF3oVsjIEM), Piter.py, 2017 + + - [Meson and the changing Linux build + landscape](https://media.ccc.de/v/ASG2017-111-meson_and_the_changing_linux_build_landscape), + All Systems Go 2017 + + - [Meson, compiling the world with + Python](https://www.youtube.com/watch?v=sEO4DC8hm34), Europython + 2017 + + - [Builds, dependencies and deployment in a modern multiplatform + world](https://www.youtube.com/embed/CTJtKtQ8R5k), Linux.conf.au + 2016 + + - [New world, new tools](https://www.youtube.com/embed/0-gx1qU2pPo), + Libre Application Summit 2016 + + - [Making build systems not + suck](https://www.youtube.com/embed/KPi0AuVpxLI), Linux.conf.au + 2015, Auckland, New Zealand + + - [Lightning talk at FOSDEM + 2014](http://mirror.onet.pl/pub/mirrors/video.fosdem.org/2014/H2215_Ferrer/Sunday/Introducing_the_Meson_build_system.webm), + The first ever public presentation on Meson diff --git a/meson/docs/markdown/Vs-External.md b/meson/docs/markdown/Vs-External.md new file mode 100644 index 000000000..ab3d191f9 --- /dev/null +++ b/meson/docs/markdown/Vs-External.md @@ -0,0 +1,57 @@ +# Visual Studio's external build projects + +Visual Studio supports developing projects that have an external build +system. If you wish to use this integration method, here is how you +set it up. This documentation describes Visual Studio 2019. Other +versions have not been tested, but they should work roughly in the +same way. + +## Creating and compiling + +Check out your entire project in some directory. Then open Visual +Studio and select `File -> New -> Project` and from the list of +project types select `Makefile project`. Click `Next`. + +Type your project's name In the `Project name` entry box. In this +example we're going to use `testproj`. Next select the `Location` +entry and browse to the root of your projet sources. Make sure that +the checkbox `Place solution and project in the same directory` is +checked. Click `Create`. + +The next dialog page defines build commands, which you should set up +as follows: + +| entry | value | +| ----- | ----- | +|build | `meson compile -C $(Configuration)` | +|clean | `meson compile -C $(Configuration) --clean` | +|rebuild| `meson compile -C $(Configuration) --clean && meson compile -C $(Configuration)` | +|Output | `$(Configuration)\name_of_your_executable.exe| + + +Then click `Finish`. + +Visual Studio has created a subdirectory in your source root. It is +named after the project name. In this case it would be `testproj`. Now +you need to set up Meson for building both Debug and Release versions +in this directory. Open a VS dev tool terminal, go to the source root +and issue the following commands. + +``` +meson testproj\Debug +meson testproj\Release --buildtype=debugoptimized +``` + +Now you should have a working VS solution that compiles and runs both +in Debug and Release modes. + +## Adding sources to the project + +This project is not very useful on its own, because it does not list +any source files. VS does not seem to support adding entire source +trees at once, so you have to add sources to the solution manually. + +In the main view go to `Solution Explorer`, right click on the project +you just created and select `Add -> Existing Item`, browse to your +source tree and select all files you want to have in this project. Now +you can use the editor and debugger as in a normal VS project. diff --git a/meson/docs/markdown/Windows-module.md b/meson/docs/markdown/Windows-module.md new file mode 100644 index 000000000..a7131a734 --- /dev/null +++ b/meson/docs/markdown/Windows-module.md @@ -0,0 +1,30 @@ +# Windows module + +This module provides functionality used to build applications for +Windows. + +## Methods + +### compile_resources + +Compiles Windows `rc` files specified in the positional arguments. +Returns an opaque object that you put in the list of sources for the +target you want to have the resources in. This method has the +following keyword argument. + +- `args` lists extra arguments to pass to the resource compiler +- `depend_files` lists resource files that the resource script depends on + (e.g. bitmap, cursor, font, html, icon, message table, binary data or manifest + files referenced by the resource script) (*since 0.47.0*) +- `depends` lists target(s) that this target depends on, even though it does not + take them as an argument (e.g. as above, but generated) (*since 0.47.0*) +- `include_directories` lists directories to be both searched by the resource + compiler for referenced resource files, and added to the preprocessor include + search path. + +The resource compiler executable used is the first which exists from the +following list: + +1. The `windres` executable given in the `[binaries]` section of the cross-file +2. The `WINDRES` environment variable +3. The resource compiler which is part of the same toolset as the C or C++ compiler in use. diff --git a/meson/docs/markdown/Wrap-best-practices-and-tips.md b/meson/docs/markdown/Wrap-best-practices-and-tips.md new file mode 100644 index 000000000..70b02250f --- /dev/null +++ b/meson/docs/markdown/Wrap-best-practices-and-tips.md @@ -0,0 +1,158 @@ +# Wrap best practices and tips + +There are several things you need to take into consideration when +writing a Meson build definition for a project. This is especially +true when the project will be used as a subproject. This page lists a +few things to consider when writing your definitions. + +## Do not put config.h in external search path + +Many projects use a `config.h` header file that they use for +configuring their project internally. These files are never installed +to the system header files so there are no inclusion collisions. This +is not the case with subprojects, your project tree may have an +arbitrary number of configuration files, so we need to ensure they +don't clash. + +The basic problem is that the users of the subproject must be able to +include subproject headers without seeing its `config.h` file. The +most correct solution is to rename the `config.h` file into something +unique, such as `foobar-config.h`. This is usually not feasible unless +you are the maintainer of the subproject in question. + +The pragmatic solution is to put the config header in a directory that +has no other header files and then hide that from everyone else. One +way is to create a top level subdirectory called `internal` and use +that to build your own sources, like this: + +```meson +subdir('internal') # create config.h in this subdir +internal_inc = include_directories('internal') +shared_library('foo', 'foo.c', include_directories : internal_inc) +``` + +Many projects keep their `config.h` in the top level directory that +has no other source files in it. In that case you don't need to move +it but can just do this instead: + +```meson +internal_inc = include_directories('.') # At top level meson.build +``` + +## Make libraries buildable both as static and shared + +Some platforms (e.g. iOS) requires linking everything in your main app +statically. In other cases you might want shared libraries. They are +also faster during development due to Meson's relinking optimization. +However building both library types on all builds is slow and +wasteful. + +Your project should use the `library` method that can be toggled +between shared and static with the `default_library` builtin option. + + +```meson +mylib = library('foo', 'foo.c') +``` + +## Declare generated headers explicitly + +Meson's Ninja backend works differently from Make and other +systems. Rather than processing things directory per directory, it +looks at the entire build definition at once and runs the individual +compile jobs in what might look to the outside as a random order. + +The reason for this is that this is much more efficient so your builds +finish faster. The downside is that you have to be careful with your +dependencies. The most common problem here is headers that are +generated at compile time with e.g. code generators. If these headers +are needed when building code that uses these libraries, the compile +job might be run before the code generation step. The fix is to make +the dependency explicit like this: + +```meson +myheader = custom_target(...) +mylibrary = shared_library(...) +mydep = declare_dependency(link_with : mylibrary, + include_directories : include_directories(...), + sources : myheader) +``` + +And then you can use the dependency in the usual way: + +```meson +executable('dep_using_exe', 'main.c', + dependencies : mydep) +``` + +Meson will ensure that the header file has been built before compiling `main.c`. + +## Avoid exposing compilable source files in declare_dependency + +The main use for the `sources` argument in `declare_dependency` is to +construct the correct dependency graph for the backends, as +demonstrated in the previous section. It is extremely important to +note that it should *not* be used to directly expose compilable +sources (`.c`, `.cpp`, etc.) of dependencies, and should rather only +be used for header/config files. The following example will illustrate +what can go wrong if you accidentally expose compilable source files. + +So you've read about unity builds and how Meson natively supports +them. You decide to expose the sources of dependencies in order to +have unity builds that include their dependencies. For your support +library you do + +```meson +my_support_sources = files(...) + +mysupportlib = shared_library( + ... + sources : my_support_sources, + ...) +mysupportlib_dep = declare_dependency( + ... + link_with : mylibrary, + sources : my_support_sources, + ...) +``` + +And for your main project you do: + +```meson +mylibrary = shared_library( + ... + dependencies : mysupportlib_dep, + ...) +myexe = executable( + ... + link_with : mylibrary, + dependencies : mysupportlib_dep, + ...) +``` + +This is extremely dangerous. When building, `mylibrary` will build and +link the support sources `my_support_sources` into the resulting +shared library. Then, for `myexe`, these same support sources will be +compiled again, will be linked into the resulting executable, in +addition to them being already present in `mylibrary`. This can +quickly run afoul of the [One Definition Rule +(ODR)](https://en.wikipedia.org/wiki/One_Definition_Rule) in C++, as +you have more than one definition of a symbol, yielding undefined +behavior. While C does not have a strict ODR rule, there is no +language in the standard which guarantees such behavior to work. +Violations of the ODR can lead to weird idiosyncratic failures such as +segfaults. In the overwhelming number of cases, exposing library +sources via the `sources` argument in `declare_dependency` is thus +incorrect. If you wish to get full cross-library performance, consider +building `mysupportlib` as a static library instead and employing LTO. + +There are exceptions to this rule. If there are some natural +constraints on how your library is to be used, you can expose sources. +For instance, the WrapDB module for GoogleTest directly exposes the +sources of GTest and GMock. This is valid, as GTest and GMock will +only ever be used in *terminal* link targets. A terminal target is the +final target in a dependency link chain, for instance `myexe` in the +last example, whereas `mylibrary` is an intermediate link target. For +most libraries this rule is not applicable though, as you cannot in +general control how others consume your library, and as such should +not expose sources. diff --git a/meson/docs/markdown/Wrap-dependency-system-manual.md b/meson/docs/markdown/Wrap-dependency-system-manual.md new file mode 100644 index 000000000..eb5de1b13 --- /dev/null +++ b/meson/docs/markdown/Wrap-dependency-system-manual.md @@ -0,0 +1,266 @@ +# Wrap dependency system manual + +One of the major problems of multiplatform development is wrangling +all your dependencies. This is awkward on many platforms, especially +on ones that do not have a built-in package manager. The latter problem +has been worked around by having third party package managers. They +are not really a solution for end user deployment, because you can't +tell them to install a package manager just to use your app. On these +platforms you must produce self-contained applications. Same applies +when destination platform is missing (up-to-date versions of) your +application's dependencies. + +The traditional approach to this has been to bundle dependencies +inside your own project. Either as prebuilt libraries and headers or +by embedding the source code inside your source tree and rewriting +your build system to build them as part of your project. + +This is both tedious and error prone because it is always done by +hand. The Wrap dependency system of Meson aims to provide an automated +way to do this. + +## How it works + +Meson has a concept of [subprojects](Subprojects.md). They are a way +of nesting one Meson project inside another. Any project that builds +with Meson can detect that it is built as a subproject and build +itself in a way that makes it easy to use (usually this means as a +static library). + +To use this kind of a project as a dependency you could just copy and +extract it inside your project's `subprojects` directory. + +However there is a simpler way. You can specify a Wrap file that tells +Meson how to download it for you. If you then use this subproject in +your build, Meson will automatically download and extract it during +build. This makes subproject embedding extremely easy. + +All wrap files must have a name of `<project_name>.wrap` form and be +in `subprojects` dir. + +Currently Meson has four kinds of wraps: +- wrap-file +- wrap-git +- wrap-hg +- wrap-svn + +## wrap format + +Wrap files are written in ini format, with a single header containing +the type of wrap, followed by properties describing how to obtain the +sources, validate them, and modify them if needed. An example +wrap-file for the wrap named `libfoobar` would have a filename +`libfoobar.wrap` and would look like this: + +```ini +[wrap-file] +directory = libfoobar-1.0 + +source_url = https://example.com/foobar-1.0.tar.gz +source_filename = foobar-1.0.tar.gz +source_hash = 5ebeea0dfb75d090ea0e7ff84799b2a7a1550db3fe61eb5f6f61c2e971e57663 +``` + +An example wrap-git will look like this: + +```ini +[wrap-git] +url = https://github.com/libfoobar/libfoobar.git +revision = head +``` + +## Accepted configuration properties for wraps + +- `directory` - name of the subproject root directory, defaults to the + name of the wrap. + +Since *0.55.0* those can be used in all wrap types, they were +previously reserved to `wrap-file`: + +- `patch_url` - download url to retrieve an optional overlay archive +- `patch_fallback_url` - fallback URL to be used when download from `patch_url` fails *Since: 0.55.0* +- `patch_filename` - filename of the downloaded overlay archive +- `patch_hash` - sha256 checksum of the downloaded overlay archive +- `patch_directory` - *Since 0.55.0* Overlay directory, alternative to `patch_filename` in the case + files are local instead of a downloaded archive. The directory must be placed in + `subprojects/packagefiles`. + +### Specific to wrap-file +- `source_url` - download url to retrieve the wrap-file source archive +- `source_fallback_url` - fallback URL to be used when download from `source_url` fails *Since: 0.55.0* +- `source_filename` - filename of the downloaded source archive +- `source_hash` - sha256 checksum of the downloaded source archive +- `lead_directory_missing` - for `wrap-file` create the leading + directory name. Needed when the source file does not have a leading + directory. + +Since *0.55.0* it is possible to use only the `source_filename` and +`patch_filename` value in a .wrap file (without `source_url` and +`patch_url`) to specify a local archive in the +`subprojects/packagefiles` directory. The `*_hash` entries are +optional when using this method. This method should be preferred over +the old `packagecache` approach described below. + +Since *0.49.0* if `source_filename` or `patch_filename` is found in the +project's `subprojects/packagecache` directory, it will be used instead +of downloading the file, even if `--wrap-mode` option is set to +`nodownload`. The file's hash will be checked. + +### Specific to VCS-based wraps +- `url` - name of the wrap-git repository to clone. Required. +- `revision` - name of the revision to checkout. Must be either: a + valid value (such as a git tag) for the VCS's `checkout` command, or + (for git) `head` to track upstream's default branch. Required. + +### Specific to wrap-git +- `depth` - shallowly clone the repository to X number of commits. Note + that git always allow shallowly cloning branches, but in order to + clone commit ids shallowly, the server must support + `uploadpack.allowReachableSHA1InWant=true`. *(since 0.52.0)* +- `push-url` - alternative url to configure as a git push-url. Useful if + the subproject will be developed and changes pushed upstream. + *(since 0.37.0)* +- `clone-recursive` - also clone submodules of the repository + *(since 0.48.0)* + +## wrap-file with Meson build patch + +Unfortunately most software projects in the world do not build with +Meson. Because of this Meson allows you to specify a patch URL. + +For historic reasons this is called a "patch", however, it serves as an +overlay to add or replace files rather than modifying them. The file +must be an archive; it is downloaded and automatically extracted into +the subproject. The extracted files will include a Meson build +definition for the given subproject. + +This approach makes it extremely simple to embed dependencies that +require build system changes. You can write the Meson build definition +for the dependency in total isolation. This is a lot better than doing +it inside your own source tree, especially if it contains hundreds of +thousands of lines of code. Once you have a working build definition, +just zip up the Meson build files (and others you have changed) and +put them somewhere where you can download them. + +Prior to *0.55.0* Meson build patches were only supported for +wrap-file mode. When using wrap-git, the repository must contain all +Meson build definitions. Since *0.55.0* Meson build patches are +supported for any wrap modes, including wrap-git. + +## `provide` section + +*Since *0.55.0* + +Wrap files can define the dependencies it provides in the `[provide]` +section. + +```ini +[provide] +dependency_names = foo-1.0 +``` + +When a wrap file provides the dependency `foo-1.0`, as above, any call to +`dependency('foo-1.0')` will automatically fallback to that subproject even if +no `fallback` keyword argument is given. A wrap file named `foo.wrap` implicitly +provides the dependency name `foo` even when the `[provide]` section is missing. + +Optional dependencies, like `dependency('foo-1.0', required: get_option('foo_opt'))` +where `foo_opt` is a feature option set to `auto`, will not fallback to the +subproject defined in the wrap file, for 2 reasons: +- It allows for looking the dependency in other ways first, for example using + `cc.find_library('foo')`, and only fallback if that fails: + +```meson +# this won't use fallback defined in foo.wrap +foo_dep = dependency('foo-1.0', required: false) +if not foo_dep.found() + foo_dep = cc.find_library('foo', has_headers: 'foo.h', required: false) + if not foo_dep.found() + # This will use the fallback + foo_dep = dependency('foo-1.0') + # or + foo_dep = dependency('foo-1.0', required: false, fallback: 'foo') + endif +endif +``` + +- Sometimes not-found dependency is preferable to a fallback when the + feature is not explicitly requested by the user. In that case + `dependency('foo-1.0', required: get_option('foo_opt'))` will only + fallback when the user sets `foo_opt` to `enabled` instead of + `auto`. +*Since 0.58.0* optional dependency like above will fallback to the subproject +defined in the wrap file in the case `wrap_mode` is set to `forcefallback` +or `force_fallback_for` contains the subproject. + +If it is desired to fallback for an optional dependency, the +`fallback` or `allow_fallback` keyword arguments must be passed +explicitly. *Since 0.56.0*, `dependency('foo-1.0', required: +get_option('foo_opt'), allow_fallback: true)` will use the fallback +even when `foo_opt` is set to `auto`. On version *0.55.0* the same +effect could be achieved with `dependency('foo-1.0', required: +get_option('foo_opt'), fallback: 'foo')`. + +This mechanism assumes the subproject calls +`meson.override_dependency('foo-1.0', foo_dep)` so Meson knows which +dependency object should be used as fallback. Since that method was +introduced in version *0.54.0*, as a transitional aid for projects +that do not yet make use of it the variable name can be provided in +the wrap file with entries in the format `foo-1.0 = foo_dep`. + +For example when using a recent enough version of glib that uses +`meson.override_dependency()` to override `glib-2.0`, `gobject-2.0` +and `gio-2.0`, a wrap file would look like: + +```ini +[wrap-git] +url=https://gitlab.gnome.org/GNOME/glib.git +revision=glib-2-62 + +[provide] +dependency_names = glib-2.0, gobject-2.0, gio-2.0 +``` + +With older version of glib dependency variable names need to be +specified: + +```ini +[wrap-git] +url=https://gitlab.gnome.org/GNOME/glib.git +revision=glib-2-62 + +[provide] +glib-2.0=glib_dep +gobject-2.0=gobject_dep +gio-2.0=gio_dep +``` + +Programs can also be provided by wrap files, with the `program_names` +key: + +```ini +[provide] +program_names = myprog, otherprog +``` + +With such wrap file, `find_program('myprog')` will automatically +fallback to use the subproject, assuming it uses +`meson.override_find_program('myprog')`. + +## Using wrapped projects + +Wraps provide a convenient way of obtaining a project into your +subproject directory. Then you use it as a regular subproject (see +[subprojects](Subprojects.md)). + +## Getting wraps + +Usually you don't want to write your wraps by hand. + +There is an online repository called +[WrapDB](https://wrapdb.mesonbuild.com) that provides many +dependencies ready to use. You can read more about WrapDB +[here](Using-the-WrapDB.md). + +There is also a Meson subcommand to get and manage wraps (see [using +wraptool](Using-wraptool.md)). diff --git a/meson/docs/markdown/Wrap-review-guidelines.md b/meson/docs/markdown/Wrap-review-guidelines.md new file mode 100644 index 000000000..670baa6b3 --- /dev/null +++ b/meson/docs/markdown/Wrap-review-guidelines.md @@ -0,0 +1,94 @@ +# Wrap review guidelines + +In order to get a package in the Wrap database it must be reviewed and +accepted by someone with admin rights. Here is a list of items to +check in the review. If some item is not met it does not mean that the +package is rejected. What should be done will be determined on a +case-by-case basis. Similarly meeting all these requirements does not +guarantee that the package will get accepted. Use common sense. + +## Setting up the tools + +The [mesonwrap repository](https://github.com/mesonbuild/mesonwrap) +provides tools to maintain the WrapDB. Read-only features such can be +used by anyone without Meson admin rights. + +## Personal access token + +Some tools require access to the Github API. A [personal access +token](https://github.com/settings/tokens) may be required if the +freebie Github API quota is exhausted. `public_repo` scope is required +for write operations. + +``` +$ cat ~/.config/mesonwrap.ini +[mesonwrap] +github_token = <github token> +``` + +## Setting up the review tooling + +The [Mesonwrap](https://github.com/mesonbuild/mesonwrap/) repository +contains review tooling. It is used to do the actual review, but +submitters can also use it to check their MRs. All issues reported by +the tool must be fixed, so using the tool can speed up the review +process considerably. + +The tool has some dependencies that are not available in all Linux +distributions. Thus using a Python +[Virtualenv](https://virtualenv.pypa.io/en/stable/). The tool can be +installed with the following commands. + +``` +git clone https://github.com/mesonbuild/mesonwrap.git +cd mesonwrap +python3 -m venv venv +bash +source venv/bin/activate +pip install -r requirements.txt +# You may need to install Meson and Ninja here as well depending on your setup +python3 setup.py install +mesonwrap review <see arguments below> +exit <when you are finished> +``` + +## Reviewing code + +``` +mesonwrap review zlib --pull-request=1 [--approve] +``` + +Since not every check can be automated please pay attention to the +following during the review: + +- Download link points to an authoritative upstream location. +- Version branch is created from master. +- Except for the existing code, `LICENSE.build` is mandatory. +- `project()` has a version and it matches the source version. +- `project()` has a license. +- Complex `configure_file()` inputs are documented. + If the file is a copy of a project file make sure it is clear what was changed. +- Unit tests are enabled if the project provides them. +- There are no guidelines if `install()` is a good or a bad thing in wraps. +- If the project can't be tested on the host platform consider using the `--cross-file` flag. + See [the issue](https://github.com/mesonbuild/mesonwrap/issues/125). + +Encourage wrap readability. Use your own judgement. + +## Approval + +If the code looks good use the `--approve` flag to merge it. +The tool automatically creates a release. + +If you need to create a release manually (because, for example, a MR +was merged by hand), the command to do it is the following: + +```shell +mesonwrap publish reponame version +``` + +An example invocation would look like this: + +```shell +mesonwrap publish expat 2.2.9 +``` diff --git a/meson/docs/markdown/Wrapdb-projects.md b/meson/docs/markdown/Wrapdb-projects.md new file mode 100644 index 000000000..64f3cb62d --- /dev/null +++ b/meson/docs/markdown/Wrapdb-projects.md @@ -0,0 +1,16 @@ +# Meson WrapDB packages + +This is a list of projects that have either an upstream Meson build system, or a +port maintained by the Meson team. [They can be used by your project to provide +its dependencies](Wrap-dependency-system-manual.md). + +Use the command line `meson wrap install <project>` to install the wrap file of +any of those projects into your project's `subprojects/` directory. +See [Meson command line documentation](Using-wraptool.md). + +If you wish to add your own project into this list, please submit your wrap file +in a [Pull Request](https://github.com/mesonbuild/wrapdb). +See [Meson documentation](Adding-new-projects-to-wrapdb.md) +for more details. + +{{ wrapdb-table.md }} diff --git a/meson/docs/markdown/_Sidebar.md b/meson/docs/markdown/_Sidebar.md new file mode 100644 index 000000000..0ca1762b5 --- /dev/null +++ b/meson/docs/markdown/_Sidebar.md @@ -0,0 +1,15 @@ +## Quick References + +* [Functions](Reference-manual.md) +* [Options](Build-options.md) +* [Configuration](Configuration.md) +* [Dependencies](Dependencies.md) +* [Tests](Unit-tests.md) +* [Syntax](Syntax.md) + +### [Modules](Module-reference.md) + +* [gnome](Gnome-module.md) +* [i18n](i18n-module.md) +* [pkgconfig](Pkgconfig-module.md) +* [rust](Rust-module.md) diff --git a/meson/docs/markdown/_include_qt_base.md b/meson/docs/markdown/_include_qt_base.md new file mode 100644 index 000000000..bf5e31b03 --- /dev/null +++ b/meson/docs/markdown/_include_qt_base.md @@ -0,0 +1,160 @@ +## compile_resources + +*New in 0.59.0* + +Compiles Qt's resources collection files (.qrc) into c++ files for compilation. + +It takes no positional arguments, and the following keyword arguments: + - `name` (string | empty): if provided a single .cpp file will be generated, + and the output of all qrc files will be combined in this file, otherwise + each qrc file be written to it's own cpp file. + - `sources` (File | string)[]: A list of sources to be transpiled. Required, + must have at least one source + - `extra_args` string[]: Extra arguments to pass directly to `qt-rcc` + - `method` string: The method to use to detect qt, see `dependency()` for more + information. + +## compile_ui + +*New in 0.59.0* + +Compiles Qt's ui files (.ui) into header files. + +It takes no positional arguments, and the following keyword arguments: + - `sources` (File | string)[]: A list of sources to be transpiled. Required, + must have at least one source + - `extra_args` string[]: Extra arguments to pass directly to `qt-uic` + - `method` string: The method to use to detect qt, see `dependency()` for more + information. + +## compile_moc + +*New in 0.59.0* + +Compiles Qt's moc files (.moc) into header and/or source files. At least one of +the keyword arguments `headers` and `sources` must be provided. + +It takes no positional arguments, and the following keyword arguments: + - `sources` (File | string)[]: A list of sources to be transpiled into .moc + files for manual inclusion. + - `headers` (File | string)[]: A list of headers to be transpiled into .cpp files + - `extra_args` string[]: Extra arguments to pass directly to `qt-moc` + - `method` string: The method to use to detect qt, see `dependency()` for more + information. + - `include_directories` (string | IncludeDirectory)[]: A list of `include_directory()` + objects used when transpiling the .moc files + +## preprocess + +Consider using `compile_resources`, `compile_ui`, and `compile_moc` instead. + +Takes sources for moc, uic, and rcc, and converts them into c++ files for +compilation. + +Has the following signature: `qt.preprocess(name: str | None, *sources: str)` + +If the `name` parameter is passed then all of the rcc files will be wirtten to a single output file + +The variadic `sources` arguments have been deprecated since Meson 0.59.0, as has the `sources` keyword argument. These passed files unmodified through the preprocessor, don't do this, just add the output of the generator to another sources list: +```meson +sources = files('a.cpp', 'main.cpp', 'bar.c') +sources += qt.preprocess(qresources : ['resources']) +``` + +This method takes the following keyword arguments: + - `qresources` (string | File)[]: Passed to the RCC compiler + - `ui_files`: (string | File | CustomTarget)[]: Passed the `uic` compiler + - `moc_sources`: (string | File | CustomTarget)[]: Passed the `moc` compiler. These are converted into .moc files meant to be `#include`ed + - `moc_headers`: (string | File | CustomTarget)[]: Passied the `moc` compiler. These will be converted into .cpp files + - `include_directories` (IncludeDirectories | string)[], the directories to add to header search path for `moc` + - `moc_extra_arguments` string[]: any additional arguments to `moc`. Since v0.44.0. + - `uic_extra_arguments` string[]: any additional arguments to `uic`. Since v0.49.0. + - `rcc_extra_arguments` string[]: any additional arguments to `rcc`. Since v0.49.0. + - `dependencies` Dependency[]: dependency objects needed by moc. Available since v0.48.0. + - `sources`: a list of extra sources, which are added to the output unchaged. Deprecated in 0.59.0. + +It returns an array of targets and sources to pass to a compilation target. + +## compile_translations (since v0.44.0) + +This method generates the necessary targets to build translation files with +lrelease, it takes no positional arguments, and the following keyword arguments: + + - `ts_files` (str | File)[], the list of input translation files produced by Qt's lupdate tool. + - `install` bool: when true, this target is installed during the install step (optional). + - `install_dir` string: directory to install to (optional). + - `build_by_default` bool: when set to true, to have this target be built by + default, that is, when invoking `meson compile`; the default value is false + (optional). + - `qresource` string: rcc source file to extract ts_files from; cannot be used + with ts_files kwarg. Available since v0.56.0. + - `rcc_extra_arguments` string[]: any additional arguments to `rcc` (optional), + when used with `qresource. Available since v0.56.0. + +Returns either: a list of custom targets for the compiled +translations, or, if using a `qresource` file, a single custom target +containing the processed source file, which should be passed to a main +build target. + +## has_tools + +This method returns `true` if all tools used by this module are found, +`false` otherwise. + +It should be used to compile optional Qt code: +```meson +qt5 = import('qt5') +if qt5.has_tools(required: get_option('qt_feature')) + moc_files = qt5.preprocess(...) + ... +endif +``` + +This method takes the following keyword arguments: +- `required` bool | FeatureOption: by default, `required` is set to `false`. If `required` is set to + `true` or an enabled [`feature`](Build-options.md#features) and some tools are + missing Meson will abort. +- `method` string: method used to find the Qt dependency (`auto` by default). + +*Since: 0.54.0* + +## Dependencies + +See [Qt dependencies](Dependencies.md#qt4-qt5) + +The 'modules' argument is used to include Qt modules in the project. +See the Qt documentation for the [list of +modules](http://doc.qt.io/qt-5/qtmodules.html). + +The 'private_headers' argument allows usage of Qt's modules private +headers. (since v0.47.0) + +## Example +A simple example would look like this: + +```meson +qt5 = import('qt5') +qt5_dep = dependency('qt5', modules: ['Core', 'Gui']) +inc = include_directories('includes') +moc_files = qt5.compile_moc(headers : 'myclass.h', + extra_arguments: ['-DMAKES_MY_MOC_HEADER_COMPILE'], + include_directories: inc, + dependencies: qt5_dep) +translations = qt5.compile_translations(ts_files : 'myTranslation_fr.ts', build_by_default : true) +executable('myprog', 'main.cpp', 'myclass.cpp', moc_files, + include_directories: inc, + dependencies : qt5_dep) +``` + +Sometimes, translations are embedded inside the binary using qresource +files. In this case the ts files do not need to be explicitly listed, +but will be inferred from the built qm files listed in the qresource +file. For example: + +```meson +qt5 = import('qt5') +qt5_dep = dependency('qt5', modules: ['Core', 'Gui']) +lang_cpp = qt5.compile_translations(qresource: 'lang.qrc') +executable('myprog', 'main.cpp', lang_cpp, + dependencies: qt5_dep) +``` diff --git a/meson/docs/markdown/fallback-wraptool.md b/meson/docs/markdown/fallback-wraptool.md new file mode 100644 index 000000000..d4f5af27d --- /dev/null +++ b/meson/docs/markdown/fallback-wraptool.md @@ -0,0 +1,43 @@ +--- +title: fallback wraptool +... + +# In case of emergency + +In case wraptool is down we have created a backup script that you can +use to download wraps directly from the GitHub repos. It is not as +slick and may have bugs but at least it will allow you to use wraps. + +## Using it + +To list all available wraps: + + ghwt.py list + +To install a wrap, go to your source root, make sure that the +`subprojects` directory exists and run this command: + + ghwt.py install <projectname> [<branchname>] + +This will stage the subproject ready to use. If you have multiple +subprojects you need to download them all manually. + +Specifying branch name is optional. If not specified, the list of +potential branches is sorted alphabetically and the last branch is +used. + +*Note* The tool was added in 0.32.0, for versions older than that you +need to delete the `foo.wrap` file to work around this issue. + +## How to upgrade an existing dir/fix broken state/any other problem + +Nuke the contents of `subprojects` and start again. + +## Known issues + +Some repositories show up in the list but are not installable. They +would not show up in the real WrapDB because they are works in +progress. + +GitHub web API limits the amount of queries you can do to 60/hour. If +you exceed that you need to wait for the timer to reset. diff --git a/meson/docs/markdown/howtox.md b/meson/docs/markdown/howtox.md new file mode 100644 index 000000000..1521f7244 --- /dev/null +++ b/meson/docs/markdown/howtox.md @@ -0,0 +1,325 @@ +# How do I do X in Meson? + +This page lists code snippets for common tasks. These are written +mostly using the C compiler, but the same approach should work on +almost all other compilers. + +## Set compiler + +When first running Meson, set it in an environment variable. + +```console +$ CC=mycc meson <options> +``` + +Note that environment variables like `CC` only works in native builds. +The `CC` refers to the compiler for the host platform, that is the +compiler used to compile programs that run on the machine we will +eventually install the project on. The compiler used to build things +that run on the machine we do the building can be specified with +`CC_FOR_BUILD`. You can use it in cross builds. + +Note that environment variables are never the idiomatic way to do +anything with Meson, however. It is better to use the native and cross +files. And the tools for the host platform in cross builds can only be +specified with a cross file. + +There is a table of all environment variables supported +[Here](Reference-tables.md#compiler-and-linker-selection-variables) + + +## Set linker + +*New in 0.53.0* + +Like the compiler, the linker is selected via the `<compiler +variable>_LD` environment variable, or through the `<compiler +entry>_ld` entry in a native or cross file. You must be aware of +whether you're using a compiler that invokes the linker itself (most +compilers including GCC and Clang) or a linker that is invoked +directly (when using MSVC or compilers that act like it, including +Clang-Cl). With the former `c_ld` or `CC_LD` should be the value to +pass to the compiler's special argument (such as `-fuse-ld` with clang +and gcc), with the latter it should be an executable, such as +`lld-link.exe`. + +*NOTE* In Meson 0.53.0 the `ld` entry in the cross/native file and the +`LD` environment variable were used, this resulted in a large number +of regressions and was changed in 0.53.1 to `<lang>_ld` and `<comp +variable>_LD`. + +```console +$ CC=clang CC_LD=lld meson <options> +``` + +or + +```console +$ CC=clang-cl CC_LD=link meson <options> +``` + +or in a cross or native file: + +```ini +[binaries] +c = 'clang' +c_ld = 'lld' +``` + +There is a table of all environment variables supported +[Here](Reference-tables.md#compiler-and-linker-selection-variables) + + +## Set default C/C++ language version + +```meson +project('myproj', 'c', 'cpp', + default_options : ['c_std=c11', 'cpp_std=c++11']) +``` + +The language version can also be set on a per-target basis. + +```meson +executable(..., override_options : ['c_std=c11']) +``` + +## Enable threads + +Lots of people seem to do this manually with `find_library('pthread')` +or something similar. Do not do that. It is not portable. Instead do +this. + +```meson +thread_dep = dependency('threads') +executable(..., dependencies : thread_dep) +``` + +## Set extra compiler and linker flags from the outside (when e.g. building distro packages) + +The behavior is the same as with other build systems, with environment +variables during first invocation. Do not use these when you need to +rebuild the source + +```console +$ CFLAGS=-fsomething LDFLAGS=-Wl,--linker-flag meson <options> +``` + +## Use an argument only with a specific compiler + +First check which arguments to use. + +```meson +if meson.get_compiler('c').get_id() == 'clang' + extra_args = ['-fclang-flag'] +else + extra_args = [] +endif +``` + +Then use it in a target. + +```meson +executable(..., c_args : extra_args) +``` + +If you want to use the arguments on all targets, then do this. + +```meson +if meson.get_compiler('c').get_id() == 'clang' + add_global_arguments('-fclang-flag', language : 'c') +endif +``` + +## Set a command's output to configuration + +```meson +txt = run_command('script', 'argument').stdout().strip() +cdata = configuration_data() +cdata.set('SOMETHING', txt) +configure_file(...) +``` + +## Generate configuration data from files + +`The [fs module](#Fs-modules) offers the `read` function` which enables adding +the contents of arbitrary files to configuration data (among other uses): + +```meson +fs = import('fs') +cdata = configuration_data() +copyright = fs.read('LICENSE') +cdata.set('COPYRIGHT', copyright) +if build_machine.system() == 'linux' + os_release = fs.read('/etc/os-release') + cdata.set('LINUX_BUILDER', os_release) +endif +configure_file(...) +``` + +## Generate a runnable script with `configure_file` + +`configure_file` preserves metadata so if your template file has +execute permissions, the generated file will have them too. + +## Producing a coverage report + +First initialize the build directory with this command. + +```console +$ meson <other flags> -Db_coverage=true +``` + +Then issue the following commands. + +```console +$ meson compile +$ meson test +$ meson compile coverage-html (or coverage-xml) +``` + +The coverage report can be found in the meson-logs subdirectory. + +*New in 0.55.0* llvm-cov support for use with clang + +## Add some optimization to debug builds + +By default the debug build does not use any optimizations. This is the +desired approach most of the time. However some projects benefit from +having some minor optimizations enabled. GCC even has a specific +compiler flag `-Og` for this. To enable its use, just issue the +following command. + +```console +$ meson configure -Dc_args=-Og +``` + +This causes all subsequent builds to use this command line argument. + +## Use address sanitizer + +Clang comes with a selection of analysis tools such as the [address +sanitizer](https://clang.llvm.org/docs/AddressSanitizer.html). Meson +has native support for these with the `b_sanitize` option. + +```console +$ meson <other options> -Db_sanitize=address +``` + +After this you just compile your code and run the test suite. Address +sanitizer will abort executables which have bugs so they show up as +test failures. + +## Use Clang static analyzer + +Install scan-build program, then do this: + +```console +$ meson setup builddir +$ ninja -C builddir scan-build +``` + +You can use the `SCANBUILD` environment variable to choose the +scan-build executable. + +```console +$ SCANBUILD=<your exe> ninja -C builddir scan-build +``` + +You can use it for passing arguments to scan-build program by +creating a script, for example: + +```sh +#!/bin/sh +scan-build -v --status-bugs "$@" +``` + +And then pass it through the variable (remember to use absolute path): + +```console +$ SCANBUILD=$(pwd)/my-scan-build.sh ninja -C builddir scan-build +``` + +## Use profile guided optimization + +Using profile guided optimization with GCC is a two phase +operation. First we set up the project with profile measurements +enabled and compile it. + +```console +$ meson setup <Meson options, such as --buildtype=debugoptimized> -Db_pgo=generate +$ meson compile -C builddir +``` + +Then we need to run the program with some representative input. This +step depends on your project. + +Once that is done we change the compiler flags to use the generated +information and rebuild. + +```console +$ meson configure -Db_pgo=use +$ meson compile +``` + +After these steps the resulting binary is fully optimized. + +## Add math library (`-lm`) portably + +Some platforms (e.g. Linux) have a standalone math library. Other +platforms (pretty much everyone else) do not. How to specify that `m` +is used only when needed? + +```meson +cc = meson.get_compiler('c') +m_dep = cc.find_library('m', required : false) +executable(..., dependencies : m_dep) +``` + +## Install an executable to `libexecdir` + +```meson +executable(..., install : true, install_dir : get_option('libexecdir')) +``` + +## Use existing `Find<name>.cmake` files + +Meson can use the CMake `find_package()` ecosystem if CMake is +installed. To find a dependency with custom `Find<name>.cmake`, set +the `cmake_module_path` property to the path in your project where the +CMake scripts are stored. + +Example for a `FindCmakeOnlyDep.cmake` in a `cmake` subdirectory: + +```meson +cm_dep = dependency('CmakeOnlyDep', cmake_module_path : 'cmake') +``` + +The `cmake_module_path` property is only needed for custom CMake scripts. System +wide CMake scripts are found automatically. + +More information can be found [here](Dependencies.md#cmake) + +## Get a default not-found dependency? + +```meson +null_dep = dependency('', required : false) +``` + +This can be used in cases where you want a default value, but might override it +later. + +```meson +# Not needed on Windows! +my_dep = dependency('', required : false) +if host_machine.system() in ['freebsd', 'netbsd', 'openbsd', 'dragonfly'] + my_dep = dependency('some dep', required : false) +elif host_machine.system() == 'linux' + my_dep = dependency('some other dep', required : false) +endif + +executable( + 'myexe', + my_sources, + deps : [my_dep] +) +``` diff --git a/meson/docs/markdown/i18n-module.md b/meson/docs/markdown/i18n-module.md new file mode 100644 index 000000000..4948fab42 --- /dev/null +++ b/meson/docs/markdown/i18n-module.md @@ -0,0 +1,53 @@ +# I18n module + +This module provides internationalisation and localisation functionality. + +## Usage + +To use this module, just do: **`i18n = import('i18n')`**. The +following functions will then be available as methods on the object +with the name `i18n`. You can, of course, replace the name `i18n` with +anything else. + +### i18n.gettext() + +Sets up gettext localisation so that translations are built and placed +into their proper locations during install. Takes one positional +argument which is the name of the gettext module. + +* `args`: list of extra arguments to pass to `xgettext` when + generating the pot file +* `data_dirs`: (*Added 0.36.0*) list of directories to be set for + `GETTEXTDATADIRS` env var (Requires gettext 0.19.8+), used for local + its files +* `languages`: list of languages that are to be generated. As of + 0.37.0 this is optional and the + [LINGUAS](https://www.gnu.org/software/gettext/manual/html_node/po_002fLINGUAS.html) + file is read. +* `preset`: (*Added 0.37.0*) name of a preset list of arguments, + current option is `'glib'`, see + [source](https://github.com/mesonbuild/meson/blob/master/mesonbuild/modules/i18n.py) + for for their value +* `install`: (*Added 0.43.0*) if false, do not install the built translations. +* `install_dir`: (*Added 0.50.0*) override default install location, default is `localedir` + +This function also defines targets for maintainers to use: +**Note**: These output to the source directory + +* `<project_id>-pot`: runs `xgettext` to regenerate the pot file +* `<project_id>-update-po`: regenerates the `.po` files from current `.pot` file +* `<project_id>-gmo`: builds the translations without installing + +### i18n.merge_file() + +This merges translations into a text file using `msgfmt`. See +[custom_target](Reference-manual.md#custom_target) +for normal keywords. In addition it accepts these keywords: + +* `data_dirs`: (*Added 0.41.0*) list of directories for its files (See + also `i18n.gettext()`) +* `po_dir`: directory containing translations, relative to current directory +* `type`: type of file, valid options are `'xml'` (default) and `'desktop'` +* `args`: (*Added 0.51.0*) list of extra arguments to pass to `msgfmt` + +*Added 0.37.0* diff --git a/meson/docs/markdown/images/buildtime.png b/meson/docs/markdown/images/buildtime.png Binary files differnew file mode 100644 index 000000000..2a44422f0 --- /dev/null +++ b/meson/docs/markdown/images/buildtime.png diff --git a/meson/docs/markdown/images/conftime.png b/meson/docs/markdown/images/conftime.png Binary files differnew file mode 100644 index 000000000..63754dbab --- /dev/null +++ b/meson/docs/markdown/images/conftime.png diff --git a/meson/docs/markdown/images/emptytime.png b/meson/docs/markdown/images/emptytime.png Binary files differnew file mode 100644 index 000000000..d80eab9f2 --- /dev/null +++ b/meson/docs/markdown/images/emptytime.png diff --git a/meson/docs/markdown/images/glib_build.png b/meson/docs/markdown/images/glib_build.png Binary files differnew file mode 100644 index 000000000..ddb994780 --- /dev/null +++ b/meson/docs/markdown/images/glib_build.png diff --git a/meson/docs/markdown/images/glib_conf.png b/meson/docs/markdown/images/glib_conf.png Binary files differnew file mode 100644 index 000000000..5de60d5a0 --- /dev/null +++ b/meson/docs/markdown/images/glib_conf.png diff --git a/meson/docs/markdown/images/glib_empty.png b/meson/docs/markdown/images/glib_empty.png Binary files differnew file mode 100644 index 000000000..5976e7f46 --- /dev/null +++ b/meson/docs/markdown/images/glib_empty.png diff --git a/meson/docs/markdown/images/glib_link.png b/meson/docs/markdown/images/glib_link.png Binary files differnew file mode 100644 index 000000000..23d90442b --- /dev/null +++ b/meson/docs/markdown/images/glib_link.png diff --git a/meson/docs/markdown/images/gtksample.png b/meson/docs/markdown/images/gtksample.png Binary files differnew file mode 100644 index 000000000..b6557c4e1 --- /dev/null +++ b/meson/docs/markdown/images/gtksample.png diff --git a/meson/docs/markdown/images/linux_alldone.png b/meson/docs/markdown/images/linux_alldone.png Binary files differnew file mode 100644 index 000000000..378c893c0 --- /dev/null +++ b/meson/docs/markdown/images/linux_alldone.png diff --git a/meson/docs/markdown/images/meson_mac1.png b/meson/docs/markdown/images/meson_mac1.png Binary files differnew file mode 100755 index 000000000..17eae0acf --- /dev/null +++ b/meson/docs/markdown/images/meson_mac1.png diff --git a/meson/docs/markdown/images/meson_mac2.png b/meson/docs/markdown/images/meson_mac2.png Binary files differnew file mode 100755 index 000000000..e5c434df1 --- /dev/null +++ b/meson/docs/markdown/images/meson_mac2.png diff --git a/meson/docs/markdown/images/meson_mac3.png b/meson/docs/markdown/images/meson_mac3.png Binary files differnew file mode 100755 index 000000000..babada173 --- /dev/null +++ b/meson/docs/markdown/images/meson_mac3.png diff --git a/meson/docs/markdown/images/meson_mac4.png b/meson/docs/markdown/images/meson_mac4.png Binary files differnew file mode 100755 index 000000000..e8089ad96 --- /dev/null +++ b/meson/docs/markdown/images/meson_mac4.png diff --git a/meson/docs/markdown/images/meson_mac5.png b/meson/docs/markdown/images/meson_mac5.png Binary files differnew file mode 100755 index 000000000..507fcdaa6 --- /dev/null +++ b/meson/docs/markdown/images/meson_mac5.png diff --git a/meson/docs/markdown/images/osx_xcode.png b/meson/docs/markdown/images/osx_xcode.png Binary files differnew file mode 100644 index 000000000..89075f308 --- /dev/null +++ b/meson/docs/markdown/images/osx_xcode.png diff --git a/meson/docs/markdown/images/py3-install-1.png b/meson/docs/markdown/images/py3-install-1.png Binary files differnew file mode 100644 index 000000000..74f081938 --- /dev/null +++ b/meson/docs/markdown/images/py3-install-1.png diff --git a/meson/docs/markdown/images/py3-install-2.png b/meson/docs/markdown/images/py3-install-2.png Binary files differnew file mode 100644 index 000000000..9a8f1fe65 --- /dev/null +++ b/meson/docs/markdown/images/py3-install-2.png diff --git a/meson/docs/markdown/images/py3-install-3.png b/meson/docs/markdown/images/py3-install-3.png Binary files differnew file mode 100644 index 000000000..b702910ab --- /dev/null +++ b/meson/docs/markdown/images/py3-install-3.png diff --git a/meson/docs/markdown/images/win_dlvs.png b/meson/docs/markdown/images/win_dlvs.png Binary files differnew file mode 100644 index 000000000..938c30d01 --- /dev/null +++ b/meson/docs/markdown/images/win_dlvs.png diff --git a/meson/docs/markdown/images/win_downloadmeson.png b/meson/docs/markdown/images/win_downloadmeson.png Binary files differnew file mode 100644 index 000000000..59170390d --- /dev/null +++ b/meson/docs/markdown/images/win_downloadmeson.png diff --git a/meson/docs/markdown/images/win_installvs.png b/meson/docs/markdown/images/win_installvs.png Binary files differnew file mode 100644 index 000000000..b2175259a --- /dev/null +++ b/meson/docs/markdown/images/win_installvs.png diff --git a/meson/docs/markdown/images/win_vstoolsprompt.png b/meson/docs/markdown/images/win_vstoolsprompt.png Binary files differnew file mode 100644 index 000000000..d3f0c2b87 --- /dev/null +++ b/meson/docs/markdown/images/win_vstoolsprompt.png diff --git a/meson/docs/markdown/images/win_working.png b/meson/docs/markdown/images/win_working.png Binary files differnew file mode 100644 index 000000000..4bc46d709 --- /dev/null +++ b/meson/docs/markdown/images/win_working.png diff --git a/meson/docs/markdown/index.md b/meson/docs/markdown/index.md new file mode 100644 index 000000000..14bdfbed8 --- /dev/null +++ b/meson/docs/markdown/index.md @@ -0,0 +1,60 @@ +--- +render-subpages: false +... + +# The Meson Build system + +## Overview + +Meson is an open source build system meant to be both extremely fast, +and, even more importantly, as user friendly as possible. + +The main design point of Meson is that every moment a developer spends +writing or debugging build definitions is a second wasted. So is every +second spent waiting for the build system to actually start compiling +code. + +## Features + +* multiplatform support for Linux, macOS, Windows, GCC, Clang, Visual Studio and others +* supported languages include C, C++, D, Fortran, Java, Rust +* build definitions in a very readable and user friendly non-Turing complete DSL +* cross compilation for many operating systems as well as bare metal +* optimized for extremely fast full and incremental builds without sacrificing correctness +* built-in multiplatform dependency provider that works together with distro packages +* fun! + +## Quickstart for beginners + +Are you an absolute beginner when it comes to programming? No worries, +read [this beginner guide](SimpleStart.md) to get started. + +## Community + +There are two main methods of connecting with other Meson +developers. The easiest way for most people is a web chat. The channel +to use is `#mesonbuild` either via Matrix ([web +interface](https://app.element.io/#/room/#mesonbuild:matrix.org)) or +[OFTC IRC](https://www.oftc.net/). + +The second one is the mailing list, which is hosted at +[Google Groups](https://groups.google.com/forum/#!forum/mesonbuild). + +### [Projects using Meson](Users.md) + +Many projects are using Meson and they're +a great resource for learning what to (and what not to!) do when +converting existing projects to Meson. + +[A short list of Meson users can be found here](Users.md) +but there are many more. We would love to hear about your success +stories too and how things could be improved too! + +## Development + +All development on Meson is done on the [GitHub +project](https://github.com/mesonbuild/meson). Instructions for +contributing can be found on the [contribution page](Contributing.md). + + +You do not need to sign a CLA to contribute to Meson. diff --git a/meson/docs/markdown/legal.md b/meson/docs/markdown/legal.md new file mode 100644 index 000000000..a14b7b93e --- /dev/null +++ b/meson/docs/markdown/legal.md @@ -0,0 +1,26 @@ +# Legal information + +Meson is copyrighted by all members of the Meson development team. +Meson is licensed under the [Apache 2 license]. + +Meson is a registered trademark of Jussi Pakkanen. + +## Meson logo licensing + +Meson's logo is (C) Jussi Pakkanen and used by the Meson project with +specific permission. It is not licensed under the same terms as the +rest of the project. + +If you are a third party and want to use the Meson logo, you must +first obtain written permission from Jussi Pakkanen. + +## Website licensing + +The meson website content is released under [Creative Commons +Attribution-ShareAlike 4.0 International]. + +All code samples on the website are released under [CC0 1.0 Universal]. + +[Creative Commons Attribution-ShareAlike 4.0 International]: https://creativecommons.org/licenses/by-sa/4.0/ +[CC0 1.0 Universal]: https://creativecommons.org/publicdomain/zero/1.0/ +[Apache 2 license]: https://www.apache.org/licenses/LICENSE-2.0 diff --git a/meson/docs/markdown/snippets/add_release_note_snippets_here b/meson/docs/markdown/snippets/add_release_note_snippets_here new file mode 100644 index 000000000..cdd57c647 --- /dev/null +++ b/meson/docs/markdown/snippets/add_release_note_snippets_here @@ -0,0 +1,3 @@ +DO NOT ADD ANYTHING TO THIS FILE! + +Add release note snippets to their own files, one file per snippet. diff --git a/meson/docs/meson.build b/meson/docs/meson.build new file mode 100644 index 000000000..73693353d --- /dev/null +++ b/meson/docs/meson.build @@ -0,0 +1,41 @@ +project('Meson documentation', version: '1.0') + +cur_bdir = meson.current_build_dir() + +# Only the script knows which files are being generated +docs_gen = custom_target( + 'gen_docs', + input: files('markdown/index.md'), + output: 'gen_docs.stamp', + command: [ + files('../tools/regenerate_docs.py'), + '--output-dir', cur_bdir, + '--dummy-output-file', '@OUTPUT@', + ], + build_by_default: true, + install: false) + +hotdoc = import('hotdoc') +documentation = hotdoc.generate_doc(meson.project_name(), + project_version: meson.project_version(), + sitemap: 'sitemap.txt', + build_by_default: true, + depends: docs_gen, + index: 'markdown/index.md', + install: false, + extra_assets: ['images/'], + include_paths: ['markdown', cur_bdir], + default_license: 'CC-BY-SAv4.0', + html_extra_theme: join_paths('theme', 'extra'), + git_upload_repository: 'git@github.com:mesonbuild/mesonbuild.github.io.git', + edit_on_github_repository: 'https://github.com/mesonbuild/meson', + syntax_highlighting_activate: true, +) + +run_target('upload', + command: [find_program('hotdoc'), 'run', + '--conf-file', documentation.config_path(), + '--git-upload', + '-vv', + ], +) diff --git a/meson/docs/sitemap.txt b/meson/docs/sitemap.txt new file mode 100644 index 000000000..d96d86597 --- /dev/null +++ b/meson/docs/sitemap.txt @@ -0,0 +1,136 @@ +index.md + SimpleStart.md + Getting-meson.md + Getting-meson_zh.md + Getting-meson_ptbr.md + Quick-guide.md + Tutorial.md + Manual.md + Overview.md + Running-Meson.md + Commands.md + Builtin-options.md + Using-with-Visual-Studio.md + Meson-sample.md + Syntax.md + Machine-files.md + Native-environments.md + Build-targets.md + Include-directories.md + Installing.md + Adding-arguments.md + Configuration.md + Compiler-properties.md + Dependencies.md + Threads.md + External-commands.md + Precompiled-headers.md + Unity-builds.md + Feature-autodetection.md + Generating-sources.md + Unit-tests.md + Cross-compilation.md + Localisation.md + Build-options.md + Subprojects.md + Disabler.md + Code-formatting.md + Modules.md + CMake-module.md + Cuda-module.md + Dlang-module.md + External-Project-module.md + Fs-module.md + Gnome-module.md + Hotdoc-module.md + Icestorm-module.md + Keyval-module.md + Pkgconfig-module.md + Python-3-module.md + Python-module.md + Qt4-module.md + Qt5-module.md + Qt6-module.md + RPM-module.md + Rust-module.md + Simd-module.md + SourceSet-module.md + Windows-module.md + i18n-module.md + Java.md + Vala.md + D.md + Cython.md + IDE-integration.md + Custom-build-targets.md + Build-system-converters.md + Configuring-a-build-directory.md + Run-targets.md + Creating-releases.md + Creating-OSX-packages.md + Creating-Linux-binaries.md + Project-templates.md + Reference-manual.md + Reference-tables.md + Style-guide.md + Rewriter.md + FAQ.md + Reproducible-builds.md + howtox.md + Wrapdb-projects.md + Wrap-dependency-system-manual.md + Adding-new-projects-to-wrapdb.md + Using-the-WrapDB.md + Using-wraptool.md + Wrap-best-practices-and-tips.md + Wrap-review-guidelines.md + Shipping-prebuilt-binaries-as-wraps.md + fallback-wraptool.md + Release-notes.md + Release-notes-for-0.59.0.md + Release-notes-for-0.58.0.md + Release-notes-for-0.57.0.md + Release-notes-for-0.56.0.md + Release-notes-for-0.55.0.md + Release-notes-for-0.54.0.md + Release-notes-for-0.53.0.md + Release-notes-for-0.52.0.md + Release-notes-for-0.51.0.md + Release-notes-for-0.50.0.md + Release-notes-for-0.49.0.md + Release-notes-for-0.48.0.md + Release-notes-for-0.47.0.md + Release-notes-for-0.46.0.md + Release-notes-for-0.45.0.md + Release-notes-for-0.44.0.md + Release-notes-for-0.43.0.md + Release-notes-for-0.42.0.md + Release-notes-for-0.41.0.md + Release-notes-for-0.40.0.md + Release-notes-for-0.39.0.md + Release-notes-for-0.38.0.md + Release-notes-for-0.37.0.md + Additional.md + Release-procedure.md + Performance-comparison.md + ARM-performance-test.md + Simple-comparison.md + Comparisons.md + Conference-presentations.md + Contact-information.md + Continuous-Integration.md + Design-rationale.md + IndepthTutorial.md + In-the-press.md + Mixing-build-systems.md + Pkg-config-files.md + Playground.md + Porting-from-autotools.md + Use-of-Python.md + Users.md + Using-multiple-build-directories.md + Vs-External.md + Contributing.md + MesonCI.md + legal.md + Videos.md diff --git a/meson/docs/theme/extra/images/favicon.png b/meson/docs/theme/extra/images/favicon.png Binary files differnew file mode 100644 index 000000000..6800fe80e --- /dev/null +++ b/meson/docs/theme/extra/images/favicon.png diff --git a/meson/docs/theme/extra/images/meson_logo.png b/meson/docs/theme/extra/images/meson_logo.png Binary files differnew file mode 100644 index 000000000..1b3915d39 --- /dev/null +++ b/meson/docs/theme/extra/images/meson_logo.png diff --git a/meson/docs/theme/extra/prism_components/prism-meson.js b/meson/docs/theme/extra/prism_components/prism-meson.js new file mode 100644 index 000000000..242af19b4 --- /dev/null +++ b/meson/docs/theme/extra/prism_components/prism-meson.js @@ -0,0 +1,16 @@ +Prism.languages.meson= { + 'triple-quoted-string': { + 'pattern': /'''[\s\S]*?'''/, + 'alias': 'string' + }, + 'comment': /#.*/, + 'string': /'(?:\\'|[^'])*'/, + 'number': /\b\d+(?:\.\d+)?\b/, + 'keyword': /\b(?:if|else|elif|endif|foreach|endforeach)\b/, + 'function': /(?=\.|\b)[a-zA-Z_]+\s*(?=\()/, + 'boolean': /\b(?:true|false)\b/, + 'builtin': /\b(?:meson|host_machine|target_machine|build_machine)(?=\.)/, + 'operator': /(?:[<>=*+\-/!]?=|%|\/|\*|-|\+|\b(?:or|and|not)\b)/, + 'punctuation': /[(),[\]]/ + // TODO: Handle ternary ?: +};
\ No newline at end of file diff --git a/meson/docs/theme/extra/prism_components/prism-meson.min.js b/meson/docs/theme/extra/prism_components/prism-meson.min.js new file mode 100644 index 000000000..7bf90e06f --- /dev/null +++ b/meson/docs/theme/extra/prism_components/prism-meson.min.js @@ -0,0 +1 @@ +Prism.languages.meson={"triple-quoted-string":{pattern:/'''[\s\S]*?'''/,alias:"string"},comment:/#.*/,string:/'(?:\\'|[^'])*'/,number:/\b\d+(?:\.\d+)?\b/,keyword:/\b(?:if|else|elif|endif|foreach|endforeach)\b/,"function":/(?=\.|\b)[a-zA-Z_]+\s*(?=\()/,"boolean":/\b(?:true|false)\b/,builtin:/\b(?:meson|host_machine|target_machine|build_machine)(?=\.)/,operator:/(?:[<>=*+\-\/!]?=|%|\/|\*|-|\+|\b(?:or|and|not)\b)/,punctuation:/[(),[\]]/};
\ No newline at end of file diff --git a/meson/docs/theme/extra/templates/brand-logo.html b/meson/docs/theme/extra/templates/brand-logo.html new file mode 100644 index 000000000..7a12347d9 --- /dev/null +++ b/meson/docs/theme/extra/templates/brand-logo.html @@ -0,0 +1 @@ +<img src="assets/images/meson_logo.png" alt=Home> diff --git a/meson/docs/theme/extra/templates/extra_head.html b/meson/docs/theme/extra/templates/extra_head.html new file mode 100644 index 000000000..29b7477ba --- /dev/null +++ b/meson/docs/theme/extra/templates/extra_head.html @@ -0,0 +1,2 @@ +<link rel="icon" type="image/png" href="assets/images/favicon.png"> +<link rel="shortcut icon" href="assets/images/favicon.png"> diff --git a/meson/docs/theme/extra/templates/license.html b/meson/docs/theme/extra/templates/license.html new file mode 100644 index 000000000..551878295 --- /dev/null +++ b/meson/docs/theme/extra/templates/license.html @@ -0,0 +1,7 @@ +@require(license, logo_path) + +<hr/> + +<div class="license-description"> + Website licensing information are available on the <a href=legal.html>Legal</a> page. +</div> diff --git a/meson/docs/theme/extra/templates/navbar_center.html b/meson/docs/theme/extra/templates/navbar_center.html new file mode 100644 index 000000000..9934be792 --- /dev/null +++ b/meson/docs/theme/extra/templates/navbar_center.html @@ -0,0 +1 @@ +<p><b>The Meson Build System</b></p> diff --git a/meson/docs/theme/extra/templates/navbar_links.html b/meson/docs/theme/extra/templates/navbar_links.html new file mode 100644 index 000000000..904a4996e --- /dev/null +++ b/meson/docs/theme/extra/templates/navbar_links.html @@ -0,0 +1,53 @@ +@require(page) + +<li class="dropdown"> + <a class="dropdown-toggle" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + Modules <span class="caret"></span> + </a> + <ul class="dropdown-menu" id="modules-menu"> + @for tup in [ \ + ("CMake-module.html","CMake"), \ + ("Cuda-module.html","CUDA"), \ + ("Dlang-module.html","Dlang"), \ + ("External-Project-module.html","External Project"), \ + ("Fs-module.html","Filesystem"), \ + ("Gnome-module.html","GNOME"), \ + ("Hotdoc-module.html","Hotdoc"), \ + ("i18n-module.html","i18n"), \ + ("Icestorm-module.html","Icestorm"), \ + ("Keyval-module.html","Keyval"), \ + ("Pkgconfig-module.html","Pkgconfig"), \ + ("Python-3-module.html","Python 3"), \ + ("Python-module.html","Python"), \ + ("Qt4-module.html","Qt4"), \ + ("Qt5-module.html","Qt5"), \ + ("Qt6-module.html","Qt6"), \ + ("RPM-module.html","RPM"), \ + ("Rust-module.html","Rust"), \ + ("Simd-module.html","Simd"), \ + ("SourceSet-module.html","SourceSet"), \ + ("Windows-module.html","Windows")]: + <li> + <a href="@tup[0]">@tup[1]</a> + </li> + @end + </ul> +</li> +\ +<li class="dropdown"> + <a class="dropdown-toggle" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> + Quick References <span class="caret"></span> + </a> + <ul class="dropdown-menu" id="quick-refs-menu"> + @for tup in (("Reference-manual.html", "Functions"), \ + ("Build-options.html", "Options"), \ + ("Configuration.html", "Configuration"), \ + ("Dependencies.html", "Dependencies"), \ + ("Unit-tests.html", "Tests"), \ + ("Syntax.html", "Syntax")): + <li> + <a href="@tup[0]">@tup[1]</a> + </li> + @end + </ul> +</li> |