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

Conversation

ee7
Copy link
Member

@ee7 ee7 commented Oct 26, 2021

See:

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

2023-08-15: The build workflow ran successfully and created a release which has a linux_arm64 asset.


To-do:

  • Strip the binary.
  • Wait for the Zig 0.9.0 release
  • Use strip -R .comment. With the initial snapcraft update for Zig 0.9.0, there's now 30 KiB of noise in the comment section.
  • Wait for non-rc clang 13.0.1 (included in Zig 0.9.1).
  • Wait for the Zig 0.10.0 release (edit: https://ziglang.org/download/0.10.0/release-notes.html, ziglang/zig@0c17017)
  • Remove the extra stripping step if it turns out that we don't need it with the latest Zig. See ziglang/zig#351.
  • Use Zig to cross compile arm64 executable(s), rather than the Linux x86_64 executable.
  • Use the Zig 0.11.0 release.
  • Pin the Zig version.
  • Test build workflow by pushing a tag
  • Either:
    • Fix macos build
    • or decide to merge this PR just with arm64 linux for now
  • See what happens for windows arm64
  • cross-compile: fix os variable value for macos
  • Locally smoke test new executable(s) with qemu
  • Non-blocking: try to strip comment section
  • Non-blocking: add testing with qemu in CI
  • Non-blocking: refactor/combine build scripts

configlet.nimble Outdated Show resolved Hide resolved
@ee7 ee7 marked this pull request as ready for review October 27, 2021 07:34
config.nims Outdated Show resolved Hide resolved
@ee7
Copy link
Member Author

ee7 commented Dec 11, 2021

I'll defer this at least until Zig 0.9.0 is released (expected 2021-12-20 - see https://github.com/ziglang/zig/milestone/11).

@ee7 ee7 marked this pull request as draft December 11, 2021 23:15
@ee7
Copy link
Member Author

ee7 commented Dec 21, 2021

Zig 0.9.0 was released. See https://ziglang.org/download/0.9.0/release-notes.html

https://snapcraft.io/zig was also updated.

@ee7
Copy link
Member Author

ee7 commented Apr 15, 2022

Possible different approach for this PR: rather than using zig to build the critical release asset, use it to cross-compile some new release assets.

@ErikSchierboom
Copy link
Member

Let me know when you want a review

@ee7 ee7 changed the title build: use zig for Linux build .github, config, nimble: use zig for Linux build Oct 26, 2022
@ee7 ee7 force-pushed the build-use-zig branch 2 times, most recently from 49fb0bd to 85aba83 Compare August 14, 2023 08:02
With the Zig 0.9.0 release (2021-12-20), the configlet binary now has
30 KiB of bloat in the comment section, repeating the clang version many
times.

Before this commit:

    $ readelf -p .comment ./configlet

    String dump of section '.comment':
      [     0]  clang version 13.0.1 (git@github.com:ziglang/zig-bootstrap.git 74211dd7f7e7174a2027641dfcfdb3fc5df62f0c)
      [...] (repeat for 30 KB)
      [  7969]  clang version 13.0.1 (git@github.com:ziglang/zig-bootstrap.git 74211dd7f7e7174a2027641dfcfdb3fc5df62f0c)
      [  79d2]  Linker: LLD 13.0.1 (git@github.com:ziglang/zig-bootstrap.git 74211dd7f7e7174a2027641dfcfdb3fc5df62f0c)

Binary size profile before this commit:

       FILE SIZE        VM SIZE
    --------------  --------------
     75.2%   368Ki  64.5%   368Ki    .text
      0.0%       0  19.6%   111Ki    .bss
     18.2%  89.1Ki  15.6%  89.1Ki    .rodata
      6.2%  30.6Ki   0.0%       0    .comment
      0.2%     816   0.1%     824    .data
      0.1%     640   0.0%       0    [ELF Section Headers]
      0.1%     392   0.1%     392    [ELF Program Headers]
      0.0%      64   0.0%      64    [ELF Header]
      0.0%      63   0.0%       0    .shstrtab
      0.0%       8   0.0%       8    .got
      0.0%       8   0.0%       8    [LOAD #1 [R]]
      0.0%       4   0.0%       3    .fini
      0.0%       3   0.0%       3    .init
    100.0%   489Ki 100.0%   570Ki    TOTAL

Strip the comment section. But print it first.
With Zig 0.10.0 (2022-10-31), `zig cc` now properly uses the `--passL:
-s` option that we use in `config.nims`. So we can remove the `-s` flag
from our post-build hook.

From the Zig 0.10.0 release notes [1]:

    `zig cc` is Zig's drop-in C compiler tool. Enhancements in this release:

    [...]
    - Integration with more linker args:

      - `--whole-archive`, `-whole-archive`
      - `--no-whole-archive`, `-no-whole-archive`
      - `-s`, `--strip-all`
      - `-S`, `--strip-debug`
    [...]

[1] https://ziglang.org/download/0.10.0/release-notes.html#zig-cc
And install Zig via script, rather than snap. One benefit is that it
allows us to pin a Zig version.

The script is adapted from one I added to the Exercism Zig repo [1].

[1] exercism/zig@9dfb95f031b1
@ee7 ee7 changed the title .github, config, nimble: use zig for Linux build .github, config, nimble: use zig to cross compile for arm64 Aug 14, 2023
`strip` can't strip a non-native executable.
--os:macos produced the error:

    /home/runner/work/configlet/configlet/nimdir/lib/system/dyncalls.nim(198, 10) Error: no implementation for dyncalls
Try to resolve error:

    error: LTO is not yet supported with the Mach-O object format. More details: ziglang/zig#8680
    Error: execution of an external compiler program
    'zigcc -c -w -ferror-limit=3 -pthread -target aarch64-macos-none -flto -Os
    -I/home/runner/work/configlet/configlet/nimdir/lib
    -I/home/runner/work/configlet/configlet/src
    -o /home/runner/.cache/nim/configlet_r/@m..@snimdir@slib@ssystem@sctypes.nim.c.o
    /home/runner/.cache/nim/configlet_r/@m..@snimdir@slib@ssystem@sctypes.nim.c'
    failed with exit code: 1
@ee7
Copy link
Member Author

ee7 commented Aug 14, 2023

I've made some good progress on this. I think I've got working cross-compilation to arm64-linux.

The build workflow ran successfully and created a release which has a linux_arm64 asset.

But cross-compiling from x86_64-Linux to arm64-macos produces the error:

CC: ../nimdir/lib/std/sysrand.nim
/home/runner/.cache/nim/configlet_r/@m..@snimdir@slib@sstd@ssysrand.nim.c:9:10: fatal error: 'Security/SecRandom.h' file not found
#include <Security/SecRandom.h>

This is a consequence of 53a75a2. I guess we can defer arm64-macos till a later PR, or either:

  • implement custom reading from /dev/urandom when compiling for macos.
  • cross-compile from x86_64-macos to arm64-macos
  • download the missing files like SecRandom.h

Disable until we can resolve the error

    CC: ../nimdir/lib/std/sysrand.nim
    /home/runner/.cache/nim/configlet_r/@m..@snimdir@slib@sstd@ssysrand.nim.c:9:10:
    fatal error: 'Security/SecRandom.h' file not found

which is due to a recent commit [1].

[1] 53a75a2 ("nimble, uuid: generate UUIDs via std/sysrand, not pragmagic/uuids", 2023-08-07)
Comment on lines 17 to 39
nimble --verbose build --cpu:"${arch}" --os:"${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
)

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

gh release upload "${build_tag}" "${artifacts_dir}"/*
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This duplicates some logic from the existing:

  • .github/bin/build
  • .github/bin/create-artifact
  • .github/bin/publish-release

because they're difficult to adapt for cross-compilation with their current factoring.

I think this will be easier to clean up when we've improved the build process to resolve #551.

configlet.nimble Outdated Show resolved Hide resolved
@ee7 ee7 marked this pull request as ready for review August 14, 2023 20:27
Copy link
Member

@ErikSchierboom ErikSchierboom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a consequence of 53a75a2. I guess we can defer arm64-macos till a later PR, or either:

implement custom reading from /dev/urandom when compiling for macos.
cross-compile from x86_64-macos to arm64-macos
download the missing files like SecRandom.h

I'm fine with whatever works best for you. I'm also fine to do it in a follow-up PR

Our `strip` doesn't support elf64-aarch64 as a target, and `zig objcopy`
doesn't have a `-R, --remove-section` option. Use llvm-strip when it's
installed.
Format with

  shfmt -i 2 -sr -kp -ci -w ./cross-compile
@ee7 ee7 changed the title .github, config, nimble: use zig to cross compile for arm64 .github, config: use Zig to cross compile arm64 Linux asset Aug 16, 2023
@ee7 ee7 merged commit 0e8d665 into exercism:main Aug 16, 2023
6 checks passed
@ee7 ee7 deleted the build-use-zig branch August 16, 2023 08:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants