mirror of
https://github.com/json-c/json-c.git
synced 2026-11-05 21:20:16 +08:00
Merge pull request #963 from sacredbanana/fbaserel
Amiga enhancements: Build for more platforms + package for Aminet
This commit is contained in:
7 files changed
+553
-4
No files matched your search
@@ -0,0 +1,73 @@
|
|||||||
|
name: amiga
|
||||||
|
|
||||||
|
# Verifies that AmigaOS 3/4 and MorphOS still cross-compile. The uploaded
|
||||||
|
# json-c.lha is a CI convenience artifact only — official json-c releases
|
||||||
|
# remain source-only. Aminet uploads are a separate, manual process and
|
||||||
|
# are not published from this job.
|
||||||
|
|
||||||
|
on: [push, pull_request, workflow_dispatch]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{github.workflow}}-${{github.event.pull_request.number || github.ref}}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
package:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 120
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v7
|
||||||
|
|
||||||
|
# Ubuntu's `lha` package is lhasa: extract-only, cannot create archives.
|
||||||
|
# Build LHa for UNIX (https://github.com/jca02266/lha) instead.
|
||||||
|
- name: Cache LHa for UNIX
|
||||||
|
id: cache-lha
|
||||||
|
uses: actions/cache@v6
|
||||||
|
with:
|
||||||
|
path: ~/.local/bin/lha
|
||||||
|
key: lha-16619b066b189ef289bb8b07b37d1c38d550da99-${{ runner.os }}
|
||||||
|
|
||||||
|
- name: Install LHa for UNIX
|
||||||
|
if: steps.cache-lha.outputs.cache-hit != 'true'
|
||||||
|
working-directory: ${{runner.temp}}
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y autoconf automake
|
||||||
|
curl -fsSL -o lha.tar.gz \
|
||||||
|
https://github.com/jca02266/lha/archive/16619b066b189ef289bb8b07b37d1c38d550da99.tar.gz
|
||||||
|
tar -xzf lha.tar.gz
|
||||||
|
cd lha-16619b066b189ef289bb8b07b37d1c38d550da99
|
||||||
|
autoreconf -is
|
||||||
|
./configure --prefix="$HOME/.local"
|
||||||
|
make -j"$(nproc)"
|
||||||
|
make install
|
||||||
|
|
||||||
|
- name: Add LHa to PATH
|
||||||
|
run: echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
||||||
|
|
||||||
|
- name: Check lha can create archives
|
||||||
|
run: |
|
||||||
|
command -v lha
|
||||||
|
d=$(mktemp -d)
|
||||||
|
echo probe > "$d/f"
|
||||||
|
( cd "$d" && lha -aq2 t.lha f )
|
||||||
|
test -s "$d/t.lha"
|
||||||
|
|
||||||
|
- name: Pull compiler images
|
||||||
|
run: |
|
||||||
|
docker pull sacredbanana/amiga-compiler:m68k-amigaos &
|
||||||
|
docker pull sacredbanana/amiga-compiler:ppc-amigaos &
|
||||||
|
docker pull sacredbanana/amiga-compiler:ppc-morphos &
|
||||||
|
wait
|
||||||
|
|
||||||
|
- name: Build and package
|
||||||
|
run: ./amiga/package-amiga.sh
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v7
|
||||||
|
with:
|
||||||
|
name: json-c.lha
|
||||||
|
path: dist/json-c.lha
|
||||||
|
if-no-files-found: error
|
||||||
@@ -94,3 +94,7 @@
|
|||||||
# Benchmarking input and output
|
# Benchmarking input and output
|
||||||
/bench/data
|
/bench/data
|
||||||
/bench/work
|
/bench/work
|
||||||
|
|
||||||
|
# AmigaOS packaging output
|
||||||
|
dist/
|
||||||
|
bld-*/
|
||||||
+71
-3
@@ -99,16 +99,77 @@ if (AMIGA)
|
|||||||
else()
|
else()
|
||||||
set(NEWLIB ON)
|
set(NEWLIB ON)
|
||||||
endif()
|
endif()
|
||||||
message(STATUS "Building for Motorola 68k AmigaOS using CRT: ${M68K_CRT}")
|
if (NOT DEFINED M68K_BASEREL)
|
||||||
|
set(M68K_BASEREL "baserel")
|
||||||
|
endif()
|
||||||
|
set(M68K_BASEREL "${M68K_BASEREL}" CACHE STRING "m68k base-relative addressing: baserel, baserel32, or off")
|
||||||
|
set_property(CACHE M68K_BASEREL PROPERTY STRINGS baserel baserel32 off)
|
||||||
|
if (NOT M68K_BASEREL STREQUAL "baserel" AND
|
||||||
|
NOT M68K_BASEREL STREQUAL "baserel32" AND
|
||||||
|
NOT M68K_BASEREL STREQUAL "off")
|
||||||
|
message(FATAL_ERROR "M68K_BASEREL must be baserel, baserel32, or off (got: ${M68K_BASEREL})")
|
||||||
|
endif()
|
||||||
|
set(M68K_CPU "${M68K_CPU}" CACHE STRING "m68k CPU target (e.g. 68020, 68040, 68060); empty uses the compiler default")
|
||||||
|
if (M68K_CPU STREQUAL "" OR M68K_CPU STREQUAL "off")
|
||||||
|
set(M68K_CPU_FLAG "")
|
||||||
|
elseif (M68K_CPU MATCHES "^-")
|
||||||
|
set(M68K_CPU_FLAG "${M68K_CPU}")
|
||||||
|
elseif (M68K_CPU MATCHES "^m")
|
||||||
|
set(M68K_CPU_FLAG "-${M68K_CPU}")
|
||||||
|
else()
|
||||||
|
set(M68K_CPU_FLAG "-m${M68K_CPU}")
|
||||||
|
endif()
|
||||||
|
if (M68K_CPU_FLAG STREQUAL "")
|
||||||
|
message(STATUS "Building for Motorola 68k AmigaOS using CRT: ${M68K_CRT}, baserel: ${M68K_BASEREL}")
|
||||||
|
else()
|
||||||
|
message(STATUS "Building for Motorola 68k AmigaOS using CRT: ${M68K_CRT}, baserel: ${M68K_BASEREL}, cpu: ${M68K_CPU_FLAG}")
|
||||||
|
endif()
|
||||||
elseif ($ENV{CROSS_PFX} STREQUAL "ppc-amigaos")
|
elseif ($ENV{CROSS_PFX} STREQUAL "ppc-amigaos")
|
||||||
set(AMIGA_PPC ON)
|
set(AMIGA_PPC ON)
|
||||||
message(STATUS "Building for PowerPC AmigaOS")
|
if (NOT DEFINED PPC_CRT)
|
||||||
|
set(PPC_CRT "newlib")
|
||||||
|
endif()
|
||||||
|
set(PPC_CRT "${PPC_CRT}" CACHE STRING "ppc-amigaos C runtime: newlib, clib2 or clib4")
|
||||||
|
set_property(CACHE PPC_CRT PROPERTY STRINGS newlib clib2 clib4)
|
||||||
|
if (NOT PPC_CRT STREQUAL "newlib" AND
|
||||||
|
NOT PPC_CRT STREQUAL "clib2" AND
|
||||||
|
NOT PPC_CRT STREQUAL "clib4")
|
||||||
|
message(FATAL_ERROR "PPC_CRT must be newlib, clib2 or clib4 (got: ${PPC_CRT})")
|
||||||
|
endif()
|
||||||
|
if (NOT PPC_CRT STREQUAL "newlib")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcrt=${PPC_CRT}")
|
||||||
|
endif()
|
||||||
|
message(STATUS "Building for PowerPC AmigaOS using CRT: ${PPC_CRT}")
|
||||||
elseif($ENV{CROSS_PFX} STREQUAL "ppc-morphos")
|
elseif($ENV{CROSS_PFX} STREQUAL "ppc-morphos")
|
||||||
set(MORPHOS ON)
|
set(MORPHOS ON)
|
||||||
|
if (NOT DEFINED MORPHOS_CLIB)
|
||||||
|
set(MORPHOS_CLIB "default")
|
||||||
|
endif()
|
||||||
|
set(MORPHOS_CLIB "${MORPHOS_CLIB}" CACHE STRING "MorphOS C library: default or libnix")
|
||||||
|
set_property(CACHE MORPHOS_CLIB PROPERTY STRINGS default libnix)
|
||||||
|
if (NOT MORPHOS_CLIB STREQUAL "default" AND NOT MORPHOS_CLIB STREQUAL "libnix")
|
||||||
|
message(FATAL_ERROR "MORPHOS_CLIB must be default or libnix (got: ${MORPHOS_CLIB})")
|
||||||
|
endif()
|
||||||
|
option(MORPHOS_BASEREL32 "MorphOS: build with -mbaserel32" OFF)
|
||||||
|
if (MORPHOS_CLIB STREQUAL "libnix")
|
||||||
|
# Same situation as the -noixemul path below: libnix's headers
|
||||||
|
# disagree with the ixemul ones about va_list, so the varargs
|
||||||
|
# helpers in debug.c trip -Wincompatible-pointer-types.
|
||||||
|
set(DISABLE_WERROR ON)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-incompatible-pointer-types")
|
||||||
|
endif()
|
||||||
|
if (MORPHOS_CLIB STREQUAL "libnix")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mclib=libnix")
|
||||||
|
endif()
|
||||||
|
if (MORPHOS_BASEREL32)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mbaserel32")
|
||||||
|
endif()
|
||||||
|
message(STATUS "Building for PowerPC MorphOS using clib: ${MORPHOS_CLIB}, baserel32: ${MORPHOS_BASEREL32}")
|
||||||
if (NOIXEMUL)
|
if (NOIXEMUL)
|
||||||
message(STATUS "Building for PowerPC MorphOS without ixemul")
|
message(STATUS "Building for PowerPC MorphOS without ixemul")
|
||||||
set(DISABLE_WERROR ON)
|
set(DISABLE_WERROR ON)
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -noixemul")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -noixemul")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-incompatible-pointer-types")
|
||||||
else()
|
else()
|
||||||
message(STATUS "Building for PowerPC MorphOS with ixemul")
|
message(STATUS "Building for PowerPC MorphOS with ixemul")
|
||||||
endif()
|
endif()
|
||||||
@@ -362,7 +423,14 @@ if ("${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER
|
|||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
||||||
endif()
|
endif()
|
||||||
if (AMIGA_M68K)
|
if (AMIGA_M68K)
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fbaserel")
|
if (M68K_BASEREL STREQUAL "baserel")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fbaserel")
|
||||||
|
elseif (M68K_BASEREL STREQUAL "baserel32")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fbaserel32")
|
||||||
|
endif()
|
||||||
|
if (NOT M68K_CPU_FLAG STREQUAL "")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${M68K_CPU_FLAG}")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-qual")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-qual")
|
||||||
|
|||||||
@@ -275,7 +275,9 @@ make install
|
|||||||
Building for Commodore Amiga or MorphOS
|
Building for Commodore Amiga or MorphOS
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
Building for Commodore Amiga is supported for both Motorola 68k (AmigaOS 3) and PowerPC (AmigaOS 4) architectures. MorphOS on compatible PowerPC hardware is also supported. You can set up a cross compiler locally, however it is much easier to use the already preconfigured Amiga development environment wtthin a Docker container.
|
Building for Commodore Amiga is supported for both Motorola 68k (AmigaOS 3) and PowerPC (AmigaOS 4) architectures. MorphOS on compatible PowerPC hardware is also supported. You can set up a cross compiler locally, however it is much easier to use the already preconfigured Amiga development environment within a Docker container.
|
||||||
|
|
||||||
|
Included below are instructions for building for specific individual systems, as well as how to build for *all* Amiga variants.
|
||||||
|
|
||||||
Install Docker on your machine if you don't already have it. You can download Docker Desktop for Windows/macOS/Linux [here](https://www.docker.com/products/docker-desktop/).
|
Install Docker on your machine if you don't already have it. You can download Docker Desktop for Windows/macOS/Linux [here](https://www.docker.com/products/docker-desktop/).
|
||||||
|
|
||||||
@@ -296,6 +298,41 @@ libjson-c.a will get created in the build directory.
|
|||||||
|
|
||||||
You can change newlib to nix20, nix13, ixemul or clib2 if you would like to build the library suited for libnix or clib2 instead. Newlib is default.
|
You can change newlib to nix20, nix13, ixemul or clib2 if you would like to build the library suited for libnix or clib2 instead. Newlib is default.
|
||||||
|
|
||||||
|
By default the m68k build uses `-fbaserel`. You can select a different base-relative mode with `-DM68K_BASEREL=`:
|
||||||
|
|
||||||
|
* `baserel` (default) — `-fbaserel`
|
||||||
|
* `baserel32` — `-fbaserel32`
|
||||||
|
* `off` — no base-relative flag
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake -DM68K_CRT=newlib -DM68K_BASEREL=baserel32 ..
|
||||||
|
cmake -DM68K_CRT=newlib -DM68K_BASEREL=off ..
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also set the target CPU with `-DM68K_CPU=`. This is passed to the compiler as `-m<cpu>` (for example `68020` becomes `-m68020`). If omitted, the compiler default is used.
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake -DM68K_CRT=newlib -DM68K_CPU=68020 ..
|
||||||
|
cmake -DM68K_CRT=newlib -DM68K_CPU=68040 -DM68K_BASEREL=baserel32 ..
|
||||||
|
```
|
||||||
|
|
||||||
|
A note on base-relative addressing (`-fbaserel`, i.e. `M68K_BASEREL=baserel`)
|
||||||
|
on m68k: a base-relative library keeps its globals at an offset from `a4`, and
|
||||||
|
`a4` is established once by the program's startup code. Such a library is only
|
||||||
|
safe inside a program that is itself base-relative **and** that declares every
|
||||||
|
function the OS can call back into (BOOPSI/MUI dispatchers, `struct Hook`
|
||||||
|
entries, interrupt servers) with `__saveds`, so `a4` is re-established on entry.
|
||||||
|
Without that, a hook entered from the OS runs with a foreign `a4` and every
|
||||||
|
`a4`-relative access made by this library -- or by libnix's `malloc` -- reads
|
||||||
|
from a wrong address.
|
||||||
|
|
||||||
|
Conversely, a library built *without* `-fbaserel` and compiled at `-O1` or above
|
||||||
|
may allocate `a4` as a scratch register. That is harmless in a program that is
|
||||||
|
also non-base-relative, but it corrupts the base pointer of a base-relative one.
|
||||||
|
|
||||||
|
In short: match `M68K_BASEREL` to the consuming program, and if that program is
|
||||||
|
base-relative make sure its OS callbacks are `__saveds`.
|
||||||
|
|
||||||
### To build for PowerPC Amiga:
|
### To build for PowerPC Amiga:
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -311,6 +348,13 @@ make
|
|||||||
|
|
||||||
libjson-c.a will get created in the build directory.
|
libjson-c.a will get created in the build directory.
|
||||||
|
|
||||||
|
Select the C runtime with `-DPPC_CRT=`: `newlib` (default), `clib2` or `clib4`.
|
||||||
|
Anything other than `newlib` is passed to the compiler as `-mcrt=<value>`.
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake -DPPC_CRT=clib4 ..
|
||||||
|
```
|
||||||
|
|
||||||
### To build for PowerPC MorphOS:
|
### To build for PowerPC MorphOS:
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -328,6 +372,72 @@ If you are making an application that absolutely requires ixemul, then remove th
|
|||||||
|
|
||||||
libjson-c.a will get created in the build directory.
|
libjson-c.a will get created in the build directory.
|
||||||
|
|
||||||
|
Two further options apply to MorphOS:
|
||||||
|
|
||||||
|
* `-DMORPHOS_CLIB=` selects `default` (ixemul) or `libnix` (passed as
|
||||||
|
`-mclib=libnix`). That is the same multilib `-noixemul` selects, and is the
|
||||||
|
self-contained ABI -- an ixemul build needs `ixemul.library` on the target.
|
||||||
|
* `-DMORPHOS_BASEREL32=ON` adds `-mbaserel32`.
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake -DMORPHOS_CLIB=libnix ..
|
||||||
|
cmake -DMORPHOS_BASEREL32=ON ..
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building and packaging every variant
|
||||||
|
|
||||||
|
Two scripts in the `amiga/` directory build the whole matrix across all three
|
||||||
|
systems, so you do not have to drive the container by hand.
|
||||||
|
|
||||||
|
* `amiga/build-amiga-sdk.sh [OS ...]` — builds every variant and installs
|
||||||
|
`libjson-c.a` plus the `json-c/` headers into an SDK tree. The location comes
|
||||||
|
from `$AMIGA_SDK` (default `/opt/amiga`); either a `<target>/` or an
|
||||||
|
AmigaSDK-gcc-style `amigaos3/sdk/<target>/` layout is accepted, and an OS
|
||||||
|
whose subdirectory is absent is skipped rather than failing.
|
||||||
|
* `amiga/package-amiga.sh [OS ...]` — builds the same matrix into a staging tree and
|
||||||
|
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`).
|
||||||
|
|
||||||
|
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 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 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
|
||||||
|
be copied straight over an SDK:
|
||||||
|
|
||||||
|
```
|
||||||
|
json-c/json-c.readme
|
||||||
|
json-c/AmigaOS3/{include,lib,...}/ plus libnix/ and clib2/ subtrees
|
||||||
|
json-c/AmigaOS4/{include,lib,lib/clib2,lib/clib4}/
|
||||||
|
json-c/MorphOS/{include,lib,lib/libb32,lib/libnix}/
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that m68k and PPC lay their C runtimes out differently, and the variant
|
||||||
|
table follows each. On m68k a runtime is a separate tree (`libnix/`, `clib2/`),
|
||||||
|
each with its own `include/` and `lib/`. On PPC a runtime is a multilib *slot*
|
||||||
|
beneath a single shared `lib/`: `-mcrt=clib4` searches `<target>/lib/clib4/`
|
||||||
|
and takes headers from `<target>/include/`. This was read off
|
||||||
|
`-print-search-dirs` rather than assumed, because installing to the wrong one
|
||||||
|
produces a library the compiler silently never finds.
|
||||||
|
|
||||||
<a name="linking"></a>
|
<a name="linking"></a>
|
||||||
Linking to `libjson-c`
|
Linking to `libjson-c`
|
||||||
----------------------
|
----------------------
|
||||||
|
|||||||
Executable
+112
@@ -0,0 +1,112 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Cross-build json-c for Amiga systems across every multilib slot and install
|
||||||
|
# the archives plus headers into an SDK tree.
|
||||||
|
#
|
||||||
|
# ./amiga/build-amiga-sdk.sh [OS ...] # default: AmigaOS3 AmigaOS4 MorphOS
|
||||||
|
#
|
||||||
|
# SDK location comes from $AMIGA_SDK (default /opt/amiga).
|
||||||
|
set -uo pipefail
|
||||||
|
|
||||||
|
SDK=${AMIGA_SDK:-/opt/amiga}
|
||||||
|
AMIGA_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||||
|
ROOT=$(cd "$AMIGA_DIR/.." && pwd)
|
||||||
|
cd "$ROOT"
|
||||||
|
OSES=("$@"); [[ ${#OSES[@]} -eq 0 ]] && OSES=(AmigaOS3 AmigaOS4 MorphOS)
|
||||||
|
|
||||||
|
# os | image tag | sdk subdir
|
||||||
|
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" ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac; }
|
||||||
|
|
||||||
|
# Where an AmigaSDK-gcc-style checkout keeps each system's target tree.
|
||||||
|
os_sdkdir() { case "$1" in
|
||||||
|
AmigaOS3) echo "amigaos3/sdk" ;;
|
||||||
|
AmigaOS4) echo "amigaos4/sdk" ;;
|
||||||
|
MorphOS) echo "morphos/sdk" ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac; }
|
||||||
|
|
||||||
|
# Per-OS variant table: "tree|slot|cmake args"
|
||||||
|
variants_AmigaOS3=(
|
||||||
|
"libnix|.|-DM68K_CRT=nix20 -DM68K_CPU=68000 -DM68K_BASEREL=off"
|
||||||
|
"libnix|libm020|-DM68K_CRT=nix20 -DM68K_CPU=68020 -DM68K_BASEREL=off"
|
||||||
|
"libnix|libb|-DM68K_CRT=nix20 -DM68K_CPU=68000 -DM68K_BASEREL=baserel"
|
||||||
|
"libnix|libb/libm020|-DM68K_CRT=nix20 -DM68K_CPU=68020 -DM68K_BASEREL=baserel"
|
||||||
|
"libnix|libb32/libm020|-DM68K_CRT=nix20 -DM68K_CPU=68020 -DM68K_BASEREL=baserel32"
|
||||||
|
".|.|-DM68K_CRT=newlib -DM68K_CPU=68000 -DM68K_BASEREL=off"
|
||||||
|
".|libm020|-DM68K_CRT=newlib -DM68K_CPU=68020 -DM68K_BASEREL=off"
|
||||||
|
".|libb|-DM68K_CRT=newlib -DM68K_CPU=68000 -DM68K_BASEREL=baserel"
|
||||||
|
".|libb/libm020|-DM68K_CRT=newlib -DM68K_CPU=68020 -DM68K_BASEREL=baserel"
|
||||||
|
".|libb32/libm020|-DM68K_CRT=newlib -DM68K_CPU=68020 -DM68K_BASEREL=baserel32"
|
||||||
|
"clib2|.|-DM68K_CRT=clib2 -DM68K_CPU=68000 -DM68K_BASEREL=off"
|
||||||
|
"clib2|libm020|-DM68K_CRT=clib2 -DM68K_CPU=68020 -DM68K_BASEREL=off"
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
# 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
|
||||||
|
# from the shared <target>/include/. Verified with -print-search-dirs:
|
||||||
|
# ppc-amigaos -mcrt=clib2 -> <target>/lib/clib2/
|
||||||
|
# ppc-amigaos -mcrt=clib4 -> <target>/lib/clib4/
|
||||||
|
# ppc-morphos -mclib=libnix-> <target>/lib/libnix/
|
||||||
|
# ppc-morphos -mbaserel32 -> <target>/lib/libb32/
|
||||||
|
variants_AmigaOS4=(
|
||||||
|
".|.|-DPPC_CRT=newlib"
|
||||||
|
".|clib2|-DPPC_CRT=clib2"
|
||||||
|
".|clib4|-DPPC_CRT=clib4"
|
||||||
|
)
|
||||||
|
# MORPHOS_CLIB=libnix (-mclib=libnix) and NOIXEMUL (-noixemul) select the same
|
||||||
|
# multilib; it is the self-contained ABI, needing no ixemul.library on target.
|
||||||
|
variants_MorphOS=(
|
||||||
|
".|.|"
|
||||||
|
".|libb32|-DMORPHOS_BASEREL32=ON"
|
||||||
|
".|libnix|-DMORPHOS_CLIB=libnix"
|
||||||
|
".|libb32/libnix|-DMORPHOS_CLIB=libnix -DMORPHOS_BASEREL32=ON"
|
||||||
|
)
|
||||||
|
|
||||||
|
# $1 out-dir-for-libs $2 out-dir-for-headers $3.. OS list
|
||||||
|
ok=0; fail=0; failed=()
|
||||||
|
for os in "${OSES[@]}"; do
|
||||||
|
read -r image sdksub <<<"$(os_image "$os")" || { echo "skip: unknown OS $os"; continue; }
|
||||||
|
# /opt/amiga keeps the target tree directly under <target>/, while an
|
||||||
|
# AmigaSDK-gcc checkout nests it under <os>/sdk/<target>. Accept either.
|
||||||
|
osdir=$(os_sdkdir "$os")
|
||||||
|
if [[ -d $SDK/$sdksub ]]; then SDKROOT=$SDK/$sdksub
|
||||||
|
elif [[ -d $SDK/$osdir/$sdksub ]]; then SDKROOT=$SDK/$osdir/$sdksub
|
||||||
|
else echo "skip $os: neither $SDK/$sdksub nor $SDK/$osdir/$sdksub"; continue; fi
|
||||||
|
|
||||||
|
eval "vars=(\"\${variants_$os[@]}\")"
|
||||||
|
for v in "${vars[@]}"; do
|
||||||
|
IFS='|' read -r tree slot cargs <<<"$v"
|
||||||
|
bdir="bld-$os-$(echo "$tree$slot$cargs" | tr -c 'A-Za-z0-9' '-' | cut -c1-40)"
|
||||||
|
printf ' %-9s %-7s %-16s ' "$os" "$tree" "$slot"
|
||||||
|
if ! docker run --rm -v "$ROOT":/work -e USER="$(id -u)" -e GROUP="$(id -g)" "$image" sh -c "
|
||||||
|
set -e
|
||||||
|
rm -rf /work/$bdir && mkdir -p /work/$bdir && cd /work/$bdir
|
||||||
|
cmake $cargs -DCMAKE_BUILD_TYPE=Release -DBUILD_APPS=NO \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=/work/$bdir/inst .. >cmake.log 2>&1
|
||||||
|
make -j\$(nproc) json-c >make.log 2>&1
|
||||||
|
make install >install.log 2>&1
|
||||||
|
" 2>/dev/null; then
|
||||||
|
echo "BUILD FAILED (logs in $bdir)"; fail=$((fail+1)); failed+=("$os/$tree/$slot"); continue
|
||||||
|
fi
|
||||||
|
lib=$bdir/libjson-c.a
|
||||||
|
[[ -f $lib ]] || lib=$bdir/inst/lib/libjson-c.a
|
||||||
|
[[ -f $lib ]] || { echo "no libjson-c.a"; fail=$((fail+1)); failed+=("$os/$tree/$slot"); continue; }
|
||||||
|
|
||||||
|
base=$SDKROOT; [[ $tree != "." ]] && base=$SDKROOT/$tree
|
||||||
|
dest=$base/lib; [[ $slot != "." ]] && dest=$base/lib/$slot
|
||||||
|
mkdir -p "$dest" "$base/include"
|
||||||
|
cp "$lib" "$dest/libjson-c.a"
|
||||||
|
cp -a "$bdir/inst/include/json-c" "$base/include/"
|
||||||
|
echo "ok"; ok=$((ok+1)); rm -rf "$bdir"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
echo "built+installed: $ok failed: $fail"
|
||||||
|
((fail)) && { printf 'failures: %s\n' "${failed[*]}"; exit 1; }
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
Short: JSON parser and generator library (static libs + headers)
|
||||||
|
Author: Michael Clark, Eric Hawicz et al.
|
||||||
|
Uploader: Cameron Armstrong (Nightfox) <cameronscottarmstrong@gmail.com>
|
||||||
|
Type: dev/lib
|
||||||
|
Version: 0.19
|
||||||
|
Architecture: m68k-amigaos >= 2.0; ppc-amigaos; ppc-morphos
|
||||||
|
Requires: an Amiga gcc compiler
|
||||||
|
Replaces: dev/lib/json-c.lha
|
||||||
|
|
||||||
|
json-c implements a reference-counted object model for JSON, a parser that
|
||||||
|
builds it from text, and a serialiser that writes it back out. This archive
|
||||||
|
contains static libraries and public headers for Amiga development.
|
||||||
|
|
||||||
|
https://github.com/json-c/json-c
|
||||||
|
|
||||||
|
|
||||||
|
Contents
|
||||||
|
|
||||||
|
json-c/json-c.readme this file
|
||||||
|
json-c/AmigaOS3/... m68k AmigaOS libraries and headers
|
||||||
|
json-c/AmigaOS4/... ppc-amigaos libraries and headers
|
||||||
|
json-c/MorphOS/... ppc-morphos libraries and headers
|
||||||
|
|
||||||
|
Under each OS directory the trees follow the compiler's own layout, so
|
||||||
|
they can be copied straight over an existing SDK, e.g.
|
||||||
|
|
||||||
|
cp -a json-c/AmigaOS3/* /opt/amiga/m68k-amigaos/
|
||||||
|
|
||||||
|
AmigaOS3 ships one set per C runtime -- newlib at the top level, plus
|
||||||
|
libnix/ and clib2/ -- and within each, one library per multilib:
|
||||||
|
|
||||||
|
lib/ 68000, absolute addressing
|
||||||
|
lib/libm020/ 68020, absolute addressing
|
||||||
|
lib/libb/ 68000, -fbaserel
|
||||||
|
lib/libb/libm020/ 68020, -fbaserel
|
||||||
|
lib/libb32/libm020/ 68020, -fbaserel32
|
||||||
|
|
||||||
|
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/:
|
||||||
|
|
||||||
|
AmigaOS4 lib/ newlib
|
||||||
|
lib/clib2/ clib2
|
||||||
|
lib/clib4/ clib4
|
||||||
|
|
||||||
|
MorphOS lib/ ixemul
|
||||||
|
lib/libb32/ ixemul, -mbaserel32
|
||||||
|
lib/libnix/ native C library (-noixemul)
|
||||||
|
lib/libb32/libnix/ native C library, -mbaserel32
|
||||||
|
|
||||||
|
-mclib=libnix and -noixemul select the same MorphOS multilib. That ABI is
|
||||||
|
the self-contained one -- an ixemul build needs ixemul.library on the
|
||||||
|
target -- so prefer lib/libnix/ for new code.
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
|
||||||
|
#include <json-c/json.h>
|
||||||
|
|
||||||
|
struct json_object *o = json_tokener_parse("{\"a\":1}");
|
||||||
|
printf("%s\n", json_object_to_json_string(o));
|
||||||
|
json_object_put(o);
|
||||||
|
|
||||||
|
Link with -ljson-c -lm, after your own objects on the command line. For
|
||||||
|
clib2 add -lunix as well, since clib2 keeps its POSIX layer there.
|
||||||
|
|
||||||
|
|
||||||
|
Which variants link
|
||||||
|
|
||||||
|
Verified by compiling the snippet above against each shipped library.
|
||||||
|
|
||||||
|
AmigaOS3 libnix all 5 slots link.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
AmigaOS4 all three (newlib, clib2, clib4) link.
|
||||||
|
|
||||||
|
MorphOS all four slots link.
|
||||||
|
|
||||||
|
|
||||||
|
A note on base-relative addressing (AmigaOS3)
|
||||||
|
|
||||||
|
A base-relative library addresses its globals through a4, which the
|
||||||
|
program's startup code sets up once. Only link the libb/ or libb32/
|
||||||
|
variants into a program that is itself base-relative AND that marks every
|
||||||
|
function the OS calls back into (BOOPSI/MUI dispatchers, struct Hook
|
||||||
|
entries, interrupt servers) with __saveds. The m68k SDI_hook.h macros set
|
||||||
|
up register arguments but do not add __saveds, so this is easy to get
|
||||||
|
wrong, and the failure mode is intermittent memory corruption rather than
|
||||||
|
a clean error -- libnix keeps malloc's heap state in a4-relative storage.
|
||||||
|
|
||||||
|
Conversely a non-base-relative library built at -O1 or above may use a4 as
|
||||||
|
a scratch register, which is harmless in a non-base-relative program but
|
||||||
|
corrupts the base pointer of one that is.
|
||||||
|
|
||||||
|
Match the variant to the program. If in doubt, use the plain lib/ or
|
||||||
|
lib/libm020/ builds.
|
||||||
|
|
||||||
|
|
||||||
|
Licence
|
||||||
|
|
||||||
|
MIT; see COPYING in the source distribution.
|
||||||
Executable
+72
@@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Build every json-c variant for the requested Amiga systems and package them
|
||||||
|
# into dist/json-c.lha.
|
||||||
|
#
|
||||||
|
# ./amiga/package-amiga.sh [OS ...] # default: all three
|
||||||
|
#
|
||||||
|
# Archive layout (single directory at the root):
|
||||||
|
# json-c/json-c.readme
|
||||||
|
# json-c/AmigaOS3/... per-OS libraries and headers
|
||||||
|
# json-c/AmigaOS4/...
|
||||||
|
# json-c/MorphOS/...
|
||||||
|
set -uo pipefail
|
||||||
|
|
||||||
|
AMIGA_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||||
|
ROOT=$(cd "$AMIGA_DIR/.." && pwd)
|
||||||
|
cd "$ROOT"
|
||||||
|
DIST=$ROOT/dist
|
||||||
|
STAGE=$DIST/stage
|
||||||
|
OSES=("$@"); [[ ${#OSES[@]} -eq 0 ]] && OSES=(AmigaOS3 AmigaOS4 MorphOS)
|
||||||
|
|
||||||
|
command -v lha >/dev/null || { echo "error: lha not found on PATH" >&2; exit 1; }
|
||||||
|
# Ubuntu's `lha` package is lhasa, which can only extract.
|
||||||
|
_lha_probe=$(mktemp -d)
|
||||||
|
echo x > "$_lha_probe/f"
|
||||||
|
if ! ( cd "$_lha_probe" && lha -aq2 t.lha f >/dev/null 2>&1 && [[ -s t.lha ]] ); then
|
||||||
|
echo "error: lha cannot create archives (is it lhasa?). Install LHa for UNIX: https://github.com/jca02266/lha" >&2
|
||||||
|
rm -rf "$_lha_probe"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
rm -rf "$_lha_probe"
|
||||||
|
|
||||||
|
# Build straight into the staging tree by pointing AMIGA_SDK at it: the build
|
||||||
|
# script's SDK layout ($SDK/<target>) is the same shape we want per OS, so each
|
||||||
|
# OS gets staged under its own directory.
|
||||||
|
rm -rf "$DIST"; mkdir -p "$STAGE/json-c"
|
||||||
|
cp "$AMIGA_DIR/json-c.readme" "$STAGE/json-c/json-c.readme"
|
||||||
|
|
||||||
|
built=()
|
||||||
|
for os in "${OSES[@]}"; do
|
||||||
|
case "$os" in
|
||||||
|
AmigaOS3) sub=m68k-amigaos ;;
|
||||||
|
AmigaOS4) sub=ppc-amigaos ;;
|
||||||
|
MorphOS) sub=ppc-morphos ;;
|
||||||
|
*) echo "skip: unknown OS $os"; continue ;;
|
||||||
|
esac
|
||||||
|
tmp=$DIST/sdk-$os
|
||||||
|
mkdir -p "$tmp/$sub"
|
||||||
|
echo "=== $os ==="
|
||||||
|
# Stage whatever landed even if some variants failed -- a single unsupported
|
||||||
|
# multilib should not drop the whole OS from the archive.
|
||||||
|
AMIGA_SDK="$tmp" "$AMIGA_DIR/build-amiga-sdk.sh" "$os" || echo " ($os: some variants failed, see above)"
|
||||||
|
if [[ -n $(find "$tmp/$sub" -name 'libjson-c.a' -print -quit 2>/dev/null) ]]; then
|
||||||
|
mkdir -p "$STAGE/json-c/$os"
|
||||||
|
cp -a "$tmp/$sub/." "$STAGE/json-c/$os/"
|
||||||
|
built+=("$os")
|
||||||
|
else
|
||||||
|
echo " $os: nothing built, omitted from the archive"
|
||||||
|
fi
|
||||||
|
rm -rf "$tmp"
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ ${#built[@]} -eq 0 ]] && { echo "nothing built"; exit 1; }
|
||||||
|
|
||||||
|
# NOTE: build the archive from a clean staging tree with `lha -aq2`. Do NOT try
|
||||||
|
# to refresh a single entry (e.g. the readme) in an existing archive with
|
||||||
|
# `lha u` -- it APPENDS a second entry with the same name rather than replacing
|
||||||
|
# it, and extraction then yields the stale copy.
|
||||||
|
( cd "$STAGE" && lha -aq2 "$DIST/json-c.lha" * >/dev/null )
|
||||||
|
rm -rf "$STAGE"
|
||||||
|
echo
|
||||||
|
echo "packaged: ${built[*]}"
|
||||||
|
ls -la "$DIST"
|
||||||
Reference in new issue
Block a user