150 lines
5.3 KiB
Rust
150 lines
5.3 KiB
Rust
use crate::context;
|
|
use std::collections::HashMap;
|
|
use std::error::Error;
|
|
|
|
/// Set environment variables for cross-compilation
|
|
pub fn setup_environment(
|
|
env: &mut HashMap<String, String>,
|
|
arch: &str,
|
|
) -> Result<(), Box<dyn Error>> {
|
|
let dpkg_architecture = String::from_utf8(
|
|
context::current()
|
|
.command("dpkg-architecture")
|
|
.arg("-a")
|
|
.arg(arch)
|
|
.output()?
|
|
.stdout,
|
|
)?;
|
|
let env_var_regex = regex::Regex::new(r"(?<key>.*)=(?<value>.*)").unwrap();
|
|
for l in dpkg_architecture.lines() {
|
|
let capture = env_var_regex.captures(l).unwrap();
|
|
let key = capture.name("key").unwrap().as_str().to_string();
|
|
let value = capture.name("value").unwrap().as_str().to_string();
|
|
|
|
env.insert(key.clone(), value.clone());
|
|
|
|
if key == "DEB_HOST_GNU_TYPE" {
|
|
env.insert("CROSS_COMPILE".to_string(), format!("{value}-"));
|
|
}
|
|
}
|
|
env.insert("DEB_BUILD_PROFILES".to_string(), "cross".to_string());
|
|
env.insert("DEB_BUILD_OPTIONS".to_string(), "nocheck".to_string());
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Ensure that repositories for target architecture are available
|
|
/// This also handles the 'ports.ubuntu.com' vs 'archive.ubuntu.com' on Ubuntu
|
|
pub fn ensure_repositories(arch: &str, series: &str) -> Result<(), Box<dyn Error>> {
|
|
let ctx = context::current();
|
|
let local_arch = crate::get_current_arch();
|
|
|
|
// Add target ('host') architecture
|
|
ctx.command("dpkg")
|
|
.arg("--add-architecture")
|
|
.arg(arch)
|
|
.status()?;
|
|
|
|
// Check if we are on Ubuntu
|
|
let os_release = String::from_utf8(ctx.command("cat").arg("/etc/os-release").output()?.stdout)?;
|
|
if !os_release.contains("ID=ubuntu") {
|
|
return Ok(());
|
|
}
|
|
|
|
// Load existing sources
|
|
let mut sources = crate::apt::sources::load(Some(ctx.clone()))?;
|
|
|
|
// Ensure all components are enabled for the primary architecture
|
|
for source in &mut sources {
|
|
if source.uri.contains("archive.ubuntu.com") || source.uri.contains("security.ubuntu.com") {
|
|
// Scope to local_arch if not already scoped
|
|
if source.architectures.is_empty() {
|
|
source.architectures.push(local_arch.clone());
|
|
}
|
|
|
|
// Ensure all components are present
|
|
let required_components = ["main", "restricted", "universe", "multiverse"];
|
|
for &comp in &required_components {
|
|
if !source.components.contains(&comp.to_string()) {
|
|
source.components.push(comp.to_string());
|
|
}
|
|
}
|
|
|
|
// Ensure all suites (pockets) are enabled, excluding 'proposed'
|
|
let required_suites = [
|
|
series.to_string(),
|
|
format!("{}-updates", series),
|
|
format!("{}-backports", series),
|
|
format!("{}-security", series),
|
|
];
|
|
for suite in required_suites {
|
|
if !source.suite.contains(&suite) {
|
|
source.suite.push(suite);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check if ports repository already exists for the target architecture
|
|
let has_ports = sources
|
|
.iter()
|
|
.any(|s| s.uri.contains("ports.ubuntu.com") && s.architectures.contains(&arch.to_string()));
|
|
|
|
if !has_ports {
|
|
// Add ports repository for the target architecture
|
|
let ports_entry = crate::apt::sources::SourceEntry {
|
|
enabled: true,
|
|
components: vec![
|
|
"main".to_string(),
|
|
"restricted".to_string(),
|
|
"universe".to_string(),
|
|
"multiverse".to_string(),
|
|
],
|
|
architectures: vec![arch.to_string()],
|
|
uri: "http://ports.ubuntu.com/ubuntu-ports".to_string(),
|
|
suite: vec![
|
|
format!("{series}"),
|
|
format!("{series}-updates"),
|
|
format!("{series}-backports"),
|
|
format!("{series}-security"),
|
|
],
|
|
};
|
|
sources.push(ports_entry);
|
|
}
|
|
|
|
// Save the updated sources
|
|
// Try to save in DEB822 format first, fall back to legacy format
|
|
let deb822_path = "/etc/apt/sources.list.d/ubuntu.sources";
|
|
if ctx
|
|
.command("test")
|
|
.arg("-f")
|
|
.arg(deb822_path)
|
|
.status()?
|
|
.success()
|
|
{
|
|
// For DEB822 format, we need to reconstruct the file content
|
|
let mut content = String::new();
|
|
for source in &sources {
|
|
if !source.enabled {
|
|
continue;
|
|
}
|
|
content.push_str("Types: deb\n");
|
|
content.push_str(&format!("URIs: {}\n", source.uri));
|
|
content.push_str(&format!("Suites: {}\n", source.suite.join(" ")));
|
|
content.push_str(&format!("Components: {}\n", source.components.join(" ")));
|
|
content.push_str("Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg\n");
|
|
content.push_str(&format!(
|
|
"Architectures: {}\n",
|
|
source.architectures.join(" ")
|
|
));
|
|
content.push('\n');
|
|
}
|
|
ctx.write_file(std::path::Path::new(deb822_path), &content)?;
|
|
} else {
|
|
// Fall back to legacy format
|
|
crate::apt::sources::save_legacy(Some(ctx.clone()), sources, "/etc/apt/sources.list")?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|