forked from mirrors/kingfisher
702 lines
27 KiB
Makefile
702 lines
27 KiB
Makefile
SHELL := /usr/bin/env bash
|
||
.SHELLFLAGS := -eu -o pipefail -c
|
||
|
||
PROJECT_NAME := kingfisher
|
||
ZIG_VERSION ?= 0.15.1
|
||
|
||
# Determine OS and whether to use gtar on darwin
|
||
OS := $(shell uname)
|
||
ifneq ($(OS),darwin)
|
||
USE_GTAR := 0
|
||
TAR_CMD := tar
|
||
TAR_OPTS := $(shell if tar --help 2>/dev/null | grep -q -- '--no-xattrs'; then echo '--no-xattrs -czf'; else echo '-czf'; fi)
|
||
else
|
||
ifneq ($(shell command -v gtar 2>/dev/null),)
|
||
USE_GTAR := 1
|
||
TAR_CMD := gtar
|
||
TAR_OPTS := --no-xattrs -czf
|
||
else
|
||
USE_GTAR := 0
|
||
TAR_CMD := tar
|
||
TAR_OPTS := -czf
|
||
endif
|
||
endif
|
||
|
||
# uname reports MSYS_NT*/MINGW*/CYGWIN* under Windows POSIX shells.
|
||
IS_WINDOWS_HOST := 0
|
||
ifneq (,$(filter Windows_NT MSYS_NT% MINGW% CYGWIN_NT%,$(OS)))
|
||
IS_WINDOWS_HOST := 1
|
||
endif
|
||
|
||
ifeq ($(OS),darwin)
|
||
export HOMEBREW_NO_INSTALL_CLEANUP=1
|
||
export HOMEBREW_NO_ENV_HINTS=1
|
||
export HOMEBREW_NO_AUTO_UPDATE=1
|
||
endif
|
||
|
||
# detect host architecture and map to our target suffixes
|
||
UNAME_M := $(shell uname -m)
|
||
ifeq ($(UNAME_M),x86_64)
|
||
ARCH := x64
|
||
else ifeq ($(UNAME_M),amd64)
|
||
ARCH := x64
|
||
else ifeq ($(UNAME_M),arm64)
|
||
ARCH := arm64
|
||
else ifeq ($(UNAME_M),aarch64)
|
||
ARCH := arm64
|
||
else
|
||
$(error Unsupported architecture: $(UNAME_M))
|
||
endif
|
||
|
||
ARCHIVE_CMD = $(TAR_CMD) $(TAR_OPTS)
|
||
SUDO_CMD := $(shell command -v sudo 2>/dev/null)
|
||
|
||
.PHONY: default help create-dockerignore ubuntu-x64 ubuntu-arm64 linux-x64 linux-arm64 darwin-arm64 darwin-x64 windows-x64 windows-arm64 windows \
|
||
linux darwin all list-archives check-docker check-rust clean tests
|
||
|
||
default: help
|
||
|
||
help:
|
||
@echo "Available targets:"
|
||
@echo " create-dockerignore"
|
||
@echo " linux-x64"
|
||
@echo " linux-arm64"
|
||
@echo " linux"
|
||
@echo " darwin-arm64"
|
||
@echo " darwin-x64"
|
||
@echo " darwin"
|
||
@echo " windows-x64"
|
||
@echo " windows-arm64"
|
||
@echo " windows"
|
||
@echo " all"
|
||
@echo " list-archives"
|
||
@echo " tests"
|
||
|
||
create-dockerignore:
|
||
@echo "target/" > .dockerignore
|
||
@echo ".git/" >> .dockerignore
|
||
@echo ".vscode/" >> .dockerignore
|
||
@echo "bin/" >> .dockerignore
|
||
|
||
|
||
.PHONY: setup-zig
|
||
setup-zig:
|
||
@install_manual_zig() { \
|
||
arch=$$(uname -m); \
|
||
case "$$arch" in \
|
||
x86_64) arch_tag=x86_64 ;; \
|
||
aarch64|arm64) arch_tag=aarch64 ;; \
|
||
*) echo "Unsupported architecture: $$arch"; exit 1 ;; \
|
||
esac; \
|
||
url_new="https://ziglang.org/download/$(ZIG_VERSION)/zig-$${arch_tag}-linux-$(ZIG_VERSION).tar.xz"; \
|
||
url_old="https://ziglang.org/download/$(ZIG_VERSION)/zig-linux-$${arch_tag}-$(ZIG_VERSION).tar.xz"; \
|
||
if ! curl -fL --retry 3 --retry-delay 2 -o /tmp/zig.tar.xz "$$url_new"; then \
|
||
echo "↩️ New Zig filename pattern failed, trying legacy pattern"; \
|
||
curl -fL --retry 3 --retry-delay 2 -o /tmp/zig.tar.xz "$$url_old"; \
|
||
fi; \
|
||
xz -t /tmp/zig.tar.xz >/dev/null 2>&1 || { \
|
||
echo "Downloaded Zig archive is invalid (not a tar.xz)."; \
|
||
ls -lh /tmp/zig.tar.xz || true; \
|
||
exit 1; \
|
||
}; \
|
||
tar -C /tmp -xf /tmp/zig.tar.xz; \
|
||
tar -tf /tmp/zig.tar.xz > /tmp/zig-contents.txt; \
|
||
IFS=/ read -r zig_dir _ < /tmp/zig-contents.txt; \
|
||
[ -n "$$zig_dir" ] || { echo "Could not determine Zig extract directory"; exit 1; }; \
|
||
$(SUDO_CMD) rm -rf /opt/zig; \
|
||
$(SUDO_CMD) mv "/tmp/$${zig_dir}" /opt/zig; \
|
||
$(SUDO_CMD) ln -sf /opt/zig/zig /usr/local/bin/zig; \
|
||
echo "✓ Zig $(ZIG_VERSION) installed to /usr/local/bin/zig"; \
|
||
}; \
|
||
installed_zig=$$(zig version 2>/dev/null || true); \
|
||
if [ "$$installed_zig" = "$(ZIG_VERSION)" ]; then \
|
||
echo "✓ Zig $(ZIG_VERSION) already installed"; \
|
||
else \
|
||
echo "⬇️ Installing Zig $(ZIG_VERSION) …"; \
|
||
if $(SUDO_CMD) apt-get update -qq && \
|
||
$(SUDO_CMD) apt-get install -y --no-install-recommends zig 2>/dev/null ; then \
|
||
apt_zig=$$(zig version 2>/dev/null || true); \
|
||
if [ "$$apt_zig" = "$(ZIG_VERSION)" ]; then \
|
||
echo "✓ Zig $(ZIG_VERSION) installed via apt"; \
|
||
else \
|
||
echo "⚠️ apt installed Zig '$$apt_zig' (need $(ZIG_VERSION)) – falling back to manual install"; \
|
||
install_manual_zig; \
|
||
fi; \
|
||
else \
|
||
echo "⚠️ Package 'zig' not in apt repos – falling back to manual install"; \
|
||
install_manual_zig; \
|
||
fi; \
|
||
fi
|
||
|
||
@if [ -f "$$HOME/.cargo/env" ]; then . $$HOME/.cargo/env; fi && \
|
||
(cargo zigbuild --help >/dev/null 2>&1 || { \
|
||
echo "⬇️ Installing cargo-zigbuild …"; \
|
||
cargo install --locked cargo-zigbuild; \
|
||
})
|
||
|
||
|
||
# ============= BAREMETAL BUILDS (Check Rust first, install if missing) =============
|
||
#
|
||
|
||
# -------------------------------------------------------------------------------------------------
|
||
# ubuntu-x64 — native static build for x86_64-unknown-linux-musl via Zig. Tested on Ubuntu 24.04.
|
||
# -------------------------------------------------------------------------------------------------
|
||
ubuntu-x64: setup-zig # ensures Zig & cargo-zigbuild exist
|
||
@echo "Checking Rust toolchain…"
|
||
@$(MAKE) check-rust || { \
|
||
echo "🦀 Installing Rust 1.92.0 …"; \
|
||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y; \
|
||
. $$HOME/.cargo/env; \
|
||
rustup toolchain install 1.92.0; \
|
||
rustup default 1.92.0; \
|
||
}
|
||
|
||
@echo "📦 Installing build dependencies (musl, cmake, etc.)…"
|
||
@$(SUDO_CMD) DEBIAN_FRONTEND=noninteractive apt-get update -qq
|
||
@$(SUDO_CMD) DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||
build-essential musl-tools musl-dev cmake pkg-config \
|
||
zlib1g-dev libbz2-dev liblzma-dev libboost-all-dev \
|
||
patch perl ragel
|
||
|
||
@echo "🔨 Building $(PROJECT_NAME) for x86_64-unknown-linux-musl …"
|
||
@. $$HOME/.cargo/env && \
|
||
rustup target add x86_64-unknown-linux-musl && \
|
||
export PKG_CONFIG_ALLOW_CROSS=1 && \
|
||
cargo zigbuild --release --target x86_64-unknown-linux-musl
|
||
|
||
@echo "🗜️ Packaging archive …"
|
||
@cd target/x86_64-unknown-linux-musl/release && \
|
||
find ./$(PROJECT_NAME) -type f -executable -exec sha256sum {} \; > CHECKSUM.txt
|
||
@mkdir -p target/release
|
||
@cp target/x86_64-unknown-linux-musl/release/$(PROJECT_NAME) target/release/
|
||
@cp target/x86_64-unknown-linux-musl/release/CHECKSUM.txt target/release/CHECKSUM-linux-x64.txt
|
||
@cd target/release && \
|
||
rm -rf $(PROJECT_NAME)-linux-x64.tgz && \
|
||
$(ARCHIVE_CMD) $(PROJECT_NAME)-linux-x64.tgz $(PROJECT_NAME) CHECKSUM-linux-x64.txt && \
|
||
sha256sum $(PROJECT_NAME)-linux-x64.tgz >> CHECKSUM-linux-x64.txt
|
||
|
||
$(MAKE) list-archives
|
||
|
||
|
||
# -------------------------------------------------------------------------------------------------
|
||
# ubuntu-arm64 — native cross-compile to aarch64-unknown-linux-musl via Zig. Tested on Ubuntu 24.04.
|
||
# -------------------------------------------------------------------------------------------------
|
||
ubuntu-arm64: setup-zig # ensures Zig & cargo-zigbuild exist
|
||
@echo "Checking Rust toolchain…"
|
||
@$(MAKE) check-rust || { \
|
||
echo "🦀 Installing Rust 1.92.0 …"; \
|
||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y; \
|
||
. $$HOME/.cargo/env; \
|
||
rustup toolchain install 1.92.0; \
|
||
rustup default 1.92.0; \
|
||
}
|
||
|
||
@echo "📦 Installing build dependencies (musl, cmake, etc.)…"
|
||
@$(SUDO_CMD) DEBIAN_FRONTEND=noninteractive apt-get update -qq
|
||
@$(SUDO_CMD) DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||
build-essential musl-tools musl-dev cmake pkg-config \
|
||
zlib1g-dev libbz2-dev liblzma-dev libboost-all-dev \
|
||
patch perl ragel
|
||
|
||
@echo "🔨 Building $(PROJECT_NAME) for aarch64-unknown-linux-musl …"
|
||
@. $$HOME/.cargo/env && \
|
||
rustup target add aarch64-unknown-linux-musl && \
|
||
export PKG_CONFIG_ALLOW_CROSS=1 && \
|
||
cargo zigbuild --release --target aarch64-unknown-linux-musl
|
||
|
||
@echo "🗜️ Packaging archive …"
|
||
@cd target/aarch64-unknown-linux-musl/release && \
|
||
find ./$(PROJECT_NAME) -type f -executable -exec sha256sum {} \; > CHECKSUM.txt
|
||
@mkdir -p target/release
|
||
@cp target/aarch64-unknown-linux-musl/release/$(PROJECT_NAME) target/release/
|
||
@cp target/aarch64-unknown-linux-musl/release/CHECKSUM.txt target/release/CHECKSUM-linux-arm64.txt
|
||
@cd target/release && \
|
||
rm -rf $(PROJECT_NAME)-linux-arm64.tgz && \
|
||
$(ARCHIVE_CMD) $(PROJECT_NAME)-linux-arm64.tgz $(PROJECT_NAME) CHECKSUM-linux-arm64.txt && \
|
||
sha256sum $(PROJECT_NAME)-linux-arm64.tgz >> CHECKSUM-linux-arm64.txt
|
||
|
||
$(MAKE) list-archives
|
||
|
||
darwin-arm64:
|
||
@echo "Checking Rust for darwin-arm64..."
|
||
@$(MAKE) check-rust || ( \
|
||
echo "Rust not found or out-of-date. Installing via Homebrew..." && \
|
||
brew install rust \
|
||
)
|
||
@brew list cmake >/dev/null 2>&1 || brew install cmake
|
||
@brew list boost >/dev/null 2>&1 || brew install boost
|
||
@brew install gcc libpcap pkg-config ragel sqlite coreutils gnu-tar
|
||
@rustup target add aarch64-apple-darwin
|
||
cargo build --release --target aarch64-apple-darwin --features system-alloc
|
||
@cd target/aarch64-apple-darwin/release && \
|
||
find ./$(PROJECT_NAME) -type f -not -name "*.d" -not -name "*.rlib" -exec shasum -a 256 {} \; > CHECKSUM.txt
|
||
@mkdir -p target/release
|
||
@cp target/aarch64-apple-darwin/release/$(PROJECT_NAME) target/release/
|
||
@cp target/aarch64-apple-darwin/release/CHECKSUM.txt target/release/CHECKSUM-darwin-arm64.txt
|
||
@cd target/release && \
|
||
rm -rf $(PROJECT_NAME)-darwin-arm64.tgz && \
|
||
$(ARCHIVE_CMD) $(PROJECT_NAME)-darwin-arm64.tgz $(PROJECT_NAME) CHECKSUM-darwin-arm64.txt && \
|
||
if [ -f $(PROJECT_NAME)-darwin-arm64.tgz ]; then \
|
||
shasum -a 256 $(PROJECT_NAME)-darwin-arm64.tgz >> CHECKSUM-darwin-arm64.txt; \
|
||
fi
|
||
$(MAKE) list-archives
|
||
|
||
darwin-dev:
|
||
cargo build --profile=dev --target aarch64-apple-darwin --features system-alloc
|
||
|
||
darwin-x64:
|
||
@echo "Checking Rust for darwin-x64..."
|
||
@$(MAKE) check-rust || ( \
|
||
echo "Rust not found or out-of-date. Installing via Homebrew..." && \
|
||
brew install rust \
|
||
)
|
||
@brew list cmake >/dev/null 2>&1 || brew install cmake
|
||
@brew list boost >/dev/null 2>&1 || brew install boost
|
||
@brew install gcc libpcap pkg-config ragel sqlite coreutils gnu-tar
|
||
@rustup target add x86_64-apple-darwin
|
||
source $$HOME/.cargo/env && cargo build --release --target x86_64-apple-darwin --features system-alloc
|
||
@cd target/x86_64-apple-darwin/release && \
|
||
find ./$(PROJECT_NAME) -type f -not -name "*.d" -not -name "*.rlib" -exec shasum -a 256 {} \; > CHECKSUM.txt
|
||
@mkdir -p target/release
|
||
@cp target/x86_64-apple-darwin/release/$(PROJECT_NAME) target/release/
|
||
@cp target/x86_64-apple-darwin/release/CHECKSUM.txt target/release/CHECKSUM-darwin-x64.txt
|
||
@cd target/release && \
|
||
rm -rf $(PROJECT_NAME)-darwin-x64.tgz && \
|
||
$(ARCHIVE_CMD) $(PROJECT_NAME)-darwin-x64.tgz $(PROJECT_NAME) CHECKSUM-darwin-x64.txt && \
|
||
if [ -f $(PROJECT_NAME)-darwin-x64.tgz ]; then \
|
||
shasum -a 256 $(PROJECT_NAME)-darwin-x64.tgz >> CHECKSUM-darwin-x64.txt; \
|
||
fi
|
||
$(MAKE) list-archives
|
||
|
||
# Windows x64 build path for MSYS2/MinGW (GNU toolchain + vectorscan from source)
|
||
windows-x64:
|
||
ifeq ($(IS_WINDOWS_HOST),1)
|
||
@echo "Detected Windows host."
|
||
else
|
||
$(error "This target can only run on Windows.")
|
||
endif
|
||
@bash -eu -o pipefail -c '\
|
||
command -v pacman >/dev/null 2>&1 || { \
|
||
echo "MSYS2 pacman not found. Run this target from an MSYS2 MinGW64 shell."; \
|
||
exit 1; \
|
||
}; \
|
||
case "$${MSYSTEM:-}" in \
|
||
MINGW64) ;; \
|
||
MSYS) \
|
||
echo "MSYSTEM=MSYS detected; continuing with /mingw64 toolchain for testing."; \
|
||
export PATH=/mingw64/bin:$$PATH; \
|
||
;; \
|
||
*) \
|
||
echo "MSYSTEM=$${MSYSTEM:-unset}. Continuing by forcing /mingw64 toolchain path."; \
|
||
export PATH=/mingw64/bin:$$PATH; \
|
||
;; \
|
||
esac; \
|
||
command -v mingw32-make >/dev/null 2>&1 || { \
|
||
echo "Installing MinGW build dependencies..."; \
|
||
pacman --noconfirm --needed -S \
|
||
mingw-w64-x86_64-toolchain \
|
||
mingw-w64-x86_64-cmake \
|
||
mingw-w64-x86_64-boost \
|
||
mingw-w64-x86_64-pkg-config \
|
||
mingw-w64-x86_64-ragel \
|
||
mingw-w64-x86_64-pcre2 \
|
||
mingw-w64-x86_64-python \
|
||
git make; \
|
||
}; \
|
||
repo_root="$$(pwd)"; \
|
||
test -d /tmp/vectorscan || git clone --depth 1 --branch vectorscan/5.4.11 https://github.com/VectorCamp/vectorscan.git /tmp/vectorscan; \
|
||
mkdir -p /tmp/vectorscan/build; \
|
||
cd /tmp/vectorscan/build; \
|
||
cmake .. \
|
||
-G "MinGW Makefiles" \
|
||
-DCMAKE_BUILD_TYPE=Release \
|
||
-DBUILD_SHARED_LIBS=OFF \
|
||
-DBUILD_TOOLS=OFF \
|
||
-DCMAKE_C_COMPILER=gcc \
|
||
-DCMAKE_CXX_COMPILER=g++ \
|
||
-DCMAKE_INSTALL_PREFIX=/mingw64; \
|
||
mingw32-make -j$$(nproc); \
|
||
mingw32-make install; \
|
||
mkdir -p /mingw64/lib/pkgconfig; \
|
||
if [ -f /mingw64/include/hs/hs.h ]; then \
|
||
hs_include=/mingw64/include/hs; \
|
||
else \
|
||
hs_include=/mingw64/include; \
|
||
fi; \
|
||
printf "%s\n" \
|
||
"prefix=/mingw64" \
|
||
"exec_prefix=\$${prefix}" \
|
||
"libdir=\$${prefix}/lib" \
|
||
"includedir=$$hs_include" \
|
||
"" \
|
||
"Name: libhs" \
|
||
"Description: Vectorscan regex library (Hyperscan fork)" \
|
||
"Version: 5.4.11" \
|
||
"Libs: -L\$${libdir} -lhs" \
|
||
"Cflags: -I\$${includedir}" \
|
||
> /mingw64/lib/pkgconfig/libhs.pc; \
|
||
export PKG_CONFIG_PATH=/mingw64/lib/pkgconfig; \
|
||
pkg-config --cflags --libs libhs; \
|
||
if ! command -v rustup >/dev/null 2>&1 && ! command -v rustup.exe >/dev/null 2>&1; then \
|
||
cargo_home_candidate=""; \
|
||
if [ -n "$${USERPROFILE:-}" ]; then \
|
||
cargo_home_candidate="$$(cygpath -u "$${USERPROFILE}")/.cargo/bin"; \
|
||
elif [ -n "$${HOMEDRIVE:-}" ] && [ -n "$${HOMEPATH:-}" ]; then \
|
||
cargo_home_candidate="$$(cygpath -u "$${HOMEDRIVE}$${HOMEPATH}")/.cargo/bin"; \
|
||
fi; \
|
||
if [ -n "$$cargo_home_candidate" ] && [ -d "$$cargo_home_candidate" ]; then \
|
||
echo "Adding Rust toolchain path: $$cargo_home_candidate"; \
|
||
export PATH="$$cargo_home_candidate:$$PATH"; \
|
||
fi; \
|
||
fi; \
|
||
if command -v rustup >/dev/null 2>&1; then \
|
||
RUSTUP_BIN=rustup; \
|
||
elif command -v rustup.exe >/dev/null 2>&1; then \
|
||
RUSTUP_BIN=rustup.exe; \
|
||
else \
|
||
echo "rustup not found. Install Rust via rustup and ensure ~/.cargo/bin is on PATH."; \
|
||
exit 1; \
|
||
fi; \
|
||
if command -v cargo >/dev/null 2>&1; then \
|
||
CARGO_BIN=cargo; \
|
||
elif command -v cargo.exe >/dev/null 2>&1; then \
|
||
CARGO_BIN=cargo.exe; \
|
||
else \
|
||
echo "cargo not found. Install Rust via rustup and ensure ~/.cargo/bin is on PATH."; \
|
||
exit 1; \
|
||
fi; \
|
||
cd "$$repo_root"; \
|
||
export HYPERSCAN_ROOT="$$(cygpath -m /mingw64)"; \
|
||
export LIBRARY_PATH="/mingw64/lib:$${LIBRARY_PATH:-}"; \
|
||
export CPATH="/mingw64/include:$${CPATH:-}"; \
|
||
extra_native_lib_dirs="-L native=/mingw64/lib"; \
|
||
if command -v x86_64-w64-mingw32-gcc >/dev/null 2>&1; then \
|
||
libgcc_a_path="$$(x86_64-w64-mingw32-gcc -print-libgcc-file-name 2>/dev/null || true)"; \
|
||
if [ -n "$$libgcc_a_path" ] && [ -f "$$libgcc_a_path" ]; then \
|
||
libgcc_dir="$$(dirname "$$libgcc_a_path")"; \
|
||
extra_native_lib_dirs="$$extra_native_lib_dirs -L native=$$libgcc_dir"; \
|
||
echo "Using libgcc from $$libgcc_dir"; \
|
||
fi; \
|
||
fi; \
|
||
export RUSTFLAGS="$${RUSTFLAGS:-} $$extra_native_lib_dirs -C target-feature=+crt-static -C link-arg=-static"; \
|
||
echo "Using HYPERSCAN_ROOT=$$HYPERSCAN_ROOT"; \
|
||
"$$RUSTUP_BIN" target add x86_64-pc-windows-gnu; \
|
||
export LIBHS_NO_PKG_CONFIG=1; \
|
||
if [ "$${WINDOWS_ONLY_DEPS:-0}" = "1" ]; then \
|
||
echo "WINDOWS_ONLY_DEPS=1 set; skipping cargo build and packaging."; \
|
||
exit 0; \
|
||
fi; \
|
||
"$$CARGO_BIN" build --release --target x86_64-pc-windows-gnu --features system-alloc; \
|
||
mkdir -p target/release; \
|
||
cp target/x86_64-pc-windows-gnu/release/$(PROJECT_NAME).exe target/release/$(PROJECT_NAME).exe; \
|
||
cd target/release; \
|
||
sha256sum $(PROJECT_NAME).exe > CHECKSUM-windows-x64.txt; \
|
||
rm -f $(PROJECT_NAME)-windows-x64.zip; \
|
||
powershell.exe -NoProfile -Command "Compress-Archive -Path '\''$(PROJECT_NAME).exe'\'','\''CHECKSUM-windows-x64.txt'\'' -DestinationPath '\''$(PROJECT_NAME)-windows-x64.zip'\'' -Force"; \
|
||
sha256sum $(PROJECT_NAME)-windows-x64.zip >> CHECKSUM-windows-x64.txt; \
|
||
echo "Built binary: target/release/$(PROJECT_NAME).exe"; \
|
||
echo "Built archive: target/release/$(PROJECT_NAME)-windows-x64.zip"; \
|
||
'
|
||
|
||
# Windows ARM64 build path for MSYS2/clangarm64 (GNU/LLVM MinGW)
|
||
windows-arm64:
|
||
ifeq ($(IS_WINDOWS_HOST),1)
|
||
@echo "Detected Windows host."
|
||
else
|
||
$(error "This target can only run on Windows.")
|
||
endif
|
||
@bash -eu -o pipefail -c '\
|
||
command -v pacman >/dev/null 2>&1 || { \
|
||
echo "MSYS2 pacman not found. Run this target from an MSYS2 shell."; \
|
||
exit 1; \
|
||
}; \
|
||
case "$${MSYSTEM:-}" in \
|
||
CLANGARM64) ;; \
|
||
MINGW64|MSYS) \
|
||
echo "MSYSTEM=$${MSYSTEM:-unset} detected; using /clangarm64 cross toolchain for ARM64."; \
|
||
export PATH=/clangarm64/bin:$$PATH; \
|
||
;; \
|
||
*) \
|
||
echo "MSYSTEM=$${MSYSTEM:-unset}. Continuing by forcing /clangarm64 toolchain path."; \
|
||
export PATH=/clangarm64/bin:$$PATH; \
|
||
;; \
|
||
esac; \
|
||
echo "Ensuring ARM64 MinGW/clang dependencies are installed..."; \
|
||
pacman --noconfirm --needed -S \
|
||
mingw-w64-clang-aarch64-toolchain \
|
||
mingw-w64-clang-aarch64-cmake \
|
||
mingw-w64-clang-aarch64-boost \
|
||
mingw-w64-clang-aarch64-pkgconf \
|
||
mingw-w64-clang-aarch64-ragel \
|
||
mingw-w64-clang-aarch64-pcre2 \
|
||
mingw-w64-clang-aarch64-python \
|
||
git make; \
|
||
repo_root="$$(pwd)"; \
|
||
test -d /tmp/vectorscan-arm64 || git clone --depth 1 --branch vectorscan/5.4.11 https://github.com/VectorCamp/vectorscan.git /tmp/vectorscan-arm64; \
|
||
mkdir -p /tmp/vectorscan-arm64/build; \
|
||
cd /tmp/vectorscan-arm64/build; \
|
||
cmake .. \
|
||
-G "MinGW Makefiles" \
|
||
-DCMAKE_BUILD_TYPE=Release \
|
||
-DBUILD_SHARED_LIBS=OFF \
|
||
-DBUILD_TOOLS=OFF \
|
||
-DCMAKE_SYSTEM_NAME=Windows \
|
||
-DCMAKE_SYSTEM_PROCESSOR=ARM64 \
|
||
-DCMAKE_C_COMPILER=clang \
|
||
-DCMAKE_CXX_COMPILER=clang++ \
|
||
-DCMAKE_INSTALL_PREFIX=/clangarm64; \
|
||
mingw32-make -j$$(nproc); \
|
||
mingw32-make install; \
|
||
mkdir -p /clangarm64/lib/pkgconfig; \
|
||
if [ -f /clangarm64/include/hs/hs.h ]; then \
|
||
hs_include=/clangarm64/include/hs; \
|
||
else \
|
||
hs_include=/clangarm64/include; \
|
||
fi; \
|
||
printf "%s\n" \
|
||
"prefix=/clangarm64" \
|
||
"exec_prefix=\$${prefix}" \
|
||
"libdir=\$${prefix}/lib" \
|
||
"includedir=$$hs_include" \
|
||
"" \
|
||
"Name: libhs" \
|
||
"Description: Vectorscan regex library (Hyperscan fork)" \
|
||
"Version: 5.4.11" \
|
||
"Libs: -L\$${libdir} -lhs" \
|
||
"Cflags: -I\$${includedir}" \
|
||
> /clangarm64/lib/pkgconfig/libhs.pc; \
|
||
export PKG_CONFIG_PATH=/clangarm64/lib/pkgconfig; \
|
||
pkg-config --cflags --libs libhs; \
|
||
if ! command -v rustup >/dev/null 2>&1 && ! command -v rustup.exe >/dev/null 2>&1; then \
|
||
cargo_home_candidate=""; \
|
||
if [ -n "$${USERPROFILE:-}" ]; then \
|
||
cargo_home_candidate="$$(cygpath -u "$${USERPROFILE}")/.cargo/bin"; \
|
||
elif [ -n "$${HOMEDRIVE:-}" ] && [ -n "$${HOMEPATH:-}" ]; then \
|
||
cargo_home_candidate="$$(cygpath -u "$${HOMEDRIVE}$${HOMEPATH}")/.cargo/bin"; \
|
||
fi; \
|
||
if [ -n "$$cargo_home_candidate" ] && [ -d "$$cargo_home_candidate" ]; then \
|
||
echo "Adding Rust toolchain path: $$cargo_home_candidate"; \
|
||
export PATH="$$cargo_home_candidate:$$PATH"; \
|
||
fi; \
|
||
fi; \
|
||
if command -v rustup >/dev/null 2>&1; then \
|
||
RUSTUP_BIN=rustup; \
|
||
elif command -v rustup.exe >/dev/null 2>&1; then \
|
||
RUSTUP_BIN=rustup.exe; \
|
||
else \
|
||
echo "rustup not found. Install Rust via rustup and ensure ~/.cargo/bin is on PATH."; \
|
||
exit 1; \
|
||
fi; \
|
||
if command -v cargo >/dev/null 2>&1; then \
|
||
CARGO_BIN=cargo; \
|
||
elif command -v cargo.exe >/dev/null 2>&1; then \
|
||
CARGO_BIN=cargo.exe; \
|
||
else \
|
||
echo "cargo not found. Install Rust via rustup and ensure ~/.cargo/bin is on PATH."; \
|
||
exit 1; \
|
||
fi; \
|
||
cd "$$repo_root"; \
|
||
export HYPERSCAN_ROOT="$$(cygpath -m /clangarm64)"; \
|
||
export LIBRARY_PATH="/clangarm64/lib:$${LIBRARY_PATH:-}"; \
|
||
export CPATH="/clangarm64/include:$${CPATH:-}"; \
|
||
export RUSTFLAGS="$${RUSTFLAGS:-} -L native=/clangarm64/lib -C target-feature=+crt-static -C link-arg=-static"; \
|
||
echo "Using HYPERSCAN_ROOT=$$HYPERSCAN_ROOT"; \
|
||
"$$RUSTUP_BIN" target add aarch64-pc-windows-gnullvm; \
|
||
export LIBHS_NO_PKG_CONFIG=1; \
|
||
if [ "$${WINDOWS_ONLY_DEPS:-0}" = "1" ]; then \
|
||
echo "WINDOWS_ONLY_DEPS=1 set; skipping cargo build and packaging."; \
|
||
exit 0; \
|
||
fi; \
|
||
"$$CARGO_BIN" build --release --target aarch64-pc-windows-gnullvm --features system-alloc; \
|
||
mkdir -p target/release; \
|
||
cp target/aarch64-pc-windows-gnullvm/release/$(PROJECT_NAME).exe target/release/$(PROJECT_NAME).exe; \
|
||
cd target/release; \
|
||
sha256sum $(PROJECT_NAME).exe > CHECKSUM-windows-arm64.txt; \
|
||
rm -f $(PROJECT_NAME)-windows-arm64.zip; \
|
||
powershell.exe -NoProfile -Command "Compress-Archive -Path '\''$(PROJECT_NAME).exe'\'','\''CHECKSUM-windows-arm64.txt'\'' -DestinationPath '\''$(PROJECT_NAME)-windows-arm64.zip'\'' -Force"; \
|
||
sha256sum $(PROJECT_NAME)-windows-arm64.zip >> CHECKSUM-windows-arm64.txt; \
|
||
echo "Built binary: target/release/$(PROJECT_NAME).exe"; \
|
||
echo "Built archive: target/release/$(PROJECT_NAME)-windows-arm64.zip"; \
|
||
'
|
||
#
|
||
# ============= DOCKER-BASED BUILDS =============
|
||
# #
|
||
|
||
linux-x64: check-docker create-dockerignore
|
||
@mkdir -p target/release
|
||
docker run --platform linux/amd64 --rm \
|
||
-v "$$(pwd):/src" -w /src rust:1.92-alpine sh -eu -c '\
|
||
apk add --no-cache \
|
||
musl-dev \
|
||
gcc g++ make cmake pkgconfig \
|
||
zlib-dev zlib-static \
|
||
bzip2-dev bzip2-static \
|
||
xz-dev xz-static \
|
||
boost-dev linux-headers \
|
||
patch perl ragel \
|
||
git openssl-dev curl && \
|
||
\
|
||
cargo test --workspace --all-targets ; \
|
||
\
|
||
rustup target add x86_64-unknown-linux-musl && \
|
||
\
|
||
export PKG_CONFIG_ALLOW_CROSS=1 ; \
|
||
export RUSTFLAGS="-C target-feature=+crt-static" ; \
|
||
\
|
||
cargo build --release --target x86_64-unknown-linux-musl && \
|
||
cd target/x86_64-unknown-linux-musl/release && \
|
||
sha256sum kingfisher > CHECKSUM.txt && \
|
||
tar -czf /src/target/release/kingfisher-linux-x64.tgz \
|
||
kingfisher CHECKSUM.txt \
|
||
'
|
||
$(MAKE) list-archives
|
||
|
||
linux-arm64: check-docker create-dockerignore
|
||
@mkdir -p target/release
|
||
docker run --platform linux/arm64 --rm \
|
||
-v "$$(pwd):/src" -w /src rust:1.92-alpine sh -eu -c '\
|
||
apk add --no-cache \
|
||
musl-dev \
|
||
gcc g++ make cmake pkgconfig \
|
||
zlib-dev zlib-static \
|
||
bzip2-dev bzip2-static \
|
||
xz-dev xz-static \
|
||
boost-dev linux-headers \
|
||
patch perl ragel \
|
||
git openssl-dev curl && \
|
||
\
|
||
rustup target add aarch64-unknown-linux-musl && \
|
||
\
|
||
cargo test --workspace --all-targets ; \
|
||
\
|
||
export PKG_CONFIG_ALLOW_CROSS=1 ; \
|
||
export RUSTFLAGS="-C target-feature=+crt-static" ; \
|
||
\
|
||
cargo build --release --target aarch64-unknown-linux-musl && \
|
||
\
|
||
cd target/aarch64-unknown-linux-musl/release && \
|
||
sha256sum kingfisher > CHECKSUM.txt && \
|
||
tar -czf /src/target/release/kingfisher-linux-arm64.tgz \
|
||
kingfisher CHECKSUM.txt \
|
||
'
|
||
$(MAKE) list-archives
|
||
|
||
|
||
# ============= AGGREGATE TARGETS =============
|
||
#
|
||
|
||
windows: windows-x64 windows-arm64
|
||
@echo "# Windows builds:" > target/release/CHECKSUMS-windows.txt
|
||
@echo -e "\n# x86_64-windows build:" >> target/release/CHECKSUMS-windows.txt
|
||
@cat target/release/CHECKSUM-windows-x64.txt >> target/release/CHECKSUMS-windows.txt
|
||
@echo -e "\n# arm64-windows build:" >> target/release/CHECKSUMS-windows.txt
|
||
@cat target/release/CHECKSUM-windows-arm64.txt >> target/release/CHECKSUMS-windows.txt
|
||
@echo -e "\nBuilt Windows archives:"
|
||
@ls -lh target/release/*.zip
|
||
@echo -e "\nWindows Checksums:"
|
||
@cat target/release/CHECKSUMS-windows.txt
|
||
|
||
linux:
|
||
$(MAKE) linux-$(ARCH)
|
||
|
||
linux-all: linux-x64 linux-arm64
|
||
@echo "# Linux builds:" > target/release/CHECKSUMS-linux.txt
|
||
@echo -e "\n# x86_64-linux build:" >> target/release/CHECKSUMS-linux.txt
|
||
@cat target/release/CHECKSUM-linux-x64.txt >> target/release/CHECKSUMS-linux.txt
|
||
@echo -e "\n# arm64-linux build:" >> target/release/CHECKSUMS-linux.txt
|
||
@cat target/release/CHECKSUM-linux-arm64.txt >> target/release/CHECKSUMS-linux.txt
|
||
@echo -e "\nBuilt Linux archives:"
|
||
@ls -lh target/release/*.tgz
|
||
@echo -e "\nLinux Checksums:"
|
||
@cat target/release/CHECKSUMS-linux.txt
|
||
|
||
darwin:
|
||
$(MAKE) darwin-$(ARCH)
|
||
|
||
darwin-all: darwin-arm64 darwin-x64
|
||
@echo "# darwin builds:" > target/release/CHECKSUMS-darwin.txt
|
||
@echo -e "\n# arm64-darwin build:" >> target/release/CHECKSUMS-darwin.txt
|
||
@cat target/release/CHECKSUM-darwin-arm64.txt >> target/release/CHECKSUMS-darwin.txt
|
||
@echo -e "\n# x86_64-darwin build:" >> target/release/CHECKSUMS-darwin.txt
|
||
@cat target/release/CHECKSUM-darwin-x64.txt >> target/release/CHECKSUMS-darwin.txt
|
||
@echo -e "\nBuilt darwin archives:"
|
||
@ls -lh target/release/*.tgz
|
||
@echo -e "\ndarwin Checksums:"
|
||
@cat target/release/CHECKSUMS-darwin.txt
|
||
|
||
all: linux darwin
|
||
@echo "# All builds:" > target/release/CHECKSUMS.txt
|
||
@echo -e "\n# Linux builds:" >> target/release/CHECKSUMS.txt
|
||
@cat target/release/CHECKSUMS-linux.txt >> target/release/CHECKSUMS.txt
|
||
@echo -e "\n# darwin builds:" >> target/release/CHECKSUMS.txt
|
||
@cat target/release/CHECKSUMS-darwin.txt >> target/release/CHECKSUMS.txt
|
||
@echo -e "\nBuilt archives:"
|
||
@ls -lh target/release/*.tgz
|
||
@echo -e "\nCombined Checksums:"
|
||
@cat target/release/CHECKSUMS.txt
|
||
|
||
dockerfile:
|
||
# Build for the host architecture (default)
|
||
docker build -f docker/Dockerfile -t kingfisher:latest .
|
||
|
||
# Cross‑build for arm64 from an x64 machine
|
||
docker buildx build -f docker/Dockerfile --platform linux/arm64 -t kingfisher:arm64 .
|
||
|
||
list-archives:
|
||
@echo -e "\n=== Built archives ==="
|
||
@found=0; \
|
||
for f in target/release/*.tgz; do \
|
||
if [ -e "$$f" ]; then \
|
||
found=1; \
|
||
realpath "$$f"; \
|
||
fi; \
|
||
done; \
|
||
if [ $$found -eq 0 ]; then \
|
||
echo "No archives found."; \
|
||
fi
|
||
|
||
check-docker:
|
||
@command -v docker >/dev/null 2>&1 || { \
|
||
echo "Docker is not installed. Please install Docker."; \
|
||
exit 1; \
|
||
}
|
||
|
||
check-rust:
|
||
@version=$$(rustc --version 2>/dev/null | awk '{print $$2}'); \
|
||
if [ -z "$$version" ]; then \
|
||
echo "Rust not found."; \
|
||
exit 1; \
|
||
fi; \
|
||
required=1.92.0; \
|
||
if [ $$(printf '%s\n' "$$required" "$$version" | sort -V | head -n1) != "$$required" ]; then \
|
||
echo "Rust version $$version is older than required $$required."; \
|
||
exit 1; \
|
||
else \
|
||
echo "Rust version $$version is acceptable."; \
|
||
fi
|
||
|
||
tests:
|
||
@echo "🔍 checking for cargo-nextest …"
|
||
@if command -v cargo-nextest >/dev/null 2>&1; then \
|
||
echo "✅ cargo-nextest already present"; \
|
||
else \
|
||
echo "📦 installing cargo-nextest …"; \
|
||
cargo install --locked cargo-nextest || true; \
|
||
fi
|
||
@echo "▶ running tests …"; \
|
||
if command -v cargo-nextest >/dev/null 2>&1; then \
|
||
cargo nextest run --workspace --all-targets; \
|
||
else \
|
||
echo "⚠️ cargo-nextest unavailable – falling back to cargo test"; \
|
||
cargo test --workspace --all-targets; \
|
||
fi
|
||
|
||
clean:
|
||
@echo "Cleaning build artifacts..."
|
||
cargo clean
|
||
rm -f .dockerignore
|
||
|
||
notices:
|
||
@echo "Generating third-party notices..."
|
||
@cargo install cargo-bundle-licenses
|
||
@cargo bundle-licenses --format yaml --output THIRD_PARTY_NOTICES
|