Skip to content

Commit b75bfee

Browse files
authored
Merge pull request #318 from DrXiao/workflow/use-arm64-runner-native
Speed up host-arm workflow via native execution on Arm64 runners
2 parents 1d90076 + fa62d30 commit b75bfee

File tree

6 files changed

+81
-30
lines changed

6 files changed

+81
-30
lines changed

.github/workflows/main.yml

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -55,37 +55,44 @@ jobs:
5555
make check DYNLINK=${{ steps.determine-mode.outputs.DYNLINK }} || exit 1
5656
5757
host-arm:
58-
runs-on: ubuntu-24.04
58+
runs-on: ubuntu-24.04-arm
5959
strategy:
6060
matrix:
6161
link_mode: [static, dynamic]
6262
steps:
63-
- name: Checkout code
64-
uses: actions/checkout@v4
65-
- name: Determine static or dynamic linking mode
66-
id: determine-mode
67-
run: |
68-
if [ "${{ matrix.link_mode }}" = "dynamic" ]; then
69-
echo "Use dynamic linking mode"
70-
echo "DYNLINK=1" >> "$GITHUB_OUTPUT"
71-
else
72-
echo "Use static linking mode"
73-
echo "DYNLINK=0" >> "$GITHUB_OUTPUT"
74-
fi
75-
- name: Build artifacts
76-
# The GitHub Action for non-x86 CPU
77-
# https://github.com/uraimo/run-on-arch-action
78-
uses: uraimo/run-on-arch-action@v3
79-
with:
80-
arch: armv7
81-
distro: ubuntu24.04
82-
githubToken: ${{ github.token }}
83-
install: |
84-
apt-get update -qq -y
85-
apt-get install -yqq build-essential
63+
- name: Checkout code
64+
uses: actions/checkout@v4
65+
66+
- name: Download dependencies
67+
run: |
68+
sudo dpkg --add-architecture armhf
69+
sudo apt-get update -q -y
70+
sudo apt-get install -q -y graphviz jq
71+
sudo apt-get install -q -y build-essential libc6:armhf
72+
sudo wget https://github.com/fastfetch-cli/fastfetch/releases/download/2.58.0/fastfetch-linux-aarch64.deb
73+
sudo dpkg -i fastfetch-linux-aarch64.deb
74+
75+
- name: Determine static or dynamic linking mode
76+
id: determine-mode
77+
run: |
78+
if [ "${{ matrix.link_mode }}" = "dynamic" ]; then
79+
echo "Use dynamic linking mode"
80+
echo "DYNLINK=1" >> "$GITHUB_OUTPUT"
81+
else
82+
echo "Use static linking mode"
83+
echo "DYNLINK=0" >> "$GITHUB_OUTPUT"
84+
fi
85+
86+
- name: Build artifacts
8687
run: |
8788
make ARCH=arm DYNLINK=${{ steps.determine-mode.outputs.DYNLINK }}
89+
90+
- name: Sanitizer-enabled stage 0 tests
91+
run: |
8892
make check-sanitizer DYNLINK=${{ steps.determine-mode.outputs.DYNLINK }} || exit 1
93+
94+
- name: Unit tests
95+
run: |
8996
make check DYNLINK=${{ steps.determine-mode.outputs.DYNLINK }} || exit 1
9097
9198
preprocessor-host:

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ STAGE0 := shecc
3636
STAGE1 := shecc-stage1.elf
3737
STAGE2 := shecc-stage2.elf
3838

