From b2d235531629be7e0c07107436e7a26a1e57df40 Mon Sep 17 00:00:00 2001 From: Kyle Lacy Date: Thu, 11 Jul 2024 01:02:39 -0700 Subject: [PATCH] Add `extraRuntimeLibraryPaths` option to autowrap --- crates/brioche-autowrap/src/lib.rs | 17 ++++++++++++- crates/brioche-ld/src/main.rs | 1 + .../brioche-packer/src/autowrap_template.rs | 24 +++++++++++++++++-- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/crates/brioche-autowrap/src/lib.rs b/crates/brioche-autowrap/src/lib.rs index 2494f3f..d455050 100644 --- a/crates/brioche-autowrap/src/lib.rs +++ b/crates/brioche-autowrap/src/lib.rs @@ -40,6 +40,7 @@ pub struct DynamicLinkingConfig { #[derive(Debug, Clone)] pub struct DynamicBinaryConfig { pub packed_executable: PathBuf, + pub extra_runtime_library_paths: Vec, pub dynamic_linking: DynamicLinkingConfig, } @@ -262,6 +263,10 @@ fn autowrap_dynamic_binary( return Ok(false); }; + let output_path_parent = output_path + .parent() + .ok_or_eyre("could not get parent of output path")?; + let contents = std::fs::read(source_path)?; let program_object = goblin::Object::parse(&contents)?; @@ -336,11 +341,21 @@ fn autowrap_dynamic_binary( .map_err(|_| eyre::eyre!("invalid UTF-8 in path")) }) .collect::>>()?; + let runtime_library_dirs = dynamic_binary_config + .extra_runtime_library_paths + .iter() + .map(|path| { + let path = pathdiff::diff_paths(path, output_path_parent).ok_or_else(|| eyre::eyre!("failed to get relative path from output path {output_path_parent:?} to runtime library path {path:?}"))?; + >::from_path_buf(path) + .map_err(|_| eyre::eyre!("invalid UTF-8 in path")) + }) + .collect::>>()?; + let pack = brioche_pack::Pack::LdLinux { program, interpreter, library_dirs, - runtime_library_dirs: vec![], + runtime_library_dirs, }; let packed_exec_path = &dynamic_binary_config.packed_executable; diff --git a/crates/brioche-ld/src/main.rs b/crates/brioche-ld/src/main.rs index 108a50e..4f57a5c 100644 --- a/crates/brioche-ld/src/main.rs +++ b/crates/brioche-ld/src/main.rs @@ -130,6 +130,7 @@ fn run() -> eyre::Result { link_dependencies: vec![ld_resource_dir], dynamic_binary: Some(brioche_autowrap::DynamicBinaryConfig { packed_executable: packed_path, + extra_runtime_library_paths: vec![], dynamic_linking: dynamic_linking_config.clone(), }), shared_library: Some(brioche_autowrap::SharedLibraryConfig { diff --git a/crates/brioche-packer/src/autowrap_template.rs b/crates/brioche-packer/src/autowrap_template.rs index 554c652..659bea7 100644 --- a/crates/brioche-packer/src/autowrap_template.rs +++ b/crates/brioche-packer/src/autowrap_template.rs @@ -1,6 +1,6 @@ use std::{ collections::{HashMap, HashSet}, - path::PathBuf, + path::{Path, PathBuf}, }; use bstr::ByteVec as _; @@ -72,7 +72,9 @@ impl AutowrapConfigTemplate { .into_iter() .map(|path| path.build(ctx)) .collect::>>()?; - let dynamic_binary = dynamic_binary.map(|opts| opts.build(ctx)).transpose()?; + let dynamic_binary = dynamic_binary + .map(|opts| opts.build(ctx, &recipe_path)) + .transpose()?; let shared_library = shared_library.map(|opts| opts.build(ctx)).transpose()?; let script = script.map(|opts| opts.build(ctx)).transpose()?; let rewrap = rewrap.map(|opts| opts.build()); @@ -163,6 +165,9 @@ impl DynamicLinkingConfigTemplate { pub struct DynamicBinaryConfigTemplate { packed_executable: TemplatePath, + #[serde(default)] + extra_runtime_library_paths: Vec, + #[serde(flatten)] dynamic_linking: DynamicLinkingConfigTemplate, } @@ -171,17 +176,32 @@ impl DynamicBinaryConfigTemplate { fn build( self, ctx: &AutowrapConfigTemplateContext, + recipe_path: &Path, ) -> eyre::Result { let Self { packed_executable, + extra_runtime_library_paths, dynamic_linking, } = self; let packed_executable = packed_executable.build(ctx)?; let dynamic_linking = dynamic_linking.build(ctx)?; + let extra_runtime_library_paths = extra_runtime_library_paths + .into_iter() + .map(|path| { + let path = recipe_path.join(path); + eyre::ensure!( + path.starts_with(recipe_path), + "path {path:?} is not relative to recipe path", + ); + eyre::Ok(path) + }) + .collect::>()?; + Ok(brioche_autowrap::DynamicBinaryConfig { packed_executable, + extra_runtime_library_paths, dynamic_linking, }) }