improved error messages and began documentation
This commit is contained in:
parent
19be0d2a6a
commit
338cc3c794
6 changed files with 175 additions and 167 deletions
128
Cargo.lock
generated
128
Cargo.lock
generated
|
@ -2,54 +2,12 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "anstream"
|
|
||||||
version = "0.6.13"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
|
|
||||||
dependencies = [
|
|
||||||
"anstyle",
|
|
||||||
"anstyle-parse",
|
|
||||||
"anstyle-query",
|
|
||||||
"anstyle-wincon",
|
|
||||||
"colorchoice",
|
|
||||||
"utf8parse",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstyle"
|
name = "anstyle"
|
||||||
version = "1.0.6"
|
version = "1.0.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
|
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "anstyle-parse"
|
|
||||||
version = "0.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
|
|
||||||
dependencies = [
|
|
||||||
"utf8parse",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "anstyle-query"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
|
|
||||||
dependencies = [
|
|
||||||
"windows-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "anstyle-wincon"
|
|
||||||
version = "3.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
|
|
||||||
dependencies = [
|
|
||||||
"anstyle",
|
|
||||||
"windows-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.1"
|
version = "4.5.1"
|
||||||
|
@ -66,10 +24,8 @@ version = "4.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb"
|
checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
|
||||||
"anstyle",
|
"anstyle",
|
||||||
"clap_lex",
|
"clap_lex",
|
||||||
"strsim",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -90,12 +46,6 @@ version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "colorchoice"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -185,12 +135,6 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "strsim"
|
|
||||||
version = "0.11.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.52"
|
version = "2.0.52"
|
||||||
|
@ -242,78 +186,6 @@ version = "1.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "utf8parse"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.52.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
|
||||||
dependencies = [
|
|
||||||
"windows-targets",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-targets"
|
|
||||||
version = "0.52.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm",
|
|
||||||
"windows_aarch64_msvc",
|
|
||||||
"windows_i686_gnu",
|
|
||||||
"windows_i686_msvc",
|
|
||||||
"windows_x86_64_gnu",
|
|
||||||
"windows_x86_64_gnullvm",
|
|
||||||
"windows_x86_64_msvc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_gnullvm"
|
|
||||||
version = "0.52.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.52.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.52.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.52.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.52.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.52.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.52.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "0.6.5"
|
version = "0.6.5"
|
||||||
|
|
|
@ -6,5 +6,5 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.5.1", features = ["derive"] }
|
clap = { version = "4.5.1", features = ["derive", "std", "help", "usage"], default-features = false }
|
||||||
toml = "0.8.10"
|
toml = "0.8.10"
|
||||||
|
|
148
README.md
148
README.md
|
@ -21,13 +21,14 @@ that any experienced programmer should be familiar with. In doing so, ngen
|
||||||
fills the gap between writing your own makefile and wrangling with
|
fills the gap between writing your own makefile and wrangling with
|
||||||
CMakeLists.txt.
|
CMakeLists.txt.
|
||||||
|
|
||||||
ngen generates files for the [Ninja](https://ninja-build.org/) build system.
|
ngen generates files for the small and modern [Ninja](https://ninja-build.org/)
|
||||||
Ninja is a small, modern build system that uses a bare-bones configuration
|
build system. "Where other build systems are high-level languages Ninja aims to
|
||||||
language that is easy to both read and generate (but not necessarily easy to
|
be an assembler," according to Ninja's website. It can be thought of as a
|
||||||
write by hand). "Where other build systems are high-level languages Ninja aims
|
|
||||||
to be an assembler," according to Ninja's website. It can be thought of as a
|
|
||||||
simpler, faster replacement for the classic `make`. It is used by default by
|
simpler, faster replacement for the classic `make`. It is used by default by
|
||||||
Meson; CMake can also be configured to use ninja as a backend.
|
Meson; CMake can also be configured to use ninja as a backend. Ninja is used by
|
||||||
|
used by Google to build Chromium, v8, etc., and it is also used to build LLVM.
|
||||||
|
(All this to say, Ninja is commonly used and it is likely installed on your
|
||||||
|
system already.)
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
|
@ -36,3 +37,138 @@ Build: `cargo build --release`
|
||||||
Install: `sudo sh install.sh`
|
Install: `sudo sh install.sh`
|
||||||
|
|
||||||
Uninstall: `sudo sh uninstall.sh`
|
Uninstall: `sudo sh uninstall.sh`
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
What follows is a tutorial of how to set up ngen for an existing executable
|
||||||
|
project. If you are looking for a reference, look <SOMEWHERE>.
|
||||||
|
|
||||||
|
The first thing you will need is an `ngen.toml` file. This is what will specify
|
||||||
|
all of the build parameters, such as compilation flags, source files to track,
|
||||||
|
etc. Start by creating this file and opening it in your editor.
|
||||||
|
|
||||||
|
The simplest valid `ngen.toml` just lists the source files you want to track.
|
||||||
|
Lets say you have a executable project that looks like this:
|
||||||
|
|
||||||
|
```txt
|
||||||
|
example
|
||||||
|
├── ngen.toml
|
||||||
|
└── src
|
||||||
|
├── foobar.c
|
||||||
|
├── functions.c
|
||||||
|
├── include
|
||||||
|
│ ├── foobar.h
|
||||||
|
│ ├── functions.h
|
||||||
|
│ ├── main.h
|
||||||
|
│ └── util.h
|
||||||
|
├── main.c
|
||||||
|
└── util.c
|
||||||
|
```
|
||||||
|
|
||||||
|
In your `ngen.toml`, write the following:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
sources = [
|
||||||
|
"src/main.c",
|
||||||
|
"src/util.c",
|
||||||
|
"src/functions.c",
|
||||||
|
"src/foobar.c",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**The `sources` key is a *list* of *strings*, each specifying a single source
|
||||||
|
file name.**
|
||||||
|
|
||||||
|
Now run `ngen`. This will generate a `build.ninja` file in the current
|
||||||
|
working directory. You won't ever have to touch file; thats what ngen is for. You
|
||||||
|
also won't ever have to run `ngen` yourself again (unless your `build.ninja`
|
||||||
|
gets deleted); Ninja will take care of regenerating the build file if
|
||||||
|
`ngen.toml` changes.
|
||||||
|
|
||||||
|
With your `build.ninja` generated, run `ninja` on the command line. Thats it!
|
||||||
|
Your project is now built, you will find it in `build/main/a.out`. Remember, you
|
||||||
|
can also freely add and remove files from this list without running `ngen`
|
||||||
|
again: Ninja will regenerate the `build.ninja` for you.
|
||||||
|
|
||||||
|
Now, while this is functional, it isn't very useful. It is very likely that you
|
||||||
|
will want to specify a compiler (gcc/clang), pass some flags, link some
|
||||||
|
libraries into your final exectuable, and definitly name your program something
|
||||||
|
other than "a.out." ngen makes these things dead simple, too.
|
||||||
|
|
||||||
|
**The `outfile` key is a *string* that specifies the name of the file produced
|
||||||
|
by the `linker` (see below).**
|
||||||
|
|
||||||
|
Lets set this to "example."
|
||||||
|
|
||||||
|
```toml
|
||||||
|
outfile = "example"
|
||||||
|
```
|
||||||
|
|
||||||
|
**The `compiler` key is a *string* that specifies the program that will be used
|
||||||
|
to turn .c files into .o files.**
|
||||||
|
|
||||||
|
By default, if not specified, `compiler` is set to "cc," which on Linux systems
|
||||||
|
should be a C compiler. It should be noted that the compiler you choose must
|
||||||
|
support the `-MD` and `-MF` flags to generate dependency files (both gcc and
|
||||||
|
clang support this). Lets say we want to use "gcc." Add the following line to
|
||||||
|
your `ngen.toml`:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
compiler = "gcc"
|
||||||
|
```
|
||||||
|
|
||||||
|
**The `compiler_flags` key is a *list* of *strings* that contains the arguments
|
||||||
|
to be passed to the `compiler` during the compilation of each `source` file.**
|
||||||
|
|
||||||
|
It is not necessary to add the `-c` or `-o outfile` flags, ngen will take care
|
||||||
|
of this for you. For example, add the following to your `ngen.toml`:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
compiler_flags = ["-Wall", "-Wextra -O2"]
|
||||||
|
```
|
||||||
|
|
||||||
|
**The `linker` key is a *string* that specifies the program that will be used
|
||||||
|
to combine the .o files into the final `outfile`.**
|
||||||
|
|
||||||
|
If the `linker` key is not found, it will be set to the value of `compiler`. For
|
||||||
|
this example, we don't have to change anything here.
|
||||||
|
|
||||||
|
**The `linker_flags` key is a *list* of *strings* that contains the arguments
|
||||||
|
to be passed to the `linker` during the linking of the `outfile`.**
|
||||||
|
|
||||||
|
Library flags (`-lm`, `lyourlib`) should NOT be included here. This is for
|
||||||
|
linker options, not libraries. There is nothing we have to set here; the sytax
|
||||||
|
works the same as `compiler_flags`.
|
||||||
|
|
||||||
|
**The `linker_libs` key is a *list* of *strings* that contains the link library
|
||||||
|
arguments to be linked to the `outfile`.**
|
||||||
|
|
||||||
|
THIS is where library flags (`-lm`, `lyourlib`) go. Lets say our example project
|
||||||
|
needs the math library:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
linker_libs = ["-lm"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, our `ngen.toml` looks like this:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
outfile = "example"
|
||||||
|
compiler = "gcc"
|
||||||
|
compiler_flags = ["-Wall", "-Wextra -O2"]
|
||||||
|
linker_libs = ["-lm"]
|
||||||
|
sources = [
|
||||||
|
"src/main.c",
|
||||||
|
"src/util.c",
|
||||||
|
"src/functions.c",
|
||||||
|
"src/foobar.c",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
This is a much more realistic looking project. Once again, any changes to any of
|
||||||
|
these values will be automatically picked up by Ninja and accounted for in the
|
||||||
|
build. Running `ninja -v` should show that the options you set were recognized,
|
||||||
|
and your files were rebuilt accordingly.
|
||||||
|
|
||||||
|
TODO: explain
|
||||||
|
- seperate targets
|
||||||
|
- config table
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use core::panic;
|
|
||||||
|
|
||||||
use toml::{Table, Value};
|
use toml::{Table, Value};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -24,7 +22,7 @@ impl Config {
|
||||||
if let Value::String(s) = table.get(k).unwrap() {
|
if let Value::String(s) = table.get(k).unwrap() {
|
||||||
self.build_dir = s.to_owned();
|
self.build_dir = s.to_owned();
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a string.");
|
panic!("error parsing config table: {k} invalid type, must be a string.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"compile_commands" => {
|
"compile_commands" => {
|
||||||
|
@ -32,17 +30,17 @@ impl Config {
|
||||||
//eprintln!("warn: config.compile_commands has no functionality (yet)");
|
//eprintln!("warn: config.compile_commands has no functionality (yet)");
|
||||||
self.compile_commands = *b;
|
self.compile_commands = *b;
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a boolean.");
|
panic!("error parsing config table: {k} invalid type, must be a boolean.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"compile_commands_target" => {
|
"compile_commands_target" => {
|
||||||
if let Value::String(s) = table.get(k).unwrap() {
|
if let Value::String(s) = table.get(k).unwrap() {
|
||||||
self.compile_commands_target = s.to_owned();
|
self.compile_commands_target = s.to_owned();
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a string.");
|
panic!("error parsing config table: {k} invalid type, must be a string.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => panic!("fatal: unrecognized key {k}."),
|
_ => panic!("error parsing config table: unrecognized key {k}."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
26
src/main.rs
26
src/main.rs
|
@ -1,7 +1,6 @@
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use core::panic;
|
|
||||||
use std::{
|
use std::{
|
||||||
fs::{read, write},
|
fs::{read_to_string, write},
|
||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
use toml::{Table, Value};
|
use toml::{Table, Value};
|
||||||
|
@ -12,15 +11,18 @@ use target::*;
|
||||||
mod config;
|
mod config;
|
||||||
use config::*;
|
use config::*;
|
||||||
|
|
||||||
|
/// ngen is a build file generator for the ninja build system.
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
struct Args {
|
struct Args {
|
||||||
|
/// Path to the toml configuration file
|
||||||
#[arg(short, long, default_value = "ngen.toml")]
|
#[arg(short, long, default_value = "ngen.toml")]
|
||||||
config_file: String,
|
config_file: String,
|
||||||
|
|
||||||
|
/// Path to generated ninja file
|
||||||
#[arg(short, long, default_value = "build.ninja")]
|
#[arg(short, long, default_value = "build.ninja")]
|
||||||
output_file: String,
|
output_file: String,
|
||||||
|
|
||||||
#[arg(long)]
|
#[arg(long, hide = true)]
|
||||||
write_compile_commands: Option<String>,
|
write_compile_commands: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +92,7 @@ fn gen_compile_commands(target: &Target, build_dir: &str) -> String {
|
||||||
let pwd = Path::new(".");
|
let pwd = Path::new(".");
|
||||||
let pwd = pwd
|
let pwd = pwd
|
||||||
.canonicalize()
|
.canonicalize()
|
||||||
.expect("cwd is non canonical (something is very wrong)");
|
.unwrap_or_else(|e| panic!("cwd is non canonical (something is very wrong): {e}"));
|
||||||
let pwd = pwd.to_str().unwrap();
|
let pwd = pwd.to_str().unwrap();
|
||||||
|
|
||||||
for (i, s) in target.sources.iter().enumerate() {
|
for (i, s) in target.sources.iter().enumerate() {
|
||||||
|
@ -120,11 +122,10 @@ fn main() {
|
||||||
let output_file = &args.output_file;
|
let output_file = &args.output_file;
|
||||||
let config_file_name = &args.config_file;
|
let config_file_name = &args.config_file;
|
||||||
|
|
||||||
let config_file_raw =
|
let config_file = read_to_string(config_file_name)
|
||||||
read(config_file_name).unwrap_or_else(|e| panic!("fatal: could not read file: {e}"));
|
.unwrap_or_else(|e| panic!("could not read config file {config_file_name}: {e}"));
|
||||||
let config_file_string = String::from_utf8_lossy(&config_file_raw);
|
let parsed_config = toml::from_str::<Table>(&config_file)
|
||||||
let parsed_config = toml::from_str::<Table>(&config_file_string)
|
.unwrap_or_else(|e| panic!("error parsing toml file {config_file_name}: {e}"));
|
||||||
.unwrap_or_else(|e| panic!("fatal: could not parse config file: {e}"));
|
|
||||||
|
|
||||||
// get config
|
// get config
|
||||||
let mut config = Config::get_default();
|
let mut config = Config::get_default();
|
||||||
|
@ -174,10 +175,10 @@ fn main() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
write(
|
write(
|
||||||
file,
|
&file,
|
||||||
&gen_compile_commands(&target_for_comp_cmds, &config.build_dir),
|
&gen_compile_commands(&target_for_comp_cmds, &config.build_dir),
|
||||||
)
|
)
|
||||||
.expect("fatal: could not write {file}");
|
.unwrap_or_else(|e| panic!("fatal: could not write {file}: {e}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let build_dir = &config.build_dir;
|
let build_dir = &config.build_dir;
|
||||||
|
@ -225,5 +226,6 @@ build {output_file}: regen_ninjafile {config_file_name} || $builddir/compile_com
|
||||||
ninjafile.push_str(&gen_ninja_code(&t));
|
ninjafile.push_str(&gen_ninja_code(&t));
|
||||||
}
|
}
|
||||||
|
|
||||||
write(output_file, ninjafile).expect("fatal: could not write ninja file");
|
write(output_file, &ninjafile)
|
||||||
|
.unwrap_or_else(|e| panic!("could not write ninja file {ninjafile}: {e}"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,14 +46,14 @@ impl Target {
|
||||||
if let Value::String(s) = table.get(k).unwrap() {
|
if let Value::String(s) = table.get(k).unwrap() {
|
||||||
ret.outfile = s.to_owned();
|
ret.outfile = s.to_owned();
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a string.");
|
panic!("error parsing target {name}: {k} invalid type, must be a string.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"compiler" => {
|
"compiler" => {
|
||||||
if let Value::String(s) = table.get(k).unwrap() {
|
if let Value::String(s) = table.get(k).unwrap() {
|
||||||
ret.compiler = s.to_owned();
|
ret.compiler = s.to_owned();
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a string.");
|
panic!("error parsing target {name}: {k} invalid type, must be a string.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"compiler_flags" => {
|
"compiler_flags" => {
|
||||||
|
@ -62,11 +62,11 @@ impl Target {
|
||||||
if let Value::String(s) = element {
|
if let Value::String(s) = element {
|
||||||
ret.compiler_flags.push(s.to_owned());
|
ret.compiler_flags.push(s.to_owned());
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a array of strings.");
|
panic!("error parsing target {name}: {k} invalid type, must be a array of strings.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a array of strings.");
|
panic!("error parsing target {name}: {k} invalid type, must be a array of strings.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"linker" => {
|
"linker" => {
|
||||||
|
@ -74,7 +74,7 @@ impl Target {
|
||||||
ret.linker = s.to_owned();
|
ret.linker = s.to_owned();
|
||||||
linker_set = true;
|
linker_set = true;
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a string.");
|
panic!("error parsing target {name}: {k} invalid type, must be a string.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"linker_flags" => {
|
"linker_flags" => {
|
||||||
|
@ -83,11 +83,11 @@ impl Target {
|
||||||
if let Value::String(s) = element {
|
if let Value::String(s) = element {
|
||||||
ret.linker_flags.push(s.to_owned());
|
ret.linker_flags.push(s.to_owned());
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a array of strings.");
|
panic!("error parsing target {name}: {k} invalid type, must be a array of strings.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a array of strings.");
|
panic!("error parsing target {name}: {k} invalid type, must be a array of strings.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"linker_libs" => {
|
"linker_libs" => {
|
||||||
|
@ -96,11 +96,11 @@ impl Target {
|
||||||
if let Value::String(s) = element {
|
if let Value::String(s) = element {
|
||||||
ret.linker_libs.push(s.to_owned());
|
ret.linker_libs.push(s.to_owned());
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a array of strings.");
|
panic!("error parsing target {name}: {k} invalid type, must be a array of strings.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a array of strings.");
|
panic!("error parsing target {name}: {k} invalid type, must be a array of strings.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"sources" => {
|
"sources" => {
|
||||||
|
@ -109,24 +109,24 @@ impl Target {
|
||||||
if let Value::String(s) = element {
|
if let Value::String(s) = element {
|
||||||
ret.sources.push(s.to_owned());
|
ret.sources.push(s.to_owned());
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a array of strings.");
|
panic!("error parsing target {name}: {k} invalid type, must be a array of strings.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a array of strings.");
|
panic!("error parsing target {name}: {k} invalid type, must be a array of strings.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"default" => {
|
"default" => {
|
||||||
if let Value::Boolean(b) = table.get(k).unwrap() {
|
if let Value::Boolean(b) = table.get(k).unwrap() {
|
||||||
ret.is_default = *b;
|
ret.is_default = *b;
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: {k} invalid type, must be a boolean.");
|
panic!("error parsing target {name}: {k} invalid type, must be a boolean.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if let Value::Table(_) = table.get(k).unwrap() {
|
if let Value::Table(_) = table.get(k).unwrap() {
|
||||||
} else {
|
} else {
|
||||||
panic!("fatal: unrecognized key {k}.");
|
panic!("error parsing target {name}: unrecognized key {k}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ impl Target {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ret.sources == Vec::<String>::new() {
|
if ret.sources == Vec::<String>::new() {
|
||||||
panic!("fatal: you MUST specify at least one source");
|
panic!("error parsing target {name}: you MUST specify at least one source");
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
Loading…
Reference in a new issue