This is a fork of magic-haversack, all honors belong to the original author.
If you are use linux, all dependencies is almost available, except zig compiler.
- BASH (version > 4.0)
- sed
- zig compiler
- Ruby (Optional), It only necessary if you want download the libraries by yourself, I will upload those libraries as assets in release page.
- git clone https://github.com/crystal-china/magic-haversack
- Run
bundle install
thenrake fetch:all
, You can skip this step if you download libraries from github release page instead, and extract it intoPROJECT_ROOT/lib
, as following:
╰─ $ tree -L1 lib
lib
├── aarch64-linux-musl
├── aarch64-monterey
├── x86_64-linux-musl
└── x86_64-monterey
-
Add
PROJECT_ROOT/bin
into system $PATH, then you can runsb
script for cross build a Crystal program, you can always usesb ...
as an alternative ofshards build ...
-
Entering the Crystal project you want to execute the build on, I use following command for built an AMD64 static binary which can copy into and running it on any linux host.
$: sb --cross-compile --target=x86_64-linux-musl --static --no-debug --link-flags=-s --release
You can use sb as a alias for shards build
, but it where take care use zig cc if cross compile.
Check following example for cross build a binary for x86_64-linux-musl
, aarch-linux-musl
,x86_64-darwin
and aarch-darwin
on my linux host.
╰─ $ sb --cross-compile --target=x86_64-linux-musl --static
zig cc -target x86_64-linux-musl bin/college.o -o bin/college -rdynamic -static -L/home/zw963/Crystal/crystal-china/magic-haversack/lib/x86_64-linux-musl -lgmp -lyaml -lz `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libssl || printf %s '-lssl -lcrypto'` `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libcrypto || printf %s '-lcrypto'` -lpcre2-8 -lgc -lpthread -ldl -levent -lunwind
╰─ $ file bin/college
bin/college: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), static-pie linked, with debug_info, not stripped
╰─ $ sb --cross-compile --target=aarch64-linux-musl --static
zig cc -target aarch64-linux-musl bin/college.o -o bin/college -rdynamic -static -L/home/zw963/Crystal/crystal-china/magic-haversack/lib/aarch64-linux-musl -lgmp -lyaml -lz `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libssl || printf %s '-lssl -lcrypto'` `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libcrypto || printf %s '-lcrypto'` -lpcre2-8 -lgc -lpthread -ldl -levent -lunwind
╰─ $ file bin/college
bin/college: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), static-pie linked, with debug_info, not stripped
╰─ $ sb --cross-compile --target=x86_64-darwin --static
zig cc -target x86_64-macos-none bin/college.o -o bin/college -rdynamic -static -L/home/zw963/Crystal/crystal-china/magic-haversack/lib/x86_64-monterey -lgmp -lyaml -lz `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libssl || printf %s '-lssl -lcrypto'` `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libcrypto || printf %s '-lcrypto'` -lpcre2-8 -lgc -lpthread -ldl -levent -liconv -lunwind
╰─ $ file bin/college
bin/college: Mach-O 64-bit x86_64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|NO_REEXPORTED_DYLIBS|PIE|HAS_TLV_DESCRIPTORS>
╰─ $ sb --cross-compile --target=aarch64-darwin --static
zig cc -target aarch64-macos-none bin/college.o -o bin/college -rdynamic -static -L/home/zw963/Crystal/crystal-china/magic-haversack/lib/aarch64-monterey -lgmp -lyaml -lz `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libssl || printf %s '-lssl -lcrypto'` `command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libcrypto || printf %s '-lcrypto'` -lpcre2-8 -lgc -lpthread -ldl -levent -liconv -lunwind
╰─ $ file bin/college
bin/college: Mach-O 64-bit arm64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|NO_REEXPORTED_DYLIBS|PIE|HAS_TLV_DESCRIPTORS>
I have been using this workflow for a long time, and it work quite well, so i don't want add unnecessary complexity for same purpose, don't misunderstand me, i use docker quite well, but I use it only necessary.
- gc-dev/gdw-gc
- gmp-dev/gmp
- pcre2-dev/pcre2
- libevent-static/libevent
- libsodium-static/libsodium
- openssl-libs-static/openssl@3
- sqlite-static/sqlite
- yaml-static/yaml
- zlib-static/zlib
- libxml2-static/libxml2
- xz-static/xz (used by libxml2)
- gnu-libiconv/libiconv (used only for macOS)
If you use other third-party libraries, please feel free to submit an issue.
- Visit https://dl-cdn.alpinelinux.org/alpine/v3.20/main/aarch64/ use browser, and find out the latest package name, e.g. gc-dev-8.2.6-r0.apk
- run `./scripts/alpine_sha256_gen gc-dev-8.2.6-r0.apk' in the terminal, it will output like following:
╰─ $ ./scripts/alpine_sha256_gen gc-dev-8.2.6-r0.apk
--2024-08-18 16:27:08-- https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.20/main/aarch64/gc-dev-8.2.6-r0.apk
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)... 2402:f000:1:400::2, 101.6.15.130
Connecting to mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)|2402:f000:1:400::2|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 538608 (526K) [application/octet-stream]
Saving to: ‘/tmp/gc-dev-8.2.6-r0.apk.aarch64’
/tmp/gc-dev-8.2.6-r0.apk.aarc 100%[===============================================>] 525.98K 987KB/s in 0.5s
2024-08-18 16:27:09 (987 KB/s) - ‘/tmp/gc-dev-8.2.6-r0.apk.aarch64’ saved [538608/538608]
--2024-08-18 16:27:09-- https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.20/main/x86_64/gc-dev-8.2.6-r0.apk
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)... 2402:f000:1:400::2, 101.6.15.130
Connecting to mirrors.tuna.tsinghua.edu.cn (mirrors.tuna.tsinghua.edu.cn)|2402:f000:1:400::2|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 546905 (534K) [application/octet-stream]
Saving to: ‘/tmp/gc-dev-8.2.6-r0.apk.x86_64’
/tmp/gc-dev-8.2.6-r0.apk.x86_ 100%[===============================================>] 534.09K 1.06MB/s in 0.5s
2024-08-18 16:27:10 (1.06 MB/s) - ‘/tmp/gc-dev-8.2.6-r0.apk.x86_64’ saved [546905/546905]
url: https://dl-cdn.alpinelinux.org/alpine/v3.20/main/aarch64/gc-dev-8.2.6-r0.apk
sha256: "6a2eec3ee1117941e25549a044f4d8db8bfc9fe3083db767e50b50c7100e6770"
url: https://dl-cdn.alpinelinux.org/alpine/v3.20/main/x86_64/gc-dev-8.2.6-r0.apk
sha256: "b9d32564cd61897c56b3d57eb8cf573f9f38bd591f75f74d5b20bceddaaf94f2"
Then override specified yaml section use the above url,sha256 output part.
- you probably need replace alpine version with latest version before running
alpine_sha256_gen
,current use alpine v3.20, except gmp, 6.3.0 still not work for now, i create a issue for tracing it.
- Visit https://github.com/Homebrew/homebrew-core/tree/master/Formula
- Typing t, then filter with the package name(probably use different name with alpine)
- Select the oldest macOS code name which support both x86_64/aarch64. for now, we use monterey.
- Copy/Paste the specified sha256 hash into correct position.
- iconv is necessary only for Darwin, you don't need update it for alpine.
Check use_zig_cc_as_an_alternative_linker
- Fork it (https://github.com/crystal-china/hashr/fork)
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
- luislavena - creator and maintainer
- Billy.Zheng - current maintainer