Skip to content

Commit

Permalink
.github: cross-compile arm64 macOS asset (#796)
Browse files Browse the repository at this point in the history
Continue the recent `zig cc` work [1], such that the next configlet
release will have two new release assets:

    configlet_4.0.0-beta.14_macos_arm64.tar.gz
    configlet_4.0.0-beta.14_macos_arm64.tar.gz.minisig

where the archive contains the executable:

    $ file ./configlet
    configlet: Mach-O 64-bit arm64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|PIE|HAS_TLV_DESCRIPTORS>

`configlet uuid` now uses [2] `std/sysrand`, which on macOS uses [3] the
Security Framework. So to produce the macOS arm64 configlet, it's
easiest to cross-compile from macOS x86_64, where the macOSX SDK is
already available. Make the cross-compile and install-zig scripts
support macOS, and add a build job for it.

It looks like the macos-12 GitHub runner has SDK versions 12.3 and 13.1
installed. Use the latest one.

The new executable is about 1.09 MiB, which is notably larger than the
655 KiB macOS x86_64 executable. Possible ways to reduce the size in
the future:

- Enable LTO when `zig ld` supports it [4].

- Compile it natively, when GitHub begins to provide a hosted arm64
  macOS runner [5].

- Compile it natively, using a non-GitHub arm64 macOS runner.

Refs: #24
Refs: #122
Refs: #764

[1] 0e8d665, ".github, config: use Zig to cross-compile arm64 Linux asset", 2023-08-13
[2] 53a75a2, "nimble, uuid: generate UUIDs via std/sysrand, not pragmagic/uuids", 2023-08-07
[3] https://github.com/nim-lang/Nim/blob/v2.0.0/lib/std/sysrand.nim#L235-L256
[4] https://www.github.com/ziglang/zig/issues/8680
[5] https://www.github.com/github/roadmap/issues/528
  • Loading branch information
ee7 committed Aug 17, 2023
1 parent 7f2611a commit f280445
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 20 deletions.
32 changes: 20 additions & 12 deletions .github/bin/cross-compile
Expand Up @@ -3,6 +3,8 @@ set -eo pipefail

archives_dir='archives'
build_tag="${GITHUB_REF_NAME}"
# shellcheck disable=SC2153
zig_target="${ZIG_TARGET}"

cross_compile() {
local target="$1"
Expand All @@ -15,7 +17,23 @@ cross_compile() {
*) nim_os="${os}" ;;
esac

nimble --verbose build --cpu:"${arch}" --os:"${nim_os}" -d:release -d:zig -d:target:"${target}"
local build_options=(
-d:release
--cpu:"${arch}"
--os:"${nim_os}"
-d:zig
-d:target:"${target}"
)
# On macOS, add to the compiler's and linker's framework search path.
dir='/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/System/Library/Frameworks'
if [[ -d "${dir}" ]]; then
build_options+=("--passC:-F${dir}")
build_options+=("--passL:-F${dir}")
# Strip
build_options+=("--passL:-s")
fi

nimble --verbose build "${build_options[@]}"
local binary_name='configlet'
if command -v llvm-strip &> /dev/null; then
echo "stripping large comment section from executable..." >&2
Expand All @@ -28,17 +46,7 @@ cross_compile() {

main() {
nimble --accept install --depsOnly

local targets=(
aarch64-linux-musl
# aarch64-macos-none
# aarch64-windows-gnu
)

for target in "${targets[@]}"; do
cross_compile "${target}"
done

cross_compile "${zig_target}"
gh release upload "${build_tag}" "${archives_dir}"/*
}

Expand Down
40 changes: 35 additions & 5 deletions .github/bin/linux-install-zig → .github/bin/install-zig
Expand Up @@ -2,8 +2,23 @@
set -eo pipefail

version='0.11.0' # 2023-08-04
release_name="zig-linux-x86_64-${version}"
archive="${release_name}.tar.xz"

case "$(uname)" in
Darwin*) os='macos' ;;
Linux*) os='linux' ;;
Windows*) os='windows' ;;
MINGW*) os='windows' ;;
MSYS_NT-*) os='windows' ;;
*) os='linux' ;;
esac

case "${os}" in
windows*) ext='zip' ;;
*) ext='tar.xz' ;;
esac

release_name="zig-${os}-x86_64-${version}"
archive="${release_name}.${ext}"
url="https://ziglang.org/download/${version}/${archive}"

curlopts=(
Expand All @@ -20,12 +35,27 @@ curl "${curlopts[@]}" --output "${archive}" "${url}"

# Check that the archive has the expected hash.
echo "Verifying archive..." >&2
archive_sha256='2d00e789fec4f71790a6e7bf83ff91d564943c5ee843c5fd966efc474b423047'
echo "${archive_sha256} ${archive}" | sha256sum -c -
case "${os}" in
linux)
archive_sha256='2d00e789fec4f71790a6e7bf83ff91d564943c5ee843c5fd966efc474b423047'
echo "${archive_sha256} ${archive}" | sha256sum -c -
;;
macos)
archive_sha256='1c1c6b9a906b42baae73656e24e108fd8444bb50b6e8fd03e9e7a3f8b5f05686'
shasum -a 256 -c <<< "${archive_sha256} *${archive}"
;;
*)
echo "${os} not yet supported" >&2
exit 1
;;
esac

# Extract the archive, then remove it.
echo "Extracting archive..." >&2
tar xJf "${archive}"
case "${ext}" in
*zip) unzip "${archive}" ;;
*) tar xJf "${archive}" ;;
esac
rm "${archive}"

# Add zig directory to `GITHUB_PATH`.
Expand Down
17 changes: 14 additions & 3 deletions .github/workflows/build.yml
Expand Up @@ -74,8 +74,18 @@ jobs:

cross-compile:
needs: [create-empty-release]
runs-on: ubuntu-22.04
name: cross-compile
strategy:
fail-fast: false
matrix:
include:
- runs-on: ubuntu-22.04
zig_target: aarch64-linux-musl

- runs-on: macos-12
zig_target: aarch64-macos-none

name: "${{ matrix.zig_target }}"
runs-on: ${{ matrix.runs-on }}
permissions:
contents: write
steps:
Expand All @@ -90,12 +100,13 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Install Zig
run: ./.github/bin/linux-install-zig
run: ./.github/bin/install-zig

- name: Cross-compile
run: ./.github/bin/cross-compile
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ZIG_TARGET: ${{ matrix.zig_target }}

checksums:
needs: [build, cross-compile]
Expand Down

0 comments on commit f280445

Please sign in to comment.