build: add ARM64 architecture support to devcontainer - #14008
Conversation
Closes: stdlib-js#4934 --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown_pkg_readmes status: na - task: lint_markdown_docs status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: na - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: na - task: lint_license_headers status: passed ---
ContextThe original issue (#4934) was filed because Problem 1: GCC/binutils version mismatch on ARM64The This breaks Reference for the AEABI build attributes feature: https://gcc.gnu.org/pipermail/gcc-patches/2024-October/666180.html Problem 2: shellcheck wrong architectureThe On ARM64, the feature picks the RISC-V binary. It installs without error and appears to run only because Docker Desktop registers QEMU binfmt handlers. On amd64, it correctly picks x86_64. The post-create script replaces the wrong binary with the correct Approaches considered
What was verified (Apple Silicon M3)
Additional fix: shellcheck.mkThe |
Follow-up: darwin arm64 support for
|
kgryte
left a comment
There was a problem hiding this comment.
LGTM. Let's go ahead and get this in so that folks can test it out.
Resolves #4934, stdlib-js/metr-issue-tracker#1123
Description
This pull request:
Related Issues
This pull request has the following related issues:
Questions
No.
Other
Analysis
The original issue was filed against the
universal:2image, which has no ARM64 manifest. PR #8600 (Dec 2025) switched the image tojavascript-node:1-22-bookworm, which ships bothlinux/amd64andlinux/arm64. So the base image blocker is already resolved.The remaining problems were found by building the devcontainer on an Apple Silicon Mac and testing every tool:
Problem 1: GCC 16 and binutils version mismatch
The
r-aptdevcontainer feature upgrades the base system from Debian bookworm to testing, which installs GCC 16. GCC 16 was built withHAVE_AS_AEABI_BUILD_ATTRIBUTES=1(it detected support for AArch64 AEABI build attributes in its build-time assembler), but the container'sasis from an older binutils that does not understand.aeabi_subsectionand.aeabi_attributedirectives. This causes every native compilation to fail on ARM64:npm install(@kaciras/deasyncnode-gyp build),make install-node-addons,make benchmark-c, andgfortran.Reference: https://gcc.gnu.org/pipermail/gcc-patches/2024-October/666180.html
Problem 2: shellcheck wrong architecture
The
devcontainers-extra/features/shellcheckfeature usesassetRegex='shellcheck-.*.tar.xz$'to match release assets, with no architecture filtering. On ARM64 it installs a RISC-V binary instead of thelinux.aarch64one. The binary appears to work only because Docker Desktop has QEMU binfmt emulation, but it is not native and would fail in environments without emulation.Approaches considered
Fix in post-create only (chosen): Add architecture detection to the post-create script. On ARM64, pin gcc/g++/gfortran back to version 12 via
update-alternativesand replace the shellcheck binary with the correct release. On x86-64, nothing changes.Separate ARM64 devcontainer.json: Create a second config under
.devcontainer/arm64/. Rejected because the base image already supports both architectures, so a second config adds maintenance burden for no gain.Replace r-apt with r-rig for everyone: Would avoid the gcc upgrade entirely, but changes the working x86-64 setup and needs separate testing.
Changes
.devcontainer/post-create: Architecture detection. On aarch64, pin gcc/g++/gfortran to version 12 beforemake install, and replace the shellcheck binary after feature install.tools/make/lib/install/shellcheck.mk: Add alinux.aarch64URL branch for ARM64 Linux, update the darwin FIXME comment to be more specific.deps/checksums/shellcheck_v0_8_0_linux_aarch64_tar_xz/sha256: Checksum for thelinux.aarch64shellcheck release.docs/contributing/setting_up_a_devcontainer.md: Remove the "does not support ARM64" note, add "supports both x86-64 and ARM64".docs/contributing/FAQ.md: Same doc update, remove the dead[devcontainer-issue]link.Verification
Tested on Apple Silicon (M3, Docker Desktop,
aarch64). After fixes:Additionally verified:
make install-node-addons): passestest.native.js): 10/10 passmake benchmark-c): ~262M ops/secmake examples-c): compile and run correctlyChecklist
AI Assistance
If you answered "yes" above, how did you use AI assistance?
Disclosure
Claude Code was used for the ARM64 investigation (building the devcontainer, probing tool architectures, diagnosing the GCC/binutils mismatch and shellcheck wrong-arch issue), writing the post-create fixups, and updating documentation.
@stdlib-js/reviewers