Fix macOS arm64 (Apple Silicon) linker support - #470
metaneutrons wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the build/link logic to support successful linking on macOS arm64 (Apple Silicon) by adjusting architecture detection and Darwin-specific linker flags/behaviors.
Changes:
- Normalize
arm64toaarch64in the makefile’sTARGET_ARCHdetection before the 32-bit ARM normalization. - Update the Darwin linker invocation in
fbc.basto add-arch arm64for AArch64 and use modern-platform_version/-syslibrootbehavior (includingxcrunSDK detection on Darwin hosts), while avoiding GNU-ld-only flags/libs on Darwin. - Make cycle profiling compile on Darwin by disabling ELF section-boundary-symbol usage and emitting an empty report payload.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| makefile | Normalizes arm64 → aarch64 ahead of 32-bit ARM matching to select the correct target CPU family on macOS Apple Silicon. |
| src/compiler/fbc.bas | Adjusts Darwin link flags for arm64 and modern Apple ld usage (SDK/sysroot handling, platform version, and default libs). |
| src/rtlib/profile_cycles.c | Guards ELF __start/__stop usage on Darwin and provides a safe no-data fallback so it compiles on Mach-O. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
uname -m reports "arm64" on Apple Silicon, which matched the arm% pattern and was normalized to "arm" -- the 32-bit family. A plain "make" on macOS therefore resolved FBTARGET to darwin-arm instead of darwin-aarch64, so objects and libraries landed in directories that do not match the ones fbc looks for at run time (lib/freebasic/darwin-aarch64). Normalize aarch64/arm64 first, then let the remaining 32-bit spellings match armv%/arm. Verified that arm-linux-gnueabihf and armv7-linux-gnueabihf still resolve to linux-arm, and that arm64-apple-darwin resolves to darwin-aarch64. Based on the corresponding change in freebasic#470 by @metaneutrons.
|
Nice work on getting the platform pieces in order — the While comparing our two approaches I ran into two things that stop this branch 1.
and no startup object reaches the link line. ld64 then fails with: because the SDK's 2. arm64 needs the DATA descriptor aligned. It is emitted as a packed That one is a hard error on arm64 (it is only a warning on x86_64). #479 fixes both, plus a couple of other arm64-specific items: Not trying to compete with this PR — happy for whichever lands first to win; I |
The compiler reads what a toolchain binary prints with INPUT, which is meant for data records: it ends the field at the first comma and strips surrounding quotes. A path like /opt/toolchains/gcc,15/lib/libgcc.a comes back as /opt/toolchains/gcc, and the remainder is left in the pipe, so a following read returns the wrong line. fbcQueryCC() is where this bites in this tree. It answers -print-libgcc-file-name, and the win32 aarch64 link line takes the compiler runtime from it: with a comma in the path fbc stops with "File not found, compiler runtime" instead of linking. Reproduced with a stub toolchain that reports such a path: the cross target for win32-aarch64 failed on the truncated path before and now passes the whole one to the linker. The same read in hGet1stOutputLineFromCommand() is fixed along with it; that one is what upstream freebasic/fbc#470 changes. Contrary to that PR's description, spaces were never the problem — INPUT returns "/Users/me/My SDKs/MacOSX.sdk" unharmed; commas and quotes are what it mangles.
## Summary The compiler reads what a toolchain binary prints with `INPUT`, which is meant for data records: it ends the field at the first comma and strips surrounding quotes. A path like `/opt/toolchains/gcc,15/lib/libgcc.a` comes back as `/opt/toolchains/gcc`, and the remainder stays in the pipe, so a following read returns the wrong line. `fbcQueryCC()` is where this bites in this tree. It answers `-print-libgcc-file-name`, and the win32 aarch64 link line takes the compiler runtime from it: with a comma in the path fbc stops with `File not found, compiler runtime` instead of linking. The same read in `hGet1stOutputLineFromCommand()`, which feeds the gold-linker probe, is fixed along with it — that is the one upstream freebasic/fbc#470 changes. Contrary to that PR's description, spaces were never the problem. Measured against a file holding realistic tool output: | line | `INPUT #` | `LINE INPUT #` | | --- | --- | --- | | `/Users/me/My SDKs/MacOSX.sdk` | unharmed | unharmed | | `/opt/toolchains/gcc,15/lib/libgcc.a` | `/opt/toolchains/gcc` | unharmed | | `"/quoted path"/lib/libgcc.a` | `/quoted path` | unharmed | ## Verification - [x] CMake build completed on the affected host (Linux x86_64). - [x] `fbc --version` or a focused compiler/runtime test passed — the three compiler regressions are green. - [x] Copyright and licence notices remain intact. - [x] No generated binaries or unrelated changes are included. Reproduced end to end with a stub toolchain whose `-print-libgcc-file-name` answers a path containing a comma: cross-targeting win32-aarch64 failed with `File not found, compiler runtime` before the change and now hands the whole path to the linker.
Summary
Fix linking on macOS arm64 (Apple Silicon, M1/M2/M3/M4).
Changes (3 files, +47/-11)
makefile:
arm64(fromuname -m) toaarch64before the 32-bitarmv%catch-allsrc/compiler/fbc.bas:
line inputinhGet1stOutputLineFromCommand(handles spaces in SDK paths)-arch arm64forFB_CPUFAMILY_AARCH64on darwin-macosx_version_minwith-platform_version macos <min> <sdk>xcrun --show-sdk-version(fallback 14.0)xcrun --show-sdk-path(only on darwin host, respects user-sysroot, quoted with QUOTE)--sysroot=on darwin (Apple ld uses-syslibroot)--eh-frame-hdron darwin (unsupported by Apple ld)-lgccfrom darwin default libs (unavailable with Apple clang)src/rtlib/profile_cycles.c:
__start_/__stop_section boundary symbol declarations and usage with!defined(HOST_DARWIN)data=NULL, length=0fallback on darwin (cycle profiling compiles but produces no output)Testing
Successfully builds fbc and runtime library on macOS 15 (Sequoia) with Apple clang 21 on M4.
Notes
-profile cyclescompiles on darwin but produces no per-procedure data (Mach-O lacks ELF section boundary symbols)bootstrap/darwin-aarch64/(copy frombootstrap/linux-aarch64/+ fix clang computed goto)