Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C backend #25

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ result
# These are backup files generated by rustfmt
**/*.rs.bk
.direnv

.vscode/
build/
**/src-gen/
tmp/
65 changes: 34 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,39 @@
# Lingo

# Lingo - A build tool for Lingua Franca program
**Contact:** <tassilo-tanneberger@tu-dresden.de>

Lingo is a build tool for lingua-franca project it will manage dependencies
configure build scripts and potentially cross compile for microcontrollers.
Lingo is a one-stop build tool for the Lingua Franca project.
Lingo will manages dependencies, configure build scripts and will potentially cross-compile for embedded platforms.


## Getting started
Lingo is a Rust project and is built with cargo. To install it simply run
`cargo install --path .`

## The command line interfac

```
lingua-franca package manager and build tool 0.1.2
tassilo.tanneberger@tu-dresden.de
Build system of lingua-franca projects

USAGE:
lingo [OPTIONS] <SUBCOMMAND>

OPTIONS:
-b, --backend <BACKEND> force lingo to use the specified backend [default: cli]
-h, --help Print help information
-V, --version Print version information

SUBCOMMANDS:
build compiling one ore multiple binaries in a lingua-franca package
clean removes build artifacts
help Print this message or the help of the given subcommand(s)
init initializing a lingua-franca project
run builds and runs binaries
update Updates the dependencies and potentially build tools
```

## The toml-based package configurations
The Lingo.toml may look something like this.

```toml
Expand Down Expand Up @@ -41,37 +70,11 @@ logging = true
[[app]]
name = "embedded"
# main_reactor = "src/SayHello.lf"
target = "zephyre"
target = "zephyr"

[[app.dependencies]]
blink = {version = "0.1.2"}

[[app.properties]]
no-compile = true
```

### command line interface

**Installing** is done on the most systems with `cargo install`.

```
lingua-franca package manager and build tool 0.1.1
tassilo.tanneberger@tu-dresden.de
Build system of lingua-franca projects

USAGE:
lingo [OPTIONS] <SUBCOMMAND>

OPTIONS:
-b, --backend <BACKEND> force lingo to use the specified backend [default: cli]
-h, --help Print help information
-V, --version Print version information

SUBCOMMANDS:
build compiling one ore multiple binaries in a lingua-franca package
clean removes build artifacts
help Print this message or the help of the given subcommand(s)
init initializing a lingua-franca project
run builds and runs binaries
update Updates the dependencies and potentially build tools
```
21 changes: 10 additions & 11 deletions src/backends/cmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ impl Backend for Cmake {
}

fn build(&self, config: &BuildArgs) -> bool {
let create_dir =
fs::create_dir_all(format!("{}/build", self.lfc.out.display().to_string())).is_ok();
let create_dir = fs::create_dir_all(format!("{}/build", self.lfc.out.display())).is_ok();

// cmake generation
let mut cmake_command = Command::new("cmake");
Expand All @@ -32,29 +31,29 @@ impl Backend for Cmake {
if config.release { "RELEASE" } else { "DEBUG" }
));
cmake_command.arg(format!("-DCMAKE_INSTALL_PREFIX={}", self.lfc.out.display()));
cmake_command.arg(format!("-DCMAKE_INSTALL_BINDIR=bin"));
cmake_command.arg(format!("-DREACTOR_CPP_VALIDATE=ON"));
cmake_command.arg(format!("-DREACTOR_CPP_TRACE=OFF"));
cmake_command.arg(format!("-DREACTOR_CPP_LOG_LEVEL=3"));
cmake_command.arg("-DCMAKE_INSTALL_BINDIR=bin");
cmake_command.arg("-DREACTOR_CPP_VALIDATE=ON");
cmake_command.arg("-DREACTOR_CPP_TRACE=OFF");
cmake_command.arg("-DREACTOR_CPP_LOG_LEVEL=3");
cmake_command.arg(format!(
"-DLF_SRC_PKG_PATH={}",
self.app.root_path.display()
));
cmake_command.arg(format!("{}/src-gen", self.lfc.out.display().to_string()));
cmake_command.arg(format!("-B {}/build", self.lfc.out.display().to_string()));
cmake_command.current_dir(format!("{}/build", self.lfc.out.display().to_string()));
cmake_command.arg(format!("{}/src-gen", self.lfc.out.display()));
cmake_command.arg(format!("-B {}/build", self.lfc.out.display()));
cmake_command.current_dir(format!("{}/build", self.lfc.out.display()));
let cmake_gen = run_and_capture(&mut cmake_command).is_ok();

// compiling
let mut cmake_build_command = Command::new("cmake");
cmake_build_command.current_dir(format!("{}/build", self.lfc.out.display().to_string()));
cmake_build_command.current_dir(format!("{}/build", self.lfc.out.display()));
cmake_build_command.arg("--build");
cmake_build_command.arg("./");
let cmake_build = run_and_capture(&mut cmake_build_command).is_ok();

