Skip to content

Commit cc06563

Browse files
committed
Upload New Files
1 parent 4cb7776 commit cc06563

File tree

9 files changed

+66
-143
lines changed

9 files changed

+66
-143
lines changed

Cargo.lock

Lines changed: 1 addition & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
[package]
22
name = "Rex"
3-
version = "1.0.0"
3+
version = "1.1.0"
44
edition = "2024"
55

66
[dependencies]
77
clap = { version = "4.0", features = ["derive"] }
88
tar = "0.4"
99
zstd = "0.13"
1010
fs_extra = "1.3"
11-
xz2 = "0.1"
1211

1312
[profile.release]
1413
opt-level = "z"

README.md

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
2-
# Rex - Static Rust Executable Generator and Runtime
1+
<p align="center">
2+
<img src="logo.png" width="256">
3+
</p>
4+
5+
<h1 align="center">Rex - Static Rust Executable Generator and Runtime</h1>
36

47
**Rex** is a small Rust project that packs a target binary together with its
58
dynamic libraries, extra binaries and files into a single executable.
@@ -19,10 +22,10 @@ target program using a suitable loader (glibc or musl) when available.
1922
* `main.rs` — CLI entrypoint. Detects whether the executable is a runtime
2023
(contains a payload) or is being run as the builder. Uses `clap` for the CLI.
2124
* `generator.rs` — The packer/generator that creates the staging directory,
22-
copies binaries/libs/files, creates a tar and compresses it (zstd or xz),
25+
copies binaries/libs/files, creates a tar and compresses it (zstd),
2326
and appends the payload and metadata to the runtime executable.
2427
* `runtime.rs` — The runtime that scans the running executable for the metadata
25-
marker, extracts the payload to a temporary directory, adjusts environment
28+
marker extracts the payload to a temporary directory, adjusts environment
2629
variables and executes the embedded binary.
2730

2831
## Building
@@ -51,23 +54,20 @@ Run `rex` (the built binary) as a generator to create a bundle:
5154
# typical full command
5255
./rex \
5356
--target-binary ./myapp \
54-
--output ./myapp.Rex \
55-
--compression zstd \
5657
--compression-level 19 \
5758
--extra-libs /usr/lib/x86_64-linux-gnu/libexample.so \
5859
--extra-bins ./helpers ./tools \
5960
--additional-files config.json README.md
6061
```
6162

62-
If you omit `--output`, the generator will produce `myapp.Rex`
63-
(target file base name + `.Rex`).
63+
The generator will produce `myapp.Rex` (target file base name + `.Rex`).
6464

6565
### Runtime flags (embedded runtime inside the produced bundle)
6666

6767
When the generated bundle runs and contains payload, the runtime inspects
6868
arguments. The runtime supports:
6969

70-
* `--rex-help` — prints a short help message (English, simplified).
70+
* `--rex-help` — prints a short help message.
7171
* `--rex-extract` — extracts the embedded bundle into the **current working directory**.
7272

7373
If no runtime flag is given, the runtime will extract to a temporary
@@ -89,13 +89,6 @@ Inside the compressed `.tar` payload the generator creates a directory named
8989
The runtime expects exactly this layout and looks up the active bundle
9090
using the `target` name provided in the appended metadata.
9191

92-
## Compression choices
93-
94-
* `zstd` (id `0`) — default/recommended, fast and efficient. Supports higher levels.
95-
* `xz` (id `1`) — stronger compression but slower.
96-
97-
The generator accepts the flags `--compression` and `--compression-level`.
98-
9992
## Loader handling and execution (Linux)
10093

10194
* The generator attempts to copy a system loader into `libs/` (ld-linux or ld-musl)
@@ -124,7 +117,7 @@ writes to the current working directory and prints progress messages.
124117
cargo build --release
125118

126119
# 2) Package your app
127-
./target/release/rex --target-binary ./target/release/myapp --output ./myapp.Rex --compression zstd --compression-level 19
120+
./target/release/rex --target-binary ./target/release/myapp --compression-level 19
128121

129122
# 3) Run the bundle
130123
./myapp.Rex
@@ -137,7 +130,6 @@ Or extract files manually to inspect contents:
137130
# this extracts into the current directory into 'myapp_bundle/' (or similar) depending on the target name
138131
```
139132

140-
141133
## License
142134

143135
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.

changelog

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
1+
Thu Oct 23 20:19:24 -03 2025:
2+
- upload version 1.1.0
3+
- refactoty code
4+
- use only zstd
5+
- remove parameters --compression --output for clean code
16
Tue Oct 21 08:04:09 -03 2025:
2-
- Upload version 1.0.0
7+
- upload version 1.0.0

