diff --git a/README.md b/README.md index 36bea72..09bbb3d 100644 --- a/README.md +++ b/README.md @@ -398,26 +398,34 @@ systems, so you do not have to drive the container by hand. produces `dist/json-c.lha` for distribution. Both default to `AmigaOS3 AmigaOS4 MorphOS`, and both take the variant list -from the same table in `amiga/build-amiga-sdk.sh`, so they cannot disagree. 22 -libraries are built in total: 15 for AmigaOS 3 (newlib, libnix and clib2, each -across the five multilib slots), 3 for AmigaOS 4 (newlib, clib2, clib4) and 4 -for MorphOS (ixemul and native, each with and without `-mbaserel32`). +from the same table in `amiga/build-amiga-sdk.sh`, so they cannot disagree. 31 +libraries are built in total: 24 for AmigaOS 3 (newlib, libnix and clib2, each +across eight multilib slots: 68000, 68020, `-fbaserel`, `-fbaserel -m68020`, +`-fbaserel32 -m68020`, and a `libm881/` FPU build of the three 68020 slots), +3 for AmigaOS 4 (newlib, clib2, clib4) and 4 for MorphOS (ixemul and native, +each with and without `-mbaserel32`). Which of them actually *link* is a separate question from whether they build, and was checked by compiling a program against each one: | target | links | |--------|-------| -| AmigaOS 3, libnix | all 5 slots | -| AmigaOS 3, clib2 | `lib/libm020/` and `lib/libb32/libm020/` only | -| AmigaOS 3, newlib | none -- the m68k newlib tree has no `gettimeofday()` | +| AmigaOS 3, libnix | all 8 slots | +| AmigaOS 3, clib2 | all 8 slots | +| AmigaOS 3, newlib | all 8 slots | | AmigaOS 4 | all 3 (newlib, clib2, clib4) | | MorphOS | all 4 slots | -The clib2 failures are inside clib2 itself: its 68000 multilib provides no -`strtoll`/`strtoull`, and 16-bit `-fbaserel` overflows with *truncated to fit: -DREL16* once json-c's data is added -- `-fbaserel32` has no 64 KB limit. Link -with `-ljson-c -lm` after your own objects, and add `-lunix` for clib2. +The AmigaOS 3 results need a compiler image with the November 2026 +AmigaSDK-gcc cleanup, which stopped stale toolchain files overwriting the +newer newlib and clib2. With an older image, clib2's 68000 multilib lacks +`strtoll`/`strtoull`, newlib lacks `gettimeofday()`, and clib2 `-fbaserel` links +fail with a *dangerous relocation*. The `libm881/` slots matter for FPU builds +(`-m68881`, `-mhard-float`, `-m68040`/`-m68060`). Without them the linker falls back +to the soft-float build, which clib2 cannot link. With clib2, add `-m68881` to a +bare `-m68040`/`-m68060`: those compile soft-float code but link the FPU +libraries. Link with `-ljson-c -lm` after your own objects, and add `-lunix` for +clib2. The archive is a single `json-c/` directory at the root, with the readme and one directory per system, each following the compiler's own layout so it can diff --git a/amiga/build-amiga-sdk.sh b/amiga/build-amiga-sdk.sh index 9669ae3..e175277 100755 --- a/amiga/build-amiga-sdk.sh +++ b/amiga/build-amiga-sdk.sh @@ -14,10 +14,12 @@ cd "$ROOT" OSES=("$@"); [[ ${#OSES[@]} -eq 0 ]] && OSES=(AmigaOS3 AmigaOS4 MorphOS) # os | image tag | sdk subdir +# Override an image with AMIGA_IMAGE_AmigaOS3 / _AmigaOS4 / _MorphOS, e.g. to +# build against a locally built compiler image before it is published. os_image() { case "$1" in - AmigaOS3) echo "sacredbanana/amiga-compiler:m68k-amigaos m68k-amigaos" ;; - AmigaOS4) echo "sacredbanana/amiga-compiler:ppc-amigaos ppc-amigaos" ;; - MorphOS) echo "sacredbanana/amiga-compiler:ppc-morphos ppc-morphos" ;; + AmigaOS3) echo "${AMIGA_IMAGE_AmigaOS3:-sacredbanana/amiga-compiler:m68k-amigaos} m68k-amigaos" ;; + AmigaOS4) echo "${AMIGA_IMAGE_AmigaOS4:-sacredbanana/amiga-compiler:ppc-amigaos} ppc-amigaos" ;; + MorphOS) echo "${AMIGA_IMAGE_MorphOS:-sacredbanana/amiga-compiler:ppc-morphos} ppc-morphos" ;; *) return 1 ;; esac; } @@ -46,6 +48,20 @@ variants_AmigaOS3=( "clib2|libb|-DM68K_CRT=clib2 -DM68K_CPU=68000 -DM68K_BASEREL=baserel" "clib2|libb/libm020|-DM68K_CRT=clib2 -DM68K_CPU=68020 -DM68K_BASEREL=baserel" "clib2|libb32/libm020|-DM68K_CRT=clib2 -DM68K_CPU=68020 -DM68K_BASEREL=baserel32" + # FPU slots (M68K_FPU=hard -> -mhard-float). -m68881, -mhard-float, and + # -m68040/-m68060 (which the specs map here too) link + # from libm020/libm881; without these the linker falls back to the + # soft-float libm020 build, whose __adddf3/__nedf2 calls clib2's FPU libm + # cannot satisfy. + "libnix|libm020/libm881|-DM68K_CRT=nix20 -DM68K_CPU=68020 -DM68K_FPU=hard -DM68K_BASEREL=off" + "libnix|libb/libm020/libm881|-DM68K_CRT=nix20 -DM68K_CPU=68020 -DM68K_FPU=hard -DM68K_BASEREL=baserel" + "libnix|libb32/libm020/libm881|-DM68K_CRT=nix20 -DM68K_CPU=68020 -DM68K_FPU=hard -DM68K_BASEREL=baserel32" + ".|libm020/libm881|-DM68K_CRT=newlib -DM68K_CPU=68020 -DM68K_FPU=hard -DM68K_BASEREL=off" + ".|libb/libm020/libm881|-DM68K_CRT=newlib -DM68K_CPU=68020 -DM68K_FPU=hard -DM68K_BASEREL=baserel" + ".|libb32/libm020/libm881|-DM68K_CRT=newlib -DM68K_CPU=68020 -DM68K_FPU=hard -DM68K_BASEREL=baserel32" + "clib2|libm020/libm881|-DM68K_CRT=clib2 -DM68K_CPU=68020 -DM68K_FPU=hard -DM68K_BASEREL=off" + "clib2|libb/libm020/libm881|-DM68K_CRT=clib2 -DM68K_CPU=68020 -DM68K_FPU=hard -DM68K_BASEREL=baserel" + "clib2|libb32/libm020/libm881|-DM68K_CRT=clib2 -DM68K_CPU=68020 -DM68K_FPU=hard -DM68K_BASEREL=baserel32" ) # Unlike m68k, where each C runtime is its own tree (libnix/, clib2/), the PPC # toolchains make the runtime a multilib SLOT under lib/, with headers coming diff --git a/amiga/json-c.readme.template b/amiga/json-c.readme.template index 0e43654..df0303c 100644 --- a/amiga/json-c.readme.template +++ b/amiga/json-c.readme.template @@ -34,6 +34,13 @@ Contents lib/libb/ 68000, -fbaserel lib/libb/libm020/ 68020, -fbaserel lib/libb32/libm020/ 68020, -fbaserel32 + lib/libm020/libm881/ 68020 + FPU (-m68881, -mhard-float, + lib/libb/libm020/libm881/ also -m68040/-m68060), absolute, + lib/libb32/libm020/libm881/ -fbaserel and -fbaserel32 + + The libm881/ builds use FPU instructions. Without them an FPU program + would fall back to the soft-float libm020/ build, which clib2 cannot link + (its FPU libm has no soft-float helpers such as __adddf3). On PPC a C runtime is not a separate tree but a multilib slot beneath one shared lib/, with headers in the single shared include/: @@ -68,18 +75,16 @@ Which variants link Verified by compiling the snippet above against each shipped library. - AmigaOS3 libnix all 5 slots link. + AmigaOS3 all 8 slots link for newlib, libnix and clib2, provided the + compiler image carries the AmigaSDK-gcc cleanup of 2026-11 that + stopped stale 2023/2024 toolchain files overwriting the newer + newlib and clib2. Older images lack strtoll()/strtoull() in + clib2's 68000 multilib and gettimeofday() in newlib, and fail + -fbaserel clib2 links with a "dangerous relocation". - clib2 lib/libm020/ and lib/libb32/libm020/ link. The other - three fail inside clib2 itself: its 68000 multilib has - no strtoll()/strtoull(), and 16-bit -fbaserel overflows - with "truncated to fit: DREL16" once json-c's data is - added. -fbaserel32 has no such limit. - - newlib builds, but does not link: the m68k newlib tree has no - gettimeofday(). The libraries are shipped anyway, since - that is a gap in the SDK rather than in json-c and a - newlib with gettimeofday() implemented would link. + Known toolchain issue: with clib2, -m68040/-m68060 on their + own compile soft-float code but link the FPU libraries. Add + -m68881. AmigaOS4 all three (newlib, clib2, clib4) link.