// installing
let mut cmake_install_command = Command::new("cmake");
cmake_install_command.current_dir(format!("{}/build", self.lfc.out.display().to_string()));
cmake_install_command.current_dir(format!("{}/build", self.lfc.out.display()));
cmake_install_command.arg("--install");
cmake_install_command.arg("./");
let cmake_install = run_and_capture(&mut cmake_install_command).is_ok();
Expand Down
11 changes: 7 additions & 4 deletions src/backends/lfc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ impl Backend for LFC {
let reactor_copy = self.target.main_reactor.clone();

let build_lambda = |main_reactor: &String| -> bool {
println!("building main reactor: {}", &main_reactor);
println!("--- Building main reactor: {}", &main_reactor);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we actually maybe need to think about using some proper logging library where we also then can configure verbosity.

// FIXME: What is this supposed to do? `lfc` does not have n `--output` argument
// also. Why isnt the lfc from the CLI `-l` used.
let mut command = Command::new("lfc");
command.arg("--output");
command.arg("--output-path");
command.arg("./");
command.arg(format!(
"{}/{}",
Expand All @@ -38,7 +38,7 @@ impl Backend for LFC {
};

if !build_lambda(&reactor_copy) {
println!("calling lfc returned an error can lfc be found in $PATH ?");
println!("--- LFC returned an error can lfc be found in $PATH ?");
return false;
}

Expand All @@ -50,7 +50,10 @@ impl Backend for LFC {
}

fn clean(&self) -> bool {
println!("removing build artifacts in {:?}", env::current_dir());
println!(
"--- Lingo removing build artifacts in {:?}",
env::current_dir()
);
// just removes all the lingua-franca build artifacts
fs::remove_dir_all("./bin").is_ok()
&& fs::remove_dir_all("./include").is_ok()
Expand Down
4 changes: 2 additions & 2 deletions src/lfc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl CodeGenerator {
lfc: Option<PathBuf>,
properties: HashMap<String, serde_json::Value>,
) -> CodeGenerator {
let lfc_path = lfc.unwrap_or(which("rustc").expect("cannot find lingua franca."));
let lfc_path = lfc.unwrap_or(which("lfc").expect("Cannot find lingua franca."));

CodeGenerator {
lfc: lfc_path,
Expand All @@ -90,7 +90,7 @@ impl CodeGenerator {
}

println!(
"Invoking code-generator: `{} --json={}`",
"--- Lingo invoking LFC code-generator: `{} --json={}`",
&self.lfc.display(),
self.properties
);
Expand Down
60 changes: 35 additions & 25 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub mod lfc;
pub mod package;
pub mod util;

use args::{BuildArgs, Command as ConsoleCommand, CommandLineArgs};
use args::{BuildArgs, Command as ConsoleCommand, CommandLineArgs, Platform};
use package::App;

use clap::Parser;
Expand All @@ -14,34 +14,44 @@ use std::process::Command;

fn build(args: &BuildArgs, config: &package::Config) {
let build_target = |app: &App| -> bool {
// path to the main reactor
let mut main_reactor_path = app.root_path.clone();
main_reactor_path.push(app.main_reactor.clone());
println!("--- Building app `{0}`", app.name);

let code_generator = lfc::CodeGenerator::new(
PathBuf::from(format!("{}/{}", app.root_path.display(), app.main_reactor)),
PathBuf::from(format!("{}/", app.root_path.display())),
args.lfc.clone().map(PathBuf::from),
app.properties.clone(),
);
match app.platform {
Platform::Zephyr => {
println!("--- Skipping app `{0}` which is Zephyr-based. Use `west lf-build` to build instead", app.name);
true
}
_ => {
// path to the main reactor
let mut main_reactor_path = app.root_path.clone();
main_reactor_path.push(app.main_reactor.clone());

if let Err(e) = code_generator.clone().generate_code(app) {
//TODO: optimize
eprintln!("cannot generate code {:?}", e);
return false;
}
let code_generator = lfc::CodeGenerator::new(
PathBuf::from(format!("{}/{}", app.root_path.display(), app.main_reactor)),
PathBuf::from(format!("{}/", app.root_path.display())),
args.lfc.clone().map(PathBuf::from),
app.properties.clone(),
);

if let Err(e) = code_generator.clone().generate_code(app) {
//TODO: optimize
eprintln!("--- Cannot generate code {:?}", e);
return false;
}

let backend = backends::select_backend(
&args.build_system.clone().unwrap_or(args::BuildSystem::LFC),
app,
&code_generator.properties,
);
let backend = backends::select_backend(
&args.build_system.clone().unwrap_or(args::BuildSystem::LFC),
app,
&code_generator.properties,
);

if !backend.build(args) {
println!("error has occured!");
return false;
if !backend.build(args) {
println!("--- An error has occured!");
return false;
}
true
}
}
true
};
util::invoke_on_selected(&args.apps, config.apps.clone(), build_target);
}
Expand Down Expand Up @@ -74,7 +84,6 @@ fn main() {
let mut working_path = lingo_path.unwrap();
working_path.pop();
let config = file_config.to_config(working_path);
println!("building ...");
build(&build_command_args, &config)
}
(Some(file_config), ConsoleCommand::Run(build_command_args)) => {
Expand All @@ -85,6 +94,7 @@ fn main() {
build(&build_command_args, &config);
let execute_binary = |app: &App| -> bool {
let mut command = Command::new(format!("./bin/{}", app.name));
// FIXME: When we execute the program we want to forward all outputs to stdout, stderr
util::command_line::run_and_capture(&mut command).is_ok()
};

Expand Down
2 changes: 1 addition & 1 deletion src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ where
sources.retain(|input: &App| apps.contains(&input.name));
}

// evaluate f on everyelement inside sources and then compute the logical conjuction
// evaluate f on every element inside sources and then compute the logical conjuction
sources
.iter()
.map(f)
Expand Down