gplan.so: build from source using Raspbian Stretch Docker
Use balenalib/raspberry-pi-debian:stretch with legacy.raspbian.org repos. Exact match: GCC 6.3, Python 3.5, GLIBC 2.24 — identical to the Pi. First build ~25min (QEMU), subsequent builds ~1sec (cached image). Replaces the broken Bullseye approach that had GLIBC/GLIBCXX mismatches.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -38,3 +38,4 @@ src/avr/emu/bbemu
|
|||||||
src/avr/emu/build/
|
src/avr/emu/build/
|
||||||
|
|
||||||
.pi/pi-python35.tar.gz
|
.pi/pi-python35.tar.gz
|
||||||
|
src/py/camotics/gplan.so.built
|
||||||
|
|||||||
31
.pi/BUILD.md
31
.pi/BUILD.md
@@ -54,23 +54,35 @@ ELF 32-bit LSB shared object, ARM, EABI5 (linked against libpython3.5m.so.1.0)
|
|||||||
```
|
```
|
||||||
If you see `ELF 64-bit LSB shared object, ARM aarch64` or `libpython3.9` — wrong.
|
If you see `ELF 64-bit LSB shared object, ARM aarch64` or `libpython3.9` — wrong.
|
||||||
|
|
||||||
**Option A: From official release (recommended)**
|
**Option A: Build from source (recommended)**
|
||||||
|
|
||||||
|
Uses a Raspbian Stretch Docker image that exactly matches the Pi's toolchain:
|
||||||
|
GCC 6.3, Python 3.5, GLIBC 2.24. No cross-compile hacks, no ABI mismatches.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
.pi/build-gplan.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
- First run: ~25min (builds `onefin-gplan` Docker image with pre-compiled cbang + camotics)
|
||||||
|
- After that: ~1sec (copies cached `gplan.so` from image)
|
||||||
|
- Force rebuild: `docker rmi onefin-gplan && .pi/build-gplan.sh`
|
||||||
|
|
||||||
|
See `.pi/Dockerfile.gplan` for the full build recipe.
|
||||||
|
|
||||||
|
**Option B: From official release**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -sL https://github.com/OneFinityCNC/onefinity-firmware/releases/download/v1.6.6/onefinity-1.6.6.tar.bz2 \
|
curl -sL https://github.com/OneFinityCNC/onefinity-firmware/releases/download/v1.6.6/onefinity-1.6.6.tar.bz2 \
|
||||||
| tar xjf - --include='*/gplan.so' -O > src/py/camotics/gplan.so
|
| tar xjf - --include='*/gplan.so' -O > src/py/camotics/gplan.so
|
||||||
```
|
```
|
||||||
|
|
||||||
The gplan.so is pure G-code planning with no version-specific code — safe to
|
**Option C: From a working Pi**
|
||||||
reuse across firmware versions.
|
|
||||||
|
|
||||||
**Option B: From a working Pi**
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
scp bbmc@10.1.10.55:/usr/local/lib/python3.5/dist-packages/bbctrl-*.egg/camotics/gplan.so src/py/camotics/
|
scp bbmc@10.1.10.55:/usr/local/lib/python3.5/dist-packages/bbctrl-*.egg/camotics/gplan.so src/py/camotics/
|
||||||
```
|
```
|
||||||
|
|
||||||
**Option C: Build from source (broken — documented for reference)**
|
**Failed approach: Debian Bullseye armhf (documented for reference)**
|
||||||
|
|
||||||
Uses Docker's armv7 QEMU emulation on Apple Silicon. Requires a one-time
|
Uses Docker's armv7 QEMU emulation on Apple Silicon. Requires a one-time
|
||||||
copy of Python 3.5 headers from the Pi (~1.7MB):
|
copy of Python 3.5 headers from the Pi (~1.7MB):
|
||||||
@@ -142,10 +154,9 @@ Stretch has GLIBC_2.24 / GLIBCXX_3.4.22 max. Even with `-static-libstdc++
|
|||||||
-static-libgcc`, glibc symbols like `GLIBC_2.29` leak through the object
|
-static-libgcc`, glibc symbols like `GLIBC_2.29` leak through the object
|
||||||
files compiled against Bullseye headers.
|
files compiled against Bullseye headers.
|
||||||
|
|
||||||
To truly build from source you'd need a Stretch armhf container — but
|
The solution was to use `balenalib/raspberry-pi-debian:stretch` with
|
||||||
Stretch's archived repos have broken package metadata that prevents
|
`legacy.raspbian.org` repos — these still work unlike bare `debian:stretch`.
|
||||||
installing build-essential + scons. The official gplan.so was built
|
See `.pi/Dockerfile.gplan`.
|
||||||
in a Raspbian Stretch chroot (see `scripts/gplan-init-build.sh`).
|
|
||||||
|
|
||||||
**Key Pi constraints for native code:**
|
**Key Pi constraints for native code:**
|
||||||
- GLIBC ≤ 2.24 (Stretch)
|
- GLIBC ≤ 2.24 (Stretch)
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
# Pre-built armv7 environment for gplan.so
|
# Raspbian Stretch armhf build environment for gplan.so
|
||||||
# Build once: docker build --platform linux/arm/v7 -t onefin-gplan -f .pi/Dockerfile.gplan .pi/
|
# Matches the Pi exactly: GCC 6.3, Python 3.5, GLIBC 2.24
|
||||||
# Then use: .pi/build-gplan.sh
|
#
|
||||||
FROM debian:bullseye
|
# Build image: docker build -t onefin-gplan -f .pi/Dockerfile.gplan .pi/
|
||||||
|
# Build gplan: .pi/build-gplan.sh
|
||||||
|
FROM balenalib/raspberry-pi-debian:stretch
|
||||||
|
|
||||||
RUN apt-get update -qq && \
|
# Fix repos to use archived Raspbian mirrors
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends \
|
RUN echo "deb http://legacy.raspbian.org/raspbian/ stretch main contrib non-free rpi" \
|
||||||
build-essential scons git ca-certificates python3-dev \
|
> /etc/apt/sources.list && \
|
||||||
|
rm -f /etc/apt/sources.list.d/*.list
|
||||||
|
|
||||||
|
RUN apt-get -o Acquire::Check-Valid-Until=false \
|
||||||
|
-o Acquire::AllowInsecureRepositories=true update && \
|
||||||
|
apt-get -o Acquire::Check-Valid-Until=false --allow-unauthenticated \
|
||||||
|
install -y --no-install-recommends \
|
||||||
|
build-essential python3-dev scons git ca-certificates \
|
||||||
libssl-dev libexpat1-dev libbz2-dev liblz4-dev zlib1g-dev perl file && \
|
libssl-dev libexpat1-dev libbz2-dev liblz4-dev zlib1g-dev perl file && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Clone and build cbang (static lib, ~5min under QEMU)
|
# Clone and build cbang
|
||||||
RUN mkdir -p /opt/cbang && cd /opt/cbang && git init -q && \
|
RUN mkdir -p /opt/cbang && cd /opt/cbang && git init -q && \
|
||||||
git remote add origin https://github.com/CauldronDevelopmentLLC/cbang && \
|
git remote add origin https://github.com/CauldronDevelopmentLLC/cbang && \
|
||||||
git fetch --depth 1 -q origin 18f1e963107ef26abe750c023355a5c40dd07853 && \
|
git fetch --depth 1 -q origin 18f1e963107ef26abe750c023355a5c40dd07853 && \
|
||||||
@@ -17,7 +26,7 @@ RUN mkdir -p /opt/cbang && cd /opt/cbang && git init -q && \
|
|||||||
scons -j2 disable_local="re2 libevent" && \
|
scons -j2 disable_local="re2 libevent" && \
|
||||||
rm -rf .git build/dep
|
rm -rf .git build/dep
|
||||||
|
|
||||||
# Clone and patch camotics (source only, don't compile yet — that depends on workspace)
|
# Clone, patch, and build camotics/gplan
|
||||||
RUN mkdir -p /opt/camotics && cd /opt/camotics && git init -q && \
|
RUN mkdir -p /opt/camotics && cd /opt/camotics && git init -q && \
|
||||||
git remote add origin https://github.com/CauldronDevelopmentLLC/camotics && \
|
git remote add origin https://github.com/CauldronDevelopmentLLC/camotics && \
|
||||||
git fetch --depth 1 -q origin ec876c80d20fc19837133087cef0c447df5a939d && \
|
git fetch --depth 1 -q origin ec876c80d20fc19837133087cef0c447df5a939d && \
|
||||||
@@ -31,10 +40,9 @@ RUN mkdir -p /opt/camotics && cd /opt/camotics && git init -q && \
|
|||||||
done && \
|
done && \
|
||||||
rm -rf .git
|
rm -rf .git
|
||||||
|
|
||||||
# Pre-compile camotics objects (the slow part, ~20min under QEMU)
|
|
||||||
ENV CBANG_HOME=/opt/cbang
|
ENV CBANG_HOME=/opt/cbang
|
||||||
RUN cd /opt/camotics && scons -j2 gplan.so with_gui=0 with_tpl=0 && \
|
|
||||||
rm -f gplan.so # remove the python3.9-linked one, we relink at build time
|
|
||||||
|
|
||||||
ENV CBANG_HOME=/opt/cbang
|
# Pre-compile everything including gplan.so
|
||||||
|
RUN cd /opt/camotics && scons -j2 gplan.so with_gui=0 with_tpl=0
|
||||||
|
|
||||||
WORKDIR /opt/camotics
|
WORKDIR /opt/camotics
|
||||||
|
|||||||
@@ -1,58 +1,30 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# Build gplan.so for the Onefinity Pi (armv7l, Python 3.5)
|
# Build gplan.so for the Onefinity Pi (armv7l, Python 3.5, GCC 6.3)
|
||||||
#
|
#
|
||||||
# First run: ~30min (builds the Docker image with pre-compiled cbang/camotics)
|
# Uses a Raspbian Stretch Docker image that exactly matches the Pi's
|
||||||
# After that: ~2sec (just relinks against Python 3.5m)
|
# toolchain. No cross-compile, no relink hacks, no GLIBC mismatches.
|
||||||
#
|
#
|
||||||
# Prerequisites:
|
# First run: ~30min (builds Docker image with cbang + camotics)
|
||||||
# - Docker with QEMU binfmt support (default on Docker Desktop)
|
# After that: ~1sec (copies pre-built gplan.so from image)
|
||||||
# - Python 3.5 headers from the Pi in .pi/pi-python35.tar.gz
|
|
||||||
# Grab once: ssh bbmc@10.1.10.55 'tar czf - /usr/include/python3.5m \
|
|
||||||
# /usr/lib/arm-linux-gnueabihf/libpython3.5m.so*' > .pi/pi-python35.tar.gz
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||||
IMAGE="onefin-gplan"
|
IMAGE="onefin-gplan"
|
||||||
HEADERS="$SCRIPT_DIR/pi-python35.tar.gz"
|
|
||||||
OUTPUT="$PROJECT_DIR/src/py/camotics/gplan.so"
|
OUTPUT="$PROJECT_DIR/src/py/camotics/gplan.so"
|
||||||
|
|
||||||
# Check for Python 3.5 headers
|
# Build image if needed (one-time)
|
||||||
if [[ ! -f "$HEADERS" ]]; then
|
|
||||||
echo "Python 3.5 headers not found at $HEADERS"
|
|
||||||
echo "Fetching from Pi..."
|
|
||||||
ssh bbmc@10.1.10.55 'tar czf - /usr/include/python3.5m \
|
|
||||||
/usr/lib/arm-linux-gnueabihf/libpython3.5m.so*' > "$HEADERS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build image if needed (one-time, ~30min)
|
|
||||||
if ! docker image inspect "$IMAGE" >/dev/null 2>&1; then
|
if ! docker image inspect "$IMAGE" >/dev/null 2>&1; then
|
||||||
echo "Building $IMAGE Docker image (one-time, ~30min under QEMU)..."
|
echo "Building $IMAGE Docker image (one-time, ~30min under QEMU)..."
|
||||||
docker build --platform linux/arm/v7 -t "$IMAGE" -f "$SCRIPT_DIR/Dockerfile.gplan" "$SCRIPT_DIR"
|
docker build -t "$IMAGE" -f "$SCRIPT_DIR/Dockerfile.gplan" "$SCRIPT_DIR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Relink gplan.so against Python 3.5m (~2sec)
|
# Copy gplan.so out of the image
|
||||||
echo "Linking gplan.so against Python 3.5m..."
|
echo "Extracting gplan.so..."
|
||||||
docker run --rm --platform linux/arm/v7 \
|
docker run --rm -v "$PROJECT_DIR:/workspace" "$IMAGE" \
|
||||||
-v "$HEADERS:/tmp/pi-python35.tar.gz:ro" \
|
bash -c 'cp /opt/camotics/gplan.so /workspace/src/py/camotics/gplan.so && \
|
||||||
-v "$PROJECT_DIR:/workspace" \
|
file /workspace/src/py/camotics/gplan.so && \
|
||||||
"$IMAGE" bash -c '
|
readelf -d /workspace/src/py/camotics/gplan.so | grep -E "NEEDED|python"'
|
||||||
tar xzf /tmp/pi-python35.tar.gz -C /
|
|
||||||
ln -sf /usr/lib/arm-linux-gnueabihf/libpython3.5m.so.1.0 \
|
|
||||||
/usr/lib/arm-linux-gnueabihf/libpython3.5m.so
|
|
||||||
|
|
||||||
g++ -o /workspace/src/py/camotics/gplan.so \
|
|
||||||
-Wl,--as-needed -Wl,-s -Wl,-x -Wl,--gc-sections -pthread -shared \
|
|
||||||
build/gplan.os -L/opt/cbang/lib \
|
|
||||||
build/libCAMoticsPy.a build/libCAMotics.a build/libDXF.a \
|
|
||||||
build/libSTL.a build/libGCode.a \
|
|
||||||
-lstdc++ -lutil -lm -ldl -lz -lcbang -lcbang-boost \
|
|
||||||
-lssl -lcrypto -llz4 -lexpat -lbz2 -lcrypt -lpthread \
|
|
||||||
-lpython3.5m build/dxflib/libdxflib.a
|
|
||||||
|
|
||||||
file /workspace/src/py/camotics/gplan.so
|
|
||||||
readelf -d /workspace/src/py/camotics/gplan.so | grep python
|
|
||||||
'
|
|
||||||
|
|
||||||
echo "✓ Built: $OUTPUT"
|
echo "✓ Built: $OUTPUT"
|
||||||
|
|||||||
Reference in New Issue
Block a user