|
root / base / neovim / build.sh
build.sh Bash 152 lines 6.9 KB
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/bin/zsh
# Build script for neovim
#
# Task 1b-4 (M2): attempted USE_BUNDLED=OFF + PREFER_LUA=ON (consume our
# system libuv/msgpack-c/unibilium/libtermkey/libvterm/tree-sitter + lua).
# That failed: neovim's cmake.deps subproject requires an EXACT Lua 5.1
# (find_package(Lua 5.1 EXACT)) to link against for either the "prefer lua"
# path (real PUC Lua 5.1) OR the default LuaJIT path - and our system `lua`
# port is 5.4.8 (no 5.1-ABI package exists in zports). Per task brief
# fallback: keep USE_BUNDLED=ON (neovim builds its own private copies of
# these deps, using the bundled LuaJIT engine) rather than sink more time
# chasing a Lua 5.1 system package that doesn't exist yet. tree-sitter
# parsers were already being pre-staged this way regardless of the flag.
#
# cmake on Hammerhead has no HTTPS support, so every ExternalProject source
# tarball cmake.deps would otherwise fetch itself must be pre-staged with
# curl into .deps/build/downloads/<subdir>/<file> first.

set -e

PORTDIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)

cd "$SRCDIR"

# LuaJIT's own Makefile probes whether $(TARGET_CC) emits eh_frame/
# __unwind_info sections in a bare test compile (no -funwind-tables) to
# decide whether to auto-define -DLUAJIT_UNWIND_EXTERNAL. GCC 14 on
# Hammerhead doesn't default to -fasynchronous-unwind-tables the way
# glibc/Linux x86_64 GCC does, so the probe comes back empty and
# lj_err.c's LJ_TARGET_X64 unwind path hits its
# "#error Broken build system" guard. Patch cmake.deps' BuildLuajit.cmake
# to force -DLUAJIT_UNWIND_EXTERNAL directly instead of relying on the
# probe.
for p in "$PORTDIR"/patches/*.patch; do
    [ -f "$p" ] || continue
    echo "==> Applying patch: $(basename "$p")"
    patch -p1 < "$p"
done

# Create cmake Platform module for Hammerhead (illumos derivative)
# cmake doesn't recognize Hammerhead and won't set UNIX=TRUE without this
mkdir -p "$SRCDIR/.cmake/Platform"
echo 'include(Platform/SunOS)' > "$SRCDIR/.cmake/Platform/Hammerhead.cmake"

MODPATH="$SRCDIR/.cmake"

export PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig:$PREFIX/share/pkgconfig:/usr/lib/pkgconfig:$PKG_CONFIG_PATH"
export CMAKE_PREFIX_PATH="$PREFIX:$CMAKE_PREFIX_PATH"

# -D__illumos__: bundled tree-sitter (and possibly other deps) gate their
# <endian.h> #include on __linux__/__illumos__/*BSD/etc; our GCC 14
# toolchain defines __sun/__SVR4 but not __illumos__, tripping
# "#error platform not supported" even though Hammerhead's libc DOES ship
# a POSIX-style <endian.h> with le16toh/be16toh (verified at
# /usr/include/endian.h). Each dep in cmake.deps is its own fresh
# ExternalProject_Add cmake invocation (only CMAKE_BUILD_TYPE is
# propagated via DEPS_CMAKE_ARGS - CMAKE_C_FLAGS passed to the outer
# `cmake -S cmake.deps -B .deps` configure does NOT flow down to
# sub-projects), so export it via the CFLAGS env var instead: cmake's
# project() seeds CMAKE_C_FLAGS from $CFLAGS on first configure, and
# ExternalProject_Add's cmake subprocess inherits our environment.
export CFLAGS="${CFLAGS:-} -D__illumos__"

# coral's build wrapper exports DESTDIR=$PKGDIR globally so a package's
# own `make install`/`cmake --install` stages into the pkg dir. That
# environment variable bleeds into cmake.deps's bundled sub-builds too
# (e.g. LuaJIT's Makefile does `DPREFIX = $(DESTDIR)$(PREFIX)`), so
# instead of installing into .deps/usr as intended, luajit/libuv/etc were
# silently installing under $PKGDIR/<absolute .deps/usr path> - meaning
# .deps/usr never got populated and every downstream dep
# (lpeg/luv - "lua.h: No such file", "missing LUAJIT_LIBRARIES") failed to
# find them. Unset it for the whole cmake.deps phase; it gets re-exported
# below just before neovim's own `cmake --install build`, which is the
# only step that should honor it.
unset DESTDIR

# Pre-download every bundled dependency cmake.deps will build with
# USE_BUNDLED=ON (default LuaJIT engine): libuv, luajit, lpeg, unibilium,
# luv, utf8proc, plus the tree-sitter runtime + parsers used for
# :checkhealth/help/runtime syntax. GETTEXT/LIBICONV are MSVC-only and
# WASMTIME/UNCRUSTIFY/LUA_DEV_DEPS/XXD/WIN32YANK are Windows- or
# lint/test-only - not needed for a plain Unix build, so they are skipped.
DLDIR="$SRCDIR/.deps/build/downloads"

echo "Pre-downloading bundled dependencies..."
while IFS=' ' read -r name url; do
    [[ -z "$name" || -z "$url" ]] && continue
    local subdir=""
    case "$name" in
        LIBUV_URL)               subdir="libuv" ;;
        LUAJIT_URL)               subdir="luajit" ;;
        LPEG_URL)                 subdir="lpeg" ;;
        UNIBILIUM_URL)            subdir="unibilium" ;;
        LUV_URL)                  subdir="luv" ;;
        LUA_COMPAT53_URL)         subdir="lua_compat53" ;;
        UTF8PROC_URL)             subdir="utf8proc" ;;
        TREESITTER_URL)           subdir="treesitter" ;;
        TREESITTER_C_URL)         subdir="treesitter_c" ;;
        TREESITTER_LUA_URL)       subdir="treesitter_lua" ;;
        TREESITTER_VIM_URL)       subdir="treesitter_vim" ;;
        TREESITTER_VIMDOC_URL)    subdir="treesitter_vimdoc" ;;
        TREESITTER_QUERY_URL)     subdir="treesitter_query" ;;
        TREESITTER_MARKDOWN_URL)  subdir="treesitter_markdown" ;;
        *)                        continue ;;
    esac
    local fname="${url##*/}"
    mkdir -p "$DLDIR/$subdir"
    if [[ ! -f "$DLDIR/$subdir/$fname" ]]; then
        echo "  Downloading $subdir/$fname ..."
        curl -fsSL -o "$DLDIR/$subdir/$fname" "$url"
    fi