logo.png

898 KB
Loading

release_git

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/sh
2+
3+
VER="$(grep -Eom1 "version = \"(([0-9]+)[.])+[0-9]+" Cargo.toml)"
4+
5+
TAG="Continuous"
6+
BINARY=target/x86_64-unknown-linux-musl/release/Rex
7+
8+
gh release delete "$TAG" --yes
9+
gh release create "$TAG" "$BINARY" --title "$TAG" --notes "Rex v${VER#*\"} Release - 64bit"
10+
11+
echo "Release '$TAG' criada/atualizada com o binário enviado."

src/generator.rs

Lines changed: 19 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,19 @@ use std::io::{self, Write};
55
use std::os::unix::fs::PermissionsExt;
66
use std::path::{Path, PathBuf};
77
use std::process::Command;
8-
use xz2::write::XzEncoder;
98
use zstd::stream::write::Encoder;
109

1110
const MAGIC_MARKER: [u8; 10] = *b"REX_BUNDLE";
1211

1312
#[repr(C, packed)]
1413
struct BundleMetadata {
1514
payload_size: u64,
16-
compression_type: u32,
1715
target_bin_name_len: u32,
1816
}
1917

2018
#[derive(Debug)]
2119
pub struct BundleArgs {
2220
pub target_binary: PathBuf,
23-
pub output: PathBuf,
24-
pub compression: String,
2521
pub compression_level: i32,
2622
pub extra_libs: Vec<PathBuf>,
2723
pub additional_files: Vec<String>,
@@ -31,12 +27,8 @@ pub struct BundleArgs {
3127
fn find_system_loader() -> Option<PathBuf> {
3228
let possible_paths = [
3329
"/lib64/ld-linux-x86-64.so.2",
34-
"/usr/lib64/ld-linux-x86-64.so.2",
35-
"/lib/ld-linux-x86-64.so.2",
36-
"/usr/lib/ld-linux-x86-64.so.2",
37-
"/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2",
38-
"/lib/ld-musl-x86_64.so.1",
39-
"/usr/lib/ld-musl-x86_64.so.1"
30+
"/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2",
31+
"/lib/ld-musl-x86_64.so.1"
4032
];
4133

4234
for path in possible_paths.iter() {
@@ -55,35 +47,25 @@ fn create_temp_dir(base_name: &str) -> Result<PathBuf, Box<dyn Error>> {
5547
Ok(path)
5648
}
5749

58-
fn create_compressed_payload(path: &Path, target: &str, cmp: &str, l: i32) -> Result<PathBuf, Box<dyn Error>> {
59-
println!("\n[Packaging] Starting TAR archiving and {} compression (level {})...", cmp, l);
60-
50+
fn create_compressed_payload(path: &Path, target: &str, l: i32) -> Result<PathBuf, Box<dyn Error>> {
6151
let tmp_dir = std::env::temp_dir().join(format!("{}_bundle_tmp", target));
6252
if tmp_dir.exists() {
6353
fs::remove_dir_all(&tmp_dir)?;
6454
}
6555
fs::create_dir_all(&tmp_dir)?;
6656

67-
let payload = tmp_dir.join(format!("{}.tar.{}", target, cmp));
57+
let payload = tmp_dir.join(format!("{target}.tar.zstd"));
6858
let file_writer = File::create(&payload)?;
6959

70-
let encoder: Box<dyn Write> = match cmp {
71-
"zstd" => {
72-
let mut enc = Encoder::new(file_writer, l)?;
73-
enc.long_distance_matching(true)?;
74-
Box::new(enc.auto_finish())
75-
}
76-
"xz" => {
77-
let enc = XzEncoder::new(file_writer, l as u32);
78-
Box::new(enc)
79-
}
80-
other => return Err(format!("Unknown compression format: {}", other).into()),
81-
};
60+
println!("\n[Packaging] Starting TAR archiving and ZSTD compression (level {l}) to:\n{}", payload.display());
61+
62+
let mut enc = Encoder::new(file_writer, l)?;
63+
enc.long_distance_matching(true)?;
64+
let encoder: Box<dyn Write> =Box::new(enc.auto_finish());
8265

8366
let bundle_dir_name = format!("{}_bundle", target);
8467
let mut builder = tar::Builder::new(encoder);
8568
builder.append_dir_all(&bundle_dir_name, path)?;
86-
fs::remove_dir_all(&tmp_dir)?;
8769

8870
Ok(payload)
8971
}
@@ -222,35 +204,27 @@ pub fn generate_bundle(args: BundleArgs) -> Result<(), Box<dyn Error>> {
222204
fs_extra::copy_items(&entry_refs, root_path, &options)?;
223205
}
224206

225-
let compressed_payload_path = create_compressed_payload(root_path, &target_name, &args.compression, args.compression_level)?;
207+
let compressed_payload_path = create_compressed_payload(root_path, &target_name, args.compression_level)?;
226208
let payload_size = compressed_payload_path.metadata()?.len();
209+
let out = format!("{}.Rex", args.target_binary.file_name().unwrap().display());
227210

228-
println!("\n[Output] Creating final bundle file: {}", args.output.display());
211+
println!("\n[Output] Creating final bundle file: {}", out);
229212

230213
let exec = std::env::current_exe()?;
231-
fs::copy(&exec, &args.output)?;
214+
fs::copy(&exec, &out)?;
232215

233-
#[cfg(unix)]
234-
{
235-
use std::fs::Permissions;
236-
let perms = Permissions::from_mode(0o755);
237-
fs::set_permissions(&args.output, perms)?;
238-
}
216+
use std::fs::Permissions;
217+
218+
let perms = Permissions::from_mode(0o755);
219+
fs::set_permissions(&out, perms)?;
239220

240-
let mut final_file = fs::OpenOptions::new().append(true).open(&args.output)?;
221+
let mut final_file = fs::OpenOptions::new().append(true).open(&out)?;
241222
let mut payload_file = File::open(&compressed_payload_path)?;
242223

243224
io::copy(&mut payload_file, &mut final_file)?;
244225

245-
let compression_id = match args.compression.to_lowercase().as_str() {
246-
"zstd" => 0,
247-
"xz" => 1,
248-
_ => 99,
249-
};
250-
251226
let metadata = BundleMetadata {
252227
payload_size,
253-
compression_type: compression_id,
254228
target_bin_name_len: target_name.len() as u32,
255229
};
256230

@@ -269,6 +243,6 @@ pub fn generate_bundle(args: BundleArgs) -> Result<(), Box<dyn Error>> {
269243
println!("\n[Generator Success]");
270244
println!(" Payload Size: {} bytes", payload_size);
271245
println!(" Metadata Size: {} bytes", size_of::<BundleMetadata>() + target_name.len() + MAGIC_MARKER.len());
272-
println!(" Compressed Bundle created at: {}", args.output.display());
246+
println!(" Compressed Bundle created at: {}", out);
273247
Ok(())
274248
}

src/main.rs

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,8 @@ struct Cli {
1818
help = "Path to the main target binary to bundle")]
1919
target_binary: Option<PathBuf>,
2020

21-
#[arg(short = 'o', long, value_name = "OUTPUT_PATH",
22-
help = "Path for the generated Rex bundle")]
23-
output: Option<PathBuf>,
24-
25-
#[arg(short = 'c', long, value_name = "COMPRESSION_TYPE", default_value = "zstd",
26-
help = "Compression type to use for the payload (zstd or xz)")]
27-
compression: String,
28-
2921
#[arg(short = 'L', long, value_name = "COMPRESSION_LEVEL", default_value_t = 5,
30-
help = "Compression level (1-22 for zstd, 0-9 for xz)")]
22+
help = "Compression level (1-22)")]
3123
compression_level: i32,
3224