39+
USE_QEMU ?= 1
3940
OUT ?= out
4041
ARCHS = arm riscv
4142
ARCH ?= $(firstword $(ARCHS))
42-
HOST_ARCH = $(shell arch 2>/dev/null)
4343
SRCDIR := $(shell find src -type d)
4444
LIBDIR := $(shell find lib -type d)
4545

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ emulation on GNU/Linux:
6666
$ sudo apt-get install qemu-user
6767
```
6868

69+
The build system is able to verify whether the running machine can perform native
70+
execution without QEMU. The host machine may install the prebuilt
71+
[fastfetch](https://github.com/fastfetch-cli/fastfetch/), which allows the build
72+
system to determine whether native execution can be enabled.
73+
6974
It is still possible to build `shecc` on macOS or Microsoft Windows. However,
7075
the second stage bootstrapping would fail due to `qemu-arm` absence.
7176

mk/arm.mk

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
ARCH_NAME = armv7l
1+
# Allow the following machines to use native execution
2+
#
3+
# - Beaglebone Black (Cortex-A8)
4+
# - Raspberry Pi 3 (Cortex-A53)
5+
# - Raspberry Pi 4 (Cortex-A72)
6+
# - Raspberry Pi 5 (Cortex-A76)
7+
ALLOW_MACHINES = BeagleBone-Black Raspberry-Pi-3 Raspberry-Pi-4 Raspberry-Pi-5
28
ARCH_RUNNER = qemu-arm
39
ARCH_DEFS = \
410
"/* target: ARM */\n$\
@@ -14,6 +20,39 @@ ARCH_DEFS = \
1420
\#define MAX_ARGS_IN_REG 4\n$\
1521
"
1622

23+
# If the running machine has the "fastfetch" tool installed, the build
24+
# system will verify whether native execution can be performed.
25+
ifneq ($(shell which fastfetch),)
26+
# 1. Replace whitespaces with hyphens after retrieving the host
27+
# machine name via the "fastfetch" tool.
28+
#
29+
# 2. If at least one machine name in the allowlist is found in
30+
# the host machine name, it can perform native execution.
31+
#
32+
# Therefore, set USE_QEMU to 0.
33+
HOST_MACHINE = $(shell fastfetch --logo none --structure Host | sed 's/ /-/g')
34+
USE_QEMU = $(if $(strip $(foreach MACHINE, $(ALLOW_MACHINES), $(findstring $(MACHINE),$(HOST_MACHINE)))),0,1)
35+
36+
# Special case: GitHub workflows on Arm64 runners
37+
#
38+
# When an Arm-hosted runner executes "fastfetch --logo none --structure Host",
39+
# it produces the following output:
40+
#
41+
# Host: Virtual Machine (Hyper-V UEFI Release v4.1)
42+
#
43+
# Arm-hosted runners are also capable of performing native execution. However,
44+
# directly adding "Virtual-Machine" to the allowlist would be ambiguous.
45+
# Therefore, the build system instead checks the CPU name using the
46+
# "fastfetch --logo none --structure CPU" command.
47+
#
48+
# If the detected CPU is "Neoverse-N2", the build system treats the running
49+
# machine as an Arm-hosted runner and enable native execution.
50+
ifeq ($(USE_QEMU),1)
51+
HOST_CPU = $(shell fastfetch --logo none --structure CPU | sed 's/ /-/g')
52+
USE_QEMU = $(if $(strip $(findstring Neoverse-N2,$(HOST_CPU))),0,1)
53+
endif
54+
endif
55+
1756
# Find the sysroot of the ARM GNU toolchain if using dynamic linking.
1857
#
1958
# Since developers may install the toolchain manually instead of
@@ -23,7 +62,7 @@ ARCH_DEFS = \
2362
# Therefore, the following process first locates find the correct
2463
# sysroot of the toolchain, and then generate the ELF interpreter
2564
# prefix for later use.
26-
ifneq ($(HOST_ARCH),$(ARCH_NAME))
65+
ifeq ($(USE_QEMU),1)
2766
ifeq ($(DYNLINK),1)
2867
CROSS_COMPILE = arm-none-linux-gnueabihf-
2968
ARM_CC = $(CROSS_COMPILE)gcc

mk/common.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pass = $(PRINTF) "$(PASS_COLOR)$1 Passed$(NO_COLOR)\n"
2525
# Check the prerequisites
2626
PREREQ_LIST := dot jq
2727
TARGET_EXEC ?=
28-
ifneq ($(HOST_ARCH),$(ARCH_NAME))
28+
ifeq ($(USE_QEMU),1)
2929
# Add qemu to the list if the host and target architectures differ
3030
PREREQ_LIST += $(ARCH_RUNNER)
3131
ifeq ($(filter $(ARCH_RUNNER),$(notdir $(shell which $(ARCH_RUNNER)))),)

mk/riscv.mk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# Enforce the use qemu of by setting the ARCH_NAME variable to empty
2-
ARCH_NAME =
1+
# Enforce the use qemu of by setting the ALLOW_MACHINES variable to empty
2+
ALLOW_MACHINES =
33
ARCH_RUNNER = qemu-riscv32
44
ARCH_DEFS = \
55
"/* target: RISCV */\n$\

0 commit comments

Comments
 (0)