Compiling static binary

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Compiling static binary

Paul Colomiets
Hi,

Is there any way to compile static binary with rust compiler? I'm
experimenting with linux conainerisation and it would be much easier
if I could compile a binary which doesn't depend on libc.

There is also an stack overflow question with no answer:
http://stackoverflow.com/questions/26202494/portable-binaries-with-rust

Thanks in advance!

--
Paul
_______________________________________________
Rust-dev mailing list
[hidden email]
https://mail.mozilla.org/listinfo/rust-dev
Reply | Threaded
Open this post in threaded view
|

Re: Compiling static binary

Kai Noda
Hi Paul,

I managed to get it working by manually tweaking linker options (this mustn't be the right way to go...)

Rust devs: what is the official way to do this?  Simply adding "-C link-args=-static" doesn't work (see my second transcript)

fn main() {
    println!("Hello, world!");
}
$ rlibs=`rustc -Z print-link-args hello-rust.rs | sed -e 's/ /\n/g' | grep rlib`
$ echo $rlibs
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libnative-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libsync-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustrt-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcollections-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/librand-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunicode-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-4e7c5e5c.rlib'
$ rustc -Z print-link-args --emit obj hello-rust.rs
$ file hello-rust.o
hello-rust.o: ELF 64-bit LSB relocatable, x86-64, version 1 (GNU/Linux), not stripped
$ eval "gcc -static -static-libgcc hello-rust.o `tr $'\n' ' '<<<$rlibs` -lpthread -lm -ldl -lrt -o hello-rust"
/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-4e7c5e5c.rlib(std-4e7c5e5c.o): In function `dynamic_lib::dl::open_internal::hda8e305d06a14b844og':
std.0.rs:(.text._ZN11dynamic_lib2dl13open_internal20hda8e305d06a14b844ogE+0x8): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-4e7c5e5c.rlib(std-4e7c5e5c.o): In function `io::net::addrinfo::get_host_addresses::hf208fefd6f07b89awSi':
std.0.rs:(.text._ZN2io3net8addrinfo18get_host_addresses20hf208fefd6f07b89awSiE+0xad): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$ file ./hello-rust
./hello-rust: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=0x7fa2ba5ebdec633b220a8e9c988c4632b26a17d9, not stripped
$ ./hello-rust
Hello, world!
$ ls -l hello-rust
-rwxrwxr-x 1 nodakai nodakai 4.3M 11月 16 04:41 hello-rust*


$ x=`rustc -Z print-link-args hello-rust.rs`
$ y=`rustc -C link-args=-static -Z print-link-args hello-rust.rs`
$ diff <(tr ' ' $'\n' <<< $x) <(tr ' ' $'\n' <<< $y)
13d12
< '-pie'
39a39
> '-static'
$ file hello-rust
hello-rust: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x3a723f38042703be0ad45679b53220ce5f21787d, not stripped
$ LANG=C ./hello-rust
zsh: no such file or directory: ./hello-rust (<-- ENOENT, ie. invalid executable)

Regards,
Kai

野田  開 <[hidden email]>

2014-11-16 0:40 GMT+08:00 Paul Colomiets <[hidden email]>:
Hi,

Is there any way to compile static binary with rust compiler? I'm
experimenting with linux conainerisation and it would be much easier
if I could compile a binary which doesn't depend on libc.

There is also an stack overflow question with no answer:
http://stackoverflow.com/questions/26202494/portable-binaries-with-rust

Thanks in advance!

--
Paul
_______________________________________________
Rust-dev mailing list
[hidden email]
https://mail.mozilla.org/listinfo/rust-dev


_______________________________________________
Rust-dev mailing list
[hidden email]
https://mail.mozilla.org/listinfo/rust-dev
Reply | Threaded
Open this post in threaded view
|

Re: Compiling static binary

Brian Anderson
I believe it is not possible to link to glibc statically. My understanding is that to get a Rust binary that does not depend on a system-provided libc at all we need to add explicit support for alternate libc implementations[1].

[1]: https://github.com/rust-lang/rust/issues/7283

On 11/15/2014 01:02 PM, Kai Noda wrote:
Hi Paul,

I managed to get it working by manually tweaking linker options (this mustn't be the right way to go...)

Rust devs: what is the official way to do this?  Simply adding "-C link-args=-static" doesn't work (see my second transcript)

fn main() {
    println!("Hello, world!");
}
$ rlibs=`rustc -Z print-link-args hello-rust.rs | sed -e 's/ /\n/g' | grep rlib`
$ echo $rlibs
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libnative-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libsync-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustrt-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcollections-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/librand-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunicode-4e7c5e5c.rlib'
'/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-4e7c5e5c.rlib'
$ rustc -Z print-link-args --emit obj hello-rust.rs
$ file hello-rust.o
hello-rust.o: ELF 64-bit LSB relocatable, x86-64, version 1 (GNU/Linux), not stripped
$ eval "gcc -static -static-libgcc hello-rust.o `tr $'\n' ' '<<<$rlibs` -lpthread -lm -ldl -lrt -o hello-rust"
/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-4e7c5e5c.rlib(std-4e7c5e5c.o): In function `dynamic_lib::dl::open_internal::hda8e305d06a14b844og':
std.0.rs:(.text._ZN11dynamic_lib2dl13open_internal20hda8e305d06a14b844ogE+0x8): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-4e7c5e5c.rlib(std-4e7c5e5c.o): In function `io::net::addrinfo::get_host_addresses::hf208fefd6f07b89awSi':
std.0.rs:(.text._ZN2io3net8addrinfo18get_host_addresses20hf208fefd6f07b89awSiE+0xad): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$ file ./hello-rust
./hello-rust: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=0x7fa2ba5ebdec633b220a8e9c988c4632b26a17d9, not stripped
$ ./hello-rust
Hello, world!
$ ls -l hello-rust
-rwxrwxr-x 1 nodakai nodakai 4.3M 11月 16 04:41 hello-rust*


$ x=`rustc -Z print-link-args hello-rust.rs`
$ y=`rustc -C link-args=-static -Z print-link-args hello-rust.rs`
$ diff <(tr ' ' $'\n' <<< $x) <(tr ' ' $'\n' <<< $y)
13d12
< '-pie'
39a39
> '-static'
$ file hello-rust
hello-rust: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x3a723f38042703be0ad45679b53220ce5f21787d, not stripped
$ LANG=C ./hello-rust
zsh: no such file or directory: ./hello-rust (<-- ENOENT, ie. invalid executable)

Regards,
Kai

野田  開 <[hidden email]>

2014-11-16 0:40 GMT+08:00 Paul Colomiets <[hidden email]>:
Hi,

Is there any way to compile static binary with rust compiler? I'm
experimenting with linux conainerisation and it would be much easier
if I could compile a binary which doesn't depend on libc.

There is also an stack overflow question with no answer:
http://stackoverflow.com/questions/26202494/portable-binaries-with-rust

Thanks in advance!

--
Paul
_______________________________________________
Rust-dev mailing list
[hidden email]
https://mail.mozilla.org/listinfo/rust-dev



_______________________________________________
Rust-dev mailing list
[hidden email]
https://mail.mozilla.org/listinfo/rust-dev


_______________________________________________
Rust-dev mailing list
[hidden email]
https://mail.mozilla.org/listinfo/rust-dev
Reply | Threaded
Open this post in threaded view
|

Re: Compiling static binary

Paul Colomiets
In reply to this post by Kai Noda
Hi Kai,

On Sat, Nov 15, 2014 at 11:02 PM, Kai Noda <[hidden email]> wrote:

> Hi Paul,
>
> I managed to get it working by manually tweaking linker options (this
> mustn't be the right way to go...)
>
> Rust devs: what is the official way to do this?  Simply adding "-C
> link-args=-static" doesn't work (see my second transcript)
>
> $ cat hello-rust.rs
> fn main() {
>     println!("Hello, world!");
> }
> $ rlibs=`rustc -Z print-link-args hello-rust.rs | sed -e 's/ /\n/g' | grep
> rlib`
> $ echo $rlibs
> '/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libnative-4e7c5e5c.rlib'
> '/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-4e7c5e5c.rlib'
> '/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libsync-4e7c5e5c.rlib'
> '/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustrt-4e7c5e5c.rlib'
> '/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcollections-4e7c5e5c.rlib'
> '/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-4e7c5e5c.rlib'
> '/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-4e7c5e5c.rlib'
> '/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/librand-4e7c5e5c.rlib'
> '/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunicode-4e7c5e5c.rlib'
> '/home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-4e7c5e5c.rlib'
> $ rustc -Z print-link-args --emit obj hello-rust.rs
> $ file hello-rust.o
> hello-rust.o: ELF 64-bit LSB relocatable, x86-64, version 1 (GNU/Linux), not
> stripped
> $ eval "gcc -static -static-libgcc hello-rust.o `tr $'\n' ' '<<<$rlibs`
> -lpthread -lm -ldl -lrt -o hello-rust"
> /home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-4e7c5e5c.rlib(std-4e7c5e5c.o):
> In function `dynamic_lib::dl::open_internal::hda8e305d06a14b844og':
> std.0.rs:(.text._ZN11dynamic_lib2dl13open_internal20hda8e305d06a14b844ogE+0x8):
> warning: Using 'dlopen' in statically linked applications requires at
> runtime the shared libraries from the glibc version used for linking
> /home/nodakai/local/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-4e7c5e5c.rlib(std-4e7c5e5c.o):
> In function `io::net::addrinfo::get_host_addresses::hf208fefd6f07b89awSi':
> std.0.rs:(.text._ZN2io3net8addrinfo18get_host_addresses20hf208fefd6f07b89awSiE+0xad):
> warning: Using 'getaddrinfo' in statically linked applications requires at
> runtime the shared libraries from the glibc version used for linking
> $ file ./hello-rust
> ./hello-rust: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux),
> statically linked, for GNU/Linux 2.6.24,
> BuildID[sha1]=0x7fa2ba5ebdec633b220a8e9c988c4632b26a17d9, not stripped
> $ ./hello-rust
> Hello, world!

Sure, this is a workaround. But it works, until rust will support
alternative libc implementations. Thanks a lot!

--
Paul
_______________________________________________
Rust-dev mailing list
[hidden email]
https://mail.mozilla.org/listinfo/rust-dev
Reply | Threaded
Open this post in threaded view
|

Re: Compiling static binary

Paul Colomiets
In reply to this post by Brian Anderson
Hi Brian,

On Sat, Nov 15, 2014 at 11:23 PM, Brian Anderson <[hidden email]> wrote:
> I believe it is not possible to link to glibc statically. My understanding
> is that to get a Rust binary that does not depend on a system-provided libc
> at all we need to add explicit support for alternate libc
> implementations[1].
>

Thanks. This really explains why problem is so hard. It seems that
it's possible to link to glibc, with the issue of non-working name
resolution (which is pluggable in glibc) and dlopen (for obvious
reasons). That would work for me for now.

Still, when you are talking about "system-provided libc", do you mean
that if I would compile Rust on e.g. Alpine linux (which has musl libc
by default), I will be able to link rust program with musl libc
statically?

--
Paul
_______________________________________________
Rust-dev mailing list
[hidden email]
https://mail.mozilla.org/listinfo/rust-dev
Reply | Threaded
Open this post in threaded view
|

Re: Compiling static binary

Daniel Micay
On 15/11/14 05:24 PM, Paul Colomiets wrote:

> Hi Brian,
>
> On Sat, Nov 15, 2014 at 11:23 PM, Brian Anderson <[hidden email]> wrote:
>> I believe it is not possible to link to glibc statically. My understanding
>> is that to get a Rust binary that does not depend on a system-provided libc
>> at all we need to add explicit support for alternate libc
>> implementations[1].
>>
>
> Thanks. This really explains why problem is so hard. It seems that
> it's possible to link to glibc, with the issue of non-working name
> resolution (which is pluggable in glibc) and dlopen (for obvious
> reasons). That would work for me for now.
>
> Still, when you are talking about "system-provided libc", do you mean
> that if I would compile Rust on e.g. Alpine linux (which has musl libc
> by default), I will be able to link rust program with musl libc
> statically?
The limited static linking support in glibc is misleading, because it's
quite broken.

Here's a simple example of a performance bug (time it with and without
using -static):

    #include <time.h>

    int main(void) {
        struct timespec ts;
        for (unsigned i = 0; i < 1000000; i++) {
            clock_gettime(CLOCK_MONOTONIC, &ts);
        }
    }

Unlike musl, glibc has no vdso support without dynamic linking.

Statically linking all libraries is also different than a *fully* static
binary which is incompatible with features like ASLR. Rust enables PIE
(full ASLR) by default so `-static` alone is poorly defined and will
likely break at compile-time or runtime.

Rust's current approach to FFI is to hard-wire the entire ABI of a
specific version / configuration of the library. It's unlikely that it
will work with musl at this time, despite musl's progress towards
support for the glibc ABI.


_______________________________________________
Rust-dev mailing list
[hidden email]
https://mail.mozilla.org/listinfo/rust-dev

signature.asc (836 bytes) Download Attachment