Unmanned Player
Unmanned Player

Reputation: 1209

What is the correct way to static link libc?

I've seen a bunch of questions here and on other forums where the suggestion is to use -static or sometimes even -static -static-libgcc along with the compile arguments. This never works on Alpine, but woks fine on Ubuntu and Fedora.

I wrote a simple hello-world program in C, then had is compiled as gcc -static test.c. And the resulting binary still lights up ldd. See,

$ gcc -s test.c -static
$ ldd ./a.out
    /lib/ld-musl-x86_64.so.1 (0x7f043eae8000)

$ file ./a.out
./a.out: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, stripped

Running the same on Ubuntu shows:

$ gcc -s test.c -static                   
$ file ./a.out 
./a.out: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=bf6bfa1c78c541ae4e81586bcd050923bca9e34a, stripped

What is the correct and consistent way to static link libc itself on any platform? Is this something to do with the way GCC itself is compiled?

Upvotes: 8

Views: 10684

Answers (3)

user7401700
user7401700

Reputation:

You may be building just fine and it looks more like a bug in file. See this bug report: https://bugs.astron.com/view.php?id=93

Summary: 0000093: file incorrectly recognizes -static-pie binaries

I had the same issue when building QEMU but I was told of the above: https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/21214#note_156907

Upvotes: 1

Unmanned Player
Unmanned Player

Reputation: 1209

I'm answering my own question here for those who naively came here searching on keywords like static link libc or something.

If this is for MSVC, your only option is /MT or /MTd. But if you came here looking for GCC, welcome to the position independent code rabbit hole.

There are several variations of GCC floating around that are patched for specific targets or patched just because they can be. So if you have, say GCC version 6.0 and expect your command line arguments to generate same behaviour, you could be a victim of some bad patch work.

Some versions of GCC as in this question enforce position independent executable (-fPIE -pie) and silently ignore the -static option as seen in this example. I wonder if this should be reported as a bug to Alpine maintainers. To force it to ignore PIE, pass -no-pie to your GCC.

$  gcc -no-pie -static test.c

And if you do

$ file ./a.out
/lib/ld-musl-x86_64.so.1: ./a.out: Not a valid dynamic program

For details of how fPIE and static read these slides from OpenBSD.

Upvotes: 5

Your Ubuntu binary isn't PIE-enabled. If you pass -no-pie to GCC on Alpine, its binary will similarly not be PIE-enabled, but then it will be statically linked as you want.

Upvotes: 1

Related Questions