| --- | 
 | short-description: Generation of source files before compilation | 
 | ... | 
 |  | 
 | # Generating sources | 
 |  | 
 | Sometimes source files need to be preprocessed before they are passed | 
 | to the actual compiler. As an example you might want build an IDL | 
 | compiler and then run some files through that to generate actual | 
 | source files. In Meson this is done with | 
 | [[generator]] or | 
 | [[custom_target]]. | 
 |  | 
 | ## Using custom_target() | 
 |  | 
 | Let's say you have a build target that must be built using sources | 
 | generated by a compiler. The compiler can either be a built target: | 
 |  | 
 | ```meson | 
 | mycomp = executable('mycompiler', 'compiler.c') | 
 | ``` | 
 |  | 
 | Or an external program provided by the system, or script inside the | 
 | source tree: | 
 |  | 
 | ```meson | 
 | mycomp = find_program('mycompiler') | 
 | ``` | 
 |  | 
 | Custom targets can take zero or more input files and use them to | 
 | generate one or more output files. Using a custom target, you can run | 
 | this compiler at build time to generate the sources: | 
 |  | 
 | ```meson | 
 | gen_src = custom_target('gen-output', | 
 |                         input : ['somefile1.c', 'file2.c'], | 
 |                         output : ['out.c', 'out.h'], | 
 |                         command : [mycomp, '@INPUT@', | 
 |                                    '--c-out', '@OUTPUT0@', | 
 |                                    '--h-out', '@OUTPUT1@']) | 
 | ``` | 
 |  | 
 | The `@INPUT@` there will be transformed to `'somefile1.c' | 
 | 'file2.c'`. Just like the output, you can also refer to each input | 
 | file individually by index. | 
 |  | 
 | Then you just put that in your program and you're done. | 
 |  | 
 | ### Generating headers | 
 |  | 
 | Adding a generated header to a source list will ensure that the header | 
 | is generated and that the proper include paths are created for the | 
 | target: | 
 |  | 
 | ```meson | 
 | prog_python = [[#find_program]]('python3') | 
 |  | 
 | foo_c = custom_target( | 
 |     'foo.c', | 
 |     output : 'foo.c', | 
 |     input : 'my_gen.py', | 
 |     command : [prog_python, '@INPUT@', '--code', '@OUTPUT@'], | 
 | ) | 
 |  | 
 | foo_h = custom_target( | 
 |     'foo.h', | 
 |     output : 'foo.h', | 
 |     input : 'my_gen.py', | 
 |     command : [prog_python, '@INPUT@', '--header', '@OUTPUT@'], | 
 | ) | 
 |  | 
 | libfoo = static_library('foo', [foo_c, foo_h]) | 
 |  | 
 | executable('myexe', ['main.c', foo_h], link_with : libfoo) | 
 | ``` | 
 |  | 
 | Each target that depends on a generated header should add that header | 
 | to its sources, as seen above with `libfoo` and `myexe`. This is | 
 | because there is no way for Meson or the backend to know that `myexe` | 
 | depends on `foo.h` just because `libfoo` does, it could be a private | 
 | header. | 
 |  | 
 | ### Generating multiple files at a time | 
 |  | 
 | Sometimes it makes sense for a single generator to create two or more | 
 | files at a time, (perhaps a header and source file), Meson has this | 
 | case covered as well. `custom_target`s can be indexed like a list to | 
 | get each output file separately. The order is the same as the order of | 
 | the output argument to `custom_target` | 
 |  | 
 | ```meson | 
 | prog_python = [[#find_program]]('python3') | 
 |  | 
 | foo_ch = custom_target( | 
 |     'foo.[ch]', | 
 |     output : ['foo.c', 'foo.h'], | 
 |     input : 'my_gen.py', | 
 |     command : [prog_python, '@INPUT@', '@OUTPUT@'], | 
 | ) | 
 |  | 
 | libfoo = static_library('foo', [foo_ch]) | 
 |  | 
 | executable('myexe', ['main.c', foo_ch[1]], link_with : libfoo) | 
 | ``` | 
 |  | 
 | In this case `libfoo` depends on both `foo.c` and `foo.h` but `myexe` | 
 | only depends on `foo.h`, the second output. | 
 |  | 
 | ### Using dependencies to manage generated resources | 
 |  | 
 | In some cases it might be easier to use `declare_dependency` to | 
 | "bundle" the header and library dependency, especially if there are | 
 | many generated headers: | 
 |  | 
 | ```meson | 
 | idep_foo = declare_dependency( | 
 |     sources : [foo_h, bar_h], | 
 |     link_with : [libfoo], | 
 | ) | 
 | ``` | 
 |  | 
 | See [dependencies](Dependencies.md#declaring-your-own), and | 
 | [[declare_dependency]] for more | 
 | information. | 
 |  | 
 | ## Using generator() | 
 |  | 
 | Generators are similar to custom targets, except that we define a | 
 | *generator*, which defines how to transform an input file into one or | 
 | more output files, and then use that on as many input files as we | 
 | want. | 
 |  | 
 | Note that generators should only be used for outputs that will only be | 
 | used as inputs for a build target or a custom target. When you use the | 
 | processed output of a generator in multiple targets, the generator | 
 | will be run multiple times to create outputs for each target. Each | 
 | output will be created in a target-private directory `@BUILD_DIR@`. | 
 |  | 
 | If you want to generate files for general purposes such as for | 
 | generating headers to be used by several sources, or data that will be | 
 | installed, and so on, use a | 
 | [[custom_target]] instead. | 
 |  | 
 |  | 
 | ```meson | 
 | gen = generator(mycomp, | 
 |                 output  : '@BASENAME@.c', | 
 |                 arguments : ['@INPUT@', '@OUTPUT@']) | 
 | ``` | 
 |  | 
 | The first argument is the executable file to run. The next file | 
 | specifies a name generation rule. It specifies how to build the output | 
 | file name for a given input name. `@BASENAME@` is a placeholder for | 
 | the input file name without preceding path or suffix (if any). So if | 
 | the input file name were `some/path/filename.idl`, then the output | 
 | name would be `filename.c`. You can also use `@PLAINNAME@`, which | 
 | preserves the suffix which would result in a file called | 
 | `filename.idl.c`. The last line specifies the command line arguments | 
 | to pass to the executable. `@INPUT@` and `@OUTPUT@` are placeholders | 
 | for the input and output files, respectively, and will be | 
 | automatically filled in by Meson. If your rule produces multiple | 
 | output files and you need to pass them to the command line, append the | 
 | location to the output holder like this: `@OUTPUT0@`, `@OUTPUT1@` and | 
 | so on. | 
 |  | 
 | With this rule specified we can generate source files and add them to | 
 | a target. | 
 |  | 
 | ```meson | 
 | gen_src = gen.process('input1.idl', 'input2.idl') | 
 | executable('program', 'main.c', gen_src) | 
 | ``` | 
 |  | 
 | Generators can also generate multiple output files with unknown names: | 
 |  | 
 | ```meson | 
 | gen2 = generator(someprog, | 
 |                  output : ['@BASENAME@.c', '@BASENAME@.h'], | 
 |                  arguments : ['--out_dir=@BUILD_DIR@', '@INPUT@']) | 
 | ``` | 
 |  | 
 | In this case you cannot use the plain `@OUTPUT@` variable, as it | 
 | would be ambiguous. This program only needs to know the output | 
 | directory, it will generate the file names by itself. | 
 |  | 
 | To make passing different additional arguments to the generator | 
 | program at each use possible, you can use the `@EXTRA_ARGS@` string in | 
 | the `arguments` list. Note that this placeholder can only be present | 
 | as a whole string, and not as a substring. The main reason is that it | 
 | represents a list of strings, which may be empty, or contain multiple | 
 | elements; and in either case, interpolating it into the middle of a | 
 | single string would be troublesome. If there are no extra arguments | 
 | passed in from a `process()` invocation, the placeholder is entirely | 
 | omitted from the actual list of arguments, so an empty string won't be | 
 | passed to the generator program because of this. If there are multiple | 
 | elements in `extra_args`, they are inserted into to the actual | 
 | argument list as separate elements. | 
 |  | 
 | ```meson | 
 | gen3 = generator(genprog, | 
 |                  output : '@BASENAME@.cc', | 
 |                  arguments : ['@INPUT@', '@EXTRA_ARGS@', '@OUTPUT@']) | 
 | gen3_src1 = gen3.process('input1.y') | 
 | gen3_src2 = gen3.process('input2.y', extra_args: '--foo') | 
 | gen3_src3 = gen3.process('input3.y', extra_args: ['--foo', '--bar']) | 
 | ``` |