done < cmake.deps/deps.txt

# Build the cmake.deps subproject with the default USE_BUNDLED=ON (private
# copies of libuv/luajit/lpeg/unibilium/luv/utf8proc/tree-sitter, all
# statically linked into nvim - no system Lua 5.1 required).
# -D__illumos__: bundled tree-sitter's portable/endian.h gates its
# `#include <endian.h>` branch on __linux__/__illumos__/*BSD/etc; our GCC
# 14 toolchain defines __sun/__SVR4 but not __illumos__, so it falls
# through to "#error platform not supported" even though Hammerhead's
# libc DOES ship a POSIX-style <endian.h> with le16toh/be16toh (verified
# at /usr/include/endian.h). Define the macro ourselves rather than patch
# every upstream file that checks for it.
cmake -S cmake.deps -B .deps -G Ninja \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_MODULE_PATH="$MODPATH" \
    -DCMAKE_C_COMPILER=/usr/bin/cc \
    -DCMAKE_C_FLAGS="-D__illumos__"

cmake --build .deps

# Build neovim against the bundled deps just built above.
cmake -B build -G Ninja \
    -DCMAKE_BUILD_TYPE=RelWithDebInfo \
    -DCMAKE_MODULE_PATH="$MODPATH" \
    -DCMAKE_C_COMPILER=/usr/bin/cc \
    -DCMAKE_C_FLAGS="-D__illumos__" \
    -DCMAKE_INSTALL_PREFIX=$PREFIX \
    -DCMAKE_INSTALL_RPATH=$PREFIX/lib \
    -DENABLE_JEMALLOC=OFF

cmake --build build

# Install - restore DESTDIR (unset above for the cmake.deps phase) so this
# final install stages into $PKGDIR as coral expects.
export DESTDIR="$PKGDIR"
cmake --install build

# Create vi/vim symlinks
ln -sf nvim "$PKGDIR$PREFIX/bin/vim"
ln -sf nvim "$PKGDIR$PREFIX/bin/vi"