129 lines
5.0 KiB
Bash
Executable File
129 lines
5.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# docker-build-linux.sh — Build native-hello for Linux using Docker.
|
|
#
|
|
# Usage:
|
|
# ./docker-build-linux.sh # build ARM64 (native on Apple Silicon)
|
|
# ./docker-build-linux.sh --x86 # also build x86_64 via QEMU
|
|
# ./docker-build-linux.sh --x86-only # only build x86_64
|
|
#
|
|
# Output binaries are placed in ./build/:
|
|
# native-hello-linux-arm64 — Linux ARM64 (Raspberry Pi 3/4/5, Apple Silicon VMs)
|
|
# native-hello-linux-x86_64 — Linux x86_64 (desktop Linux, CI servers)
|
|
#
|
|
# Prerequisites:
|
|
# - Docker (Rancher Desktop / Docker Desktop)
|
|
# - elc at ../../../lang/dist/platform/elc or in PATH
|
|
#
|
|
# How it works:
|
|
# 1. elc generates C sources from the el program (macOS, ARM64 native elc)
|
|
# 2. Docker builds those C sources inside Ubuntu 22.04 + GTK4
|
|
# 3. The resulting ELF binary is extracted from the image
|
|
#
|
|
# Linux toolchain notes:
|
|
# - GNU ld rejects duplicate symbol definitions that macOS ld accepts silently.
|
|
# The Dockerfile uses objcopy --localize-symbol to hide duplicates between
|
|
# el_seed.o / el_runtime.o and el_native_vessel.o / native_hello.o.
|
|
# - el_gtk4.c requires _GNU_SOURCE for RTLD_DEFAULT (dlfcn.h).
|
|
# - G_APPLICATION_DEFAULT_FLAGS was added in GLib 2.74; Ubuntu 22.04 ships
|
|
# GLib 2.72, so the Dockerfile adds a compatibility define.
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
EL_LANG_ROOT="${SCRIPT_DIR}/../../../lang"
|
|
EL_UI_ROOT="${SCRIPT_DIR}/../.."
|
|
EL_RUNTIME="${EL_LANG_ROOT}/el-compiler/runtime"
|
|
EL_NATIVE_VESSEL="${EL_UI_ROOT}/vessels/el-native/src/main.el"
|
|
BUILD_DIR="${SCRIPT_DIR}/build"
|
|
DOCKER_CTX="${SCRIPT_DIR}/build-docker"
|
|
|
|
BUILD_X86=0
|
|
BUILD_ARM64=1
|
|
|
|
for arg in "$@"; do
|
|
case "${arg}" in
|
|
--x86) BUILD_X86=1 ;;
|
|
--x86-only) BUILD_X86=1; BUILD_ARM64=0 ;;
|
|
esac
|
|
done
|
|
|
|
# ── Locate elc ────────────────────────────────────────────────────────────────
|
|
if command -v elc &>/dev/null; then
|
|
ELC="elc"
|
|
elif [ -x "${EL_LANG_ROOT}/dist/platform/elc" ]; then
|
|
ELC="${EL_LANG_ROOT}/dist/platform/elc"
|
|
else
|
|
echo "Error: elc not found. Add it to PATH or place at:"
|
|
echo " ${EL_LANG_ROOT}/dist/platform/elc"
|
|
exit 1
|
|
fi
|
|
|
|
# ── Step 1: Generate C sources ────────────────────────────────────────────────
|
|
echo "==> Generating C sources with elc..."
|
|
mkdir -p "${DOCKER_CTX}/runtime"
|
|
|
|
# App
|
|
EL_MANIFEST="${SCRIPT_DIR}/manifest.el" \
|
|
"${ELC}" "${SCRIPT_DIR}/src/main.el" > "${DOCKER_CTX}/native_hello.c"
|
|
|
|
# Vessel
|
|
"${ELC}" "${EL_NATIVE_VESSEL}" > "${DOCKER_CTX}/el_native_vessel.c"
|
|
|
|
# Vessel header (declarations only — stop before first function body)
|
|
"${ELC}" --emit-header "${EL_NATIVE_VESSEL}" \
|
|
| awk 'BEGIN{in_body=0} /^[a-zA-Z_].+\)[[:space:]]*\{/ {in_body=1} !in_body{print}' \
|
|
> "${DOCKER_CTX}/el_native_vessel.h"
|
|
|
|
# Runtime C sources
|
|
cp "${EL_RUNTIME}/el_gtk4.c" \
|
|
"${EL_RUNTIME}/el_seed.c" \
|
|
"${EL_RUNTIME}/el_seed.h" \
|
|
"${EL_RUNTIME}/el_runtime.c" \
|
|
"${EL_RUNTIME}/el_runtime.h" \
|
|
"${EL_RUNTIME}/el_native_target.h" \
|
|
"${DOCKER_CTX}/runtime/"
|
|
|
|
echo "==> C sources ready in ${DOCKER_CTX}/"
|
|
|
|
mkdir -p "${BUILD_DIR}"
|
|
|
|
# ── Step 2: Docker build (ARM64) ─────────────────────────────────────────────
|
|
if [ "${BUILD_ARM64}" -eq 1 ]; then
|
|
echo "==> Building Linux ARM64 image..."
|
|
docker build \
|
|
--platform linux/arm64 \
|
|
-f "${SCRIPT_DIR}/Dockerfile.linux-gtk4" \
|
|
--tag el-native-linux-gtk4-arm64 \
|
|
"${DOCKER_CTX}/"
|
|
|
|
echo "==> Extracting ARM64 binary..."
|
|
docker create --name el-extract-arm64 el-native-linux-gtk4-arm64
|
|
docker cp el-extract-arm64:/build/native-hello-linux "${BUILD_DIR}/native-hello-linux-arm64"
|
|
docker rm el-extract-arm64
|
|
|
|
echo "==> ARM64 binary: ${BUILD_DIR}/native-hello-linux-arm64"
|
|
file "${BUILD_DIR}/native-hello-linux-arm64"
|
|
fi
|
|
|
|
# ── Step 3: Docker build (x86_64) ────────────────────────────────────────────
|
|
if [ "${BUILD_X86}" -eq 1 ]; then
|
|
echo "==> Building Linux x86_64 image (QEMU emulation — slower)..."
|
|
docker build \
|
|
--platform linux/amd64 \
|
|
-f "${SCRIPT_DIR}/Dockerfile.linux-gtk4" \
|
|
--tag el-native-linux-gtk4-x86_64 \
|
|
"${DOCKER_CTX}/"
|
|
|
|
echo "==> Extracting x86_64 binary..."
|
|
docker create --name el-extract-x86 el-native-linux-gtk4-x86_64
|
|
docker cp el-extract-x86:/build/native-hello-linux "${BUILD_DIR}/native-hello-linux-x86_64"
|
|
docker rm el-extract-x86
|
|
|
|
echo "==> x86_64 binary: ${BUILD_DIR}/native-hello-linux-x86_64"
|
|
file "${BUILD_DIR}/native-hello-linux-x86_64"
|
|
fi
|
|
|
|
echo ""
|
|
echo "==> Done. Binaries in ${BUILD_DIR}/"
|
|
ls -lh "${BUILD_DIR}"/native-hello-linux-* 2>/dev/null || true
|