diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2017-08-21 01:37:18 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-21 01:37:18 +0300 |
commit | 6fab0430beafed684283468c157ee1f90c8c533d (patch) | |
tree | d95b2f4df3bc8c5923dc0e549a5ce2ac0c0d94b5 /docs/markdown | |
parent | 511a37085647ffbc45c8f8b7c408ef7898fb998d (diff) | |
parent | 9b5a5c2e61b3eda633acbe859b0e40e9597dac25 (diff) | |
download | meson-6fab0430beafed684283468c157ee1f90c8c533d.zip meson-6fab0430beafed684283468c157ee1f90c8c533d.tar.gz meson-6fab0430beafed684283468c157ee1f90c8c533d.tar.bz2 |
Merge pull request #2224 from mesonbuild/morealpha
More doc alphabetisation
Diffstat (limited to 'docs/markdown')
-rw-r--r-- | docs/markdown/Cross-compilation.md | 171 | ||||
-rw-r--r-- | docs/markdown/Design-rationale.md | 197 | ||||
-rw-r--r-- | docs/markdown/Gnome-module.md | 253 | ||||
-rw-r--r-- | docs/markdown/Manual.md | 4 | ||||
-rw-r--r-- | docs/markdown/Pkgconfig-module.md | 44 | ||||
-rw-r--r-- | docs/markdown/Python-3-module.md | 15 | ||||
-rw-r--r-- | docs/markdown/Qt4-module.md | 3 | ||||
-rw-r--r-- | docs/markdown/Qt5-module.md | 13 | ||||
-rw-r--r-- | docs/markdown/RPM-module.md | 10 | ||||
-rw-r--r-- | docs/markdown/Reference-manual.md | 1214 | ||||
-rw-r--r-- | docs/markdown/Reproducible-builds.md | 19 | ||||
-rw-r--r-- | docs/markdown/Windows-module.md | 11 | ||||
-rw-r--r-- | docs/markdown/Wrap-best-practices-and-tips.md | 93 | ||||
-rw-r--r-- | docs/markdown/Wrap-dependency-system-manual.md | 113 | ||||
-rw-r--r-- | docs/markdown/Wrap-review-guidelines.md | 7 | ||||
-rw-r--r-- | docs/markdown/i18n-module.md | 36 |
16 files changed, 1691 insertions, 512 deletions
diff --git a/docs/markdown/Cross-compilation.md b/docs/markdown/Cross-compilation.md index b7ef354..e232033 100644 --- a/docs/markdown/Cross-compilation.md +++ b/docs/markdown/Cross-compilation.md @@ -4,28 +4,64 @@ 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 +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 (this is only meaningful for programs such as compilers that, when run, produce object code for a different CPU than what the program is being run on) -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. 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 and both your *host* and *target machines* are 32 bit ARM Linux. This should be quite understandable as well. - -It gets a bit trickier when we think about how the cross compiler was generated. It was built and it runs on a specific platform but the output it generates is for a different platform. In this case *build* and *host machines* are the same, but *target machine* is different. - -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. - -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. +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. 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 and both your *host* and *target +machines* are 32 bit ARM Linux. This should be quite understandable as +well. + +It gets a bit trickier when we think about how the cross compiler was +generated. It was built and it runs on a specific platform but the +output it generates is for a different platform. In this case *build* +and *host machines* are the same, but *target machine* is different. + +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. + +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. The first one is the list of executables that we are going to use. A sample snippet might look like this: +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. The first one is the list of +executables that we are going to use. A sample snippet might look like +this: ```ini [binaries] @@ -36,9 +72,17 @@ strip = '/usr/i586-mingw32msvc/bin/strip' exe_wrapper = 'wine' # A command used to run generated executables. ``` -The entries are pretty self explanatory but the last line is special. It 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. +The entries are pretty self explanatory but the last line is +special. It 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. -The next section lists properties of the cross compiler and thus of the target system. It looks like this: +The next section lists properties of the cross compiler and thus of +the target system. It looks like this: ```ini [properties] @@ -56,16 +100,40 @@ c_args = ['-DCROSS=1', '-DSOMETHING=3'] c_link_args = ['-some_link_arg'] ``` -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'`). - -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: +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'`). + +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 ``` -The last 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. +The last 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] @@ -75,11 +143,26 @@ 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. Common values might include `x86`, `arm` or `x86_64`. 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. +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. Common values might +include `x86`, `arm` or `x86_64`. 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 @@ -90,20 +173,24 @@ Once you have the cross file, starting a build is simple $ meson srcdir builddir --cross-file cross_file.txt ``` -Once configuration is done, compilation is started by invoking Ninja in the usual way. +Once configuration is done, compilation is started by invoking Ninja +in the usual way. ## Introspection and system checks -The main *meson* object provides two functions to determine cross compilation status. +The main *meson* object provides two functions to determine cross +compilation status. ```meson meson.is_cross_build() # returns true when cross compiling meson.has_exe_wrapper() # returns true if an exe wrapper has been defined ``` -Note that the latter gives undefined return value when doing a native build. +Note that the latter gives undefined return value when doing a native +build. -You can run system checks on both the system compiler or the cross compiler. You just have to specify which one to use. +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) @@ -115,7 +202,10 @@ 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. +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) @@ -125,22 +215,35 @@ You can then take `native_exe` and use it as part of a generator rule or anythin ## 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: +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, dependency 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. +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. ## 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. +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: +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] diff --git a/docs/markdown/Design-rationale.md b/docs/markdown/Design-rationale.md index 611b7f4..269f688 100644 --- a/docs/markdown/Design-rationale.md +++ b/docs/markdown/Design-rationale.md @@ -5,76 +5,174 @@ 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. +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. +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. +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. +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? +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. +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. +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. +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. +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. +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. +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. +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. +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. +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. +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. @@ -83,9 +181,15 @@ 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. +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. +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') @@ -102,9 +206,13 @@ sources = ['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. +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. +Here's a slightly more complicated definition. It should still be +understandable. ```meson project('build library', 'c') @@ -114,20 +222,37 @@ 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 `ninja 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 no tbe installed, but instead it is added to the list of unit tests, which can be run with the command `ninja test`. +First we build a shared library named foobar. It is marked +installable, so running `ninja 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 no tbe installed, but instead it is added to the list +of unit tests, which can be run with the command `ninja test`. -Above we mentioned precompiled headers as a feature not supported by other build systems. Here's how you would use them. +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. +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. +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. +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/docs/markdown/Gnome-module.md b/docs/markdown/Gnome-module.md index 0e24bb0..e81875a 100644 --- a/docs/markdown/Gnome-module.md +++ b/docs/markdown/Gnome-module.md @@ -1,68 +1,121 @@ # GNOME module -This module provides helper tools for build operations needed when building Gnome/GLib programs. +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. +**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. +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. +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` -* `source_dir`: a list of subdirectories where the resource compiler should look up the files, relative to the location of the XML file -* `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 -* `gresource_bundle`: (*Added 0.37.0*) if true, output a `.gresource` file instead of source -* `install_header`: (*Added 0.37.0*) if true, install the header file + +* `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 -* `extra_args`: extra command line arguments to pass to the resource compiler -Returns an array containing: `[c_source, header_file]` or `[gresource_bundle]` +* `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 subdirectories where the resource compiler + should look up the files, relative to the location of the XML file + + compiler + +Returns an array containing: `[c_source, header_file]` or +`[gresource_bundle]` ### gnome.generate_gir() -Generates GObject introspection data. Takes one positional argument, the build target you want to build gir data for. There are several keyword arguments. Many of these map directly to the `g-ir-scanner` tool so see its documentation for more information. +Generates GObject introspection data. Takes one positional argument, +the build target you want to build gir data for. 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 -* `symbol_prefix`: the symbol prefix for the gir object, e.g. `gtk` -* `identifier_prefix`: the identifier prefix for the gir object, e.g. `Gtk` -* `export_packages`: extra packages the gir file exports + +* `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 -* `dependencies`: deps to use during introspection scanning -* `link_with`: list of libraries to link with + * `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 -* `extra_args`: command line arguments to pass to gir compiler -Returns an array of two elements which are: `[gir_target, typelib_target]` +* `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` + +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. +Generates a marshal file using the `glib-genmarshal` tool. The first +argument is the basename of the output files. -* `sources`: the list of sources to use as inputs -* `prefix`: the prefix to use for symbols +* `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 -* `stdinc`: if true, include the standard marshallers from glib -* `nostdinc`: if true, don't include the standard marshallers from glib -* `internal`: if true, mark generated sources as internal +* `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 -* `extra_args`: (*Added 0.42.0*) additional command line arguments to pass - to `glib-genmarshal` (*Requires GLib 2.54*) *Added 0.35.0* @@ -70,23 +123,31 @@ 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. +Generates enum files for GObject using the `glib-mkenums` tool. The +first argument is the base name of the output files. -This method is essentially a wrapper around the `glib-mkenums` tool's command line API. It is the most featureful method for enum creation. +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. +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. +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`. +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`. -* `sources`: the list of sources to make enums with * `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 -* `comments`: comment passed to the command -* `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 * `eprod`: enum text * `fhead`: file header @@ -101,24 +162,31 @@ 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`. - -* `sources`: the list of sources to make enums with +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 -* `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) -* `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 -* `body_prefix`: additional prefix at the top of the body file, e.g. for extra includes Example: @@ -144,68 +212,87 @@ 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. +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. ### gnome.gdbus_codegen() -Compiles the given XML schema into gdbus source code. Takes two positional arguments, the first one specifies the name of the source files and the second specifies the XML file name. There are three keyword arguments. `interface_prefix` and `namespace` map to corresponding features of the compiler while `object_manager` (since 0.40.0), when set to true, generates object manager code. +Compiles the given XML schema into gdbus source code. Takes two +positional arguments, the first one specifies the name of the source +files and the second specifies the XML file name. There are three +keyword arguments. `interface_prefix` and `namespace` map to +corresponding features of the compiler while `object_manager` (since +0.40.0), when set to true, generates object manager code. -Returns an opaque object containing the source files. Add it to a top level target's source list. +Returns an opaque object containing the source files. Add it to a top +level target's source list. ### gnome.generate_vapi() -Creates a VAPI file from gir. The first argument is the name of the library. +Creates a VAPI file from gir. The first argument is the name of the +library. -* `sources`: the gir source to generate the VAPI from -* `packages`: VAPI packages that are depended upon -* `metadata_dirs`: extra directories to include for metadata files * `gir_dirs`: extra directories to include for gir files -* `vapi_dirs`: extra directories to include for VAPI 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. +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. +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`. +This also creates two targets for translations +`help-$project-update-po` and `help-$project-pot`. -* `sources`: list of pages +* `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) -* `languages`: list of languages for translations -Note that very old versions of yelp may not support symlinked media; At least 3.10 should work. +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. +Compiles and installs gtkdoc documentation into +`prefix/share/gtk-doc/html`. Takes one positional argument: The name +of the module. -* `main_xml`: specifies the main XML file -* `main_sgml`: equal to `main_xml` -* `src_dir`: include_directories to include +* `content_files`: a list of content files * `dependencies`: a list of dependencies -* `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) -* `scan_args`: a list of arguments to pass to `gtkdoc-scan` -* `scanobjs_args`: a list of arguments to pass to `gtkdoc-scangobj` -* `gobject_typesfile`: a list of type files * `fixxref_args`: a list of arguments to pass to `gtkdoc-fixxref` -* `html_args` a list of arguments to pass to `gtkdoc-mkhtml` +* `gobject_typesfile`: a list of type files +* `ignore_headers`: a list of header files to ignore * `html_assets`: a list of assets for the HTML pages -* `content_files`: a list of content files +* `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` -* `ignore_headers`: a list of header files to ignore +* `scan_args`: a list of arguments to pass to `gtkdoc-scan` +* `scanobjs_args`: a list of arguments to pass to `gtkdoc-scangobj` +* `src_dir`: include_directories to include -This creates a `$module-doc` target that can be ran to build docs and normally these are only built on install. +This creates a `$module-doc` target that can be ran to build docs and +normally these are only built on install. ### 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. +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. diff --git a/docs/markdown/Manual.md b/docs/markdown/Manual.md index 0c126c0..988efa1 100644 --- a/docs/markdown/Manual.md +++ b/docs/markdown/Manual.md @@ -4,4 +4,6 @@ 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. +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/docs/markdown/Pkgconfig-module.md b/docs/markdown/Pkgconfig-module.md index 2424421..8814d19 100644 --- a/docs/markdown/Pkgconfig-module.md +++ b/docs/markdown/Pkgconfig-module.md @@ -1,24 +1,42 @@ # Pkgconfig module -This module is a simple generator for [pkg-config](https://pkg-config.freedesktop.org/) files. +This module is a simple generator for +[pkg-config](https://pkg-config.freedesktop.org/) files. ## Usage -To use this module, just do: **`pkg = import('pkgconfig')`**. The following function will then be available as `pkg.generate()`. You can, of course, replace the name `pkg` with anything else. +To use this module, just do: **`pkg = import('pkgconfig')`**. The +following function will then be available as `pkg.generate()`. You +can, of course, replace the name `pkg` with anything else. ### pkg.generate() -The generated file's properties are specified with the following keyword arguments. +The generated file's properties are specified with the following +keyword arguments. -- `libraries` a list of built libraries (usually results of shared_library) that the user needs to link against -- `version` a string describing the version of this library -- `name` the name of this library - `description` a string describing the library -- `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` -- `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` +- `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 +- `libraries_private` list of strings to put in the + `Libraries.private` field +- `name` the name of this library +- `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 to put in the `Requires` field -- `requires_private` list of strings to put in the `Requires.private` field -- `libraries_private` list of strings to put in the `Libraries.private` field -- `install_dir` the directory to install to, defaults to the value of option `libdir` followed by `/pkgconfig` -- `extra_cflags` a list of extra compiler flags to be added to the `Cflags` field after the header search path -- `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 `installdir` are reserved and may not be used. +- `requires_private` list of strings to put in the `Requires.private` + field +- `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 + `installdir` are reserved and may not be used. +- `version` a string describing the version of this library diff --git a/docs/markdown/Python-3-module.md b/docs/markdown/Python-3-module.md index 2a33ba8..fa1d78e 100644 --- a/docs/markdown/Python-3-module.md +++ b/docs/markdown/Python-3-module.md @@ -1,16 +1,22 @@ # Python 3 module -This module provides support for dealing with Python 3. It has the following methods. +This module provides support for dealing with Python 3. It has the +following methods. ## 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 object. +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 object. *Added 0.38.0* ## 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). +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). *Added 0.38.0* @@ -22,6 +28,7 @@ Returns a string with the Python language version such as `3.5`. ## sysconfig_path -Returns the Python sysconfig path without prefix, such as `lib/python3.6/site-packages`. +Returns the Python sysconfig path without prefix, such as +`lib/python3.6/site-packages`. *Added 0.40.0* diff --git a/docs/markdown/Qt4-module.md b/docs/markdown/Qt4-module.md index 77e271d..4be1be5 100644 --- a/docs/markdown/Qt4-module.md +++ b/docs/markdown/Qt4-module.md @@ -1,3 +1,4 @@ # 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). +This module provides support for Qt4's `moc`, `uic` and `rcc` +tools. It is used identically to the [Qt 5 module](Qt5-module.md). diff --git a/docs/markdown/Qt5-module.md b/docs/markdown/Qt5-module.md index 64d2920..7082309 100644 --- a/docs/markdown/Qt5-module.md +++ b/docs/markdown/Qt5-module.md @@ -1,10 +1,15 @@ # Qt5 module -The Qt5 module provides tools to automatically deal with the various tools and steps required for Qt. The module has one method. +The Qt5 module provides tools to automatically deal with the various +tools and steps required for Qt. The module has one method. ## preprocess -This method takes four keyword arguments, `moc_headers`, `moc_sources`, `ui_files` and `qresources` which define the files that require preprocessing with `moc`, `uic` and `rcc`. It returns an opaque object that should be passed to a main build target. A simple example would look like this: +This method takes four keyword arguments, `moc_headers`, +`moc_sources`, `ui_files` and `qresources` which define the files that +require preprocessing with `moc`, `uic` and `rcc`. It returns an +opaque object that should be passed to a main build target. A simple +example would look like this: ```meson qt5 = import('qt5') @@ -15,4 +20,6 @@ executable('myprog', 'main.cpp', 'myclass.cpp', moc_files, ``` -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 '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). diff --git a/docs/markdown/RPM-module.md b/docs/markdown/RPM-module.md index 3939937..cab6d96 100644 --- a/docs/markdown/RPM-module.md +++ b/docs/markdown/RPM-module.md @@ -1,10 +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. +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. +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/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index c98bd79..91f7edd 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -2,7 +2,9 @@ ## 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). +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() @@ -11,13 +13,24 @@ The following functions are available in build files. Click on each to see the d void add_global_arguments(arg1, arg2, ...) ``` -Adds the positional arguments to the compiler command line for the language specified in `language` keyword argument. 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. +Adds the positional arguments to the compiler command line for the +language specified in `language` keyword argument. 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. -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. +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:** 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', ...` +**Note:** You must pass always arguments individually `arg1, arg2, + ...` rather than as a string `'arg1 arg2', ...` ### add_global_link_arguments() @@ -33,7 +46,9 @@ Like `add_global_arguments` but the arguments are passed to the linker. add_languages(*langs*) ``` -Add support for new programming languages. Equivalent to having them in the `project` declaration. This function is usually used to add languages that are only used on some platforms like this: +Add support for new programming languages. Equivalent to having them +in the `project` declaration. This function is usually used to add +languages that are only used on some platforms like this: ```meson project('foobar', 'c') @@ -42,7 +57,10 @@ if compiling_for_osx endif ``` -Takes one keyword argument, `required`. It defaults to `true`, which means that if any of the languages specified is not found, Meson will halt. Returns true if all languages specified were found and false otherwise. +Takes one keyword argument, `required`. It defaults to `true`, which +means that if any of the languages specified is not found, Meson will +halt. Returns true if all languages specified were found and false +otherwise. ### add_project_arguments() @@ -50,7 +68,9 @@ Takes one keyword argument, `required`. It defaults to `true`, which means that 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. +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() @@ -66,7 +86,9 @@ Like `add_project_arguments` but the arguments are passed to the linker. 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: +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` an [environment object](#environment-object) to use a custom environment - `exe_wrapper` a list containing the wrapper command or script followed by the arguments to it @@ -75,7 +97,9 @@ Add a custom test setup that can be used to run the tests with a custom setup, f To use the test setup, run `mesontest --setup=*name*` inside the build dir. -Note that all these options are also available while running the `mesontest` script for running tests instead of `ninja test` or `msbuild RUN_TESTS.vcxproj`, etc depending on the backend. +Note that all these options are also available while running the +`mesontest` script for running tests instead of `ninja test` or +`msbuild RUN_TESTS.vcxproj`, etc depending on the backend. ### benchmark() @@ -83,11 +107,15 @@ Note that all these options are also available while running the `mesontest` scr 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` with the exception that there is no `is_parallel` keyword, because benchmarks are never run in parallel. +Creates a benchmark item that will be run when the benchmark target is +run. The behavior of this function is identical to `test` with the +exception that there is no `is_parallel` keyword, because benchmarks +are never run in parallel. ### build_target() -Creates a build target whose type can be set dynamically with the `target_type` keyword argument. This declaration: +Creates a build target whose type can be set dynamically with the +`target_type` keyword argument. This declaration: ```meson executable(<arguments and keyword arguments>) @@ -99,7 +127,10 @@ is equivalent to this: 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. +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() @@ -107,7 +138,9 @@ The object returned by `build_target` and all convenience wrappers for `build_ta 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`. +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`. ### configure_file() @@ -115,11 +148,18 @@ Creates an empty configuration object. You should add your configuration with [i generated_file = configure_file(...) ``` -This function can run in two modes depending on the keyword arguments passed to it. +This function can run in two 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). +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). -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. +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. These are all the supported keyword arguments: @@ -209,14 +249,21 @@ The returned object also has methods that are documented in the 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. +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. - - `include_directories`, the directories to add to header search path - - `link_with`, libraries to link against - - `sources`, sources to add to targets (or generated header files that should be built before sources including them are built) - - `dependencies`, other dependencies needed to use this dependency - `compile_args`, compile arguments to use + - `dependencies`, other dependencies needed to use this dependency + - `include_directories`, the directories to add to header search path - `link_args`, link arguments to use + - `link_with`, libraries to link against + - `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` ### dependency() @@ -225,19 +272,47 @@ This function returns a [dependency object](#dependency-object) that behaves lik dependency_object dependency(*dependency_name*, ...) ``` -Finds an external dependency (usually a library installed on your system) with the given name with `pkg-config` if possible and with [library-specific fallback detection logic](Dependencies.md) otherwise. This function supports the following keyword arguments: - -- `modules` specifies submodules to use for dependencies such as Qt5 or Boost. -- `required`, when set to false, Meson will proceed with the build even if the dependency is not found -- `version`, 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. (*Added 0.37.0*) You can also specify multiple restrictions by passing a list to this keyword argument, such as: `['>=3.14.0', '<=4.1.0']`. -- `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. -- `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) -- `fallback` specifies a subproject fallback to use in case the dependency is not found in the system. The value is an array `['subproj_name', 'subproj_dep']` where the first value is the name of the subproject and the second is the variable name in that subproject that contains the value of [`declare_dependency`](#declare_dependency). -- `default_options` *(added 0.37.0)* an array of option values that override those set in the project's `default_options` invocation (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) -- `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 for this (though `auto` will work on all of them) -- `language` *(added 0.42.0)* defines what language-specific dependency to find if it's available for multiple languages. +Finds an external dependency (usually a library installed on your +system) with the given name with `pkg-config` if possible and with +[library-specific fallback detection logic](Dependencies.md) +otherwise. This function supports the following keyword arguments: + +- `default_options` *(added 0.37.0)* an array of option values that + override those set in the project's `default_options` invocation + (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) +- `fallback` specifies a subproject fallback to use in case the + dependency is not found in the system. The value is an array + `['subproj_name', 'subproj_dep']` where the first value is the name + of the subproject and the second is the variable name in that + subproject that contains the value of + [`declare_dependency`](#declare_dependency). +- `language` *(added 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 for this (though + `auto` will work on all of them) +- `modules` specifies submodules to use for dependencies such as Qt5 + or Boost. +- `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. +- `required`, when set to false, Meson will proceed with the build + even if the dependency is not found +- `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`, 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. (*Added 0.37.0*) + You can also specify multiple restrictions by passing a list to this + keyword argument, such as: `['>=3.14.0', '<=4.1.0']`. -The returned object also has methods that are documented in the [object methods section](#dependency-object) below. +The returned object also has methods that are documented in the +[object methods section](#dependency-object) below. ### error() @@ -261,47 +336,110 @@ Returns an empty [environment variable object](#environment-object). 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: +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, objects (`.o`, `.obj`) and libraries (`.so`, `.dll`, etc) will be linked, and all other files (headers, unknown extensions, etc) will be ignored. - -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. For all input files (generated and non-generated), Meson uses the [dependency file](https://ninja-build.org/manual.html#ref_headers) generated by your compiler to determine when to rebuild sources. The behavior is similar for other backends. +- 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, objects (`.o`, `.obj`) and +libraries (`.so`, `.dll`, etc) will be linked, and all other files +(headers, unknown extensions, etc) will be ignored. + +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. For all input +files (generated and non-generated), Meson uses the [dependency +file](https://ninja-build.org/manual.html#ref_headers) generated by +your compiler to determine when to rebuild sources. 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). -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). - -- `link_with`, one or more shared or static libraries (built by this project) that this target should be linked with, If passed a list this list will be flattened as of 0.41.0. -- `link_whole` links all contents of the given static libraries whether they are used by not, equivalent to the `-Wl,--whole-archive` argument flag of GCC, available since 0.40.0. As of 0.41.0 if passed a list that list will be flattened. - `<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++ -- `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. -- `include_directories` one or more objects created with the `include_directories` function -- `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) -- `gui_app` when set to true flags this target as a GUI application on platforms where this makes a difference (e.g. Windows) -- `extra_files` are not used for the build itself but are shown as source files in IDEs that group files by targets (such as Visual Studio) +- `<languagename>_args` compiler flags to use for the given language; + eg: `cpp_args` for C++ +- `build_by_default` causes, when set to true, to have this target be + built by default, that is, when invoking plain `ninja`, the default + value is true for all built target types, since 0.38.0 +- `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` are 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 difference (e.g. Windows) +- `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 + automaticallytrigger a re-link (but not a re-compile) of the target + when this file changes. +- `link_whole` links all contents of the given static libraries + whether they are used by not, equivalent to the + `-Wl,--whole-archive` argument flag of GCC, available since + 0.40.0. As of 0.41.0 if passed a list that list will be flattened. +- `link_with`, one or more shared or static libraries (built by this + project) that this target should be linked with, If passed a list + this list will be flattened as of 0.41.0. +- `implib` 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). Since + 0.42.0 +- `implicit_include_directories` is a boolean telling whether Meson + adds the current source and build directories to the include path, + defaults to `true`, since 0.42.0 +- `include_directories` one or more objects created with the + `include_directories` function - `install`, when set to true, this executable should be installed -- `install_rpath` a string to set the target's rpath to after install (but *not* before that) -- `build_rpath` a string to add to target's rpath definition in the build dir, but which will be removed on install -- `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'`. -- `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. -- `build_by_default` causes, when set to true, to have this target be built by default, that is, when invoking plain `ninja`, the default value is true for all built target types, since 0.38.0 -- `override_options` takes an array of strings in the same format as `project`'s `default_options` overriding the values of these options for this target only, since 0.40.0 -- `implib` 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). Since 0.42.0 -- `implicit_include_directories` is a boolean telling whether Meson adds the current source and build directories to the include path, defaults to `true`, since 0.42.0 - -The list of `sources`, `objects`, and `dependencies` is always flattened, which means you can freely nest and add lists while creating the final list. As a corollary, the best way to handle a 'disabled dependency' is by assigning an empty list `[]` to it and passing it like any other dependency to the `dependencies:` keyword argument. +- `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_rpath` a string to set the target's rpath to after install + (but *not* before that) +- `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. +- `override_options` takes an array of strings in the same format as + `project`'s `default_options` overriding the values of these options + for this target only, since 0.40.0 + +The list of `sources`, `objects`, and `dependencies` is always +flattened, which means you can freely nest and add lists while +creating the final list. As a corollary, the best way to handle a +'disabled dependency' is by assigning an empty list `[]` to it and +passing it like any other dependency to the `dependencies:` keyword +argument. -The returned object also has methods that are documented in the [object methods section](#build-target-object) below. +The returned object also has methods that are documented in the +[object methods section](#build-target-object) below. ### find_library() -This function is deprecated and in the 0.31.0 release it was moved to [the compiler object](#compiler-object) as obtained from `meson.get_compiler(lang)`. +This function is deprecated and in the 0.31.0 release it was moved to +[the compiler object](#compiler-object) as obtained from +`meson.get_compiler(lang)`. ### find_program() @@ -309,27 +447,46 @@ This function is deprecated and in the 0.31.0 release it was moved to [the compi 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 a script in the current source directory. +`program_name1` here is a string that can be an executable or script +to be searched for in `PATH`, or a script in the current source +directory. -`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. Meson versions earlier than 0.37.0 only accept one argument. +`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. Meson versions earlier than +0.37.0 only accept one argument. 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 to check whether it was found or not. +- `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 to check + whether it was found or not. -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. +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. -``` -setcap = find_program('setcap', '/usr/sbin/setcap', '/sbin/setcap', required : false) -``` +If you need to check for a program in a non-standard location, you can +just pass an absolute path to `find_program`, e.g. ``` setcap = +find_program('setcap', '/usr/sbin/setcap', '/sbin/setcap', required : +false) ``` + +It is also possible to pass an array to `find_program` in case you +need to construct the set of paths to search on the fly: -It is also possible to pass an array to `find_program` in case you need to construct the set of paths to search on the fly: ``` setcap = find_program(['setcap', '/usr/sbin/setcap', '/sbin/setcap'], required : false) ``` -The returned object also has methods that are documented in the [object methods section](#external-program-object) below. +The returned object also has methods that are documented in the +[object methods section](#external-program-object) below. ### files() @@ -337,7 +494,14 @@ The returned object also has methods that are documented in the [object methods 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: +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') @@ -359,22 +523,37 @@ Meson will then do the right thing. 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 -- `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 -- `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 +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 +- `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 -The returned object also has methods that are documented in the [object methods section](#generator-object) below. +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: +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 `outputs` keyword argument *must* be constructed using one or both of these two substitutions. +Each string passed to the `outputs` 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: +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 @@ -382,9 +561,16 @@ In addition to the above substitutions, the `arguments` keyword argument also ac - `@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@`. +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. +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() @@ -400,7 +586,12 @@ Obtains the value of the [project build option](Build-options.md) specified in t 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. +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() @@ -408,7 +599,9 @@ This function can be used to dynamically obtain a variable. `res = get_variable( module_object import(module_name) ``` -Imports the given extension module. Returns an opaque object that can be used to call the methods of the module. Here's an example for a hypothetical `testmod` module. +Imports the given extension module. Returns an opaque 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') @@ -421,13 +614,22 @@ Imports the given extension module. Returns an opaque object that can be used to 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. +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). +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). -Each directory given is converted to two include paths: one that is relative to the source root and one relative to the build root. +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`: +For example, with the following source tree layout in +`/home/user/project.git`: `meson.build`: ```meson @@ -467,10 +669,16 @@ This function has one keyword argument `is_system` which, if set, flags the spec void install_data(list_of_files, ...) ``` -Installs files from the source tree that are listed as positional arguments. The following keyword arguments are supported: +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. -- `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. -- `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` 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 @@ -486,9 +694,16 @@ Installs files from the source tree that are listed as positional arguments. The 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`. +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`: +For example, this will install `common.h` and `kola.h` into +`/{prefix}/include`: ```meson install_headers('common.h', 'proj/kola.h') @@ -512,7 +727,11 @@ install_headers('common.h', 'proj/kola.h', install_dir : 'cust', subdir : 'mypro 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. All man pages are compressed during installation and installed with a `.gz` suffix. +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. All man pages are compressed during installation and +installed with a `.gz` suffix. ### install_subdir() @@ -520,15 +739,21 @@ Installs the specified man files from the source tree into system's man director void install_subdir(subdir_name, install_dir : ..., exclude_files : ..., exclude_directories : ...) ``` -Installs the entire given subdirectory and its contents from the source tree to the location specified by the keyword argument `install_dir`. Note that due to implementation issues this command deletes the entire target dir before copying the files, so you should never use `install_subdir` to install into two overlapping directories (such as `foo` and `foo/bar`) because if you do the behavior is undefined. +Installs the entire given subdirectory and its contents from the +source tree to the location specified by the keyword argument +`install_dir`. Note that due to implementation issues this command +deletes the entire target dir before copying the files, so you should +never use `install_subdir` to install into two overlapping directories +(such as `foo` and `foo/bar`) because if you do the behavior is +undefined. The following keyword arguments are supported: -- `install_dir`: the location to place the installed subdirectory. - `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. ### is_variable() @@ -544,7 +769,10 @@ Returns true if a variable of the given name exists and false otherwise. 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`. +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() @@ -552,7 +780,10 @@ Build a jar from the specified Java source files. Keyword arguments are the same string join_paths(string1, string2, ...) ``` -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`. +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`. *Added 0.36.0* @@ -562,12 +793,22 @@ Joins the given strings into a file system path segment. For example `join_paths buildtarget library(library_name, list_of_sources, ...) ``` -Builds a library that is either static or shared depending on the value of `default_library` user option. You should use this instead of [`shared_library`](#shared_library) or [`static_library`](#static_library) most of the time. This allows you to toggle your entire project (including subprojects) from shared to static with only one option. +Builds a library that is either static or shared depending on the +value of `default_library` user option. You should use this instead of +[`shared_library`](#shared_library) or +[`static_library`](#static_library) most of the time. This allows you +to toggle your entire project (including subprojects) from shared to +static with only one option. 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 suffix for the target by overriding the default (only used for libraries). By default this is `lib` on all platforms and compilers except with MSVC where it is omitted. -- `rust_crate_type` specifies the crate type for Rust libraries. Defaults to `dylib` for shared libraries and `rlib` for static libraries. +- `name_prefix` the string that will be used as the suffix for the + target by overriding the default (only used for libraries). By + default this is `lib` on all platforms and compilers except with + MSVC where it is omitted. +- `rust_crate_type` specifies the crate type for Rust + libraries. Defaults to `dylib` for shared libraries and `rlib` for + static libraries. `static_library` and `shared_library` also accept these keyword arguments. @@ -585,21 +826,55 @@ This function prints its argument to stdout. void project(project_name, list_of_languages, ...) ``` -The first argument to this function must be a string defining the name of this project. It is followed by programming languages that the project uses. Supported values for languages are `c`, `cpp` (for `C++`), `objc`, `objcpp`, `fortran`, `java`, `cs` (for `C#`) and `vala`. In versions before `0.40.0` you must have at least one language listed. +The first argument to this function must be a string defining the name +of this project. It is followed by programming languages that the +project uses. Supported values for languages are `c`, `cpp` (for +`C++`), `objc`, `objcpp`, `fortran`, `java`, `cs` (for `C#`) and +`vala`. In versions before `0.40.0` you must have at least one +language listed. -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_. +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_. Project supports the following keyword arguments. - - `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()`. - - - `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. - - - `meson_version` takes a string describing which Meson version the project requires. Usually something like `>0.28.0`. - - - `license` takes a string or array of strings describing the license(s) the code is under. Usually this would be something like `license : 'GPL2+'`, but if the code has multiple licenses you can specify them as an array like this: `license : ['proprietary', 'GPL3']`. 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. - - - `default_options` takes an array of strings. The strings are in the form `key=value` and have the same format as options to `mesonconf`. 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. + - `default_options` takes an array of strings. The strings are in the + form `key=value` and have the same format as options to + `mesonconf`. 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. Usually this would be something like + `license : 'GPL2+'`, but if the code has multiple licenses you can + specify them as an array like this: `license : ['proprietary', + 'GPL3']`. 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. + + - `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()`. ### run_command() @@ -607,7 +882,13 @@ Project supports the following keyword arguments. runresult run_command(command, list_of_args) ``` -Runs the command specified in positional arguments. Returns [an opaque object](#run-result-object) containing the result of the invocation. The script 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. +Runs the command specified in positional arguments. Returns [an opaque +object](#run-result-object) containing the result of the +invocation. The script 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. ### run_target @@ -615,12 +896,24 @@ Runs the command specified in positional arguments. Returns [an opaque object](# buildtarget 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, with Ninja you can run it as `ninja target_name`. - -The script 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) +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, with Ninja you can +run it as `ninja target_name`. + +The script 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) ### set_variable() @@ -628,7 +921,8 @@ The script is run from an *unspecified* directory, and Meson will set three envi void set_variable(variable_name, value) ``` -Assigns a value to the given variable name. Calling `set_variable('foo', bar)` is equivalent to `foo = bar`. +Assigns a value to the given variable name. Calling +`set_variable('foo', bar)` is equivalent to `foo = bar`. ### shared_library() @@ -636,11 +930,26 @@ Assigns a value to the given variable name. Calling `set_variable('foo', bar)` i 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. - -- `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 below). -- `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. For example, if `version` is `3.6.0` and `soversion` is not defined, it is set to `3`. -- `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). +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. 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 below). +- `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() @@ -648,9 +957,12 @@ Builds a shared library with the given sources. Positional and keyword arguments buildtarget shared_module(module_name, list_of_sources, ...) ``` -Builds a shared module with the given sources. Positional and keyword arguments are the same as for [`library`](#library). +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. +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. *Added 0.37.0* @@ -660,9 +972,14 @@ This is useful for building modules that will be `dlopen()`ed and hence may cont buildtarget static_library(library_name, list_of_sources, ...) ``` -Builds a static library with the given sources. Positional and keyword arguments are otherwise the same as for [`library`](#library), but it has one argument the others don't have: +Builds a static library with the given sources. Positional and keyword +arguments are otherwise the same as for [`library`](#library), but it +has one argument the others don't have: - - `pic`, (*Added 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. + - `pic`, (*Added 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. ### subdir() @@ -670,9 +987,15 @@ Builds a static library with the given sources. Positional and keyword arguments 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()`. +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. +Note that this means that each `meson.build` file in a source tree can +and must only be executed once. ### subproject() @@ -680,12 +1003,28 @@ Note that this means that each `meson.build` file in a source tree can and must 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: - - - `version` keyword argument that works just like the one in `dependency`. It specifies what version the subproject should be, as an example `>=1.0.1` - - `default_options`, *(added 0.37.0)* an array of default option values that override those set in the project's `default_options` invocation (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) - -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). +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`, *(added 0.37.0)* an array of default option + values that override those set in the project's `default_options` + invocation (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) + - `version` keyword argument that works just like the one in + `dependency`. It specifies what version the subproject should be, + as an example `>=1.0.1` + +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). ### test() @@ -693,16 +1032,33 @@ Note that you can use the returned [subproject object](#subproject-object) to ac void test(name, executable, ...) ``` -Defines a unit test. Takes two positional arguments, the first is the name of this test and the second is the executable to run. Keyword arguments are the following. +Defines a unit test. Takes two positional arguments, the first is the +name of this test and the second is the executable to run. Keyword +arguments are the following. - `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 -- `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) -- `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 -- `workdir` absolute path that will be used as the working directory for the test -Defined tests can be run in a backend-agnostic way by calling `mesontest` inside the build dir, or by using backend-specific commands, such as `ninja test` or `msbuild RUN_TESTS.vcxproj`. +- `env` environment variables to set, such as `['NAME1=value1', + 'NAME2=value2']`, or an [`environment()` + object](#environment-object) which allows more sophisticated + environment juggling + +- `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) + +- `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 + +- `workdir` absolute path that will be used as the working directory + for the test + +Defined tests can be run in a backend-agnostic way by calling +`mesontest` inside the build dir, or by using backend-specific +commands, such as `ninja test` or `msbuild RUN_TESTS.vcxproj`. ### vcs_tag() @@ -710,15 +1066,27 @@ Defined tests can be run in a backend-agnostic way by calling `mesontest` inside 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`. +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) -- `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()`) -- `command` string list with the command to execute, see [`custom_target`](#custom_target) for details on how this command must be specified -- `replace_string` string in the input file to substitute with the commit information (defaults to `@VCS_TAG@`) +- `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 an opaque [`custom_target`](#custom_target) object that can be used as source. If you desire more specific behavior than what this command provides, you should use `custom_target`. +Meson will read the contents of `input`, substitute the +`replace_string` with the detected revision number, and write the +result to `output`. This method returns an opaque +[`custom_target`](#custom_target) object that can be used as +source. If you desire more specific behavior than what this command +provides, you should use `custom_target`. ## Built-in objects @@ -726,35 +1094,92 @@ 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. - -- `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. - -- `backend()` *(added 0.37.0)* returns a string representing the current backend: `ninja`, `vs2010`, `vs2015`, `vs2017`, or `xcode`. - -- `is_cross_build()` returns `true` if the current build is a [cross build](Cross-compilation.md) 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. - -- `is_subproject()` returns `true` if the current project is being built as a subproject of some other project and `false` otherwise. - -- `has_exe_wrapper()` returns true when doing a cross build if there is a wrapper command that can be used to execute cross built binaries (for example when cross compiling from Linux to Windows, one can use `wine` as the wrapper). - -- `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 additional arguments are passed as parameters. - - To determine the installation location, the script should use the `DESTDIR`, `MESON_INSTALL_PREFIX`, `MESON_INSTALL_DESTDIR_PREFIX` variables. `DESTDIR` will be set only if it is inherited from the outside environment. `MESON_INSTALL_PREFIX` is always set and has the value of the `prefix` option passed to Meson. `MESON_INSTALL_DESTDIR_PREFIX` is always set and contains `DESTDIR` and `prefix` joined together. This is useful because both are absolute paths, and many path-joining functions such as [`os.path.join` in Python](https://docs.python.org/3/library/os.path.html#os.path.join) special-case absolute paths. - - `MESONINTROSPECT` contains the path to the `mesonintrospect` executable that corresponds to the `meson` executable that was used to configure the build. (This might be a different path then the first `mesonintrospect` executable found in `PATH`.) It can be used to query build configuration. - -- `add_postconf_script(script_name, arg1, arg2, ...)` will run 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. - -- `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()`. - -- `current_build_dir()` returns a string with the absolute path to the current build directory. - -- `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()`. - -- `build_root()` returns a string with the absolute path to the build root directory. +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_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 + additional arguments are passed as parameters. + +- `add_postconf_script(script_name, arg1, arg2, ...)` will run 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. + +- `backend()` *(added 0.37.0)* returns a string representing the + current backend: `ninja`, `vs2010`, `vs2015`, `vs2017`, or `xcode`. + +- `build_root()` returns a string with the absolute path to the build + root directory. + +- `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_cross_property(propname, fallback_value)` returns the given + property from a cross file, the optional second argument is returned + if not cross compiling or the given property is not found. + +- `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. + +- `has_exe_wrapper()` returns true when doing a cross build if there + is a wrapper command that can be used to execute cross built + binaries (for example when cross compiling from Linux to Windows, + one can use `wine` as the wrapper). + +- `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. + + To determine the installation location, the script should use the + `DESTDIR`, `MESON_INSTALL_PREFIX`, `MESON_INSTALL_DESTDIR_PREFIX` + variables. `DESTDIR` will be set only if it is inherited from the + outside environment. `MESON_INSTALL_PREFIX` is always set and has + the value of the `prefix` option passed to + Meson. `MESON_INSTALL_DESTDIR_PREFIX` is always set and contains + `DESTDIR` and `prefix` joined together. This is useful because both + are absolute paths, and many path-joining functions such as + [`os.path.join` in + Python](https://docs.python.org/3/library/os.path.html#os.path.join) + special-case absolute paths. + + `MESONINTROSPECT` contains the path to the `mesonintrospect` + executable that corresponds to the `meson` executable that was used + to configure the build. (This might be a different path then the + first `mesonintrospect` executable found in `PATH`.) It can be used + to query build configuration. + +- `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()`. - `project_version()` returns the version string specified in `project` function call. @@ -762,96 +1187,253 @@ The `meson` object allows you to introspect various properties of the system. Th - `version()` return a string with the version of Meson. -- `get_cross_property(propname, fallback_value)` returns the given property from a cross file, the optional second argument is returned if not cross compiling or the given property is not found. +### `build_machine` object -- `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. +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: -### `build_machine` object +- `cpu_family()` returns the CPU family name. Guaranteed to return + `x86` for 32-bit userland on x86 CPUs, `x86_64` for 64-bit userland + on x86 CPUs, `arm` for 32-bit userland on all ARM CPUs, etc. + +- `cpu()` returns a more specific CPU name, such as `i686`, `amd64`, + etc. -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: +- `system()` returns the operating system name, such as `windows` (all + versions of Windows), `linux` (all Linux distros), `darwin` (all + versions of OS X/macOS), `cygwin` (for Cygwin), and `bsd` (all *BSD + OSes). -- `cpu_family()` returns the CPU family name. Guaranteed to return `x86` for 32-bit userland on x86 CPUs, `x86_64` for 64-bit userland on x86 CPUs, `arm` for 32-bit userland on all ARM CPUs, etc. -- `cpu()` returns a more specific CPU name, such as `i686`, `amd64`, etc. -- `system()` returns the operating system name, such as `windows` (all versions of Windows), `linux` (all Linux distros), `darwin` (all versions of OS X/macOS), `cygwin` (for Cygwin), and `bsd` (all *BSD OSes). -- `endian()` returns `big` on big-endian systems and `little` on little-endian systems. +- `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 above list, please file [a bug report](https://github.com/mesonbuild/meson/issues/new) with details and we'll look into it. +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 above list, 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). +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) +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. +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). +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). +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. +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. ### `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: +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. + +- `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. + +- `first_supported_argument(list_of_strings)`, given a list of + strings, returns the first argument that passes the `has_argument` + test above 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. + +- `get_id()` returns a string identifying the compiler. For example, + `gcc`, `msvc`, [and more](Compiler-properties.md#compiler-id). + +- `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. + +- `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, + you can specify external dependencies to use with `dependencies` + keyword argument. + +- `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. + +- `has_header` returns true if the specified header can be included, + 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`. + +- `has_header_symbol(headername, symbolname)` allows one to detect + 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. + +- `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, ...)` is the same as + `has_argument` but takes multiple arguments and uses them all in a + single compiler invocation, available since 0.37.0. + +- `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()` returns `true` if the C symbol + mangling is one underscore (`_`) prefixed to the symbol, available + since 0.37.0. + +- `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. -- `get_id()` returns a string identifying the compiler. For example, `gcc`, `msvc`, [and more](Compiler-properties.md#compiler-id). - `version()` returns the compiler's version number as a string. -- `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. -- `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. -- `alignment(typename)` returns the alignment of the type specified in the positional argument, you can specify external dependencies to use with `dependencies` keyword argument. -- `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. -- `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. -- `has_header` returns true if the specified header can be included, 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`. -- `has_type(typename)` returns true if the specified token is a type, you can specify external dependencies to use with `dependencies` keyword argument. -- `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. -- `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_header_symbol(headername, symbolname)` allows one to detect 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. -- `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, you can specify external dependencies to use with `dependencies` keyword argument. -- `has_multi_arguments(arg1, arg2, arg3, ...)` is the same as `has_argument` but takes multiple arguments and uses them all in a single compiler invocation, available since 0.37.0. -- `first_supported_argument(list_of_strings)`, given a list of strings, returns the first argument that passes the `has_argument` test above or an empty array if none pass. -- `symbols_have_underscore_prefix()` returns `true` if the C symbol mangling is one underscore (`_`) prefixed to the symbol, available since 0.37.0. -- `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. -- `get_define(definename)` returns the given preprocessor symbol's value as a string or empty string if it is not defined. The following keyword arguments can be used: -- `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. +- `args` can be 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. In versions newer than 0.38.0 you + should use the `include_directories` keyword described above. 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` specifies extra directories for header + searches. *(added 0.38.0)* + +- `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. + +- `prefix` can be used to add #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`, + `has_header_symbol`. + +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> + +### `string` object -- `prefix` can be used to add #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`, `has_header_symbol`. +All [strings](Syntax.md#strings) have the following methods. Strings +are immutable, all operations return their results as a new string. -- `include_directories` specifies extra directories for header searches. *(added 0.38.0)* +- `contains(string)` returns true if string contains the string + specified as the argument -- `args` can be 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. In versions newer than 0.38.0 you should use the `include_directories` keyword described above. 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`. +- `endswith(string)` returns true if string ends with the string + specified as the argument -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. +- `format()` formats text, see the [Syntax + manual](Syntax.md#string-formatting) for usage info -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> +- `join(list_of_strings)` is the opposite of split, for example + `'.'.join(['a', 'b', 'c']` yields `'a.b.c'` -### `string` object +- `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 + +- `strip()` removes whitespace at the beginning and end of the string + +- `to_int` returns the string converted to an integer (error if string + is not a number) -All [strings](Syntax.md#strings) have the following methods. Strings are immutable, all operations return their results as a new string. - - - `strip()` removes whitespace at the beginning and end of the string - - `format()` formats text, see the [Syntax manual](Syntax.md#string-formatting) for usage info - - `to_upper()` creates an upper case version of the string - - `to_lower()` creates a lower case version of the string - - `underscorify()` creates a string where every non-alphabetical non-number character is replaced with `_` - - `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 - - `endswith(string)` returns true if string ends with the string specified as the argument - - `contains(string)` returns true if string contains the string specified as the argument - - `to_int` returns the string converted to an integer (error if string is not a number) - - `join(list_of_strings)` is the opposite of split, for example `'.'.join(['a', 'b', 'c']` yields `'a.b.c'` - - `version_compare(comparison_string)` does semantic version comparison, if `x = '1.2.3'` then `x.version_compare('>1.0.0')` returns `true` +- `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 @@ -864,18 +1446,30 @@ All [strings](Syntax.md#strings) have the following methods. Strings are immutab A [boolean](Syntax.md#booleans) object has two simple methods: - - `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. - - `to_int()` as above, but returns either `1` or `0` +- `to_int()` as above, but 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): - - `length()`, the size of the array - - `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 *(added 0.38.0)* or, if it is not specified, causes a fatal error +- `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 *(added 0.38.0)* or, if it is + not specified, causes a fatal error -You can also iterate over arrays with the [`foreach` statement](https://github.com/mesonbuild/meson/wiki/Syntax#foreach-statements). +- `length()`, the size of the array + +You can also iterate over arrays with the [`foreach` +statement](https://github.com/mesonbuild/meson/wiki/Syntax#foreach-statements). ## Returned objects @@ -883,16 +1477,27 @@ These are objects returned by the [functions listed above](#functions). ### `build target` object -A build target is either an [executable](#executable), [shared](#shared_library), [static library](#static_library) or [shared module](#shared_module). - -- `extract_objects()` returns an opaque value representing the generated object files of arguments, usually used to take single object files and link them to unit tests or to compile some source files with custom flags. To use the object file(s) in another build target, use the `objects:` keyword argument. +A build target is either an [executable](#executable), +[shared](#shared_library), [static library](#static_library) or +[shared module](#shared_module). -- `extract_all_objects()` is same as above but returns all object files generated by this target +- `extract_all_objects()` is same as `extract_objects` but returns all + object files generated by this target -- `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 +- `extract_objects()` returns an opaque value representing the + generated object files of arguments, usually used to take single + object files and link them to unit tests or to compile some source + files with custom flags. To use the object file(s) in another build + target, use the `objects:` keyword argument. - `full_path()` returns a full path pointing to the result target file +- `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 + + ### `configuration` data object This object is returned by @@ -901,12 +1506,24 @@ 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 *(added 0.38.0)* and errors out if not - - `has(varname)`, returns `true` if the specified variable is set - - `merge_from(other)` takes as argument a different configuration data object and copies all entries from that object to the current object, available since 0.42.0 - - `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 (`"`) +- `get(varname, default_value)` returns the value of `varname`, if the + value has not been set returns `default_value` if it is defined + *(added 0.38.0)* and errors out if not + +- `has(varname)`, returns `true` if the specified variable is set + +- `merge_from(other)` takes as argument a different configuration data + object and copies all entries from that object to the current + object, available since 0.42.0 + +- `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 @@ -916,57 +1533,87 @@ cause a syntax error. ### `custom target` object -This object is returned by [`custom_target`](#custom_target) and contains a target with the following methods: +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 ### `dependency` object -This object is returned by [`dependency()`](#dependency) and contains an external dependency with the following methods: +This object is returned by [`dependency()`](#dependency) and contains +an external dependency with the following methods: - `found()` which returns whether the dependency was found - - `type_name()` which returns a string describing the type of the dependency, the most common values are `internal` for deps created with `declare_dependencies` and `pkgconfig` for system dependencies obtained with Pkg-config. + + - `get_pkgconfig_variable(varname)` (*Added 0.36.0*) will get the + pkg-config variable specified, or, if invoked on a non pkg-config + dependency, error out + + - `type_name()` which returns a string describing the type of the + dependency, the most common values are `internal` for deps created + with `declare_dependencies` and `pkgconfig` for system dependencies + obtained with Pkg-config. + - `version()` is the version number as a string, for example `1.2.8` - - `get_pkgconfig_variable(varname)` (*Added 0.36.0*) will get the pkg-config variable specified, or, if invoked on a non pkg-config dependency, error out + ### `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: +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()` which returns whether the executable was found -- `path()` which returns an array pointing to the executable (this is an array as opposed to a string because the program might be `['python', 'foo.py']`, for example) + +- `path()` which returns an array pointing to the executable (this is + an array as opposed to a string because the program might be + `['python', 'foo.py']`, for example) ### `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. It has the following methods. +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. It has the following methods. + +- `append(varname, value)` appends the given value to the old value of + the environment variable, e.g. `env.append'('FOO', 'BAR', separator + : ';')` produces `BOB;BAR` if `FOO` had the value `BOB` and plain + `BAR` 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. -- `set(varname, value)` sets environment variable in the first - argument to the value in the second argument, e.g. - `env.set('FOO', 'BAR') sets envvar`FOO`to value`BAR\` -- `append(varname, value)` appends the given value to the old value of - the environment variable, e.g. - `env.append'('FOO', 'BAR', separator : ';')` produces `BOB;BAR` if - `FOO` had the value `BOB` and plain `BAR` 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, value)` is the same as `append` except that it - writes to the beginning of the variable +- `prepend(varname, value)` is the same as `append` except that it + writes to the beginning of the variable +- `set(varname, value)` sets environment variable in the first + argument to the value in the second argument, e.g. + `env.set('FOO', 'BAR') sets envvar`FOO`to value`BAR\` ### `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 only one method, `found`, which returns whether the library was found. +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 only one method, `found`, which returns +whether the library was found. ### `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). +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. +* `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. ### `subproject` object -This object is returned by [`subproject()`](#subproject) and is an opaque object representing it. +This object is returned by [`subproject()`](#subproject) and is an +opaque object representing it. - `get_variable(name)` fetches the specified variable from inside the subproject. This is useful to, for instance, get a [declared @@ -974,9 +1621,12 @@ This object is returned by [`subproject()`](#subproject) and is an opaque object ### `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: +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 +- `compiled()` if true, the compilation succeeded, if false it did not + and the other methods return unspecified data - `returncode()` the return code of executing the compiled binary -- `stdout()` the standard out produced when the binary was run -- `stderr()` the standard error produced when the binary was run +- `stderr()` the standard error produced when the command was run +- `stdout()` the standard out produced when the command was run diff --git a/docs/markdown/Reproducible-builds.md b/docs/markdown/Reproducible-builds.md index e28ca7a..1e00fea 100644 --- a/docs/markdown/Reproducible-builds.md +++ b/docs/markdown/Reproducible-builds.md @@ -1,9 +1,20 @@ # Reproducible builds -A reproducible build means the following (as quoted from [the reproducible builds project site](https://reproducible-builds.org/)): +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. +> 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. +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. +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/docs/markdown/Windows-module.md b/docs/markdown/Windows-module.md index b2b5145..1d4b9bf 100644 --- a/docs/markdown/Windows-module.md +++ b/docs/markdown/Windows-module.md @@ -1,12 +1,17 @@ # Windows module -This module provides functionality used to build applications for Windows. +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. +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 - - `include_directories` which does the same thing as it does on target declarations: specifies header search directories +- `include_directories` which does the same thing as it does on target + declarations: specifies header search directories diff --git a/docs/markdown/Wrap-best-practices-and-tips.md b/docs/markdown/Wrap-best-practices-and-tips.md index b164ec5..d7bd150 100644 --- a/docs/markdown/Wrap-best-practices-and-tips.md +++ b/docs/markdown/Wrap-best-practices-and-tips.md @@ -1,14 +1,29 @@ # 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. +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. +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 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: +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 @@ -16,7 +31,9 @@ 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: +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 @@ -24,9 +41,15 @@ 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. +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 provide a toggle specifying which type of library it should build. As an example if you have a Meson option called `shared_lib` then you could do this: +Your project should provide a toggle specifying which type of library +it should build. As an example if you have a Meson option called +`shared_lib` then you could do this: ```meson if get_option('shared_lib') @@ -41,9 +64,18 @@ mylib = build_target('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. +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: +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(...) @@ -64,9 +96,18 @@ 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. +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 +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(...) @@ -96,6 +137,30 @@ myexe = executable( ...) ``` -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. +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/docs/markdown/Wrap-dependency-system-manual.md b/docs/markdown/Wrap-dependency-system-manual.md index fc41b61..a850896 100644 --- a/docs/markdown/Wrap-dependency-system-manual.md +++ b/docs/markdown/Wrap-dependency-system-manual.md @@ -1,16 +1,36 @@ # Wrap dependency system manual -One of the major problems of multiplatform development is wrangling all your dependencies. This is easy on Linux where you can use system packages but awkward on other platforms. Most of those do not have a package manager at all. This 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. - -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. +One of the major problems of multiplatform development is wrangling +all your dependencies. This is easy on Linux where you can use system +packages but awkward on other platforms. Most of those do not have a +package manager at all. This 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. + +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). +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. An example wrap file would look like this and should be put in `subprojects/foobar.wrap`: +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. An example wrap file would look like this +and should be put in `subprojects/foobar.wrap`: ```ini [wrap-file] @@ -21,9 +41,16 @@ source_filename = foobar-1.0.tar.gz source_hash = 5ebeea0dfb75d090ea0e7ff84799b2a7a1550db3fe61eb5f6f61c2e971e57663 ``` -If you then use this subproject in your build, Meson will automatically download and extract it during build. This makes subproject embedding extremely easy. +If you then use this subproject in your build, Meson will +automatically download and extract it during build. This makes +subproject embedding extremely easy. -Unfortunately most software projects in the world do not build with Meson. Because of this Meson allows you to specify a patch URL. This works in much the same way as Debian's distro patches. That is, they are downloaded and automatically applied to the subproject. These files contain a Meson build definition for the given subproject. A wrap file with an additional patch URL would look like this. +Unfortunately most software projects in the world do not build with +Meson. Because of this Meson allows you to specify a patch URL. This +works in much the same way as Debian's distro patches. That is, they +are downloaded and automatically applied to the subproject. These +files contain a Meson build definition for the given subproject. A +wrap file with an additional patch URL would look like this. ``` [wrap-file] @@ -38,13 +65,23 @@ patch_filename = libfoobar-meson.tar.gz patch_hash = 8c9d00702d5fe4a6bf25a36b821a332f6b2dfd117c66fe818b88b23d604635e9 ``` -In this example the Wrap manager would download the patch and unzip it in libfoobar's directory. +In this example the Wrap manager would download the patch and unzip it +in libfoobar's directory. -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. +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. ## Branching subprojects directly from git -The above mentioned scheme assumes that your subproject is working off packaged files. Sometimes you want to check code out directly from Git. Meson supports this natively. All you need to do is to write a slightly different wrap file. +The above mentioned scheme assumes that your subproject is working off +packaged files. Sometimes you want to check code out directly from +Git. Meson supports this natively. All you need to do is to write a +slightly different wrap file. ``` [wrap-git] @@ -53,11 +90,20 @@ url=https://github.com/jpakkane/samplesubproject.git revision=head ``` -The format is straightforward. The only thing to note is the revision element that can have one of two values. The first is `head` which will cause Meson to track the master head (doing a repull whenever the build definition is altered). The second type is a commit hash. In this case Meson will use the commit specified (with `git checkout [hash id]`). +The format is straightforward. The only thing to note is the revision +element that can have one of two values. The first is `head` which +will cause Meson to track the master head (doing a repull whenever the +build definition is altered). The second type is a commit hash. In +this case Meson will use the commit specified (with `git checkout +[hash id]`). -Note that in this case you cannot specify an extra patch file to use. The git repo must contain all necessary Meson build definitions. +Note that in this case you cannot specify an extra patch file to +use. The git repo must contain all necessary Meson build definitions. -Usually you would use subprojects as read only. However in some cases you want to do commits to subprojects and push them upstream. For these cases you can specify the upload URL by adding the following at the end of your wrap file: +Usually you would use subprojects as read only. However in some cases +you want to do commits to subprojects and push them upstream. For +these cases you can specify the upload URL by adding the following at +the end of your wrap file: ```ini push-url=git@git.example.com:projects/someproject.git # Supported since version 0.37.0 @@ -71,7 +117,9 @@ To use a subproject simply do this in your top level `meson.build`. foobar_sp = subproject('foobar') ``` -Usually dependencies consist of some header files plus a library to link against. To do this you would declare this internal dependency like this: +Usually dependencies consist of some header files plus a library to +link against. To do this you would declare this internal dependency +like this: ```meson foobar_dep = declare_dependency(link_with : mylib, @@ -85,13 +133,21 @@ executable('toplevel_exe', 'prog.c', dependencies : foobar_sp.get_variable('foobar_dep')) ``` -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. +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 distro packages and embedded source -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. +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. -Doing this with Meson and Wrap is simple. Here's how you would use distro packages and fall back to embedding if the dependency is not available. +Doing this with Meson and Wrap is simple. Here's how you would use +distro packages and fall back to embedding if the dependency is not +available. ```meson foobar_dep = dependency('foobar', required : false) @@ -107,16 +163,27 @@ executable('toplevel_exe', 'prog.c', dependencies : foobar_dep) ``` -Because this is such a common operation, Meson provides a shortcut for this use case. +Because this is such a common operation, Meson provides a shortcut for +this use case. ```meson foobar_dep = dependency('foobar', fallback : ['foobar', 'foobar_dep']) ``` -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. +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. -With this setup when foobar is provided by the system, we use it. When that is not the case we use the embedded version. Note that `foobar_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. +With this setup when foobar is provided by the system, we use it. When +that is not the case we use the embedded version. Note that +`foobar_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. ## Getting wraps -Usually you don't want to write your wraps by hand. There is an online repository called [WrapDB](Using-the-WrapDB.md) that provides many dependencies ready to use. +Usually you don't want to write your wraps by hand. There is an online +repository called [WrapDB](Using-the-WrapDB.md) that provides many +dependencies ready to use. diff --git a/docs/markdown/Wrap-review-guidelines.md b/docs/markdown/Wrap-review-guidelines.md index beda0c2..39acadc 100644 --- a/docs/markdown/Wrap-review-guidelines.md +++ b/docs/markdown/Wrap-review-guidelines.md @@ -1,6 +1,11 @@ # 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. +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. ## Checklist ## diff --git a/docs/markdown/i18n-module.md b/docs/markdown/i18n-module.md index 172f73e..5e6004a 100644 --- a/docs/markdown/i18n-module.md +++ b/docs/markdown/i18n-module.md @@ -4,16 +4,33 @@ 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. +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. +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. -* `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. -* `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 -* `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 -* `args`: list of extra arguments to pass to `xgettext` when generating the pot file +* `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 This function also defines targets for maintainers to use: **Note**: These output to the source directory @@ -24,10 +41,13 @@ This function also defines targets for maintainers to use: ### i18n.merge_file() -This merges translations into a text file using `msgfmt`. See [custom_target](https://github.com/mesonbuild/meson/wiki/Reference%20manual#custom_target) for normal keywords. In addition it accepts these keywords: +This merges translations into a text file using `msgfmt`. See +[custom_target](https://github.com/mesonbuild/meson/wiki/Reference%20manual#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 -* `data_dirs`: (*Added 0.41.0*) list of directories for its files (See also `i18n.gettext()`) * `type`: type of file, valid options are `'xml'` (default) and `'desktop'` *Added 0.37.0* |