196 lines
6.7 KiB
Rust
196 lines
6.7 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(());
|
|
}
|
|
|
|
// Handle DEB822 format (Ubuntu 24.04+)
|
|
let deb822_path = "/etc/apt/sources.list.d/ubuntu.sources";
|
|
let has_deb822 = ctx
|
|
.command("test")
|
|
.arg("-f")
|
|
.arg(deb822_path)
|
|
.status()?
|
|
.success();
|
|
|
|
if has_deb822 {
|
|
ensure_repositories_deb822(&ctx, arch, &local_arch, series, deb822_path)?;
|
|
} else {
|
|
ensure_repositories_legacy(&ctx, arch, &local_arch, series, "/etc/apt/sources.list")?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn ensure_repositories_deb822(
|
|
ctx: &context::Context,
|
|
arch: &str,
|
|
local_arch: &str,
|
|
series: &str,
|
|
deb822_path: &str,
|
|
) -> Result<(), Box<dyn Error>> {
|
|
// Scope existing to local_arch if not already scoped
|
|
ctx.command("sed")
|
|
.arg("-i")
|
|
.arg(format!("/URIs:.*\\(archive\\|security\\)\\.ubuntu\\.com/ {{ n; /^Architectures:/ ! i Architectures: {} }}", local_arch))
|
|
.arg(deb822_path)
|
|
.status()?;
|
|
|
|
// Ensure all components are enabled for the primary architecture
|
|
ctx.command("sed")
|
|
.arg("-i")
|
|
.arg("/URIs:.*\\(archive\\|security\\)\\.ubuntu\\.com/,/Components:/ s/^Components:.*/Components: main restricted universe multiverse/")
|
|
.arg(deb822_path)
|
|
.status()?;
|
|
|
|
// Ensure all suites (pockets) are enabled for the primary architecture
|
|
// Excluding 'proposed' as it contains unstable software
|
|
let suites = format!("{series} {series}-updates {series}-backports {series}-security");
|
|
ctx.command("sed")
|
|
.arg("-i")
|
|
.arg(format!(
|
|
"/URIs:.*\\(archive\\|security\\)\\.ubuntu\\.com/,/Suites:/ s/^Suites:.*/Suites: {}/",
|
|
suites
|
|
))
|
|
.arg(deb822_path)
|
|
.status()?;
|
|
|
|
// Add ports if not already present
|
|
let has_ports = ctx
|
|
.command("grep")
|
|
.arg("-q")
|
|
.arg("ports.ubuntu.com")
|
|
.arg(deb822_path)
|
|
.status()?
|
|
.success();
|
|
|
|
if !has_ports {
|
|
let ports_block = format!(
|
|
"\nTypes: deb\nURIs: http://ports.ubuntu.com/ubuntu-ports\nSuites: {series} {series}-updates {series}-backports {series}-security\nComponents: main restricted universe multiverse\nSigned-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg\nArchitectures: {arch}\n"
|
|
);
|
|
ctx.command("sh")
|
|
.arg("-c")
|
|
.arg(format!("echo '{}' >> {}", ports_block, deb822_path))
|
|
.status()?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
fn ensure_repositories_legacy(
|
|
ctx: &context::Context,
|
|
arch: &str,
|
|
local_arch: &str,
|
|
series: &str,
|
|
sources_path: &str,
|
|
) -> Result<(), Box<dyn Error>> {
|
|
// Scope archive.ubuntu.com and security.ubuntu.com to local_arch if not already scoped
|
|
ctx.command("sed")
|
|
.arg("-i")
|
|
.arg(format!(
|
|
r"/archive.ubuntu.com\|security.ubuntu.com/ {{ /arch=/ ! {{ /^deb \[/ ! s/^deb /deb [arch={}] /; /^deb \[/ s/^deb \[\([^]]*\)\]/deb [arch={} \1]/ }} }}",
|
|
local_arch, local_arch
|
|
))
|
|
.arg(sources_path)
|
|
.status()?;
|
|
|
|
// Ensure all components (main restricted universe multiverse) are present for all archive/security lines
|
|
ctx.command("sed")
|
|
.arg("-i")
|
|
.arg(r"/archive.ubuntu.com\|security.ubuntu.com/ s/\( main\)\?\([ ]\+restricted\)\?\([ ]\+universe\)\?\([ ]\+multiverse\)\?$/ main restricted universe multiverse/")
|
|
.arg(sources_path)
|
|
.status()?;
|
|
|
|
// Ensure all pockets exist. If not, we append them.
|
|
for pocket in ["", "-updates", "-backports", "-security"] {
|
|
let suite = format!("{}{}", series, pocket);
|
|
let has_suite = ctx
|
|
.command("grep")
|
|
.arg("-q")
|
|
.arg(format!(" {}", suite))
|
|
.arg(sources_path)
|
|
.status()?
|
|
.success();
|
|
|
|
if !has_suite {
|
|
let line = format!(
|
|
"deb [arch={}] http://archive.ubuntu.com/ubuntu/ {} main restricted universe multiverse",
|
|
local_arch, suite
|
|
);
|
|
ctx.command("sh")
|
|
.arg("-c")
|
|
.arg(format!("echo '{}' >> {}", line, sources_path))
|
|
.status()?;
|
|
}
|
|
}
|
|
|
|
// Add ports repository to sources.list if not already present
|
|
let has_ports = ctx
|
|
.command("grep")
|
|
.arg("-q")
|
|
.arg("ports.ubuntu.com")
|
|
.arg(sources_path)
|
|
.status()?
|
|
.success();
|
|
|
|
if !has_ports {
|
|
let ports_lines = format!(
|
|
"deb [arch={arch}] http://ports.ubuntu.com/ubuntu-ports {series} main restricted universe multiverse\n\
|
|
deb [arch={arch}] http://ports.ubuntu.com/ubuntu-ports {series}-updates main restricted universe multiverse\n\
|
|
deb [arch={arch}] http://ports.ubuntu.com/ubuntu-ports {series}-backports main restricted universe multiverse\n\
|
|
deb [arch={arch}] http://ports.ubuntu.com/ubuntu-ports {series}-security main restricted universe multiverse"
|
|
);
|
|
ctx.command("sh")
|
|
.arg("-c")
|
|
.arg(format!("echo '{}' >> {}", ports_lines, sources_path))
|
|
.status()?;
|
|
}
|
|
Ok(())
|
|
}
|