3325
#[arg(short = 'l', long, value_name = "EXTRA_LIBRARIES",
@@ -51,27 +43,14 @@ fn rex_main(runtime: &mut Runtime) -> Result<(), Box<dyn Error>> {
5143
return runtime.run()
5244
}
5345

54-
let has_no_args = args_vec.len() == 1;
55-
if has_no_args && !is_runtime {
56-
let mut cmd = Cli::command();
57-
cmd.print_help()?;
58-
return Ok(())
46+
if args_vec.len() == 1 {
47+
Cli::command().print_help()?;
48+
return Ok(());
5949
}
6050

6151
let cli = Cli::parse();
62-
let target = cli.target_binary.unwrap();
63-
let final_output = match cli.output {
64-
Some(p) => p,
65-
None => {
66-
let file_name = target.file_name().unwrap().to_str().unwrap();
67-
PathBuf::from(format!("{}.Rex", file_name))
68-
}
69-
};
70-
7152
let args = generator::BundleArgs {
72-
target_binary: target,
73-
output: final_output,
74-
compression: cli.compression,
53+
target_binary: cli.target_binary.unwrap(),
7554
compression_level: cli.compression_level,
7655
extra_libs: cli.extra_libs,
7756
extra_bins: cli.extra_bins,

0 commit comments

Comments
 (0)