Split executable file

#1

As we can not call the ‘.rlib’ for directly, and need to have the source code, we ended up having SINGLE executable file, which could be a huge one.

Is there a way to support the executable/bin guess into multiple files (bun and libs)?

0 Likes

#2

I didn’t test it, but i think dynamic linking is supported, resulting in split executables/libraries:

cargo rustc [--debug or --release] -- -C prefer-dynamic
1 Like

#3

What’s your goal here? If you merely dynamically link the same code, the total size and memory usage will be the same.

If you want to reduce disk size, use LTO. Use system allocator.

If you want to reduce memory use, that’s going to be tricky, as you’ll need to dynamically load and unload libraries.

0 Likes

#4

I’m just thinking what if the executable gone very huge, and want to share it via link with some one else, it could be easier to download multiple small files than one huge, if internet connection is poor like here, downloading huge file could be a night mare.

0 Likes

#5

many download managers support continuing a download. for example, most linux distros ship with wget, where you can continue a download like so:

wget --continue https://whatever.tld/hugerustexecutable

Btw this sounds like a terrible case of XY-Problem to me :smiley: https://en.wikipedia.org/wiki/XY_problem

2 Likes

#6

A valid point, but let’s say my question is for curiosity rather than having answer how to download big files, thanks any way :slight_smile:

0 Likes

#7

It refused to work with --debug, and with the --release the executable file size had been reduced from (586 KB on disk) to (12 KB on disk). the release folder size had been reduced from (1.2 MB on disk) to (70 KB on disk)

Once I tried to run the executable, I got the below error:

Hasans-Air:release h_ajsf$ ./hello
dyld: Library not loaded: @rpath/libstd-4d43049bfe4b28e8.dylib
Referenced from: /Users/h_ajsf/IdeaProjects/mix_rust/target/release/./hello
Reason: image not found
Abort trap: 6

My app structure is:

├── Cargo.toml
├── bin
│   ├── Cargo.toml
│   └── src
│       └── main.rs
├── lib
    ├── Cargo.toml
    └── src
        └── lib.rs

And my files are:

#Cargo.toml
[workspace]
members = [
    "bin",
    "lib"
]
#lib/Cargo.toml
[package]
name = "greetings"
version = "0.1.0"
authors = ["Hasan Yousef"]
edition = "2018"

[dependencies]
// lib/src/lib.rs
pub fn hello() {
    println!("Hello, world!");
}
#bin/Cargo.toml
[package]
name = "hello"
version = "0.1.0"
authors = ["Hasan Yousef"]
edition = "2018"

[dependencies]
greetings = { path = "../lib" }
// bin/src/main.rs
use greetings::hello;

fn main() {
    hello();
}

And executed the command from the bin subfolder, as:

Hasans-Air:bin h_ajsf$ cargo rustc --release -- -C prefer-dynamic

Note:
Once I tried to execute the command from the root of the project, i got the below error:

Hasans-Air: rust_app h_ajsf$ cargo rustc --release -- -C prefer-dynamic
error: manifest path `/Users/h_ajsf/IdeaProjects/mix_rust/Cargo.toml` is a virtual manifest, but this command requires running against an actual package in this workspace
0 Likes

#8

it seems that the libraries it tries to dynamically link are not in the directories where the linker looks for them. Do you have the relevant files in ~/.rustup/toolchains/stable-whatever-your-target-triplet-looks-like/lib?

0 Likes

#9

It is there, I’ve the same path in the sam root, as shown below

Hasans-Air:release h_ajsf$ rustc --print=sysroot
/Users/h_ajsf/.rustup/toolchains/stable-x86_64-apple-darwin

I copied this file to the release folder, but did not work, still getting same error

0 Likes

#10

BTW, even if you get this working, it will not solve your problem of large download size, because you will have to distribute the libraries with the executable.
You’re replacing a large executable with a small executable, but tied to large libraries. The result will be large either way. In fact, with dynamic linking it’s probably even larger in total, because unused code is not removed from the libraries.

1 Like