Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.github, config: use Zig to cross compile arm64 Linux asset #460

Merged
merged 19 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/bin/cross-compile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash

set -eo pipefail

artifacts_dir='artifacts'
build_tag="${GITHUB_REF_NAME}"

cross_compile() {
local target="$1"
local arch='arm64'
local os
os="$(cut -d'-' -f2 <<<"${target}")"
local nim_os
case "${os}" in
macos) nim_os='macosx' ;;
*) nim_os="${os}" ;;
esac

nimble --verbose build --cpu:"${arch}" --os:"${nim_os}" -d:release -d:zig -d:target:"${target}"

mkdir -p "${artifacts_dir}"

local binary_name='configlet'

local artifact_file="${artifacts_dir}/${binary_name}_${build_tag}_${os}_${arch}.tar.gz"
tar -cvzf "${artifact_file}" "${binary_name}"
}

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

gh release upload "${build_tag}" "${artifacts_dir}"/*
}

main
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
#!/usr/bin/env sh

# Install musl
sudo apt-get install musl-dev musl-tools
45 changes: 45 additions & 0 deletions .github/bin/linux-install-zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -eo pipefail

version='0.11.0' # 2023-08-04
release_name="zig-linux-x86_64-${version}"
archive="${release_name}.tar.xz"
url="https://ziglang.org/download/${version}/${archive}"

curlopts=(
--silent
--show-error
--fail
--location
--retry 3
)

# Download the release archive.
echo "Downloading Zig release archive..." >&2
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 -

# Extract the archive, then remove it.
echo "Extracting archive..." >&2
tar xJf "${archive}"
rm "${archive}"

# Add zig directory to `GITHUB_PATH`.
zig_dir="$(pwd)/${release_name}"
echo "${zig_dir}" >> "${GITHUB_PATH}"

# Install `zigcc`, which is just a wrapper for `zig cc`. We need this because
# the value of e.g. `--clang.exe` cannot contain a space (Nim requires the value
# to be an executable, not a command).
zigcc_path="${zig_dir}/zigcc"
printf '#!/usr/bin/env sh\nzig cc $@\n' > "${zigcc_path}"
chmod +x "${zigcc_path}"

# Print the versions of Zig and Clang.
"${zig_dir}"/zig version
"${zig_dir}"/zig cc --version
echo "Successfully installed Zig ${version}."
29 changes: 27 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:

- name: On Linux, install musl
if: matrix.os == 'linux'
run: ./.github/bin/linux-install-build-tools
run: ./.github/bin/linux-install-musl

- name: Install Nim
uses: iffy/install-nim@ac410af52523f06e0fa037ee81d06ead7b95692c
Expand All @@ -62,9 +62,34 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

checksums:
cross-compile:
needs: [build]
runs-on: ubuntu-22.04
name: cross-compile
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9

- name: Install Nim
uses: iffy/install-nim@ac410af52523f06e0fa037ee81d06ead7b95692c
with:
version: "binary:2.0.0"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

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

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

checksums:
needs: [cross-compile]
runs-on: ubuntu-22.04
name: Upload signatures and checksums
permissions:
contents: write
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:

- name: On Linux, install musl
if: matrix.os == 'linux'
run: ./.github/bin/linux-install-build-tools
run: ./.github/bin/linux-install-musl

- name: Install Nim
uses: iffy/install-nim@ac410af52523f06e0fa037ee81d06ead7b95692c
Expand Down
20 changes: 17 additions & 3 deletions config.nims
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,30 @@ switch("mm", "refc")
patchFile("stdlib", "json", "src/patched_stdlib/json")
patchFile("stdlib", "parsejson", "src/patched_stdlib/parsejson")

if defined(zig) and findExe("zigcc").len > 0:
switch("cc", "clang")
# We can't write `zig cc` below, because the value cannot contain a space.
switch("clang.exe", "zigcc")
switch("clang.linkerexe", "zigcc")
const target {.strdefine.} = ""
if target.len > 0:
switch("passC", "-target " & target)
switch("passL", "-target " & target)

if defined(release):
switch("opt", "size")
switch("passC", "-flto")
switch("passL", "-flto")

if not (defined(zig) and defined(macosx)):
# `zig ld` doesn't support LTO.
# See https://github.com/ziglang/zig/issues/8680
switch("passC", "-flto")
switch("passL", "-flto")

if defined(linux) or defined(windows):
switch("passL", "-s")
switch("passL", "-static")

if defined(linux):
if defined(linux) and not defined(zig):
if defined(gcc):
switch("gcc.exe", "musl-gcc")
switch("gcc.linkerexe", "musl-gcc")
Expand Down
9 changes: 9 additions & 0 deletions configlet.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,12 @@ task test, "Runs the test suite":
if not fileExists("nimble.paths"):
exec "nimble setup"
exec "nim r ./tests/all_tests.nim"

# Strip the binary when it is produced by `zig cc`.
when defined(linux):
after build:
if existsEnv("GITHUB_ACTIONS") and findExe("zigcc").len > 0:
ee7 marked this conversation as resolved.
Show resolved Hide resolved
exec "readelf -p .comment ./configlet"
# TODO: strip
# echo "stripping large comment section from executable..."
# exec "strip -R .comment ./configlet"
ee7 marked this conversation as resolved.
Show resolved Hide resolved