Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 80 additions & 1 deletion pyoxidizer/src/project_building.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,27 @@ pub fn build_python_executable<'a>(
.context("resolving Rust toolchain")?
.cargo_exe;

build_python_executable_temp(
env,
bin_name,
exe,
target_triple,
opt_level,
release,
cargo_exe,
)

}

fn build_python_executable_temp<'a>(
env: &Environment,
bin_name: &str,
exe: &'a (dyn PythonBinaryBuilder + 'a),
target_triple: &str,
opt_level: &str,
release: bool,
cargo_exe: PathBuf,
)->Result<BuiltExecutable<'a>>{
let temp_dir = env.temporary_directory("pyoxidizer")?;

// Directory needs to have name of project.
Expand Down Expand Up @@ -467,8 +488,66 @@ pub fn build_python_executable<'a>(
build.exe_path = None;

temp_dir.close().context("closing temporary directory")?;
Ok(build)
}
/// Build a Python executable with local or init Rust project.
///
/// Returns the binary data constituting the built executable.
pub fn build_python_executable_local<'a>(
env: &Environment,
bin_name: &str,
exe: &'a (dyn PythonBinaryBuilder + 'a),
target_triple: &str,
opt_level: &str,
release: bool,
cwd: PathBuf,
) -> Result<BuiltExecutable<'a>> {
let cargo_exe = env
.ensure_rust_toolchain(Some(target_triple))
.context("resolving Rust toolchain")?
.cargo_exe;

Ok(build)
let toml = cwd.join("Cargo.toml");

if toml.exists() {
let project_path = cwd.clone();
let build_path = cwd.join("build");
let artifacts_path = cwd.join("artifacts");
let mut build = build_executable_with_rust_project(
env,
&project_path,
bin_name,
exe,
&build_path,
&artifacts_path,
target_triple,
opt_level,
release,
// Always build with locked because we crated a Cargo.lock with the
// Rust project we just created.
true,
// Don't include license for self because the Rust project is temporary and its
// licensing isn't material.
false,
)
.context("building executable with Rust project")?;

// Blank out the path since it is in the temporary directory.
build.exe_path = None;

Ok(build)
} else {
build_python_executable_temp(
env,
bin_name,
exe,
target_triple,
opt_level,
release,
cargo_exe,
)
}

}

/// Build artifacts needed by the pyembed crate.
Expand Down
7 changes: 4 additions & 3 deletions pyoxidizer/src/starlark/file_resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use {
python_package_resource::PythonPackageResourceValue,
},
crate::{
project_building::build_python_executable,
project_building::build_python_executable_local,
py_packaging::{binary::PythonBinaryBuilder, resource::AddToFileManifest},
},
anyhow::{anyhow, Context, Result},
Expand All @@ -29,7 +29,7 @@ use {
starlark_signature_extraction, starlark_signatures,
},
},
std::{ops::DerefMut, path::Path},
std::{ops::DerefMut, path::{Path,PathBuf}},
tugger::starlark::file_manifest::FileManifestValue,
};

Expand All @@ -42,10 +42,11 @@ pub fn file_manifest_add_python_executable(
target: &str,
release: bool,
opt_level: &str,
cwd: PathBuf,
) -> Result<()> {
const LABEL: &str = "FileManifest.add_python_executable()";

let build = build_python_executable(env, &exe.name(), exe, target, opt_level, release)
let build = build_python_executable_local(env, &exe.name(), exe, target, opt_level, release,cwd)
.context("building Python executable")?;

let content = FileEntry::new_from_data(build.exe_data.clone(), true);
Expand Down
12 changes: 7 additions & 5 deletions pyoxidizer/src/starlark/python_executable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use {
},
crate::{
licensing::licenses_from_cargo_manifest,
project_building::build_python_executable,
project_building::build_python_executable_local,
py_packaging::binary::PythonBinaryBuilder,
py_packaging::binary::{PackedResourcesLoadMode, WindowsRuntimeDllsMode},
},
Expand Down Expand Up @@ -82,15 +82,16 @@ pub fn build_internal(
target: &str,
context: &PyOxidizerEnvironmentContext,
) -> Result<(ResolvedTarget, PathBuf)> {
// Build an executable by writing out a temporary Rust project
// and building it.
let build = build_python_executable(
// Build an executable if can't find local toml file
// will writing out a temporary Rust project and building it.
let build = build_python_executable_local(
context.env(),
&exe.name(),
&**exe,
&context.build_target_triple,
&context.build_opt_level,
context.build_release,
context.cwd.clone(),
)
.context("building Python executable")?;

Expand Down Expand Up @@ -827,7 +828,7 @@ impl PythonExecutableValue {
/// PythonExecutable.to_file_manifest(prefix)
pub fn to_file_manifest(&self, type_values: &TypeValues, prefix: String) -> ValueResult {
const LABEL: &str = "PythonExecutable.to_file_manifest()";

let pyoxidizer_context_value = get_context(type_values)?;
let pyoxidizer_context = pyoxidizer_context_value
.downcast_ref::<PyOxidizerEnvironmentContext>()
Expand All @@ -850,6 +851,7 @@ impl PythonExecutableValue {
&pyoxidizer_context.build_target_triple,
pyoxidizer_context.build_release,
&pyoxidizer_context.build_opt_level,
pyoxidizer_context.cwd.clone(),
)
.context("adding PythonExecutable to FileManifest")
})?;
Expand Down