diff --git a/pyoxidizer/src/project_building.rs b/pyoxidizer/src/project_building.rs index 13fbb7deb..82a015f24 100644 --- a/pyoxidizer/src/project_building.rs +++ b/pyoxidizer/src/project_building.rs @@ -4,7 +4,7 @@ use { crate::{ - environment::{canonicalize_path, Environment, RustEnvironment}, + environment::{Environment, RustEnvironment}, project_layout::initialize_project, py_packaging::{ binary::{LibpythonLinkMode, PythonBinaryBuilder}, @@ -17,6 +17,7 @@ use { duct::cmd, slog::warn, starlark_dialect_build_targets::ResolvedTarget, + starlark::values::Value, std::{ collections::HashMap, fs::create_dir_all, @@ -443,12 +444,6 @@ pub fn build_pyembed_artifacts( ) -> Result<()> { create_dir_all(artifacts_path)?; - let artifacts_path = canonicalize_path(artifacts_path)?; - - if artifacts_current(logger, config_path, &artifacts_path) { - return Ok(()); - } - let mut context: EvaluationContext = EvaluationContextBuilder::new( env, logger.clone(), @@ -462,6 +457,8 @@ pub fn build_pyembed_artifacts( .build_script_mode(true) .try_into()?; + context.set_var("_OUT_DIR", Value::from(artifacts_path.to_str().unwrap())).unwrap(); + context.eval("set_build_path(_OUT_DIR)")?; context.evaluate_file(config_path)?; // TODO should we honor only the specified target if one is given? @@ -471,25 +468,9 @@ pub fn build_pyembed_artifacts( // Presence of the generated default python config file implies this is a valid // artifacts directory. let default_python_config = resolved.output_path.join(DEFAULT_PYTHON_CONFIG_FILENAME); - if !default_python_config.exists() { - continue; - } - - for p in std::fs::read_dir(&resolved.output_path).context(format!( - "reading directory {}", - &resolved.output_path.display() - ))? { - let p = p?; - - let dest_path = artifacts_path.join(p.file_name()); - std::fs::copy(&p.path(), &dest_path).context(format!( - "copying {} to {}", - p.path().display(), - dest_path.display() - ))?; + if default_python_config.exists() { + return Ok(()); } - - return Ok(()); } Err(anyhow!( diff --git a/pyoxidizer/src/py_packaging/embedding.rs b/pyoxidizer/src/py_packaging/embedding.rs index 38b2d8522..02a155f44 100644 --- a/pyoxidizer/src/py_packaging/embedding.rs +++ b/pyoxidizer/src/py_packaging/embedding.rs @@ -349,6 +349,28 @@ impl<'a> EmbeddedPythonContext<'a> { Ok(()) } + /// Write an archive containing extra files. + pub fn write_extra_files(&self, dest_dir: impl AsRef) -> Result<()> { + let mut fh = std::fs::File::create(dest_dir.as_ref().join("extra_files.tar.zstd"))?; + let mut ar = tar::Builder::new(zstd::Encoder::new(fh, 0)?); + ar.mode(tar::HeaderMode::Deterministic); + for (path, e) in self.extra_files.iter_entries() { + if let Some(src) = e.file_data().backing_path() { + ar.append_path_with_name(src, path)?; + continue; + } + let b = e.resolve_content()?; + let mut h = tar::Header::new_gnu(); + h.set_size(b.len() as u64); + h.set_mode(if e.is_executable() { 0o755 } else { 0o644 }); + h.set_uid(0); + h.set_gid(0); + h.set_mtime(1153704088); + ar.append_data(&mut h, path, b.as_slice())?; + } + Ok(ar.into_inner()?.finish()?.sync_data()?) + } + /// Write out files needed to build a binary against our configuration. pub fn write_files(&self, dest_dir: &Path) -> Result<()> { self.write_packed_resources(&dest_dir) diff --git a/pyoxidizer/src/starlark/python_embedded_resources.rs b/pyoxidizer/src/starlark/python_embedded_resources.rs index 2483e2ca5..cb22bec7e 100644 --- a/pyoxidizer/src/starlark/python_embedded_resources.rs +++ b/pyoxidizer/src/starlark/python_embedded_resources.rs @@ -58,7 +58,7 @@ impl PythonEmbeddedResourcesValue { context: &PyOxidizerEnvironmentContext, ) -> Result { let output_path = context - .get_output_path(type_values, target) + .build_path(type_values) .map_err(|_| anyhow!("unable to resolve output path"))?; warn!( @@ -76,6 +76,7 @@ impl PythonEmbeddedResourcesValue { std::fs::create_dir_all(&output_path) .with_context(|| format!("creating output directory: {}", output_path.display()))?; embedded.write_files(&output_path)?; + embedded.write_extra_files(&output_path)?; Ok(ResolvedTarget { run_mode: RunMode::None,