Implement Perl build helper commands and integrate into CLI
- Added `run_helper_configure` and `run_helper_install` functions in `perl.rs` to handle Perl-specific build configurations and installations. - Introduced new internal commands in `cli.rs` for Perl configuration and installation. - Updated `internal.rs` to execute Perl helper commands using the new functions. - Enhanced `shell_helpers.rs` to include scripts for Perl configure and install commands. - Modified `hooks.rs` to apply build helper context and directories for post-extract and post-configure commands. - Added tests to ensure the correct execution of Perl build helper commands and their integration with the build process.
This commit is contained in:
Generated
+1
-1
@@ -451,7 +451,7 @@ checksum = "807800ff3288b621186fe0a8f3392c4652068257302709c24efd918c3dffcdc2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "depot"
|
name = "depot"
|
||||||
version = "0.35.1"
|
version = "0.36.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"ar",
|
"ar",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "depot"
|
name = "depot"
|
||||||
version = "0.35.1"
|
version = "0.36.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[lints.rust]
|
[lints.rust]
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
project(
|
project(
|
||||||
'depot',
|
'depot',
|
||||||
version: '0.35.1',
|
version: '0.36.0',
|
||||||
meson_version: '>=0.60.0',
|
meson_version: '>=0.60.0',
|
||||||
default_options: ['buildtype=release'],
|
default_options: ['buildtype=release'],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
//! GNU Autotools build system (configure && make && make install)
|
//! GNU Autotools build system (configure && make && make install)
|
||||||
|
|
||||||
|
use crate::builder::BuildHelperContext;
|
||||||
use crate::builder::state::{BuildStep, StateTracker};
|
use crate::builder::state::{BuildStep, StateTracker};
|
||||||
use crate::cross::CrossConfig;
|
use crate::cross::CrossConfig;
|
||||||
use crate::fakeroot;
|
use crate::fakeroot;
|
||||||
@@ -501,6 +502,202 @@ pub(crate) fn ensure_host_build(
|
|||||||
.with_context(|| format!("Failed to resolve host build dir: {}", build_dir.display()))
|
.with_context(|| format!("Failed to resolve host build dir: {}", build_dir.display()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_helper_configure(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
source_dir: Option<&Path>,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
cross: Option<&CrossConfig>,
|
||||||
|
env_vars: &[(String, String)],
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
let flags = context.build_flags();
|
||||||
|
let source_dir = source_dir
|
||||||
|
.map(Path::to_path_buf)
|
||||||
|
.unwrap_or(std::env::current_dir().context("Failed to determine current directory")?);
|
||||||
|
let build_dir = build_dir.map(Path::to_path_buf).unwrap_or_else(|| {
|
||||||
|
flags
|
||||||
|
.build_dir
|
||||||
|
.as_ref()
|
||||||
|
.map(|dir| source_dir.join(dir))
|
||||||
|
.unwrap_or_else(|| source_dir.clone())
|
||||||
|
});
|
||||||
|
fs::create_dir_all(&build_dir)
|
||||||
|
.with_context(|| format!("Failed to create build directory: {}", build_dir.display()))?;
|
||||||
|
|
||||||
|
let mut helper_env = env_vars.to_vec();
|
||||||
|
let cc = if let Some(cc_cfg) = cross {
|
||||||
|
cc_cfg.cc.clone()
|
||||||
|
} else {
|
||||||
|
helper_env
|
||||||
|
.iter()
|
||||||
|
.find(|(key, _)| key == "CC")
|
||||||
|
.map(|(_, value)| value.clone())
|
||||||
|
.unwrap_or_else(|| flags.cc.clone())
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(cflags_str) = helper_env
|
||||||
|
.iter()
|
||||||
|
.find(|(key, _)| key == "CFLAGS")
|
||||||
|
.map(|(_, value)| value.clone())
|
||||||
|
.filter(|value| !value.trim().is_empty())
|
||||||
|
{
|
||||||
|
let expanded = expand_shell_commands(&cflags_str, &cc)?;
|
||||||
|
crate::builder::set_env_var(&mut helper_env, "CFLAGS", expanded);
|
||||||
|
}
|
||||||
|
|
||||||
|
let configure_path = helper_configure_path(context, &source_dir);
|
||||||
|
let mut configure_cmd = Command::new(&configure_path);
|
||||||
|
configure_cmd.current_dir(&build_dir);
|
||||||
|
crate::builder::prepare_tool_command(&mut configure_cmd, &helper_env);
|
||||||
|
|
||||||
|
let help_text = configure_help_text(&configure_path, &build_dir, &helper_env);
|
||||||
|
configure_cmd.arg(format!("--prefix={}", flags.prefix));
|
||||||
|
for default_dir_arg in default_configure_install_dirs(&flags, help_text.as_deref()) {
|
||||||
|
configure_cmd.arg(default_dir_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
let supports_host =
|
||||||
|
configure_supports_option(help_text.as_deref(), "--host", &flags.configure_file);
|
||||||
|
let supports_build =
|
||||||
|
configure_supports_option(help_text.as_deref(), "--build", &flags.configure_file);
|
||||||
|
|
||||||
|
let requested_host = if let Some(cc_cfg) = cross {
|
||||||
|
Some(cc_cfg.host_triple().to_string())
|
||||||
|
} else if !flags.chost.is_empty() {
|
||||||
|
Some(flags.chost.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
.map(|host| {
|
||||||
|
if flags.lib32_variant {
|
||||||
|
lib32_host_triple(&host)
|
||||||
|
} else {
|
||||||
|
host
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let requested_build = if cross.is_some() {
|
||||||
|
CrossConfig::build_triple().ok()
|
||||||
|
} else if !flags.cbuild.is_empty() {
|
||||||
|
Some(flags.cbuild.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(host) = requested_host {
|
||||||
|
if supports_host {
|
||||||
|
configure_cmd.arg(format!("--host={host}"));
|
||||||
|
} else {
|
||||||
|
crate::log_info!(" configure does not support --host; skipping {}", host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(build) = requested_build {
|
||||||
|
if supports_build {
|
||||||
|
configure_cmd.arg(format!("--build={build}"));
|
||||||
|
} else {
|
||||||
|
crate::log_info!(" configure does not support --build; skipping {}", build);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for arg in &flags.configure {
|
||||||
|
configure_cmd.arg(expand_with_envs(&context.expand_vars(arg), &helper_env));
|
||||||
|
}
|
||||||
|
for arg in crate::builder::static_build_args_for(crate::package::BuildType::Autotools, &flags)?
|
||||||
|
{
|
||||||
|
add_auto_configure_arg_if_supported(&mut configure_cmd, help_text.as_deref(), &arg);
|
||||||
|
}
|
||||||
|
for arg in extra_args {
|
||||||
|
add_auto_configure_arg_if_supported(
|
||||||
|
&mut configure_cmd,
|
||||||
|
help_text.as_deref(),
|
||||||
|
&expand_with_envs(&context.expand_vars(arg), &helper_env),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let status = crate::interrupts::command_status(&mut configure_cmd)
|
||||||
|
.with_context(|| format!("Failed to run helper configure in {}", build_dir.display()))?;
|
||||||
|
if !status.success() {
|
||||||
|
anyhow::bail!("configure failed with status: {}", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_helper_install(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
env_vars: &[(String, String)],
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
let flags = context.build_flags();
|
||||||
|
let source_dir = helper_source_dir();
|
||||||
|
let build_dir = build_dir.map(Path::to_path_buf).unwrap_or_else(|| {
|
||||||
|
flags
|
||||||
|
.build_dir
|
||||||
|
.as_ref()
|
||||||
|
.map(|dir| source_dir.join(dir))
|
||||||
|
.unwrap_or_else(|| source_dir.clone())
|
||||||
|
});
|
||||||
|
let destdir = std::env::var("DESTDIR").context("DESTDIR must be set for autotools_install")?;
|
||||||
|
let make_exec = resolve_make_exec(&flags.make_exec);
|
||||||
|
let install_dirs = resolve_make_dirs(
|
||||||
|
&build_dir,
|
||||||
|
&flags.make_install_dirs,
|
||||||
|
"build.flags.make_install_dirs",
|
||||||
|
)?;
|
||||||
|
let install_targets = phase_targets(
|
||||||
|
&flags.make_install_target,
|
||||||
|
&flags.make_install_targets,
|
||||||
|
Some("install"),
|
||||||
|
);
|
||||||
|
|
||||||
|
for install_dir in install_dirs {
|
||||||
|
let mut install_cmd = fakeroot::wrap_install_command(make_exec, Path::new(&destdir));
|
||||||
|
install_cmd.current_dir(&install_dir);
|
||||||
|
if make_exec_supports_make_assignments(make_exec)
|
||||||
|
&& !has_make_variable_override(&flags.make_install_vars, "DESTDIR")
|
||||||
|
{
|
||||||
|
install_cmd.arg(format!("DESTDIR={destdir}"));
|
||||||
|
}
|
||||||
|
add_make_variable_overrides_if_supported(
|
||||||
|
&mut install_cmd,
|
||||||
|
make_exec,
|
||||||
|
&flags.make_install_vars,
|
||||||
|
"install",
|
||||||
|
)?;
|
||||||
|
for install_target in &install_targets {
|
||||||
|
install_cmd.arg(install_target);
|
||||||
|
}
|
||||||
|
for arg in extra_args {
|
||||||
|
install_cmd.arg(context.expand_vars(arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut install_env = env_vars.to_vec();
|
||||||
|
crate::builder::set_env_var(&mut install_env, "DESTDIR", destdir.clone());
|
||||||
|
crate::builder::prepare_tool_command(&mut install_cmd, &install_env);
|
||||||
|
|
||||||
|
let status = crate::interrupts::command_status(&mut install_cmd).with_context(|| {
|
||||||
|
format!(
|
||||||
|
"Failed to run helper {} {} in {}",
|
||||||
|
make_exec,
|
||||||
|
install_targets.join(" "),
|
||||||
|
install_dir.display()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
if !status.success() {
|
||||||
|
anyhow::bail!(
|
||||||
|
"{} {} failed with status: {} (dir: {})",
|
||||||
|
make_exec,
|
||||||
|
install_targets.join(" "),
|
||||||
|
status,
|
||||||
|
install_dir.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn num_cpus() -> usize {
|
fn num_cpus() -> usize {
|
||||||
std::thread::available_parallelism()
|
std::thread::available_parallelism()
|
||||||
.map(|n| n.get())
|
.map(|n| n.get())
|
||||||
@@ -544,6 +741,22 @@ fn resolve_configure_path(spec: &PackageSpec, actual_src: &Path) -> PathBuf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn helper_configure_path(context: &BuildHelperContext, actual_src: &Path) -> PathBuf {
|
||||||
|
let flags = context.build_flags();
|
||||||
|
let configured = context.expand_vars(&flags.configure_file);
|
||||||
|
let trimmed = configured.trim();
|
||||||
|
if trimmed.is_empty() {
|
||||||
|
return actual_src.join("configure");
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = Path::new(trimmed);
|
||||||
|
if path.is_absolute() {
|
||||||
|
path.to_path_buf()
|
||||||
|
} else {
|
||||||
|
actual_src.join(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn configure_help_text(
|
fn configure_help_text(
|
||||||
configure_path: &Path,
|
configure_path: &Path,
|
||||||
build_dir: &Path,
|
build_dir: &Path,
|
||||||
@@ -823,6 +1036,12 @@ fn nonempty_trimmed(value: &str) -> Option<&str> {
|
|||||||
(!trimmed.is_empty()).then_some(trimmed)
|
(!trimmed.is_empty()).then_some(trimmed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn helper_source_dir() -> PathBuf {
|
||||||
|
std::env::var(crate::builder::DEPOT_BUILD_HELPER_SOURCE_DIR_ENV)
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.unwrap_or_else(|_| std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")))
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn resolve_make_exec(configured: &str) -> &str {
|
pub(crate) fn resolve_make_exec(configured: &str) -> &str {
|
||||||
nonempty_trimmed(configured).unwrap_or("make")
|
nonempty_trimmed(configured).unwrap_or("make")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
//! CMake build system
|
//! CMake build system
|
||||||
|
|
||||||
|
use crate::builder::BuildHelperContext;
|
||||||
use crate::builder::state::{BuildStep, StateTracker};
|
use crate::builder::state::{BuildStep, StateTracker};
|
||||||
use crate::cross::CrossConfig;
|
use crate::cross::CrossConfig;
|
||||||
use crate::fakeroot;
|
use crate::fakeroot;
|
||||||
@@ -359,6 +360,139 @@ pub(crate) fn ensure_host_build(
|
|||||||
.with_context(|| format!("Failed to resolve host build dir: {}", build_dir.display()))
|
.with_context(|| format!("Failed to resolve host build dir: {}", build_dir.display()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_helper_configure(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
source_dir: Option<&Path>,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
cross: Option<&CrossConfig>,
|
||||||
|
env_vars: &[(String, String)],
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
let flags = context.build_flags();
|
||||||
|
let source_dir = source_dir
|
||||||
|
.map(Path::to_path_buf)
|
||||||
|
.unwrap_or(std::env::current_dir().context("Failed to determine current directory")?);
|
||||||
|
let build_dir = build_dir.map(Path::to_path_buf).unwrap_or_else(|| {
|
||||||
|
flags
|
||||||
|
.build_dir
|
||||||
|
.as_ref()
|
||||||
|
.map(|dir| source_dir.join(dir))
|
||||||
|
.unwrap_or_else(|| source_dir.join("build"))
|
||||||
|
});
|
||||||
|
let prefix = effective_cmake_install_prefix(&flags);
|
||||||
|
|
||||||
|
fs::create_dir_all(&build_dir)
|
||||||
|
.with_context(|| format!("Failed to create build directory: {}", build_dir.display()))?;
|
||||||
|
|
||||||
|
let toolchain_file = if let Some(cc_cfg) = cross {
|
||||||
|
Some(cc_cfg.generate_cmake_toolchain(&build_dir)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut cmake_cmd = Command::new("cmake");
|
||||||
|
cmake_cmd.current_dir(&build_dir);
|
||||||
|
cmake_cmd.arg("-S").arg(&source_dir);
|
||||||
|
cmake_cmd.arg("-B").arg(&build_dir);
|
||||||
|
cmake_cmd.arg(format!("-DCMAKE_INSTALL_PREFIX={prefix}"));
|
||||||
|
cmake_cmd.arg("-DCMAKE_BUILD_TYPE=Release");
|
||||||
|
for arg in cmake_install_dir_args(&flags, prefix) {
|
||||||
|
cmake_cmd.arg(arg);
|
||||||
|
}
|
||||||
|
for arg in cmake_lib32_target_args(&flags, cross) {
|
||||||
|
cmake_cmd.arg(arg);
|
||||||
|
}
|
||||||
|
if let Some(toolchain_file) = &toolchain_file {
|
||||||
|
cmake_cmd.arg(format!(
|
||||||
|
"-DCMAKE_TOOLCHAIN_FILE={}",
|
||||||
|
toolchain_file.display()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let make_exec_override = flags.make_exec.trim();
|
||||||
|
if !make_exec_override.is_empty() {
|
||||||
|
if !cmake_configure_flags_specify_generator(&flags.configure)
|
||||||
|
&& let Some(generator) = cmake_generator_for_make_exec(make_exec_override)
|
||||||
|
{
|
||||||
|
cmake_cmd.arg("-G").arg(generator);
|
||||||
|
}
|
||||||
|
if !cmake_configure_flags_set_make_program(&flags.configure) {
|
||||||
|
cmake_cmd.arg(format!("-DCMAKE_MAKE_PROGRAM={make_exec_override}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for flag in &flags.configure {
|
||||||
|
cmake_cmd.arg(expand_with_envs(&context.expand_vars(flag), env_vars));
|
||||||
|
}
|
||||||
|
for arg in crate::builder::static_build_args_for(crate::package::BuildType::CMake, &flags)? {
|
||||||
|
cmake_cmd.arg(arg);
|
||||||
|
}
|
||||||
|
for arg in extra_args {
|
||||||
|
cmake_cmd.arg(expand_with_envs(&context.expand_vars(arg), env_vars));
|
||||||
|
}
|
||||||
|
|
||||||
|
crate::builder::prepare_tool_command(&mut cmake_cmd, &env_vars.to_vec());
|
||||||
|
|
||||||
|
let status = crate::interrupts::command_status(&mut cmake_cmd)
|
||||||
|
.context("Failed to run helper cmake configure")?;
|
||||||
|
if !status.success() {
|
||||||
|
anyhow::bail!("cmake configure failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_helper_install(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
env_vars: &[(String, String)],
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
let flags = context.build_flags();
|
||||||
|
let source_dir = helper_source_dir();
|
||||||
|
let build_dir = build_dir.map(Path::to_path_buf).unwrap_or_else(|| {
|
||||||
|
flags
|
||||||
|
.build_dir
|
||||||
|
.as_ref()
|
||||||
|
.map(|dir| source_dir.join(dir))
|
||||||
|
.unwrap_or_else(|| source_dir.join("build"))
|
||||||
|
});
|
||||||
|
let destdir = std::env::var("DESTDIR").context("DESTDIR must be set for cmake_install")?;
|
||||||
|
let install_targets = phase_targets(&flags.make_install_target, &flags.make_install_targets);
|
||||||
|
|
||||||
|
let mut install_cmd = fakeroot::wrap_install_command("cmake", Path::new(&destdir));
|
||||||
|
if install_targets.is_empty() {
|
||||||
|
install_cmd.arg("--install").arg(&build_dir);
|
||||||
|
} else {
|
||||||
|
install_cmd.arg("--build").arg(&build_dir);
|
||||||
|
install_cmd.arg("--target");
|
||||||
|
for target in &install_targets {
|
||||||
|
install_cmd.arg(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for arg in extra_args {
|
||||||
|
install_cmd.arg(context.expand_vars(arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut install_env = env_vars.to_vec();
|
||||||
|
crate::builder::set_env_var(&mut install_env, "DESTDIR", destdir);
|
||||||
|
crate::builder::prepare_tool_command(&mut install_cmd, &install_env);
|
||||||
|
|
||||||
|
let status = crate::interrupts::command_status(&mut install_cmd)
|
||||||
|
.context("Failed to run helper cmake install")?;
|
||||||
|
if !status.success() {
|
||||||
|
if install_targets.is_empty() {
|
||||||
|
anyhow::bail!("cmake install failed");
|
||||||
|
}
|
||||||
|
anyhow::bail!(
|
||||||
|
"cmake install target(s) '{}' failed",
|
||||||
|
install_targets.join(" ")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Expand environment variables in a string (e.g., $DEPOT_SYSROOT)
|
/// Expand environment variables in a string (e.g., $DEPOT_SYSROOT)
|
||||||
fn expand_env_vars(input: &str) -> String {
|
fn expand_env_vars(input: &str) -> String {
|
||||||
let mut result = input.to_string();
|
let mut result = input.to_string();
|
||||||
@@ -580,6 +714,12 @@ fn num_cpus() -> usize {
|
|||||||
.unwrap_or(1)
|
.unwrap_or(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn helper_source_dir() -> PathBuf {
|
||||||
|
std::env::var(crate::builder::DEPOT_BUILD_HELPER_SOURCE_DIR_ENV)
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.unwrap_or_else(|_| std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")))
|
||||||
|
}
|
||||||
|
|
||||||
/// Resolve `source_subdir` with multiple fallbacks:
|
/// Resolve `source_subdir` with multiple fallbacks:
|
||||||
/// - empty -> use `src_dir`
|
/// - empty -> use `src_dir`
|
||||||
/// - absolute path -> use if exists
|
/// - absolute path -> use if exists
|
||||||
|
|||||||
+18
-8
@@ -51,6 +51,8 @@ pub fn build(
|
|||||||
let mut env_vars = crate::builder::standard_build_env(spec, cross, true, export_compiler_flags);
|
let mut env_vars = crate::builder::standard_build_env(spec, cross, true, export_compiler_flags);
|
||||||
let shell_helpers = crate::shell_helpers::ShellHelpers::new(&install_destdir)?;
|
let shell_helpers = crate::shell_helpers::ShellHelpers::new(&install_destdir)?;
|
||||||
shell_helpers.apply_to_env_vars(&mut env_vars);
|
shell_helpers.apply_to_env_vars(&mut env_vars);
|
||||||
|
crate::builder::apply_build_helper_context_env(&mut env_vars, spec)?;
|
||||||
|
crate::builder::apply_build_helper_dirs_env(&mut env_vars, Some(src_dir), Some(&build_dir));
|
||||||
|
|
||||||
// For custom builds, look for a build.sh script in the source directory
|
// For custom builds, look for a build.sh script in the source directory
|
||||||
let build_script = src_dir.join("build.sh");
|
let build_script = src_dir.join("build.sh");
|
||||||
@@ -280,19 +282,27 @@ fn build_function_mode_install_command(
|
|||||||
"DEPOT_OUTPUT_NAME='{q_name}'; DEPOT_OUTPUT_DESTDIR='{q_dest}'; DESTDIR=\"$DEPOT_OUTPUT_DESTDIR\"; export DEPOT_OUTPUT_NAME DEPOT_OUTPUT_DESTDIR DESTDIR\n"
|
"DEPOT_OUTPUT_NAME='{q_name}'; DEPOT_OUTPUT_DESTDIR='{q_dest}'; DESTDIR=\"$DEPOT_OUTPUT_DESTDIR\"; export DEPOT_OUTPUT_NAME DEPOT_OUTPUT_DESTDIR DESTDIR\n"
|
||||||
));
|
));
|
||||||
wrapper.push_str("depot_output_installed=0\n");
|
wrapper.push_str("depot_output_installed=0\n");
|
||||||
wrapper.push_str(&format!(
|
|
||||||
"if depot_has_function depot_install_{fn_suffix}; then depot_install_{fn_suffix}; depot_output_installed=1;\n"
|
|
||||||
));
|
|
||||||
wrapper.push_str(&format!(
|
|
||||||
"elif depot_has_function install_{fn_suffix}; then install_{fn_suffix}; depot_output_installed=1;\n"
|
|
||||||
));
|
|
||||||
if out.name == *primary {
|
if out.name == *primary {
|
||||||
wrapper
|
wrapper.push_str(
|
||||||
.push_str("elif depot_has_function depot_install; then depot_install; depot_output_installed=1;\n");
|
"if depot_has_function depot_install; then depot_install; depot_output_installed=1;\n",
|
||||||
|
);
|
||||||
wrapper.push_str(
|
wrapper.push_str(
|
||||||
"elif depot_has_function install; then install; depot_output_installed=1;\n",
|
"elif depot_has_function install; then install; depot_output_installed=1;\n",
|
||||||
);
|
);
|
||||||
|
wrapper.push_str(&format!(
|
||||||
|
"elif depot_has_function depot_install_{fn_suffix}; then depot_install_{fn_suffix}; depot_output_installed=1;\n"
|
||||||
|
));
|
||||||
|
wrapper.push_str(&format!(
|
||||||
|
"elif depot_has_function install_{fn_suffix}; then install_{fn_suffix}; depot_output_installed=1;\n"
|
||||||
|
));
|
||||||
wrapper.push_str("elif [ \"$depot_build_ran\" = 1 ]; then depot_output_installed=1;\n");
|
wrapper.push_str("elif [ \"$depot_build_ran\" = 1 ]; then depot_output_installed=1;\n");
|
||||||
|
} else {
|
||||||
|
wrapper.push_str(&format!(
|
||||||
|
"if depot_has_function depot_install_{fn_suffix}; then depot_install_{fn_suffix}; depot_output_installed=1;\n"
|
||||||
|
));
|
||||||
|
wrapper.push_str(&format!(
|
||||||
|
"elif depot_has_function install_{fn_suffix}; then install_{fn_suffix}; depot_output_installed=1;\n"
|
||||||
|
));
|
||||||
}
|
}
|
||||||
wrapper.push_str("fi\n");
|
wrapper.push_str("fi\n");
|
||||||
wrapper.push_str("if [ \"$depot_output_installed\" != 1 ]; then\n");
|
wrapper.push_str("if [ \"$depot_output_installed\" != 1 ]; then\n");
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
//! Meson build system
|
//! Meson build system
|
||||||
|
|
||||||
|
use crate::builder::BuildHelperContext;
|
||||||
use crate::builder::state::{BuildStep, StateTracker};
|
use crate::builder::state::{BuildStep, StateTracker};
|
||||||
use crate::cross::CrossConfig;
|
use crate::cross::CrossConfig;
|
||||||
use crate::fakeroot;
|
use crate::fakeroot;
|
||||||
@@ -267,12 +268,106 @@ pub(crate) fn ensure_host_build(
|
|||||||
.with_context(|| format!("Failed to resolve host build dir: {}", build_dir.display()))
|
.with_context(|| format!("Failed to resolve host build dir: {}", build_dir.display()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_helper_configure(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
source_dir: Option<&Path>,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
cross: Option<&CrossConfig>,
|
||||||
|
env_vars: &[(String, String)],
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
let flags = context.build_flags();
|
||||||
|
let source_dir = source_dir
|
||||||
|
.map(Path::to_path_buf)
|
||||||
|
.unwrap_or(std::env::current_dir().context("Failed to determine current directory")?);
|
||||||
|
let build_dir = build_dir
|
||||||
|
.map(Path::to_path_buf)
|
||||||
|
.unwrap_or_else(|| resolve_build_dir(&source_dir, &flags));
|
||||||
|
|
||||||
|
fs::create_dir_all(&build_dir)
|
||||||
|
.with_context(|| format!("Failed to create build directory: {}", build_dir.display()))?;
|
||||||
|
|
||||||
|
let mut helper_env = env_vars.to_vec();
|
||||||
|
configure_pkg_config_env(&mut helper_env, &flags, cross);
|
||||||
|
|
||||||
|
let cross_file = if let Some(cc_cfg) = cross {
|
||||||
|
Some(cc_cfg.generate_meson_cross_file(&build_dir)?)
|
||||||
|
} else if flags.lib32_variant {
|
||||||
|
Some(generate_lib32_meson_cross_file(&flags, &build_dir)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut meson_cmd = Command::new("meson");
|
||||||
|
meson_cmd.current_dir(&source_dir);
|
||||||
|
meson_cmd.arg("setup");
|
||||||
|
meson_cmd.arg(&build_dir);
|
||||||
|
|
||||||
|
for arg in meson_setup_args(&flags, cross_file.as_deref(), &helper_env) {
|
||||||
|
meson_cmd.arg(arg);
|
||||||
|
}
|
||||||
|
for arg in crate::builder::static_build_args_for(crate::package::BuildType::Meson, &flags)? {
|
||||||
|
meson_cmd.arg(arg);
|
||||||
|
}
|
||||||
|
for arg in extra_args {
|
||||||
|
meson_cmd.arg(context.expand_vars(arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
crate::builder::prepare_tool_command(&mut meson_cmd, &helper_env);
|
||||||
|
|
||||||
|
let status = crate::interrupts::command_status(&mut meson_cmd)
|
||||||
|
.context("Failed to run helper meson setup")?;
|
||||||
|
if !status.success() {
|
||||||
|
bail!("meson setup failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_helper_install(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
env_vars: &[(String, String)],
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
let flags = context.build_flags();
|
||||||
|
let build_dir = build_dir
|
||||||
|
.map(Path::to_path_buf)
|
||||||
|
.unwrap_or_else(|| resolve_build_dir(&helper_source_dir(), &flags));
|
||||||
|
let destdir = std::env::var("DESTDIR").context("DESTDIR must be set for meson_install")?;
|
||||||
|
|
||||||
|
let mut install_cmd = fakeroot::wrap_install_command("meson", Path::new(&destdir));
|
||||||
|
install_cmd.arg("install");
|
||||||
|
install_cmd.arg("-C").arg(&build_dir);
|
||||||
|
for arg in extra_args {
|
||||||
|
install_cmd.arg(context.expand_vars(arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut install_env = env_vars.to_vec();
|
||||||
|
crate::builder::set_env_var(&mut install_env, "DESTDIR", destdir);
|
||||||
|
crate::builder::prepare_tool_command(&mut install_cmd, &install_env);
|
||||||
|
|
||||||
|
let status = crate::interrupts::command_status(&mut install_cmd)
|
||||||
|
.context("Failed to run helper meson install")?;
|
||||||
|
if !status.success() {
|
||||||
|
bail!("meson install failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn num_cpus() -> usize {
|
fn num_cpus() -> usize {
|
||||||
std::thread::available_parallelism()
|
std::thread::available_parallelism()
|
||||||
.map(|n| n.get())
|
.map(|n| n.get())
|
||||||
.unwrap_or(1)
|
.unwrap_or(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn helper_source_dir() -> PathBuf {
|
||||||
|
std::env::var(crate::builder::DEPOT_BUILD_HELPER_SOURCE_DIR_ENV)
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.unwrap_or_else(|_| std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")))
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_build_dir(actual_src: &Path, flags: &crate::package::BuildFlags) -> PathBuf {
|
fn resolve_build_dir(actual_src: &Path, flags: &crate::package::BuildFlags) -> PathBuf {
|
||||||
if let Some(dir) = flags
|
if let Some(dir) = flags
|
||||||
.build_dir
|
.build_dir
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ use walkdir::WalkDir;
|
|||||||
|
|
||||||
pub type EnvVars = Vec<(String, String)>;
|
pub type EnvVars = Vec<(String, String)>;
|
||||||
pub(crate) const DEPOT_BUILD_HOST_DIR_ENV: &str = "DEPOT_BUILD_HOST_DIR";
|
pub(crate) const DEPOT_BUILD_HOST_DIR_ENV: &str = "DEPOT_BUILD_HOST_DIR";
|
||||||
|
pub(crate) const DEPOT_BUILD_HELPER_CONTEXT_ENV: &str = "DEPOT_BUILD_HELPER_CONTEXT";
|
||||||
|
pub(crate) const DEPOT_BUILD_HELPER_SOURCE_DIR_ENV: &str = "DEPOT_BUILD_HELPER_SOURCE_DIR";
|
||||||
|
pub(crate) const DEPOT_BUILD_HELPER_BUILD_DIR_ENV: &str = "DEPOT_BUILD_HELPER_BUILD_DIR";
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum TargetBuildKind {
|
pub enum TargetBuildKind {
|
||||||
@@ -45,6 +48,154 @@ pub(crate) struct InstallDirs {
|
|||||||
pub infodir: String,
|
pub infodir: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub(crate) struct BuildHelperContext {
|
||||||
|
pub package_name: String,
|
||||||
|
pub package_version: String,
|
||||||
|
pub spec_dir: PathBuf,
|
||||||
|
pub flags: BuildFlags,
|
||||||
|
pub lib32_variant: bool,
|
||||||
|
pub host_build_dir: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuildHelperContext {
|
||||||
|
pub(crate) fn from_spec(spec: &PackageSpec) -> Self {
|
||||||
|
Self {
|
||||||
|
package_name: spec.package.name.clone(),
|
||||||
|
package_version: spec.package.version.clone(),
|
||||||
|
spec_dir: spec.spec_dir.clone(),
|
||||||
|
flags: spec.build.flags.clone(),
|
||||||
|
lib32_variant: spec.build.flags.lib32_variant,
|
||||||
|
host_build_dir: spec.build.flags.host_build_dir.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn expand_vars(&self, input: &str) -> String {
|
||||||
|
let specdir = self.spec_dir.to_string_lossy();
|
||||||
|
input
|
||||||
|
.replace("$name", &self.package_name)
|
||||||
|
.replace("$version", &self.package_version)
|
||||||
|
.replace("$specdir", &specdir)
|
||||||
|
.replace("$DEPOT_SPECDIR", &specdir)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn build_flags(&self) -> BuildFlags {
|
||||||
|
let mut flags = self.flags.clone();
|
||||||
|
flags.lib32_variant = self.lib32_variant;
|
||||||
|
flags.host_build_dir = self.host_build_dir.clone();
|
||||||
|
flags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn apply_build_helper_context_env(
|
||||||
|
env_vars: &mut EnvVars,
|
||||||
|
spec: &PackageSpec,
|
||||||
|
) -> Result<()> {
|
||||||
|
let encoded = toml::to_string(&BuildHelperContext::from_spec(spec))
|
||||||
|
.context("Failed to serialize build helper context")?;
|
||||||
|
set_env_var(env_vars, DEPOT_BUILD_HELPER_CONTEXT_ENV, encoded);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn apply_build_helper_dirs_env(
|
||||||
|
env_vars: &mut EnvVars,
|
||||||
|
source_dir: Option<&Path>,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
) {
|
||||||
|
if let Some(source_dir) = source_dir {
|
||||||
|
set_env_var(
|
||||||
|
env_vars,
|
||||||
|
DEPOT_BUILD_HELPER_SOURCE_DIR_ENV,
|
||||||
|
source_dir.to_string_lossy().into_owned(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if let Some(build_dir) = build_dir {
|
||||||
|
set_env_var(
|
||||||
|
env_vars,
|
||||||
|
DEPOT_BUILD_HELPER_BUILD_DIR_ENV,
|
||||||
|
build_dir.to_string_lossy().into_owned(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_autotools_helper_configure(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
source_dir: Option<&Path>,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
cross: Option<&CrossConfig>,
|
||||||
|
env_vars: &EnvVars,
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
autotools::run_helper_configure(context, source_dir, build_dir, cross, env_vars, extra_args)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_autotools_helper_install(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
env_vars: &EnvVars,
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
autotools::run_helper_install(context, build_dir, env_vars, extra_args)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_cmake_helper_configure(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
source_dir: Option<&Path>,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
cross: Option<&CrossConfig>,
|
||||||
|
env_vars: &EnvVars,
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
cmake::run_helper_configure(context, source_dir, build_dir, cross, env_vars, extra_args)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_cmake_helper_install(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
env_vars: &EnvVars,
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
cmake::run_helper_install(context, build_dir, env_vars, extra_args)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_meson_helper_configure(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
source_dir: Option<&Path>,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
cross: Option<&CrossConfig>,
|
||||||
|
env_vars: &EnvVars,
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
meson::run_helper_configure(context, source_dir, build_dir, cross, env_vars, extra_args)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_meson_helper_install(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
env_vars: &EnvVars,
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
meson::run_helper_install(context, build_dir, env_vars, extra_args)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_perl_helper_configure(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
source_dir: Option<&Path>,
|
||||||
|
env_vars: &EnvVars,
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
perl::run_helper_configure(context, source_dir, env_vars, extra_args)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_perl_helper_install(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
env_vars: &EnvVars,
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
perl::run_helper_install(context, build_dir, env_vars, extra_args)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_env_var(env_vars: &mut EnvVars, key: &str, value: impl Into<String>) {
|
pub fn set_env_var(env_vars: &mut EnvVars, key: &str, value: impl Into<String>) {
|
||||||
let value = value.into();
|
let value = value.into();
|
||||||
if let Some((_, existing)) = env_vars.iter_mut().find(|(k, _)| k == key) {
|
if let Some((_, existing)) = env_vars.iter_mut().find(|(k, _)| k == key) {
|
||||||
@@ -1353,6 +1504,17 @@ mod tests {
|
|||||||
assert_eq!(lib32_dirs.libexecdir, "/usr/lib32");
|
assert_eq!(lib32_dirs.libexecdir, "/usr/lib32");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_build_helper_context_restores_runtime_build_flags() {
|
||||||
|
let mut spec = mk_spec(Vec::new(), Vec::new());
|
||||||
|
spec.build.flags.lib32_variant = true;
|
||||||
|
spec.build.flags.host_build_dir = Some("/tmp/build-host".into());
|
||||||
|
|
||||||
|
let restored = BuildHelperContext::from_spec(&spec).build_flags();
|
||||||
|
assert!(restored.lib32_variant);
|
||||||
|
assert_eq!(restored.host_build_dir.as_deref(), Some("/tmp/build-host"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_install_dirs_respect_explicit_overrides_and_derived_defaults() {
|
fn test_install_dirs_respect_explicit_overrides_and_derived_defaults() {
|
||||||
let dirs = install_dirs(&BuildFlags {
|
let dirs = install_dirs(&BuildFlags {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
//! Perl MakeMaker build system (`perl Makefile.PL && make && make test && make install`)
|
//! Perl MakeMaker build system (`perl Makefile.PL && make && make test && make install`)
|
||||||
|
|
||||||
|
use crate::builder::BuildHelperContext;
|
||||||
use crate::builder::autotools;
|
use crate::builder::autotools;
|
||||||
use crate::builder::state::{BuildStep, StateTracker};
|
use crate::builder::state::{BuildStep, StateTracker};
|
||||||
use crate::cross::CrossConfig;
|
use crate::cross::CrossConfig;
|
||||||
@@ -261,6 +262,124 @@ pub fn build(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_helper_configure(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
source_dir: Option<&Path>,
|
||||||
|
env_vars: &[(String, String)],
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
let flags = context.build_flags();
|
||||||
|
let source_dir = source_dir
|
||||||
|
.map(Path::to_path_buf)
|
||||||
|
.unwrap_or(std::env::current_dir().context("Failed to determine current directory")?);
|
||||||
|
let configure_script = helper_configure_script(context, &source_dir);
|
||||||
|
let mut helper_env = env_vars.to_vec();
|
||||||
|
crate::builder::set_env_var(&mut helper_env, "PERL_MM_USE_DEFAULT", "1");
|
||||||
|
if !flags.rootfs.is_empty() && flags.rootfs != "/" {
|
||||||
|
crate::builder::set_env_var(
|
||||||
|
&mut helper_env,
|
||||||
|
"PKG_CONFIG_SYSROOT_DIR",
|
||||||
|
flags.rootfs.clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut configure_cmd =
|
||||||
|
Command::new(resolved_command_path("perl").unwrap_or_else(|| PathBuf::from("perl")));
|
||||||
|
configure_cmd.current_dir(&source_dir);
|
||||||
|
configure_cmd.arg(&configure_script);
|
||||||
|
if !has_assignment_prefix(&flags.configure, "INSTALLDIRS") {
|
||||||
|
configure_cmd.arg("INSTALLDIRS=vendor");
|
||||||
|
}
|
||||||
|
for arg in &flags.configure {
|
||||||
|
configure_cmd.arg(context.expand_vars(arg));
|
||||||
|
}
|
||||||
|
for arg in crate::builder::static_build_args_for(crate::package::BuildType::Perl, &flags)? {
|
||||||
|
configure_cmd.arg(arg);
|
||||||
|
}
|
||||||
|
for arg in extra_args {
|
||||||
|
configure_cmd.arg(context.expand_vars(arg));
|
||||||
|
}
|
||||||
|
crate::builder::prepare_tool_command(&mut configure_cmd, &helper_env);
|
||||||
|
|
||||||
|
let status = command_status_with_sh_fallback(&mut configure_cmd)
|
||||||
|
.context("Failed to run helper perl configure")?;
|
||||||
|
if !status.success() {
|
||||||
|
anyhow::bail!("perl Makefile.PL failed with status: {}", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_helper_install(
|
||||||
|
context: &BuildHelperContext,
|
||||||
|
build_dir: Option<&Path>,
|
||||||
|
env_vars: &[(String, String)],
|
||||||
|
extra_args: &[String],
|
||||||
|
) -> Result<()> {
|
||||||
|
let flags = context.build_flags();
|
||||||
|
let build_dir = build_dir
|
||||||
|
.map(Path::to_path_buf)
|
||||||
|
.unwrap_or_else(helper_source_dir);
|
||||||
|
let destdir = std::env::var("DESTDIR").context("DESTDIR must be set for perl_install")?;
|
||||||
|
let make_exec = autotools::resolve_make_exec(&flags.make_exec);
|
||||||
|
let install_dirs = autotools::resolve_make_dirs(
|
||||||
|
&build_dir,
|
||||||
|
&flags.make_install_dirs,
|
||||||
|
"build.flags.make_install_dirs",
|
||||||
|
)?;
|
||||||
|
let install_targets = autotools::phase_targets(
|
||||||
|
&flags.make_install_target,
|
||||||
|
&flags.make_install_targets,
|
||||||
|
Some("install"),
|
||||||
|
);
|
||||||
|
|
||||||
|
for install_dir in install_dirs {
|
||||||
|
let mut install_cmd = fakeroot::wrap_install_command(make_exec, Path::new(&destdir));
|
||||||
|
install_cmd.current_dir(&install_dir);
|
||||||
|
if autotools::make_exec_supports_make_assignments(make_exec)
|
||||||
|
&& !autotools::has_make_variable_override(&flags.make_install_vars, "DESTDIR")
|
||||||
|
{
|
||||||
|
install_cmd.arg(format!("DESTDIR={destdir}"));
|
||||||
|
}
|
||||||
|
autotools::add_make_variable_overrides_if_supported(
|
||||||
|
&mut install_cmd,
|
||||||
|
make_exec,
|
||||||
|
&flags.make_install_vars,
|
||||||
|
"install",
|
||||||
|
)?;
|
||||||
|
for target in &install_targets {
|
||||||
|
install_cmd.arg(target);
|
||||||
|
}
|
||||||
|
for arg in extra_args {
|
||||||
|
install_cmd.arg(context.expand_vars(arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut install_env = env_vars.to_vec();
|
||||||
|
crate::builder::set_env_var(&mut install_env, "DESTDIR", destdir.clone());
|
||||||
|
crate::builder::prepare_tool_command(&mut install_cmd, &install_env);
|
||||||
|
|
||||||
|
let status = command_status_with_sh_fallback(&mut install_cmd).with_context(|| {
|
||||||
|
format!(
|
||||||
|
"Failed to run helper {} {} in {}",
|
||||||
|
make_exec,
|
||||||
|
install_targets.join(" "),
|
||||||
|
install_dir.display()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
if !status.success() {
|
||||||
|
anyhow::bail!(
|
||||||
|
"{} {} failed with status: {} (dir: {})",
|
||||||
|
make_exec,
|
||||||
|
install_targets.join(" "),
|
||||||
|
status,
|
||||||
|
install_dir.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_perl_configure_script(spec: &PackageSpec, actual_src: &Path) -> PathBuf {
|
fn resolve_perl_configure_script(spec: &PackageSpec, actual_src: &Path) -> PathBuf {
|
||||||
let configured = spec.expand_vars(&spec.build.flags.configure_file);
|
let configured = spec.expand_vars(&spec.build.flags.configure_file);
|
||||||
let trimmed = configured.trim();
|
let trimmed = configured.trim();
|
||||||
@@ -276,6 +395,22 @@ fn resolve_perl_configure_script(spec: &PackageSpec, actual_src: &Path) -> PathB
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn helper_configure_script(context: &BuildHelperContext, actual_src: &Path) -> PathBuf {
|
||||||
|
let flags = context.build_flags();
|
||||||
|
let configured = context.expand_vars(&flags.configure_file);
|
||||||
|
let trimmed = configured.trim();
|
||||||
|
if trimmed.is_empty() {
|
||||||
|
return actual_src.join("Makefile.PL");
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = Path::new(trimmed);
|
||||||
|
if path.is_absolute() {
|
||||||
|
path.to_path_buf()
|
||||||
|
} else {
|
||||||
|
actual_src.join(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn command_status_with_sh_fallback(cmd: &mut Command) -> std::io::Result<std::process::ExitStatus> {
|
fn command_status_with_sh_fallback(cmd: &mut Command) -> std::io::Result<std::process::ExitStatus> {
|
||||||
match crate::interrupts::command_status(cmd) {
|
match crate::interrupts::command_status(cmd) {
|
||||||
Ok(status) => Ok(status),
|
Ok(status) => Ok(status),
|
||||||
@@ -346,6 +481,12 @@ fn has_assignment_prefix(args: &[String], name: &str) -> bool {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn helper_source_dir() -> PathBuf {
|
||||||
|
std::env::var(crate::builder::DEPOT_BUILD_HELPER_SOURCE_DIR_ENV)
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.unwrap_or_else(|_| std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
+40
@@ -316,6 +316,46 @@ pub enum InternalCommands {
|
|||||||
},
|
},
|
||||||
#[command(hide = true)]
|
#[command(hide = true)]
|
||||||
Clone { repo: String, dest: Option<PathBuf> },
|
Clone { repo: String, dest: Option<PathBuf> },
|
||||||
|
#[command(hide = true)]
|
||||||
|
AutotoolsConfigure {
|
||||||
|
#[arg(value_name = "ARG", num_args = 0.., allow_hyphen_values = true)]
|
||||||
|
args: Vec<String>,
|
||||||
|
},
|
||||||
|
#[command(hide = true)]
|
||||||
|
AutotoolsInstall {
|
||||||
|
#[arg(value_name = "ARG", num_args = 0.., allow_hyphen_values = true)]
|
||||||
|
args: Vec<String>,
|
||||||
|
},
|
||||||
|
#[command(hide = true)]
|
||||||
|
CmakeConfigure {
|
||||||
|
#[arg(value_name = "ARG", num_args = 0.., allow_hyphen_values = true)]
|
||||||
|
args: Vec<String>,
|
||||||
|
},
|
||||||
|
#[command(hide = true)]
|
||||||
|
CmakeInstall {
|
||||||
|
#[arg(value_name = "ARG", num_args = 0.., allow_hyphen_values = true)]
|
||||||
|
args: Vec<String>,
|
||||||
|
},
|
||||||
|
#[command(hide = true)]
|
||||||
|
MesonConfigure {
|
||||||
|
#[arg(value_name = "ARG", num_args = 0.., allow_hyphen_values = true)]
|
||||||
|
args: Vec<String>,
|
||||||
|
},
|
||||||
|
#[command(hide = true)]
|
||||||
|
MesonInstall {
|
||||||
|
#[arg(value_name = "ARG", num_args = 0.., allow_hyphen_values = true)]
|
||||||
|
args: Vec<String>,
|
||||||
|
},
|
||||||
|
#[command(hide = true)]
|
||||||
|
PerlConfigure {
|
||||||
|
#[arg(value_name = "ARG", num_args = 0.., allow_hyphen_values = true)]
|
||||||
|
args: Vec<String>,
|
||||||
|
},
|
||||||
|
#[command(hide = true)]
|
||||||
|
PerlInstall {
|
||||||
|
#[arg(value_name = "ARG", num_args = 0.., allow_hyphen_values = true)]
|
||||||
|
args: Vec<String>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Args)]
|
#[derive(Debug, Clone, Args)]
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::builder::BuildHelperContext;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
fn current_process_env_vars() -> Vec<(String, String)> {
|
fn current_process_env_vars() -> Vec<(String, String)> {
|
||||||
const ALLOWED_ENV_VARS: &[&str] = &[
|
const ALLOWED_ENV_VARS: &[&str] = &[
|
||||||
@@ -13,6 +15,10 @@ fn current_process_env_vars() -> Vec<(String, String)> {
|
|||||||
"CFLAGS",
|
"CFLAGS",
|
||||||
"CXX",
|
"CXX",
|
||||||
"CXXFLAGS",
|
"CXXFLAGS",
|
||||||
|
crate::builder::DEPOT_BUILD_HELPER_BUILD_DIR_ENV,
|
||||||
|
crate::builder::DEPOT_BUILD_HELPER_CONTEXT_ENV,
|
||||||
|
crate::builder::DEPOT_BUILD_HELPER_SOURCE_DIR_ENV,
|
||||||
|
crate::builder::DEPOT_BUILD_HOST_DIR_ENV,
|
||||||
"DEPOT_ROOTFS",
|
"DEPOT_ROOTFS",
|
||||||
"DEPOT_SPECDIR",
|
"DEPOT_SPECDIR",
|
||||||
"DESTDIR",
|
"DESTDIR",
|
||||||
@@ -41,6 +47,42 @@ fn current_process_env_vars() -> Vec<(String, String)> {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn current_build_helper_context() -> Result<BuildHelperContext> {
|
||||||
|
let raw = std::env::var(crate::builder::DEPOT_BUILD_HELPER_CONTEXT_ENV).with_context(|| {
|
||||||
|
format!(
|
||||||
|
"{} must be set for internal build helpers",
|
||||||
|
crate::builder::DEPOT_BUILD_HELPER_CONTEXT_ENV
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
toml::from_str(&raw).context("Failed to parse build helper context")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_helper_source_dir() -> Option<PathBuf> {
|
||||||
|
std::env::var(crate::builder::DEPOT_BUILD_HELPER_SOURCE_DIR_ENV)
|
||||||
|
.ok()
|
||||||
|
.map(PathBuf::from)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_helper_build_dir() -> Option<PathBuf> {
|
||||||
|
std::env::var(crate::builder::DEPOT_BUILD_HELPER_BUILD_DIR_ENV)
|
||||||
|
.ok()
|
||||||
|
.map(PathBuf::from)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_cross_config() -> Result<Option<crate::cross::CrossConfig>> {
|
||||||
|
let Some(prefix) = std::env::var("CROSS_PREFIX")
|
||||||
|
.ok()
|
||||||
|
.map(|value| value.trim().to_string())
|
||||||
|
.filter(|value| !value.is_empty())
|
||||||
|
else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
|
||||||
|
crate::cross::CrossConfig::from_prefix(&prefix)
|
||||||
|
.map(Some)
|
||||||
|
.with_context(|| format!("Failed to resolve cross-compilation tools for {}", prefix))
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn run_internal_command(command: InternalCommands) -> Result<()> {
|
pub(crate) fn run_internal_command(command: InternalCommands) -> Result<()> {
|
||||||
match command {
|
match command {
|
||||||
InternalCommands::PythonBuild {
|
InternalCommands::PythonBuild {
|
||||||
@@ -101,5 +143,219 @@ pub(crate) fn run_internal_command(command: InternalCommands) -> Result<()> {
|
|||||||
&[],
|
&[],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
InternalCommands::AutotoolsConfigure { args } => {
|
||||||
|
let env_vars = current_process_env_vars();
|
||||||
|
let context = current_build_helper_context()?;
|
||||||
|
let cross = current_cross_config()?;
|
||||||
|
crate::builder::run_autotools_helper_configure(
|
||||||
|
&context,
|
||||||
|
current_helper_source_dir().as_deref(),
|
||||||
|
current_helper_build_dir().as_deref(),
|
||||||
|
cross.as_ref(),
|
||||||
|
&env_vars,
|
||||||
|
&args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
InternalCommands::AutotoolsInstall { args } => {
|
||||||
|
let env_vars = current_process_env_vars();
|
||||||
|
let context = current_build_helper_context()?;
|
||||||
|
crate::builder::run_autotools_helper_install(
|
||||||
|
&context,
|
||||||
|
current_helper_build_dir().as_deref(),
|
||||||
|
&env_vars,
|
||||||
|
&args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
InternalCommands::CmakeConfigure { args } => {
|
||||||
|
let env_vars = current_process_env_vars();
|
||||||
|
let context = current_build_helper_context()?;
|
||||||
|
let cross = current_cross_config()?;
|
||||||
|
crate::builder::run_cmake_helper_configure(
|
||||||
|
&context,
|
||||||
|
current_helper_source_dir().as_deref(),
|
||||||
|
current_helper_build_dir().as_deref(),
|
||||||
|
cross.as_ref(),
|
||||||
|
&env_vars,
|
||||||
|
&args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
InternalCommands::CmakeInstall { args } => {
|
||||||
|
let env_vars = current_process_env_vars();
|
||||||
|
let context = current_build_helper_context()?;
|
||||||
|
crate::builder::run_cmake_helper_install(
|
||||||
|
&context,
|
||||||
|
current_helper_build_dir().as_deref(),
|
||||||
|
&env_vars,
|
||||||
|
&args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
InternalCommands::MesonConfigure { args } => {
|
||||||
|
let env_vars = current_process_env_vars();
|
||||||
|
let context = current_build_helper_context()?;
|
||||||
|
let cross = current_cross_config()?;
|
||||||
|
crate::builder::run_meson_helper_configure(
|
||||||
|
&context,
|
||||||
|
current_helper_source_dir().as_deref(),
|
||||||
|
current_helper_build_dir().as_deref(),
|
||||||
|
cross.as_ref(),
|
||||||
|
&env_vars,
|
||||||
|
&args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
InternalCommands::MesonInstall { args } => {
|
||||||
|
let env_vars = current_process_env_vars();
|
||||||
|
let context = current_build_helper_context()?;
|
||||||
|
crate::builder::run_meson_helper_install(
|
||||||
|
&context,
|
||||||
|
current_helper_build_dir().as_deref(),
|
||||||
|
&env_vars,
|
||||||
|
&args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
InternalCommands::PerlConfigure { args } => {
|
||||||
|
let env_vars = current_process_env_vars();
|
||||||
|
let context = current_build_helper_context()?;
|
||||||
|
crate::builder::run_perl_helper_configure(
|
||||||
|
&context,
|
||||||
|
current_helper_source_dir().as_deref(),
|
||||||
|
&env_vars,
|
||||||
|
&args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
InternalCommands::PerlInstall { args } => {
|
||||||
|
let env_vars = current_process_env_vars();
|
||||||
|
let context = current_build_helper_context()?;
|
||||||
|
crate::builder::run_perl_helper_install(
|
||||||
|
&context,
|
||||||
|
current_helper_build_dir().as_deref(),
|
||||||
|
&env_vars,
|
||||||
|
&args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::package::BuildFlags;
|
||||||
|
use crate::test_support::TestEnv;
|
||||||
|
use std::fs;
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
use tempfile::tempdir;
|
||||||
|
|
||||||
|
fn write_executable(path: &Path, contents: &str) -> Result<()> {
|
||||||
|
fs::write(path, contents).with_context(|| format!("Failed to write {}", path.display()))?;
|
||||||
|
let mut perms = fs::metadata(path)?.permissions();
|
||||||
|
perms.set_mode(0o755);
|
||||||
|
fs::set_permissions(path, perms)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn helper_context(flags: BuildFlags, spec_dir: &Path) -> BuildHelperContext {
|
||||||
|
BuildHelperContext {
|
||||||
|
package_name: "demo".into(),
|
||||||
|
package_version: "1.0".into(),
|
||||||
|
spec_dir: spec_dir.to_path_buf(),
|
||||||
|
flags,
|
||||||
|
lib32_variant: false,
|
||||||
|
host_build_dir: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn meson_configure_uses_build_helper_context_defaults() -> Result<()> {
|
||||||
|
let source = tempdir()?;
|
||||||
|
let tools = tempdir()?;
|
||||||
|
let log = tools.path().join("meson.log");
|
||||||
|
let flags = BuildFlags {
|
||||||
|
prefix: "/opt/demo".into(),
|
||||||
|
build_dir: Some("builddir".into()),
|
||||||
|
..BuildFlags::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
write_executable(
|
||||||
|
&tools.path().join("meson"),
|
||||||
|
&format!("#!/bin/sh\nprintf '%s\\n' \"$@\" > '{}'\n", log.display()),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let mut env = TestEnv::new();
|
||||||
|
env.set_var("PATH", tools.path());
|
||||||
|
env.set_var(
|
||||||
|
crate::builder::DEPOT_BUILD_HELPER_CONTEXT_ENV,
|
||||||
|
toml::to_string(&helper_context(flags, source.path()))?,
|
||||||
|
);
|
||||||
|
env.set_var(
|
||||||
|
crate::builder::DEPOT_BUILD_HELPER_SOURCE_DIR_ENV,
|
||||||
|
source.path(),
|
||||||
|
);
|
||||||
|
|
||||||
|
run_internal_command(InternalCommands::MesonConfigure {
|
||||||
|
args: vec!["-Dfeature=enabled".into()],
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let output = fs::read_to_string(&log)?;
|
||||||
|
assert!(output.contains("setup"));
|
||||||
|
assert!(output.contains("--prefix=/opt/demo"));
|
||||||
|
assert!(output.contains("--buildtype=release"));
|
||||||
|
assert!(output.contains("-Dfeature=enabled"));
|
||||||
|
assert!(output.contains(source.path().join("builddir").to_string_lossy().as_ref()));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cmake_install_uses_fakeroot_and_destdir() -> Result<()> {
|
||||||
|
let source = tempdir()?;
|
||||||
|
let build_dir = source.path().join("build");
|
||||||
|
let tools = tempdir()?;
|
||||||
|
let fakeroot_log = tools.path().join("fakeroot.log");
|
||||||
|
let cmake_log = tools.path().join("cmake.log");
|
||||||
|
let destdir = source.path().join("dest");
|
||||||
|
fs::create_dir_all(&build_dir)?;
|
||||||
|
fs::create_dir_all(&destdir)?;
|
||||||
|
|
||||||
|
write_executable(
|
||||||
|
&tools.path().join("fakeroot"),
|
||||||
|
&format!(
|
||||||
|
"#!/bin/sh\nprintf '%s\\n' \"$@\" > '{}'\n[ \"$1\" = \"--\" ]\nshift\nexec \"$@\"\n",
|
||||||
|
fakeroot_log.display()
|
||||||
|
),
|
||||||
|
)?;
|
||||||
|
write_executable(
|
||||||
|
&tools.path().join("cmake"),
|
||||||
|
&format!(
|
||||||
|
"#!/bin/sh\n{{ printf 'DESTDIR=%s\\n' \"$DESTDIR\"; printf '%s\\n' \"$@\"; }} > '{}'\n",
|
||||||
|
cmake_log.display()
|
||||||
|
),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let mut env = TestEnv::new();
|
||||||
|
env.set_var("PATH", tools.path());
|
||||||
|
env.set_var("DESTDIR", &destdir);
|
||||||
|
env.set_var(
|
||||||
|
crate::builder::DEPOT_BUILD_HELPER_CONTEXT_ENV,
|
||||||
|
toml::to_string(&helper_context(BuildFlags::default(), source.path()))?,
|
||||||
|
);
|
||||||
|
env.set_var(
|
||||||
|
crate::builder::DEPOT_BUILD_HELPER_SOURCE_DIR_ENV,
|
||||||
|
source.path(),
|
||||||
|
);
|
||||||
|
env.set_var(crate::builder::DEPOT_BUILD_HELPER_BUILD_DIR_ENV, &build_dir);
|
||||||
|
|
||||||
|
run_internal_command(InternalCommands::CmakeInstall {
|
||||||
|
args: vec!["--component".into(), "runtime".into()],
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let fakeroot_output = fs::read_to_string(&fakeroot_log)?;
|
||||||
|
assert!(fakeroot_output.contains("--"));
|
||||||
|
assert!(fakeroot_output.contains("cmake"));
|
||||||
|
|
||||||
|
let cmake_output = fs::read_to_string(&cmake_log)?;
|
||||||
|
assert!(cmake_output.contains(&format!("DESTDIR={}", destdir.display())));
|
||||||
|
assert!(cmake_output.contains("--install"));
|
||||||
|
assert!(cmake_output.contains(build_dir.to_string_lossy().as_ref()));
|
||||||
|
assert!(cmake_output.contains("--component"));
|
||||||
|
assert!(cmake_output.contains("runtime"));
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-6
@@ -6,10 +6,16 @@ use crate::cli::{
|
|||||||
use crate::test_support::TestEnv;
|
use crate::test_support::TestEnv;
|
||||||
use git2::{Oid, Repository};
|
use git2::{Oid, Repository};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Mutex;
|
use std::sync::{Mutex, MutexGuard};
|
||||||
|
|
||||||
static ASSUME_YES_TEST_LOCK: Mutex<()> = Mutex::new(());
|
static ASSUME_YES_TEST_LOCK: Mutex<()> = Mutex::new(());
|
||||||
|
|
||||||
|
fn assume_yes_test_lock() -> MutexGuard<'static, ()> {
|
||||||
|
ASSUME_YES_TEST_LOCK
|
||||||
|
.lock()
|
||||||
|
.unwrap_or_else(|err| err.into_inner())
|
||||||
|
}
|
||||||
|
|
||||||
fn rootfs_args(rootfs: impl Into<PathBuf>) -> RootfsArgs {
|
fn rootfs_args(rootfs: impl Into<PathBuf>) -> RootfsArgs {
|
||||||
RootfsArgs {
|
RootfsArgs {
|
||||||
rootfs: rootfs.into(),
|
rootfs: rootfs.into(),
|
||||||
@@ -189,6 +195,16 @@ fn register_installed_test_package(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn register_required_development_package_if_configured(
|
||||||
|
config: &config::Config,
|
||||||
|
rootfs: &Path,
|
||||||
|
) -> Result<()> {
|
||||||
|
if let Some(package_name) = builder::requested_development_package() {
|
||||||
|
register_installed_test_package(config, rootfs, &package_name, "1.0.0")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn write_test_repo_spec(path: &Path, name: &str, version: &str) -> Result<()> {
|
fn write_test_repo_spec(path: &Path, name: &str, version: &str) -> Result<()> {
|
||||||
if let Some(parent) = path.parent() {
|
if let Some(parent) = path.parent() {
|
||||||
fs::create_dir_all(parent)?;
|
fs::create_dir_all(parent)?;
|
||||||
@@ -2216,7 +2232,7 @@ file = "missing.patch"
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn build_command_checks_manual_sources_before_dependency_resolution() -> Result<()> {
|
fn build_command_checks_manual_sources_before_dependency_resolution() -> Result<()> {
|
||||||
let _guard = ASSUME_YES_TEST_LOCK.lock().expect("assume-yes test lock");
|
let _guard = assume_yes_test_lock();
|
||||||
let temp = tempfile::tempdir().context("Failed to create temp dir")?;
|
let temp = tempfile::tempdir().context("Failed to create temp dir")?;
|
||||||
let rootfs = temp.path().join("rootfs");
|
let rootfs = temp.path().join("rootfs");
|
||||||
let spec_dir = temp.path().join("packages").join("demo");
|
let spec_dir = temp.path().join("packages").join("demo");
|
||||||
@@ -2534,7 +2550,7 @@ fn build_type_runs_automatic_tests_matches_builder_behavior() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn requested_test_deps_prompt_can_disable_tests() -> Result<()> {
|
fn requested_test_deps_prompt_can_disable_tests() -> Result<()> {
|
||||||
let _guard = ASSUME_YES_TEST_LOCK.lock().expect("assume-yes test lock");
|
let _guard = assume_yes_test_lock();
|
||||||
let mut spec = test_package_spec(package::BuildType::Meson, None, &[]);
|
let mut spec = test_package_spec(package::BuildType::Meson, None, &[]);
|
||||||
spec.dependencies.test = vec!["pytest".into()];
|
spec.dependencies.test = vec!["pytest".into()];
|
||||||
|
|
||||||
@@ -2553,7 +2569,7 @@ fn requested_test_deps_prompt_can_disable_tests() -> Result<()> {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn requested_test_deps_prompt_is_ignored_for_non_automatic_test_builders() -> Result<()> {
|
fn requested_test_deps_prompt_is_ignored_for_non_automatic_test_builders() -> Result<()> {
|
||||||
let _guard = ASSUME_YES_TEST_LOCK.lock().expect("assume-yes test lock");
|
let _guard = assume_yes_test_lock();
|
||||||
let mut spec = test_package_spec(package::BuildType::Custom, None, &[]);
|
let mut spec = test_package_spec(package::BuildType::Custom, None, &[]);
|
||||||
spec.dependencies.test = vec!["pytest".into()];
|
spec.dependencies.test = vec!["pytest".into()];
|
||||||
|
|
||||||
@@ -2572,7 +2588,7 @@ fn requested_test_deps_prompt_is_ignored_for_non_automatic_test_builders() -> Re
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn requested_test_deps_prompt_is_ignored_for_multilib_builds() -> Result<()> {
|
fn requested_test_deps_prompt_is_ignored_for_multilib_builds() -> Result<()> {
|
||||||
let _guard = ASSUME_YES_TEST_LOCK.lock().expect("assume-yes test lock");
|
let _guard = assume_yes_test_lock();
|
||||||
let mut spec = test_package_spec(package::BuildType::Meson, None, &[]);
|
let mut spec = test_package_spec(package::BuildType::Meson, None, &[]);
|
||||||
spec.build.flags.build_32 = true;
|
spec.build.flags.build_32 = true;
|
||||||
spec.dependencies.test = vec!["pytest".into()];
|
spec.dependencies.test = vec!["pytest".into()];
|
||||||
@@ -2777,7 +2793,7 @@ fn live_rootfs_child_install_batches_group_consecutive_binary_steps() -> Result<
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn build_command_requires_install_deps_flag_for_missing_dependencies() -> Result<()> {
|
fn build_command_requires_install_deps_flag_for_missing_dependencies() -> Result<()> {
|
||||||
let _guard = ASSUME_YES_TEST_LOCK.lock().expect("assume-yes test lock");
|
let _guard = assume_yes_test_lock();
|
||||||
let temp = tempfile::tempdir().context("Failed to create temp dir")?;
|
let temp = tempfile::tempdir().context("Failed to create temp dir")?;
|
||||||
let rootfs = temp.path().join("rootfs");
|
let rootfs = temp.path().join("rootfs");
|
||||||
let repo_root = temp.path().join("packages");
|
let repo_root = temp.path().join("packages");
|
||||||
@@ -2841,6 +2857,9 @@ optional = []
|
|||||||
)
|
)
|
||||||
.with_context(|| format!("Failed to write {}", dep_spec.display()))?;
|
.with_context(|| format!("Failed to write {}", dep_spec.display()))?;
|
||||||
|
|
||||||
|
let config = config::Config::for_rootfs(&rootfs);
|
||||||
|
register_required_development_package_if_configured(&config, &rootfs)?;
|
||||||
|
|
||||||
let result = run(Cli {
|
let result = run(Cli {
|
||||||
command: Commands::Build(BuildArgs {
|
command: Commands::Build(BuildArgs {
|
||||||
rootfs_args: rootfs_args(rootfs.clone()),
|
rootfs_args: rootfs_args(rootfs.clone()),
|
||||||
|
|||||||
+261
-87
@@ -15,6 +15,14 @@ const DEPOT_SUBDESTDIR_HELPER_ENV: &str = "DEPOT_SUBDESTDIR_HELPER";
|
|||||||
const DEPOT_PYTHON_BUILD_HELPER_ENV: &str = "DEPOT_PYTHON_BUILD_HELPER";
|
const DEPOT_PYTHON_BUILD_HELPER_ENV: &str = "DEPOT_PYTHON_BUILD_HELPER";
|
||||||
const DEPOT_PYTHON_INSTALL_HELPER_ENV: &str = "DEPOT_PYTHON_INSTALL_HELPER";
|
const DEPOT_PYTHON_INSTALL_HELPER_ENV: &str = "DEPOT_PYTHON_INSTALL_HELPER";
|
||||||
const DEPOT_CLONE_HELPER_ENV: &str = "DEPOT_CLONE_HELPER";
|
const DEPOT_CLONE_HELPER_ENV: &str = "DEPOT_CLONE_HELPER";
|
||||||
|
const DEPOT_AUTOTOOLS_CONFIGURE_HELPER_ENV: &str = "DEPOT_AUTOTOOLS_CONFIGURE_HELPER";
|
||||||
|
const DEPOT_AUTOTOOLS_INSTALL_HELPER_ENV: &str = "DEPOT_AUTOTOOLS_INSTALL_HELPER";
|
||||||
|
const DEPOT_CMAKE_CONFIGURE_HELPER_ENV: &str = "DEPOT_CMAKE_CONFIGURE_HELPER";
|
||||||
|
const DEPOT_CMAKE_INSTALL_HELPER_ENV: &str = "DEPOT_CMAKE_INSTALL_HELPER";
|
||||||
|
const DEPOT_MESON_CONFIGURE_HELPER_ENV: &str = "DEPOT_MESON_CONFIGURE_HELPER";
|
||||||
|
const DEPOT_MESON_INSTALL_HELPER_ENV: &str = "DEPOT_MESON_INSTALL_HELPER";
|
||||||
|
const DEPOT_PERL_CONFIGURE_HELPER_ENV: &str = "DEPOT_PERL_CONFIGURE_HELPER";
|
||||||
|
const DEPOT_PERL_INSTALL_HELPER_ENV: &str = "DEPOT_PERL_INSTALL_HELPER";
|
||||||
const DEPOT_EXECUTABLE_ENV: &str = "DEPOT_EXECUTABLE";
|
const DEPOT_EXECUTABLE_ENV: &str = "DEPOT_EXECUTABLE";
|
||||||
|
|
||||||
/// Ephemeral helper command directory to prepend to PATH while running scripts.
|
/// Ephemeral helper command directory to prepend to PATH while running scripts.
|
||||||
@@ -28,6 +36,14 @@ pub struct ShellHelpers {
|
|||||||
python_build_path: PathBuf,
|
python_build_path: PathBuf,
|
||||||
python_install_path: PathBuf,
|
python_install_path: PathBuf,
|
||||||
clone_path: PathBuf,
|
clone_path: PathBuf,
|
||||||
|
autotools_configure_path: PathBuf,
|
||||||
|
autotools_install_path: PathBuf,
|
||||||
|
cmake_configure_path: PathBuf,
|
||||||
|
cmake_install_path: PathBuf,
|
||||||
|
meson_configure_path: PathBuf,
|
||||||
|
meson_install_path: PathBuf,
|
||||||
|
perl_configure_path: PathBuf,
|
||||||
|
perl_install_path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShellHelpers {
|
impl ShellHelpers {
|
||||||
@@ -49,99 +65,43 @@ impl ShellHelpers {
|
|||||||
.context("Failed to locate depot executable for shell helpers")?;
|
.context("Failed to locate depot executable for shell helpers")?;
|
||||||
|
|
||||||
let haul_path = bin_dir.join("haul");
|
let haul_path = bin_dir.join("haul");
|
||||||
fs::write(&haul_path, HAUL_SCRIPT).with_context(|| {
|
write_helper_script(&haul_path, HAUL_SCRIPT)?;
|
||||||
format!(
|
|
||||||
"Failed to write shell helper command: {}",
|
|
||||||
haul_path.display()
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
use std::os::unix::fs::PermissionsExt;
|
|
||||||
let mut perms = fs::metadata(&haul_path)
|
|
||||||
.with_context(|| format!("Failed to stat helper: {}", haul_path.display()))?
|
|
||||||
.permissions();
|
|
||||||
perms.set_mode(0o755);
|
|
||||||
fs::set_permissions(&haul_path, perms)
|
|
||||||
.with_context(|| format!("Failed to chmod helper: {}", haul_path.display()))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let subdestdir_path = bin_dir.join("subdestdir");
|
let subdestdir_path = bin_dir.join("subdestdir");
|
||||||
fs::write(&subdestdir_path, SUBDESTDIR_SCRIPT).with_context(|| {
|
write_helper_script(&subdestdir_path, SUBDESTDIR_SCRIPT)?;
|
||||||
format!(
|
|
||||||
"Failed to write shell helper command: {}",
|
|
||||||
subdestdir_path.display()
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
use std::os::unix::fs::PermissionsExt;
|
|
||||||
let mut perms = fs::metadata(&subdestdir_path)
|
|
||||||
.with_context(|| format!("Failed to stat helper: {}", subdestdir_path.display()))?
|
|
||||||
.permissions();
|
|
||||||
perms.set_mode(0o755);
|
|
||||||
fs::set_permissions(&subdestdir_path, perms).with_context(|| {
|
|
||||||
format!("Failed to chmod helper: {}", subdestdir_path.display())
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let python_build_path = bin_dir.join("python_build");
|
let python_build_path = bin_dir.join("python_build");
|
||||||
fs::write(&python_build_path, PYTHON_BUILD_SCRIPT).with_context(|| {
|
write_helper_script(&python_build_path, PYTHON_BUILD_SCRIPT)?;
|
||||||
format!(
|
|
||||||
"Failed to write shell helper command: {}",
|
|
||||||
python_build_path.display()
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
use std::os::unix::fs::PermissionsExt;
|
|
||||||
let mut perms = fs::metadata(&python_build_path)
|
|
||||||
.with_context(|| format!("Failed to stat helper: {}", python_build_path.display()))?
|
|
||||||
.permissions();
|
|
||||||
perms.set_mode(0o755);
|
|
||||||
fs::set_permissions(&python_build_path, perms).with_context(|| {
|
|
||||||
format!("Failed to chmod helper: {}", python_build_path.display())
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let python_install_path = bin_dir.join("python_install");
|
let python_install_path = bin_dir.join("python_install");
|
||||||
fs::write(&python_install_path, PYTHON_INSTALL_SCRIPT).with_context(|| {
|
write_helper_script(&python_install_path, PYTHON_INSTALL_SCRIPT)?;
|
||||||
format!(
|
|
||||||
"Failed to write shell helper command: {}",
|
|
||||||
python_install_path.display()
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
use std::os::unix::fs::PermissionsExt;
|
|
||||||
let mut perms = fs::metadata(&python_install_path)
|
|
||||||
.with_context(|| {
|
|
||||||
format!("Failed to stat helper: {}", python_install_path.display())
|
|
||||||
})?
|
|
||||||
.permissions();
|
|
||||||
perms.set_mode(0o755);
|
|
||||||
fs::set_permissions(&python_install_path, perms).with_context(|| {
|
|
||||||
format!("Failed to chmod helper: {}", python_install_path.display())
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let clone_path = bin_dir.join("depot_clone");
|
let clone_path = bin_dir.join("depot_clone");
|
||||||
fs::write(&clone_path, CLONE_SCRIPT).with_context(|| {
|
write_helper_script(&clone_path, CLONE_SCRIPT)?;
|
||||||
format!(
|
|
||||||
"Failed to write shell helper command: {}",
|
let autotools_configure_path = bin_dir.join("autotools_configure");
|
||||||
clone_path.display()
|
write_helper_script(&autotools_configure_path, AUTOTOOLS_CONFIGURE_SCRIPT)?;
|
||||||
)
|
|
||||||
})?;
|
let autotools_install_path = bin_dir.join("autotools_install");
|
||||||
#[cfg(unix)]
|
write_helper_script(&autotools_install_path, AUTOTOOLS_INSTALL_SCRIPT)?;
|
||||||
{
|
|
||||||
use std::os::unix::fs::PermissionsExt;
|
let cmake_configure_path = bin_dir.join("cmake_configure");
|
||||||
let mut perms = fs::metadata(&clone_path)
|
write_helper_script(&cmake_configure_path, CMAKE_CONFIGURE_SCRIPT)?;
|
||||||
.with_context(|| format!("Failed to stat helper: {}", clone_path.display()))?
|
|
||||||
.permissions();
|
let cmake_install_path = bin_dir.join("cmake_install");
|
||||||
perms.set_mode(0o755);
|
write_helper_script(&cmake_install_path, CMAKE_INSTALL_SCRIPT)?;
|
||||||
fs::set_permissions(&clone_path, perms)
|
|
||||||
.with_context(|| format!("Failed to chmod helper: {}", clone_path.display()))?;
|
let meson_configure_path = bin_dir.join("meson_configure");
|
||||||
}
|
write_helper_script(&meson_configure_path, MESON_CONFIGURE_SCRIPT)?;
|
||||||
|
|
||||||
|
let meson_install_path = bin_dir.join("meson_install");
|
||||||
|
write_helper_script(&meson_install_path, MESON_INSTALL_SCRIPT)?;
|
||||||
|
|
||||||
|
let perl_configure_path = bin_dir.join("perl_configure");
|
||||||
|
write_helper_script(&perl_configure_path, PERL_CONFIGURE_SCRIPT)?;
|
||||||
|
|
||||||
|
let perl_install_path = bin_dir.join("perl_install");
|
||||||
|
write_helper_script(&perl_install_path, PERL_INSTALL_SCRIPT)?;
|
||||||
|
|
||||||
let path_value = crate::runtime_env::prepend_helper_to_safe_path(&bin_dir);
|
let path_value = crate::runtime_env::prepend_helper_to_safe_path(&bin_dir);
|
||||||
|
|
||||||
@@ -155,6 +115,14 @@ impl ShellHelpers {
|
|||||||
python_build_path,
|
python_build_path,
|
||||||
python_install_path,
|
python_install_path,
|
||||||
clone_path,
|
clone_path,
|
||||||
|
autotools_configure_path,
|
||||||
|
autotools_install_path,
|
||||||
|
cmake_configure_path,
|
||||||
|
cmake_install_path,
|
||||||
|
meson_configure_path,
|
||||||
|
meson_install_path,
|
||||||
|
perl_configure_path,
|
||||||
|
perl_install_path,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,6 +160,46 @@ impl ShellHelpers {
|
|||||||
DEPOT_CLONE_HELPER_ENV,
|
DEPOT_CLONE_HELPER_ENV,
|
||||||
self.clone_path.to_string_lossy().into_owned(),
|
self.clone_path.to_string_lossy().into_owned(),
|
||||||
);
|
);
|
||||||
|
set_env_var(
|
||||||
|
env_vars,
|
||||||
|
DEPOT_AUTOTOOLS_CONFIGURE_HELPER_ENV,
|
||||||
|
self.autotools_configure_path.to_string_lossy().into_owned(),
|
||||||
|
);
|
||||||
|
set_env_var(
|
||||||
|
env_vars,
|
||||||
|
DEPOT_AUTOTOOLS_INSTALL_HELPER_ENV,
|
||||||
|
self.autotools_install_path.to_string_lossy().into_owned(),
|
||||||
|
);
|
||||||
|
set_env_var(
|
||||||
|
env_vars,
|
||||||
|
DEPOT_CMAKE_CONFIGURE_HELPER_ENV,
|
||||||
|
self.cmake_configure_path.to_string_lossy().into_owned(),
|
||||||
|
);
|
||||||
|
set_env_var(
|
||||||
|
env_vars,
|
||||||
|
DEPOT_CMAKE_INSTALL_HELPER_ENV,
|
||||||
|
self.cmake_install_path.to_string_lossy().into_owned(),
|
||||||
|
);
|
||||||
|
set_env_var(
|
||||||
|
env_vars,
|
||||||
|
DEPOT_MESON_CONFIGURE_HELPER_ENV,
|
||||||
|
self.meson_configure_path.to_string_lossy().into_owned(),
|
||||||
|
);
|
||||||
|
set_env_var(
|
||||||
|
env_vars,
|
||||||
|
DEPOT_MESON_INSTALL_HELPER_ENV,
|
||||||
|
self.meson_install_path.to_string_lossy().into_owned(),
|
||||||
|
);
|
||||||
|
set_env_var(
|
||||||
|
env_vars,
|
||||||
|
DEPOT_PERL_CONFIGURE_HELPER_ENV,
|
||||||
|
self.perl_configure_path.to_string_lossy().into_owned(),
|
||||||
|
);
|
||||||
|
set_env_var(
|
||||||
|
env_vars,
|
||||||
|
DEPOT_PERL_INSTALL_HELPER_ENV,
|
||||||
|
self.perl_install_path.to_string_lossy().into_owned(),
|
||||||
|
);
|
||||||
set_env_var(
|
set_env_var(
|
||||||
env_vars,
|
env_vars,
|
||||||
DEPOT_EXECUTABLE_ENV,
|
DEPOT_EXECUTABLE_ENV,
|
||||||
@@ -204,10 +212,26 @@ impl ShellHelpers {
|
|||||||
/// through `/bin/sh`, avoiding direct execution from mounts that may be `noexec`.
|
/// through `/bin/sh`, avoiding direct execution from mounts that may be `noexec`.
|
||||||
pub fn wrap_shell_command(command: &str) -> String {
|
pub fn wrap_shell_command(command: &str) -> String {
|
||||||
format!(
|
format!(
|
||||||
"haul() {{ /bin/sh \"${{{DEPOT_HAUL_HELPER_ENV}:?}}\" \"$@\"; }}\nsubdestdir() {{ /bin/sh \"${{{DEPOT_SUBDESTDIR_HELPER_ENV}:?}}\" \"$@\"; }}\npython_build() {{ /bin/sh \"${{{DEPOT_PYTHON_BUILD_HELPER_ENV}:?}}\" \"$@\"; }}\npython_install() {{ /bin/sh \"${{{DEPOT_PYTHON_INSTALL_HELPER_ENV}:?}}\" \"$@\"; }}\ndepot_clone() {{ /bin/sh \"${{{DEPOT_CLONE_HELPER_ENV}:?}}\" \"$@\"; }}\n{command}"
|
"haul() {{ /bin/sh \"${{{DEPOT_HAUL_HELPER_ENV}:?}}\" \"$@\"; }}\nsubdestdir() {{ /bin/sh \"${{{DEPOT_SUBDESTDIR_HELPER_ENV}:?}}\" \"$@\"; }}\npython_build() {{ /bin/sh \"${{{DEPOT_PYTHON_BUILD_HELPER_ENV}:?}}\" \"$@\"; }}\npython_install() {{ /bin/sh \"${{{DEPOT_PYTHON_INSTALL_HELPER_ENV}:?}}\" \"$@\"; }}\ndepot_clone() {{ /bin/sh \"${{{DEPOT_CLONE_HELPER_ENV}:?}}\" \"$@\"; }}\nautotools_configure() {{ /bin/sh \"${{{DEPOT_AUTOTOOLS_CONFIGURE_HELPER_ENV}:?}}\" \"$@\"; }}\nautotools_install() {{ /bin/sh \"${{{DEPOT_AUTOTOOLS_INSTALL_HELPER_ENV}:?}}\" \"$@\"; }}\ncmake_configure() {{ /bin/sh \"${{{DEPOT_CMAKE_CONFIGURE_HELPER_ENV}:?}}\" \"$@\"; }}\ncmake_install() {{ /bin/sh \"${{{DEPOT_CMAKE_INSTALL_HELPER_ENV}:?}}\" \"$@\"; }}\nmeson_configure() {{ /bin/sh \"${{{DEPOT_MESON_CONFIGURE_HELPER_ENV}:?}}\" \"$@\"; }}\nmeson_install() {{ /bin/sh \"${{{DEPOT_MESON_INSTALL_HELPER_ENV}:?}}\" \"$@\"; }}\nperl_configure() {{ /bin/sh \"${{{DEPOT_PERL_CONFIGURE_HELPER_ENV}:?}}\" \"$@\"; }}\nperl_install() {{ /bin/sh \"${{{DEPOT_PERL_INSTALL_HELPER_ENV}:?}}\" \"$@\"; }}\n{command}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn write_helper_script(path: &Path, content: &str) -> Result<()> {
|
||||||
|
fs::write(path, content)
|
||||||
|
.with_context(|| format!("Failed to write shell helper command: {}", path.display()))?;
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
let mut perms = fs::metadata(path)
|
||||||
|
.with_context(|| format!("Failed to stat helper: {}", path.display()))?
|
||||||
|
.permissions();
|
||||||
|
perms.set_mode(0o755);
|
||||||
|
fs::set_permissions(path, perms)
|
||||||
|
.with_context(|| format!("Failed to chmod helper: {}", path.display()))?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert a package name into a safe shell identifier suffix.
|
/// Convert a package name into a safe shell identifier suffix.
|
||||||
pub fn shell_ident_suffix(pkg_name: &str) -> String {
|
pub fn shell_ident_suffix(pkg_name: &str) -> String {
|
||||||
let mut out = String::with_capacity(pkg_name.len().max(1));
|
let mut out = String::with_capacity(pkg_name.len().max(1));
|
||||||
@@ -474,6 +498,114 @@ fail() {
|
|||||||
exec "$DEPOT_EXECUTABLE" internal clone "$@"
|
exec "$DEPOT_EXECUTABLE" internal clone "$@"
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
|
const AUTOTOOLS_CONFIGURE_SCRIPT: &str = r#"#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo "autotools_configure: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "${DEPOT_EXECUTABLE:-}" != "" ] || fail "DEPOT_EXECUTABLE is not set"
|
||||||
|
|
||||||
|
exec "$DEPOT_EXECUTABLE" internal autotools-configure "$@"
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const AUTOTOOLS_INSTALL_SCRIPT: &str = r#"#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo "autotools_install: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "${DEPOT_EXECUTABLE:-}" != "" ] || fail "DEPOT_EXECUTABLE is not set"
|
||||||
|
[ "${DESTDIR:-}" != "" ] || fail "DESTDIR is not set"
|
||||||
|
|
||||||
|
exec "$DEPOT_EXECUTABLE" internal autotools-install "$@"
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const CMAKE_CONFIGURE_SCRIPT: &str = r#"#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo "cmake_configure: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "${DEPOT_EXECUTABLE:-}" != "" ] || fail "DEPOT_EXECUTABLE is not set"
|
||||||
|
|
||||||
|
exec "$DEPOT_EXECUTABLE" internal cmake-configure "$@"
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const CMAKE_INSTALL_SCRIPT: &str = r#"#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo "cmake_install: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "${DEPOT_EXECUTABLE:-}" != "" ] || fail "DEPOT_EXECUTABLE is not set"
|
||||||
|
[ "${DESTDIR:-}" != "" ] || fail "DESTDIR is not set"
|
||||||
|
|
||||||
|
exec "$DEPOT_EXECUTABLE" internal cmake-install "$@"
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const MESON_CONFIGURE_SCRIPT: &str = r#"#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo "meson_configure: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "${DEPOT_EXECUTABLE:-}" != "" ] || fail "DEPOT_EXECUTABLE is not set"
|
||||||
|
|
||||||
|
exec "$DEPOT_EXECUTABLE" internal meson-configure "$@"
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const MESON_INSTALL_SCRIPT: &str = r#"#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo "meson_install: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "${DEPOT_EXECUTABLE:-}" != "" ] || fail "DEPOT_EXECUTABLE is not set"
|
||||||
|
[ "${DESTDIR:-}" != "" ] || fail "DESTDIR is not set"
|
||||||
|
|
||||||
|
exec "$DEPOT_EXECUTABLE" internal meson-install "$@"
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const PERL_CONFIGURE_SCRIPT: &str = r#"#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo "perl_configure: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "${DEPOT_EXECUTABLE:-}" != "" ] || fail "DEPOT_EXECUTABLE is not set"
|
||||||
|
|
||||||
|
exec "$DEPOT_EXECUTABLE" internal perl-configure "$@"
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const PERL_INSTALL_SCRIPT: &str = r#"#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo "perl_install: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "${DEPOT_EXECUTABLE:-}" != "" ] || fail "DEPOT_EXECUTABLE is not set"
|
||||||
|
[ "${DESTDIR:-}" != "" ] || fail "DESTDIR is not set"
|
||||||
|
|
||||||
|
exec "$DEPOT_EXECUTABLE" internal perl-install "$@"
|
||||||
|
"#;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{INTERNAL_DEPOT_DIR, ShellHelpers, shell_ident_suffix, wrap_shell_command};
|
use super::{INTERNAL_DEPOT_DIR, ShellHelpers, shell_ident_suffix, wrap_shell_command};
|
||||||
@@ -557,15 +689,57 @@ mod tests {
|
|||||||
.any(|(key, _)| key == "DEPOT_PYTHON_INSTALL_HELPER")
|
.any(|(key, _)| key == "DEPOT_PYTHON_INSTALL_HELPER")
|
||||||
);
|
);
|
||||||
assert!(envs.iter().any(|(key, _)| key == "DEPOT_CLONE_HELPER"));
|
assert!(envs.iter().any(|(key, _)| key == "DEPOT_CLONE_HELPER"));
|
||||||
|
assert!(
|
||||||
|
envs.iter()
|
||||||
|
.any(|(key, _)| key == "DEPOT_AUTOTOOLS_CONFIGURE_HELPER")
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
envs.iter()
|
||||||
|
.any(|(key, _)| key == "DEPOT_AUTOTOOLS_INSTALL_HELPER")
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
envs.iter()
|
||||||
|
.any(|(key, _)| key == "DEPOT_CMAKE_CONFIGURE_HELPER")
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
envs.iter()
|
||||||
|
.any(|(key, _)| key == "DEPOT_CMAKE_INSTALL_HELPER")
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
envs.iter()
|
||||||
|
.any(|(key, _)| key == "DEPOT_MESON_CONFIGURE_HELPER")
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
envs.iter()
|
||||||
|
.any(|(key, _)| key == "DEPOT_MESON_INSTALL_HELPER")
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
envs.iter()
|
||||||
|
.any(|(key, _)| key == "DEPOT_PERL_CONFIGURE_HELPER")
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
envs.iter()
|
||||||
|
.any(|(key, _)| key == "DEPOT_PERL_INSTALL_HELPER")
|
||||||
|
);
|
||||||
assert!(envs.iter().any(|(key, _)| key == "DEPOT_EXECUTABLE"));
|
assert!(envs.iter().any(|(key, _)| key == "DEPOT_EXECUTABLE"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn wrap_shell_command_exposes_python_helpers() {
|
fn wrap_shell_command_exposes_python_helpers() {
|
||||||
let wrapped = wrap_shell_command("python_build\npython_install\ndepot_clone foo");
|
let wrapped = wrap_shell_command(
|
||||||
|
"python_build\npython_install\ndepot_clone foo\nmeson_configure\ncmake_install",
|
||||||
|
);
|
||||||
assert!(wrapped.contains("python_build()"));
|
assert!(wrapped.contains("python_build()"));
|
||||||
assert!(wrapped.contains("python_install()"));
|
assert!(wrapped.contains("python_install()"));
|
||||||
assert!(wrapped.contains("depot_clone()"));
|
assert!(wrapped.contains("depot_clone()"));
|
||||||
|
assert!(wrapped.contains("autotools_configure()"));
|
||||||
|
assert!(wrapped.contains("autotools_install()"));
|
||||||
|
assert!(wrapped.contains("cmake_configure()"));
|
||||||
|
assert!(wrapped.contains("cmake_install()"));
|
||||||
|
assert!(wrapped.contains("meson_configure()"));
|
||||||
|
assert!(wrapped.contains("meson_install()"));
|
||||||
|
assert!(wrapped.contains("perl_configure()"));
|
||||||
|
assert!(wrapped.contains("perl_install()"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
+7
-4
@@ -13,9 +13,12 @@ use crate::builder::state::{BuildStep, StateTracker};
|
|||||||
fn hook_env_vars(
|
fn hook_env_vars(
|
||||||
spec: &PackageSpec,
|
spec: &PackageSpec,
|
||||||
shell_helpers: &crate::shell_helpers::ShellHelpers,
|
shell_helpers: &crate::shell_helpers::ShellHelpers,
|
||||||
|
source_dir: &Path,
|
||||||
) -> Result<crate::builder::EnvVars> {
|
) -> Result<crate::builder::EnvVars> {
|
||||||
let mut env_vars = crate::builder::standard_build_env(spec, None, true, true);
|
let mut env_vars = crate::builder::standard_build_env(spec, None, true, true);
|
||||||
shell_helpers.apply_to_env_vars(&mut env_vars);
|
shell_helpers.apply_to_env_vars(&mut env_vars);
|
||||||
|
crate::builder::apply_build_helper_context_env(&mut env_vars, spec)?;
|
||||||
|
crate::builder::apply_build_helper_dirs_env(&mut env_vars, Some(source_dir), None);
|
||||||
Ok(env_vars)
|
Ok(env_vars)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +99,7 @@ fn run_post_extract_commands(spec: &PackageSpec, source: &Source, src_dir: &Path
|
|||||||
);
|
);
|
||||||
let helper_root = tempfile::tempdir().context("Failed to create post-extract helper root")?;
|
let helper_root = tempfile::tempdir().context("Failed to create post-extract helper root")?;
|
||||||
let shell_helpers = crate::shell_helpers::ShellHelpers::new(helper_root.path())?;
|
let shell_helpers = crate::shell_helpers::ShellHelpers::new(helper_root.path())?;
|
||||||
let env_vars = hook_env_vars(spec, &shell_helpers)?;
|
let env_vars = hook_env_vars(spec, &shell_helpers, src_dir)?;
|
||||||
|
|
||||||
for cmd in &source.post_extract {
|
for cmd in &source.post_extract {
|
||||||
let cmd_str = spec.expand_vars(cmd);
|
let cmd_str = spec.expand_vars(cmd);
|
||||||
@@ -132,7 +135,7 @@ pub fn run_post_configure_commands(
|
|||||||
|
|
||||||
crate::log_info!("Running {} post-configure command(s)...", commands.len());
|
crate::log_info!("Running {} post-configure command(s)...", commands.len());
|
||||||
let shell_helpers = crate::shell_helpers::ShellHelpers::new(destdir)?;
|
let shell_helpers = crate::shell_helpers::ShellHelpers::new(destdir)?;
|
||||||
let mut env_vars = hook_env_vars(spec, &shell_helpers)?;
|
let mut env_vars = hook_env_vars(spec, &shell_helpers, src_dir)?;
|
||||||
crate::builder::set_env_var(
|
crate::builder::set_env_var(
|
||||||
&mut env_vars,
|
&mut env_vars,
|
||||||
"DESTDIR",
|
"DESTDIR",
|
||||||
@@ -168,7 +171,7 @@ pub fn run_post_compile_commands(spec: &PackageSpec, src_dir: &Path, destdir: &P
|
|||||||
|
|
||||||
crate::log_info!("Running {} post-compile command(s)...", commands.len());
|
crate::log_info!("Running {} post-compile command(s)...", commands.len());
|
||||||
let shell_helpers = crate::shell_helpers::ShellHelpers::new(destdir)?;
|
let shell_helpers = crate::shell_helpers::ShellHelpers::new(destdir)?;
|
||||||
let mut env_vars = hook_env_vars(spec, &shell_helpers)?;
|
let mut env_vars = hook_env_vars(spec, &shell_helpers, src_dir)?;
|
||||||
crate::builder::set_env_var(
|
crate::builder::set_env_var(
|
||||||
&mut env_vars,
|
&mut env_vars,
|
||||||
"DESTDIR",
|
"DESTDIR",
|
||||||
@@ -208,7 +211,7 @@ pub fn run_post_install_commands_in_dir(
|
|||||||
|
|
||||||
crate::log_info!("Running {} post-install command(s)...", commands.len());
|
crate::log_info!("Running {} post-install command(s)...", commands.len());
|
||||||
let shell_helpers = crate::shell_helpers::ShellHelpers::new(destdir)?;
|
let shell_helpers = crate::shell_helpers::ShellHelpers::new(destdir)?;
|
||||||
let mut env_vars = hook_env_vars(spec, &shell_helpers)?;
|
let mut env_vars = hook_env_vars(spec, &shell_helpers, work_dir)?;
|
||||||
crate::builder::set_env_var(
|
crate::builder::set_env_var(
|
||||||
&mut env_vars,
|
&mut env_vars,
|
||||||
"DESTDIR",
|
"DESTDIR",
|
||||||
|
|||||||
Reference in New Issue
Block a user