Add pkg-config stuff

This commit is contained in:
2026-03-23 12:35:09 -05:00
parent 4a2e959535
commit 0e3da1c77e
2 changed files with 112 additions and 0 deletions

View File

@@ -55,6 +55,11 @@ enum Subcommand {
}, },
/// List available build modes /// List available build modes
List, List,
/// Add a new package to the project (throguh pkg-config)
Add {
/// The package to be added
package: String,
},
} }
#[derive(clap::Subcommand)] #[derive(clap::Subcommand)]
@@ -168,9 +173,68 @@ impl App {
std::process::exit(1); std::process::exit(1);
} }
} }
Subcommand::Add { package } => {
if let Err(e) = add_package(&package) {
eprintln!("Error adding package {package} to project: {e}");
std::process::exit(1);
} }
} }
} }
}
}
fn add_package(package: &str) -> std::io::Result<()> {
let status = Command::new("pkg-config")
.arg("--exists")
.arg(&package)
.status()
.map_err(|_| {
std::io::Error::new(
std::io::ErrorKind::NotFound,
"pkg-config not found - please install it first",
)
})?;
if !status.success() {
eprintln!(
" {} pkg-config could not find package '{package}'",
"Error".red().bold()
);
eprintln!(
" {} try installing the development package for '{package}', e.g.:",
"Hint".yellow().bold()
);
eprintln!(" Arch: sudo pacman -S {package}");
eprintln!(" Debian: sudo apt install lib{package}-dev");
std::process::exit(1);
}
let mut conf = get_config().ok_or(std::io::Error::new(
std::io::ErrorKind::NotFound,
"no Pallet.toml found in local directory",
))?;
let deps = conf.dependencies.get_or_insert_with(Vec::new);
if deps.contains(&package.to_owned()) {
println!(
" {} '{package}' is already a dependency",
"Warning".yellow().bold()
);
return Ok(());
}
deps.push(package.to_owned());
std::fs::write(
"Pallet.toml",
toml::to_string_pretty(&conf).expect("valid TOML"),
)?;
println!(" {} {package}", "Added".green().bold());
Ok(())
}
fn gen_compile_commands(mode: &Option<String>) -> std::io::Result<()> { fn gen_compile_commands(mode: &Option<String>) -> std::io::Result<()> {
let conf = get_config().ok_or(std::io::Error::new( let conf = get_config().ok_or(std::io::Error::new(
@@ -314,6 +378,50 @@ fn build(mode: &Option<String>, force_recompile: bool) -> std::io::Result<()> {
let compiler = conf.compiler.as_deref().unwrap_or("gcc"); let compiler = conf.compiler.as_deref().unwrap_or("gcc");
let mut extra_compile_flags: Vec<String> = Vec::new();
let mut extra_link_flags: Vec<String> = Vec::new();
if let Some(deps) = &conf.dependencies {
if !deps.is_empty() {
let cflags = Command::new("pkg-config")
.arg("--cflags")
.args(deps)
.output()
.map_err(|_| {
std::io::Error::new(std::io::ErrorKind::NotFound, "pkg-config not found")
})?;
if !cflags.status.success() {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"pkg-config --cflags failed - is the package installed?",
));
}
let libs = Command::new("pkg-config")
.arg("--libs")
.args(deps)
.output()
.map_err(|_| {
std::io::Error::new(std::io::ErrorKind::NotFound, "pkg-config not found")
})?;
if !libs.status.success() {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"pkg-config --libs failed - is the pacakge installed?",
));
}
extra_compile_flags = String::from_utf8_lossy(&cflags.stdout)
.split_whitespace()
.map(str::to_owned)
.collect();
extra_link_flags = String::from_utf8_lossy(&libs.stdout)
.split_whitespace()
.map(str::to_owned)
.collect();
}
}
let source_files: Vec<PathBuf> = glob("src/*.c") let source_files: Vec<PathBuf> = glob("src/*.c")
.map_err(|e| std::io::Error::new(std::io::ErrorKind::NotFound, format!("{e}")))? .map_err(|e| std::io::Error::new(std::io::ErrorKind::NotFound, format!("{e}")))?
.filter_map(|e| e.ok()) .filter_map(|e| e.ok())
@@ -339,6 +447,7 @@ fn build(mode: &Option<String>, force_recompile: bool) -> std::io::Result<()> {
let status = Command::new(compiler) let status = Command::new(compiler)
.args(&build_config.args) .args(&build_config.args)
.args(&extra_compile_flags)
.arg("-c") .arg("-c")
.arg(src) .arg(src)
.arg("-o") .arg("-o")
@@ -378,6 +487,7 @@ fn build(mode: &Option<String>, force_recompile: bool) -> std::io::Result<()> {
let status = Command::new(compiler) let status = Command::new(compiler)
.args(&obj_files) .args(&obj_files)
.args(&extra_link_flags)
.arg("-o") .arg("-o")
.arg(&binary) .arg(&binary)
.status()?; .status()?;

View File

@@ -14,6 +14,8 @@ pub struct Config {
pub authors: Option<Vec<String>>, pub authors: Option<Vec<String>>,
/// Build configs /// Build configs
pub build: Vec<BuildConf>, pub build: Vec<BuildConf>,
/// Build dependnecies verified by pkg-config
pub dependencies: Option<Vec<String>>,
} }
impl Config { impl Config {