Request for ARM Assembly(64bit) Track

Normally I would agree but the problem is the assembly syntax is different on macOS ARM64 vs linux ARM64. Specially the sys calls are different and some of the neumonics. If we target macOS, any student working locally would have to have a Mac with a M processor.

I am wondering if we just take this time to add a bunch of exercises and then go live when the proper runner is available? I don’t really want to put this on hold, but that may be the best option?

5 Likes

Ok, looks like I have a working solution. Just needed to install Qemu on an x64_64 runner and then we can use an arm64 container.

2 Likes

GitHub Actions images for arm64 just arrived.

4 Likes

Thanks for posting. This will make things easier.

A test generator:

1 Like

I don’t really do reviews anymore, but it looks good! I’d just merge it :)

1 Like

I’ve just merged 20 exercises :)

Could someone with CLI write access please merge Add arm64-assembly test configuration by keiravillekode · Pull Request #1178 · exercism/cli · GitHub

1 Like

PR merged. Thanks!

Continuous integration using qemu. Tests currently take about 20s to run.

I think the arm64 runners are generally available now. Not sure if you would prefer to use them over qemu?

Many students and contributors, such as myself, use x86 hardware, so we need to ensure support for qemu is retained.

1 Like

This is a great effort, thanks! What’s missing for getting the already implemented exercises live? There are quite a few already!

See arm64-assembly-test-runner issue #8 for the current status.

Thanks, that helps. However, the discussion has stopped some months ago and there’s an unfinished PR to switch the image to x86_64. Do I understand correctly that it is unclear whether changes to the container hosts are required, and if yes, whether they’re acceptable? AFAIU, there should be no issue running the tests with an x86_64 image on an unmodified x86_64 container host. We could just do the exact same thing that students are asked to do locally: use a cross-compiler to build an aarch64 binary and then invoke the QEMU userspace emulator via qemu-aarch64 to run it. In addition to the cross compiler we’d need a minimal sysroot containing libc, but that should be about it. I tried doing that based on a debian:12-slim image and it works fine. Alpine doesn’t include all the tools necessary out-of-the-box, so some manual effort is involved, but it is just as well possible. Should I just open another PR in that repo?

About native macOS support, I do understand that syscalls would be different between Linux and macOS, but what exercises are there even that require the student to use syscalls? Other than that, the only difference seems to be that macOS needs a leading underscore when calling a function that’s implemented in assembly code, whereas on Linux no leading underscore should be added. That could be easily handled in the test code using the preprocessor. I played with two or three exercises and the example implementations worked fine on macOS for me. I suppose there would be more students using Apple Silicon than those with Raspberry Pis. Not being able to target that out of the box I would find really sad. x86_64 macOS would have to use emulation, just like x86_64 Linux.

This is all excellent. Would you also be interested in helping with a risc-v test runner?

About 35 tracks use Alpine, 7 use Debian, 11 use Ubuntu, and others use existing images for their languages. There isn’t a strict requirement, but larger images cost Exercism more.

We can list grep as foregone, i.e. an exercise the track won’t implement. So none of the track’s exercises require syscalls.

We currently have

extern const char *hello(void);

and

hello:
    ...

Can we have something like

extern const char* ASSEMBLY hello(void);

where the Makefile would define ASSEMBLY to tell macOS there is no leading underscore?

1 Like

I think we want a solution where no changes to container hosts are required.

PRs very welcome. I think there is a test runner reviewer team that gives helpful feedback.

About the test runner image, I played a bit more with different options and it looks as if ubuntu is actually the best base here, since we end up with the smallest image (~370 MB) without having to do any hacks. Best of all, the existing Makefiles work unmodified. alpine doesn’t support cross compilation that targets Linux. Their aarch64 gcc is apparently meant to build code for MCUs. I was able to manually install (i.e., extract) aarch64 musl and musl-dev and then tell the aarch64 gcc to link against those, but only static binaries worked and quite a few extra flags are necessary to make it work. So that’d require changes to the makefiles. Fedora has a cross compiler and a sysroot package with the libs and all. That worked also, but at least the --sysroot argument is required, so also changes to the Makefile. And the resulting image was also 330 MB or so, so not that much smaller than ubuntu. Anyway, I will put the proposal with ubuntu as a base in a PR.

About RISC V, I think the exact same pattern could be used. Simply replace aarch64 with riscv64 in the package names.

Lastly, I also looked a bit into the macOS issue. I was under the impression that the underscore needs to be added from C, but it is actually the other way around: when you have extern const char* hello(void); in C, your asssembly code must export _hello. So a preprocessor #ifdef doesn’t really help here. One approach could be requesting from everyone, no matter the platform, to use leading underscores in their assembly code and then add it to the calling code via preprocessor for Linux. Another approach that works is telling the compiler explicitly the name of the assembly symbol:

extern const char* hello(void) __asm__("hello");

This works for gcc and clang with this syntax and also makes Linux gcc as well as macOS clang accept the same assembly. However, when playing with other exercises, I got some warnings about alignment requirements that apparently exist on macOS and not on Linux. So it’s possible that there are more differences than just syscalls and leading underscore. If those are a show stopper remains to be seen. Anyway, that’s for later. Let’s focus on the test runner for now to get this track going. Not supporting macOS for local development for now is fine.

2 Likes

I opened a PR now: Switch test runner image to amd64 by ahans · Pull Request #25 · exercism/arm64-assembly-test-runner · GitHub

I hope that this is good enough to launch the track! Let’s discuss what else is missing.

1 Like

Would you and Isaac like to be added as track maintainers?

Here are the next steps as I understand them.

We need to request that branch protection be enabled, so no individual maintainer can commit a change without it having been reviewed. (This was very convenient earlier when I was rapidly adding exercises.)

After merging your test runner PR, we need to update config.json to say we have a test runner.

Then we need to verify the track works as expected, and invite all maintainers to give feedback. (At this stage exercism.org/tracks/arm64-assembly/ will still only work for maintainers.)

Then we update config.json again to say the track is active, and celebrate by telling this forum the track is live.

1 Like