update readme

This commit is contained in:
Noah Swerhun 2024-03-15 09:41:30 -05:00
parent 3363b23335
commit 1d14522182

View file

@ -68,6 +68,7 @@ example
In your `ngen.toml`, write the following: In your `ngen.toml`, write the following:
```toml ```toml
[targets.main]
sources = [ sources = [
"src/main.c", "src/main.c",
"src/util.c", "src/util.c",
@ -153,6 +154,7 @@ linker_libs = ["-lm"]
Now, our `ngen.toml` looks like this: Now, our `ngen.toml` looks like this:
```toml ```toml
[targets.main]
outfile = "example" outfile = "example"
compiler = "gcc" compiler = "gcc"
compiler_flags = ["-Wall", "-Wextra -O2"] compiler_flags = ["-Wall", "-Wextra -O2"]
@ -179,25 +181,22 @@ configuration as easy as possible.
### Targets ### Targets
When we were specifying parameters above, we were doing so in the "global When we were specifying parameters above, we were doing so in the main target
scope," so to speak, of the TOML file. Without knowing it, we were actually `[targets.main]`. A "target" is a self-contained build process that builds its
configuring the `main` target (this is why the outfiles were placed in `outfile` from the `sources` and other paramenters provided. We could have named
`build/*main/*`. The main target is special because it does not need to be this target whatever we wanted, but the target named `main` is special, as we shall
labeled: all build parameters placed in the global scope (or, more accurately, presently see. Lets create a new target called `debug`. Add the following to your `ngen.toml`:
the TOML "root table"), will be used for the `main` target. To specify
additional targets, we create a TOML table with the name of our target. Let's
create a target called `debug`. Add the following to your `ngen.toml`:
```toml ```toml
[debug] [targets.debug]
outfile = "example_dbg" outfile = "example_dbg"
compiler_flags = ["-g"] compiler_flags = ["-g"]
``` ```
What's going on here? How does `debug` know what files to operate on, what What's going on here? How does `debug` know what files to operate on, what
compiler to use, etc? Well, the `main` target is special in another way: all compiler to use, etc? Well, the `main` target is special: all targets *inherit*
targets *inherit* the parameters set in the main target. Inheritance works the parameters set in the main target. Inheritance works according to two simple
according to two simple rules: **a**rrays **a**ppend, **s**trings **s**upercede. rules: **a**rrays **a**ppend, **s**trings **s**upercede.
The first thing that happens is `debug` takes on all the same parameters from The first thing that happens is `debug` takes on all the same parameters from
main. Then, ngen reads the outfile key in `debug`. Becuase outfile is a string, main. Then, ngen reads the outfile key in `debug`. Becuase outfile is a string,
@ -213,6 +212,7 @@ from `main` and place it in a new target called `release`. Our `ngen.toml`
should now look like this: should now look like this:
```toml ```toml
[targets.main]
outfile = "example" outfile = "example"
compiler = "gcc" compiler = "gcc"
compiler_flags = ["-Wall", "-Wextra"] compiler_flags = ["-Wall", "-Wextra"]
@ -224,11 +224,11 @@ sources = [
"src/foobar.c", "src/foobar.c",
] ]
[debug] [targets.debug]
outfile = "example_dbg" outfile = "example_dbg"
compiler_flags = ["-g"] compiler_flags = ["-g"]
[release] [targets.release]
compiler_flags = ["-O2"] compiler_flags = ["-O2"]
``` ```
@ -239,6 +239,10 @@ parameters for specific use cases, as we saw in the above example.
In a nutshell, inheritance allows you to easily create multiple targets with In a nutshell, inheritance allows you to easily create multiple targets with
small variations, without having to rewrite the same thing over and over again. small variations, without having to rewrite the same thing over and over again.
You can always disable inheritance using the `opts.inherit = false` key on
targets that you do not want to inherit from `main`. You can also change the
parent target that a target inherits from using the `opts.inherit_from =
"target"` key, replacing `target` with the name of the desired parent target.
Save `ngen.toml`, and try running `ninja -v debug` or `ninja -v release`. You Save `ngen.toml`, and try running `ninja -v debug` or `ninja -v release`. You
should see that each of these targets uses the parameters that we specified with should see that each of these targets uses the parameters that we specified with
@ -250,9 +254,9 @@ inheritance system).
Note that by default, running `ninja` alone with no target specifed will run Note that by default, running `ninja` alone with no target specifed will run
*every single target* it finds. You can change this behavor by adding the *every single target* it finds. You can change this behavor by adding the
`default = true` key to the targets you want to be built when Ninja is invoked `opts.default = true` key to the targets you want to be built when Ninja is invoked
with no arguments. Say that this example project is under active developemnt, with no arguments. Say that this example project is under active developemnt,
and you will be building the `debug` target alot. You can add the `default = and you will be building the `debug` target alot. You can add the `opts.default =
true` flag to the `[debug]` table, and now running `ninja` by itself will only true` flag to the `[debug]` table, and now running `ninja` by itself will only
build the `debug` target. You can still build the release and main targets by build the `debug` target. You can still build the release and main targets by
running `ninja release` and `ninja main`. running `ninja release` and `ninja main`.
@ -263,15 +267,15 @@ However, ngen has a few more features that you may find useful.
### Configuration ### Configuration
The `config` table is where you can specify certain options which change the way The `config` table is where you can specify certain options which change the way
ngen behaves. Right now, this only involves a single feature: generating a ngen behaves. One useful feature is generating a compile\_commands.json file for
compile\_commands.json file for the `clangd` LSP. the `clangd` LSP.
To enable the generation of compile\_commands.json, simply add the following To enable the generation of compile\_commands.json, simply add the following
line to the **top** of your `ngen.toml` **(all `config` keys MUST be at the TOP line to your `ngen.toml`:
of the file)**:
```toml ```toml
config.compile_commands = true [config]
compile_commands = true
``` ```
The next time you run Ninja, ngen will automatically generate The next time you run Ninja, ngen will automatically generate
@ -284,16 +288,20 @@ specs of the `main` target. To change which target it is generated for, use the
`config.compile_commands_target` key. For example, `config.compile_commands_target` key. For example,
```toml ```toml
config.compile_commands_target = "debug" [config]
compile_commands = true
compile_commands_target = "debug"
``` ```
will generate the the compile\_commands for the `debug` target. will generate the the compile\_commands for the `debug` target.
Our final `ngen.toml` looks like this: Our final `ngen.toml` looks like this:
```toml ```toml
config.compile_commands = true [config]
config.compile_commands_target = "debug" compile_commands = true
compile_commands_target = "debug"
[targets.main]
outfile = "example" outfile = "example"
compiler = "gcc" compiler = "gcc"
compiler_flags = ["-Wall", "-Wextra"] compiler_flags = ["-Wall", "-Wextra"]
@ -305,12 +313,12 @@ sources = [
"src/foobar.c", "src/foobar.c",
] ]
[debug] [targets.debug]
opts.default = true
outfile = "example_dbg" outfile = "example_dbg"
compiler_flags = ["-g"] compiler_flags = ["-g"]
default = true
[release] [targets.release]
compiler_flags = ["-O2"] compiler_flags = ["-O2"]
``` ```