zw963
January 20, 2024, 11:22am
1
This approach was originally verified by @luislavena and first posted here , here and here , big thanks to him for proving this solutin work, and he showed a little bit of this in following videos:
[Building CLIs with Crystal - Quick cross-compilation - Part 1](https://www.youtube.com/watch?v=ij7alYEvfTg)
[Building CLIs with Crystal - Quick cross-compilation - Part 2](https://www.youtube.com/watch?v=LdVNqdf_kBI)
Here are some links explain how zig cc
link work:
zig cc
: a Powerful Drop-In Replacement for GCC/Clang
How Uber Uses Zig
PR: Add guide: Use zig cc as a alternative linker (draft version) by zw963 · Pull Request #737 · crystal-lang/crystal-book · GitHub
@straight-shoota , we can also discuss here.
zw963
January 20, 2024, 3:07pm
3
@luislavena , because the original gem GitHub - luislavena/magic-haversack: Facilitate Crystal cross-compilation , there is no way to create issue, i just create it here.
As the example code following, A minimal hello world code, if linked to macOS using zig cc, the libiconv
is necessary.
╰─ $ echo ‘puts “hello”’ > hello.cr
╰─ $ crystal build hello.cr --release --no-debug --cross-compile --target=x86_64-darwin --link-flags=-s
cc hello.o -o hello -s -rdynamic -L/home/zw963/Crystal/bin/…/lib/crystal -lpcre2-8 -lgc -lpthread -ldl -levent -liconv
But, this library not exists in magic-haversack.
tl;dr: you need macOS SDK to link against their dynamic version of iconv, the one used by Crystal by default when targeting macOS platforms.
You could workaround that by downloading libiconv for macOS (the static library) and forcing the link to it.
See this Crystal PR that covers all the details of iconv on macOS.
Or you can download existing versions of macOS SDK and grab the .tld
files necessary for the dynamic linking to work.
I cannot distribute bundled versions of the SDK without breaking Apple’s terms.
Cheers.
zw963
January 20, 2024, 3:50pm
5
How about adding libiconv for macOS (the static library) to magic-haversack? it can be installed use brew anyway.
zw963
January 20, 2024, 4:40pm
6
Add a bash script example make cross link aarch64-linux-musl
/x86_64-linux-musl
use zig cc
automate.
# Use zig cc as an alternative linker
This approach was originally verified by @luislavena and first posted [here](https://forum.crystal-lang.org/t/a-github-action-template-for-do-release-assets-when-push-a-tag-it-should-fitable-for-any-shards/4635/5), [here](https://forum.crystal-lang.org/t/a-github-action-template-for-do-release-assets-when-push-a-tag-it-should-fitable-for-any-shards/4635/8) and [here](https://forum.crystal-lang.org/t/does-anyone-deploy-crystal-app-on-arm-based-linux-server-what-is-the-deployment-process-like/5588/5), big thanks to him for proving this solution work, and he showed a little bit of this in following videos:
[Building CLIs with Crystal - Quick cross-compilation - Part 1](https://www.youtube.com/watch?v=ij7alYEvfTg)
[Building CLIs with Crystal - Quick cross-compilation - Part 2](https://www.youtube.com/watch?v=LdVNqdf_kBI)
Here are some links explain how `zig cc` link work:
[`zig cc`: a Powerful Drop-In Replacement for GCC/Clang](https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html)
[How Uber Uses Zig](https://jakstys.lt/2022/how-uber-uses-zig/)
# What are the benefits?
You can use a `system-independent` way to generate (static) bianry for the following platforms.
```sh
╰─ $ zig targets | jq .libc
This file has been truncated. show original
zw963
January 21, 2024, 10:58am
7
Add a new bash script, it can build and link binary on my AMD64 laptop for x86_64-linux-musl/aarch64-linux-musl/x86_64-darwin/arrch64-darwin
now without needs docker.
╰─ $ cd ~/Crystal/crystal-lang/shards
╰─ $ git clean -fdx && shards build --production --static --no-debug --cross-compile --target=aarch64-linux-musl --link-flags=-s
Removing bin/shards
Removing bin/shards.o
Removing lib/
zig cc -target aarch64-linux-musl /home/zw963/Crystal/crystal-lang/shards/bin/shards.o -o /home/zw963/Crystal/crystal-lang/shards/bin/shards -s -rdynamic -static -L/home/zw963/Crystal/static_libraries/aarch64-linux-musl -lyaml -lpcre2-8 -lgc -lpthread -ldl -levent -lunwind
╰─ $ file bin/shards
bin/shards: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), static-pie linked, stripped
╰─ $ git clean -fdx && shards build --production --static --no-debug --cross-compile --target=x86_64-linux-musl --link-flags=-s
Removing bin/shards
Removing bin/shards.o
Removing lib/
zig cc -target x86_64-linux-musl /home/zw963/Crystal/crystal-lang/shards/bin/shards.o -o /home/zw963/Crystal/crystal-lang/shards/bin/shards -s -rdynamic -static -L/home/zw963/Crystal/static_libraries/x86_64-linux-musl -lyaml -lpcre2-8 -lgc -lpthread -ldl -levent -lunwind
╰─ $ file bin/shards
bin/shards: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), static-pie linked, stripped
╰─ $ git clean -fdx && shards build --production --static --no-debug --cross-compile --target=x86_64-darwin --link-flags=-s
Removing bin/shards
Removing bin/shards.o
Removing lib/
zig cc -target x86_64-macos-none /home/zw963/Crystal/crystal-lang/shards/bin/shards.o -o /home/zw963/Crystal/crystal-lang/shards/bin/shards -s -rdynamic -static -L/home/zw963/Crystal/static_libraries/x86_64-apple-darwin21.0 -lyaml -lpcre2-8 -lgc -lpthread -ldl -levent -liconv -lunwind
╰─ $ file bin/shards
bin/shards: Mach-O 64-bit x86_64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|PIE|HAS_TLV_DESCRIPTORS>
╰─ $ git clean -fdx && shards build --production --static --no-debug --cross-compile --target=aarch64-darwin --link-flags=-s
Removing bin/shards
Removing bin/shards.o
Removing lib/
zig cc -target aarch64-macos-none /home/zw963/Crystal/crystal-lang/shards/bin/shards.o -o /home/zw963/Crystal/crystal-lang/shards/bin/shards -s -rdynamic -static -L/home/zw963/Crystal/static_libraries/aarch64-apple-darwin21.0 -lyaml -lpcre2-8 -lgc -lpthread -ldl -levent -liconv -lunwind
╰─ $ file bin/shards
bin/shards: Mach-O 64-bit arm64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|PIE|HAS_TLV_DESCRIPTORS>
# Use zig cc as an alternative linker
This approach was originally verified by @luislavena and first posted [here](https://forum.crystal-lang.org/t/a-github-action-template-for-do-release-assets-when-push-a-tag-it-should-fitable-for-any-shards/4635/5), [here](https://forum.crystal-lang.org/t/a-github-action-template-for-do-release-assets-when-push-a-tag-it-should-fitable-for-any-shards/4635/8) and [here](https://forum.crystal-lang.org/t/does-anyone-deploy-crystal-app-on-arm-based-linux-server-what-is-the-deployment-process-like/5588/5), big thanks to him for proving this solution work, and he showed a little bit of this in following videos:
[Building CLIs with Crystal - Quick cross-compilation - Part 1](https://www.youtube.com/watch?v=ij7alYEvfTg)
[Building CLIs with Crystal - Quick cross-compilation - Part 2](https://www.youtube.com/watch?v=LdVNqdf_kBI)
Here are some links explain how `zig cc` link work:
[`zig cc`: a Powerful Drop-In Replacement for GCC/Clang](https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html)
[How Uber Uses Zig](https://jakstys.lt/2022/how-uber-uses-zig/)
# What are the benefits?
You can use a `system-independent` way to generate (static) bianry for the following platforms.
```sh
╰─ $ zig targets | jq .libc
This file has been truncated. show original