Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,13 @@ jobs:
for archive in dist/*.tar.gz; do
archive_basename=$(basename "$archive")
name=$(basename "$archive_basename" .tar.gz)
platform=$(tar -axf "$archive" "$name/README" -O | grep '^Platform: ' | cut -c 11-)
platform=$(tar -axf "$archive" "$name/README" -O | grep '^platform: ' | cut -c 11-)
archive_url="${{ github.server_url }}/${{ github.repository }}/releases/download/${{ github.ref_name }}/$archive_basename"
echo "- [$platform]($archive_url) [[sig]($archive_url.sig)]" >> dist/release-notes.md
done
for archive in dist/*.zip; do
archive_basename=$(basename "$archive")
platform=$(unzip -p "$archive" README | grep '^Platform: ' | cut -c 11-)
platform=$(unzip -p "$archive" README | grep '^platform: ' | cut -c 11-)
archive_url="${{ github.server_url }}/${{ github.repository }}/releases/download/${{ github.ref_name }}/$archive_basename"
echo "- [$platform]($archive_url) [[sig]($archive_url.sig)]" >> dist/release-notes.md
done
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jobs:

- name: Test (include ignored)
if: ${{ inputs.include-ignored }}
run: cargo test -- --include-ignored
run: cargo test --locked -- --include-ignored

- name: Doc
run: cargo doc --no-deps
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 13 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ resolver = "2"

[workspace.package]
edition = "2024"
version = "5.0.1"
version = "5.0.2"
authors = ["Théo Rozier <contact@theorozier.fr>"]
homepage = "https://github.com/mindstorm38/portablemc"
repository = "https://github.com/mindstorm38/portablemc"
Expand All @@ -14,7 +14,7 @@ readme = "README.md"
rust-version = "1.88.0"

[workspace.dependencies]
portablemc = { path = "portablemc", version = "=5.0.1" }
portablemc = { path = "portablemc", version = "=5.0.2" }

# Utils
thiserror = "2.0.3"
Expand Down Expand Up @@ -71,3 +71,14 @@ ctrlc = "3.4.5"
# Testing
tempfile = "3.19.1"
mockito = "1.7.1"

[profile.release]
opt-level = 3
strip = "debuginfo"
codegen-units = 4
lto = true

# Profile history:
# - Reducing codegen units from default (16) to 1 have reduced by 20% the size of
# the final binary (but LTO are disabled);
# - Increasing codegen units from 1 to 4 but set lto = true gave 10% improvement;
158 changes: 106 additions & 52 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::process::{Command, ExitCode};
use std::fmt::Write as _;
use std::ffi::{OsStr, OsString};
use std::path::Path;
use std::fs::File;
use std::{env, fs};
use std::fs::File;

use flate2::Compression;
use flate2::write::GzEncoder;
Expand All @@ -21,7 +22,7 @@ fn main() -> ExitCode {
["dist", target] => dist(Some(target)),
["dist"] => dist(None),
_ => {
eprintln!("usage: {} dist [target]", args[0]);
eprintln!("usage: {} dist", args[0]);
ExitCode::FAILURE
}
}
Expand All @@ -30,6 +31,23 @@ fn main() -> ExitCode {

fn dist(target: Option<&str>) -> ExitCode {

let mut cargo_env = vec![
OsString::from("OUT_DIR"),
OsString::from("CARGO"),
OsString::from("CARGO_MANIFEST_DIR"),
OsString::from("CARGO_MANIFEST_PATH"),
OsString::from("CARGO_CRATE_NAME"),
OsString::from("CARGO_PRIMARY_PACKAGE"),
OsString::from("CARGO_TARGET_TMPDIR"),
];

for (name, _val) in env::vars_os() {
if name.as_encoded_bytes().starts_with(b"CARGO_PKG_")
|| name.as_encoded_bytes().starts_with(b"CARGO_BIN_") {
cargo_env.push(name);
}
}

let xtask_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let root_dir = xtask_dir.parent().unwrap();
env::set_current_dir(&root_dir).unwrap();
Expand All @@ -49,6 +67,11 @@ fn dist(target: Option<&str>) -> ExitCode {
};
println!("Target dir: {}", target_dir.display());

let cargo_exec = Path::new(env!("CARGO"));
println!("Exec cargo: {cargo_exec:?}");
let rustc_exec = cargo_exec.parent().unwrap().join("rustc");
println!("Exec rustc: {rustc_exec:?}");

let version = env!("CARGO_PKG_VERSION");
let mut version_long = version.to_string();

Expand All @@ -63,7 +86,7 @@ fn dist(target: Option<&str>) -> ExitCode {
}

println!("Finding rustc version...");
let rustc_vv_output = Command::new("rustc")
let rustc_vv_output = Command::new(&rustc_exec)
.arg("-vV")
.output()
.unwrap();
Expand All @@ -87,43 +110,48 @@ fn dist(target: Option<&str>) -> ExitCode {
}

println!("Finding target spec...");
let mut cmd = Command::new("rustc");
cmd.args(["+nightly", "-Z", "unstable-options", "--print", "target-spec-json"]);
if let Some(target) = target {
cmd.args(["--target", target]);

println!(" Requested target: {target}");
write!(version_long, "\ntarget: {target}").unwrap();

let platform = match target {
"aarch64-apple-darwin" => "macOS (aarch64, 11.0+, Big Sur+)",
"x86_64-apple-darwin" => "macOS (x86_64, 10.12+, Sierra+)",
"x86_64-pc-windows-msvc" => "Windows (x86_64, MSVC, 10+, Server 2016+)",
"x86_64-pc-windows-gnu" => "Windows (x86_64, MinGW, 10+, Server 2016+)",
"i686-pc-windows-msvc" => "Windows (x86, MSVC, 10+, Server 2016+, Pentium 4)",
"i686-unknown-linux-gnu" => "Linux (x86, kernel 3.2+, glibc 2.17+, Pentium 4)",
"x86_64-unknown-linux-gnu" => "Linux (x86_64, kernel 3.2+, glibc 2.17+)",
"aarch64-unknown-linux-gnu" => "Linux (aarch64, kernel 4.1+, glibc 2.17+)",
"arm-unknown-linux-gnueabi" => "Linux (armv6, kernel 3.2+, glibc 2.17)",
"arm-unknown-linux-gnueabihf" => "Linux (armv6-hf, kernel 3.2+, glibc 2.17)",
_ => ""
};

if !platform.is_empty() {
println!(" Platform description: {platform}");
write!(version_long, "\nplatform: {platform}").unwrap();
}

} else {
println!(" Not found, skipped");
}
let target_spec_output = cmd.output().unwrap();
let target_spec = serde_json::from_slice::<serde_json::Value>(&target_spec_output.stdout).unwrap();
let target_llvm = target_spec
.get("llvm-target").unwrap()
.as_str().unwrap();
let target_platform = target_spec
.get("metadata").unwrap()
.get("description").unwrap()
.as_str().unwrap();
let target_os = target_spec
.get("os").unwrap()
.as_str().unwrap();
let target_arch = target_spec
.get("arch").unwrap()
.as_str().unwrap();

println!(" Found: {target_llvm} ({target_platform})");
write!(version_long, "\ntarget: {target_llvm}").unwrap();
write!(version_long, "\nplatform: {target_platform}").unwrap();


if let Ok(more) = env::var("PMC_VERSION_LONG") {
version_long.push('\n');
version_long.push_str(&more);
}

println!("Building release artifacts...");

// Reducing codegen units count have reduced by 20% the size of the final binary.
let mut cmd = Command::new("cargo");
cmd.env("PMC_VERSION_LONG", version_long);
cmd.env("RUSTFLAGS", "-Copt-level=3 -Cstrip=debuginfo -Ccodegen-units=1");
cmd.args(["build", "--release"]);
let mut cmd = Command::new(cargo_exec);
// We remove all the cargo env variables that are forwarded by "cargo run", so
// that no build script could mention a change in environment.
for cargo_var in cargo_env {
cmd.env_remove(&cargo_var);
}
cmd.env("PMC_VERSION_LONG", &version_long);
cmd.args(["--color", "always", "build", "--release"]);
if let Some(target) = target {
cmd.args(["--target", target]);
}
Expand All @@ -133,7 +161,27 @@ fn dist(target: Option<&str>) -> ExitCode {
}

println!("Building archive directory...");
let archive_name = format!("portablemc-{version}-{target_os}-{target_arch}");
let mut archive_name = format!("portablemc-{version}");
if let Some(target) = target {

let mut target_parts = target.splitn(4, "-");
let arch = target_parts.next().unwrap();
let vendor = target_parts.next().unwrap();
let sys = target_parts.next().unwrap();
let abi = target_parts.next();

let sys = match (vendor, sys) {
("apple", "darwin") => "macos",
(_, sys) => sys,
};

write!(archive_name, "-{sys}-{arch}").unwrap();
if let Some(abi) = abi {
write!(archive_name, "-{abi}").unwrap();
}

}

let archive_dir = dist_dir.join(&archive_name);
if archive_dir.exists() {
fs::remove_dir_all(&archive_dir).unwrap();
Expand All @@ -150,34 +198,40 @@ fn dist(target: Option<&str>) -> ExitCode {
fs::copy(root_dir.join("LICENSE"), archive_dir.join("LICENSE")).unwrap();

let mut readme = fs::read_to_string(xtask_dir.join("data/README")).unwrap();
writeln!(readme, "Version: {version}").unwrap();
writeln!(readme, "Target: {target_llvm}").unwrap();
writeln!(readme, "Platform: {target_platform}").unwrap();
writeln!(readme, "version: {version_long}").unwrap();
fs::write(archive_dir.join("README"), &readme).unwrap();

println!("Building archive...");
if cfg!(windows) {

let archive_file = dist_dir.join(format!("{archive_name}.zip"));
let archive_write = File::create(&archive_file).unwrap();
let mut archive_write = ZipWriter::new(archive_write);
archive_write.set_comment(readme);
if has_non_empty_var("PMC_NO_ARCHIVE") {
println!("Not building archive because PMC_NO_ARCHIVE is not empty.");
} else {
println!("Building archive...");
if cfg!(windows) {

let archive_file = dist_dir.join(format!("{archive_name}.zip"));
let archive_write = File::create(&archive_file).unwrap();
let mut archive_write = ZipWriter::new(archive_write);
archive_write.set_comment(readme);

let options = SimpleFileOptions::default()
.compression_method(CompressionMethod::Deflated);
let options = SimpleFileOptions::default()
.compression_method(CompressionMethod::Deflated);

archive_write.create_from_directory_with_options(&archive_dir, |_| options, &DefaultEntryHandler).unwrap();
archive_write.create_from_directory_with_options(&archive_dir, |_| options, &DefaultEntryHandler).unwrap();

} else {
} else {

let archive_file = dist_dir.join(format!("{archive_name}.tar.gz"));
let archive_write = File::create(&archive_file).unwrap();
let archive_write = GzEncoder::new(archive_write, Compression::default());
let mut archive_write = tar::Builder::new(archive_write);
archive_write.append_dir_all(archive_name, &archive_dir).unwrap();
let archive_file = dist_dir.join(format!("{archive_name}.tar.gz"));
let archive_write = File::create(&archive_file).unwrap();
let archive_write = GzEncoder::new(archive_write, Compression::default());
let mut archive_write = tar::Builder::new(archive_write);
archive_write.append_dir_all(archive_name, &archive_dir).unwrap();

}
}

ExitCode::SUCCESS

}

fn has_non_empty_var<S: AsRef<OsStr>>(name: S) -> bool {
env::var_os(name).is_some_and(|val| val.as_encoded_bytes() != b"")
}