|
| 1 | +#!/bin/sh |
| 2 | +# SPDX-License-Identifier: MIT |
| 3 | +# Build liblkl.a from source (lkl/linux) and populate lkl-<ARCH>/. |
| 4 | +# |
| 5 | +# Usage: ./scripts/build-lkl.sh [ARCH] |
| 6 | +# ARCH defaults to the host architecture (x86_64 or aarch64). |
| 7 | +# Override LKL_DIR to change the output directory. |
| 8 | +# Override LKL_SRC to reuse an existing source tree (skip clone). |
| 9 | +# Override LKL_REF to check out a specific branch/tag/commit |
| 10 | +# (default: HEAD of master). |
| 11 | + |
| 12 | +set -eu |
| 13 | + |
| 14 | +case "${1:-$(uname -m)}" in |
| 15 | + x86_64 | amd64) ARCH="x86_64" ;; |
| 16 | + aarch64 | arm64) ARCH="aarch64" ;; |
| 17 | + *) |
| 18 | + echo "error: unsupported architecture: ${1:-$(uname -m)}" >&2 |
| 19 | + exit 1 |
| 20 | + ;; |
| 21 | +esac |
| 22 | + |
| 23 | +LKL_DIR="${LKL_DIR:-lkl-${ARCH}}" |
| 24 | +LKL_SRC="${LKL_SRC:-build/lkl-src}" |
| 25 | +LKL_UPSTREAM="https://github.com/lkl/linux" |
| 26 | + |
| 27 | +die() { echo "error: $*" >&2; exit 1; } |
| 28 | + |
| 29 | +# ---- Clone or update source tree ---------------------------------------- |
| 30 | + |
| 31 | +if [ -d "${LKL_SRC}/.git" ]; then |
| 32 | + echo " SRC ${LKL_SRC} (exists, skipping clone)" |
| 33 | + if [ -n "${LKL_REF:-}" ]; then |
| 34 | + echo " CHECKOUT ${LKL_REF}" |
| 35 | + git -C "${LKL_SRC}" fetch --depth=1 origin "${LKL_REF}" |
| 36 | + git -C "${LKL_SRC}" checkout FETCH_HEAD |
| 37 | + fi |
| 38 | +else |
| 39 | + echo " CLONE ${LKL_UPSTREAM} -> ${LKL_SRC}" |
| 40 | + mkdir -p "$(dirname "${LKL_SRC}")" |
| 41 | + |
| 42 | + if [ -n "${LKL_REF:-}" ]; then |
| 43 | + # Shallow clone of a specific ref. |
| 44 | + git clone --depth=1 --branch "${LKL_REF}" \ |
| 45 | + "${LKL_UPSTREAM}" "${LKL_SRC}" |
| 46 | + else |
| 47 | + # Shallow clone of default branch. |
| 48 | + git clone --depth=1 "${LKL_UPSTREAM}" "${LKL_SRC}" |
| 49 | + fi |
| 50 | +fi |
| 51 | + |
| 52 | +# ---- Configure ----------------------------------------------------------- |
| 53 | + |
| 54 | +echo " CONFIG ARCH=lkl defconfig" |
| 55 | +make -C "${LKL_SRC}" ARCH=lkl defconfig |
| 56 | + |
| 57 | +# Enable features required by kbox (mirrors build-lkl.yml). |
| 58 | +for opt in \ |
| 59 | + CONFIG_DEVTMPFS \ |
| 60 | + CONFIG_DEVTMPFS_MOUNT \ |
| 61 | + CONFIG_DEVPTS_FS \ |
| 62 | + CONFIG_DEBUG_INFO \ |
| 63 | + CONFIG_GDB_SCRIPTS \ |
| 64 | + CONFIG_SCHED_DEBUG \ |
| 65 | + CONFIG_PROC_SYSCTL \ |
| 66 | + CONFIG_PRINTK \ |
| 67 | + CONFIG_TRACEPOINTS \ |
| 68 | + CONFIG_FTRACE \ |
| 69 | + CONFIG_DEBUG_FS \ |
| 70 | +; do |
| 71 | + "${LKL_SRC}/scripts/config" --file "${LKL_SRC}/.config" --enable "${opt}" |
| 72 | +done |
| 73 | + |
| 74 | +"${LKL_SRC}/scripts/config" --file "${LKL_SRC}/.config" \ |
| 75 | + --set-val CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT y |
| 76 | + |
| 77 | +for opt in \ |
| 78 | + CONFIG_MODULES \ |
| 79 | + CONFIG_SOUND \ |
| 80 | + CONFIG_USB_SUPPORT \ |
| 81 | + CONFIG_INPUT \ |
| 82 | + CONFIG_NFS_FS \ |
| 83 | + CONFIG_CIFS \ |
| 84 | +; do |
| 85 | + "${LKL_SRC}/scripts/config" --file "${LKL_SRC}/.config" --disable "${opt}" |
| 86 | +done |
| 87 | + |
| 88 | +make -C "${LKL_SRC}" ARCH=lkl olddefconfig |
| 89 | + |
| 90 | +# ---- Build --------------------------------------------------------------- |
| 91 | + |
| 92 | +NPROC=$(nproc 2>/dev/null || echo 1) |
| 93 | + |
| 94 | +echo " BUILD ARCH=lkl kernel (-j${NPROC})" |
| 95 | +make -C "${LKL_SRC}" ARCH=lkl -j"${NPROC}" |
| 96 | + |
| 97 | +echo " BUILD tools/lkl (-j${NPROC})" |
| 98 | +make -C "${LKL_SRC}/tools/lkl" -j"${NPROC}" |
| 99 | + |
| 100 | +# ---- Verify -------------------------------------------------------------- |
| 101 | + |
| 102 | +test -f "${LKL_SRC}/tools/lkl/liblkl.a" \ |
| 103 | + || die "build succeeded but liblkl.a not found" |
| 104 | + |
| 105 | +echo " VERIFY symbols" |
| 106 | +for sym in lkl_init lkl_start_kernel lkl_cleanup lkl_syscall \ |
| 107 | + lkl_strerror lkl_disk_add lkl_mount_dev \ |
| 108 | + lkl_host_ops lkl_dev_blk_ops; do |
| 109 | + if ! nm "${LKL_SRC}/tools/lkl/liblkl.a" 2>/dev/null \ |
| 110 | + | awk -v s="$sym" '$3==s && $2~/^[TtDdBbRr]$/{found=1} END{exit !found}'; then |
| 111 | + die "MISSING symbol: ${sym}" |
| 112 | + fi |
| 113 | +done |
| 114 | + |
| 115 | +# ---- Install into lkl-<ARCH>/ ------------------------------------------- |
| 116 | + |
| 117 | +echo " INSTALL ${LKL_DIR}/" |
| 118 | +mkdir -p "${LKL_DIR}" |
| 119 | + |
| 120 | +cp "${LKL_SRC}/tools/lkl/liblkl.a" "${LKL_DIR}/" |
| 121 | +cp "${LKL_SRC}/tools/lkl/include/lkl.h" "${LKL_DIR}/" 2>/dev/null || true |
| 122 | +cp "${LKL_SRC}/tools/lkl/include/lkl/autoconf.h" "${LKL_DIR}/" 2>/dev/null || true |
| 123 | +cp "${LKL_SRC}/scripts/gdb/vmlinux-gdb.py" "${LKL_DIR}/" 2>/dev/null || true |
| 124 | + |
| 125 | +printf 'commit=%s\ndate=%s\narch=%s\n' \ |
| 126 | + "$(git -C "${LKL_SRC}" rev-parse HEAD)" \ |
| 127 | + "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ |
| 128 | + "${ARCH}" \ |
| 129 | + > "${LKL_DIR}/BUILD_INFO" |
| 130 | + |
| 131 | +( cd "${LKL_DIR}" && sha256sum ./* > sha256sums.txt ) |
| 132 | + |
| 133 | +echo "OK: ${LKL_DIR}/liblkl.a" |
0 commit comments