Add ability to make compile_commands.json (#13)
issue: #8 Reviewed-on: http://192.168.1.227:3000/sfrembling/pallet/pulls/13 Co-authored-by: godsfryingpan <sfrembling@gmail.com> Co-committed-by: godsfryingpan <sfrembling@gmail.com>
This commit was merged in pull request #13.
This commit is contained in:
64
src/app.rs
64
src/app.rs
@@ -9,7 +9,7 @@ use colored::Colorize;
|
||||
use glob::glob;
|
||||
|
||||
const MAIN_C: &str = include_str!("templates/main.c");
|
||||
const GITIGNORE: &str = "target/";
|
||||
const GITIGNORE: &str = "target/\ncompile_commands.json\n";
|
||||
|
||||
#[derive(clap::Parser)]
|
||||
#[clap(version, about)]
|
||||
@@ -65,6 +65,11 @@ enum UtilSubcommand {
|
||||
#[arg(value_enum, long, short)]
|
||||
shell: ShellCompletions,
|
||||
},
|
||||
/// Generate compile_commands.json for IDE support
|
||||
GenCompileCommands {
|
||||
/// The build mode to generate for
|
||||
mode: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, clap::ValueEnum)]
|
||||
@@ -150,6 +155,12 @@ impl App {
|
||||
),
|
||||
}
|
||||
}
|
||||
UtilSubcommand::GenCompileCommands { mode } => {
|
||||
if let Err(e) = gen_compile_commands(&mode) {
|
||||
eprintln!("Error generating compile commands: {e}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
},
|
||||
Subcommand::List => {
|
||||
if let Err(e) = list() {
|
||||
@@ -161,6 +172,55 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_compile_commands(mode: &Option<String>) -> std::io::Result<()> {
|
||||
let conf = get_config().ok_or(std::io::Error::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
"no Pallet.toml found in current directory",
|
||||
))?;
|
||||
|
||||
let build_config = conf.get_or_default(mode).ok_or(std::io::Error::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
"build layout not found",
|
||||
))?;
|
||||
|
||||
let compiler = conf.compiler.as_deref().unwrap_or("gcc");
|
||||
let cwd = std::env::current_dir()?;
|
||||
let obj_dir = format!("target/{}/obj", build_config.name);
|
||||
|
||||
let source_files: Vec<PathBuf> = glob("src/*.c")
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::NotFound, format!("{e}")))?
|
||||
.filter_map(|e| e.ok())
|
||||
.collect();
|
||||
|
||||
let entries: Vec<serde_json::Value> = source_files
|
||||
.iter()
|
||||
.map(|src| {
|
||||
let stem = src.file_stem().unwrap().to_string_lossy();
|
||||
let obj = format!("{}/{}.o", obj_dir, stem);
|
||||
let command = std::iter::once(compiler.to_string())
|
||||
.chain(build_config.args.iter().cloned())
|
||||
.chain(["-c".to_string(), src.to_string_lossy().to_string()])
|
||||
.chain(["-o".to_string(), obj])
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
serde_json::json!({
|
||||
"directory": cwd.to_string_lossy(),
|
||||
"file": cwd.join(src).to_string_lossy(),
|
||||
"command": command
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
let json = serde_json::to_string_pretty(&entries)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("{e}")))?;
|
||||
|
||||
std::fs::write("compile_commands.json", json)?;
|
||||
|
||||
println!(" {} compile_commands.json", "Generated".green().bold());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn list() -> std::io::Result<()> {
|
||||
let conf = get_config().ok_or(std::io::Error::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
@@ -331,6 +391,8 @@ fn build(mode: &Option<String>, force_recompile: bool) -> std::io::Result<()> {
|
||||
|
||||
let stop = start.elapsed();
|
||||
|
||||
gen_compile_commands(&mode)?;
|
||||
|
||||
println!(
|
||||
" {} '{}' profile for project '{}' in {:.2}s",
|
||||
"Finished".green().bold(),
|
||||
|
||||
Reference in New Issue
Block a user