What is the difference of with or without --static option when --cross-compile --target=x86_64-linux-musl?

Following is a example when i try build tartrazine.

without --static

 ╰─ $ shards build --cross-compile --target=x86_64-linux-musl
Dependencies are satisfied
Building: tartrazine
cc /home/zw963/Crystal/git/tartrazine/bin/tartrazine.o -o /home/zw963/Crystal/git/tartrazine/bin/tartrazine  -rdynamic -L/home/zw963/Crystal/bin/../lib/crystal -lyaml -lxml2 -lz -lpcre2-8 -lgc -lpthread -ldl -levent

with static.

 ╰─ $ shards build --cross-compile --target=x86_64-linux-musl --static
Dependencies are satisfied
Building: tartrazine
cc /home/zw963/Crystal/git/tartrazine/bin/tartrazine.o -o /home/zw963/Crystal/git/tartrazine/bin/tartrazine  -rdynamic -static -L/home/zw963/Crystal/bin/../lib/crystal -lyaml -lxml2 -lm -licuuc -licudata -lpthread -lm -lz -llzma -pthread -lpthread -licui18n -lz -lpcre2-8 -lgc -lpthread -ldl -levent

As you can see, the latter add the -licuuc -licudata -licui18n into the cc output.

But, the wired things is, it doesn’t matter which one you use for linking, both of them with generate static version binary use zig cc, even, binary size is almost same, and both of them works when copy binary into a new linux host.

 ╰─ $ ldd tartrazine_no_static tartrazine_static
tartrazine_no_static:
        statically linked
tartrazine_static:
        statically linked

 ╰─ $ file tartrazine_no_static tartrazine_static
tartrazine_no_static: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), static-pie linked, with debug_info, not stripped
tartrazine_static:    ELF 64-bit LSB executable, x86-64, version 1 (SYSV), static-pie linked, with debug_info, not stripped

 ╰─ $ ls -lh tartrazine_no_static tartrazine_static
Permissions Size User  Date Modified Name
.rwxr-xr-x   11M zw963 8 minutes     tartrazine_no_static*
.rwxr-xr-x   11M zw963 8 minutes     tartrazine_static*

So, my question is, why the latter --static version, will add -licuuc -licudata -licui18n as linking dependencies? It’s seem like never used them when linking, right?

Thanks.

Just out of curiosity, what about the hash and byte size between the 2 generated binaries?

To get the exact byte size: stat <file>

First of all: If you use a different command (zig cc) than what the --cross-compile output specified (cc), it is to be expected that the result might be different than what you would get with the system cc.
I’m not familiar with zig cc but maybe it always links statically, regardless of the -static option? :person_shrugging:

The different libraries come from the fact that when the compiler is told to link statically (--static) it passes the --static flag to pkg-config --libs when collecting the linker flags. So apparently some library has these libraries as dependencies when linked statically (but not when linked dynamically).

1 Like

The static version is slightly larger than the non-static version

 ╰─ $ stat tartrazine_*
  File: tartrazine_no_static
  Size: 10635440        Blocks: 20776      IO Block: 4096   regular file
Device: 0,50    Inode: 15738067    Links: 1

  File: tartrazine_static
  Size: 10639912        Blocks: 20784      IO Block: 4096   regular file
Device: 0,50    Inode: 15738106    Links: 1