Files
hakorune/tools/build_llvm.sh
Selfhosting Dev b573c3e5b8 feat: LLVM_SYS_180_PREFIX環境変数削除完了!llvm-harness経路でRust LLVMバインディング不要化達成
🚀 Phase 15.5 MIR Call統一革命 - LLVM環境変数削除フェーズ完了

##  完了内容
- **条件分岐実装**: llvm-harness(デフォルト)はLLVM_SYS_180_PREFIX不要
- **後方互換性維持**: llvm-inkwell-legacy使用時はLLVM_SYS_180_PREFIX必要
- **全ツール統一**: 12個のビルドスクリプト・テストスクリプトを一括更新
- **ドキュメント更新**: ENV_VARS.mdでLLVM feature選択方法を明記

## 🛠️ 更新ファイル
- **コアビルド**: src/runner/build.rs, tools/build_llvm.sh, build_llvm.sh
- **スモークテスト**: tools/llvm_smoke.sh, tools/test/smoke/llvm/ir_phi_empty_check.sh
- **CI設定**: .github/workflows/min-gate.yml
- **Windows版**: build_llvm_wsl.sh, build_llvm_wsl_msvc.sh (cross-compilation)
- **開発ツール**: tools/build_compiler_exe.sh, tools/ny_mir_builder.sh
- **ドキュメント**: docs/development/runtime/ENV_VARS.md

##  技術的成果
- **環境変数削減**: LLVM_SYS_180_PREFIX → 条件付き使用のみ
- **Python LLVM統合**: llvmliteハーネス経路でRust LLVM依存完全除去
- **ビルド簡略化**: デフォルトでllvm-config-18のみ必要
- **動作確認**: tools/llvm_smoke.sh成功 (1648バイト.oファイル生成)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-24 03:28:24 +09:00

150 lines
5.5 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
set -euo pipefail
if [[ "${NYASH_CLI_VERBOSE:-0}" == "1" ]]; then
set -x
fi
usage() {
cat << USAGE
Usage: tools/build_llvm.sh <input.nyash> [-o <output>]
Compiles a Nyash program with the LLVM backend to an object (.o),
links it with the NyRT static runtime, and produces a native executable.
Options:
-o <output> Output executable path (default: tmp/app)
Requirements:
- LLVM 18 development (llvm-config-18)
- NyRT static runtime (crates/nyrt)
USAGE
}
if [[ $# -lt 1 ]]; then usage; exit 1; fi
INPUT=""
OUT="tmp/app"
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help) usage; exit 0 ;;
-o) OUT="$2"; shift 2 ;;
*) INPUT="$1"; shift ;;
esac
done
if [[ ! -f "$INPUT" ]]; then
echo "error: input file not found: $INPUT" >&2
exit 1
fi
if ! command -v llvm-config-18 >/dev/null 2>&1; then
echo "error: llvm-config-18 not found (install LLVM 18 dev)." >&2
exit 2
fi
echo "[1/4] Building nyash (feature selectable) ..."
# Select LLVM feature: default harness (llvm), or legacy inkwell when NYASH_LLVM_FEATURE=llvm-inkwell-legacy
LLVM_FEATURE=${NYASH_LLVM_FEATURE:-llvm}
# Use 24 threads for parallel build
if [[ "$LLVM_FEATURE" == "llvm-inkwell-legacy" ]]; then
# Legacy inkwell需要LLVM_SYS_180_PREFIX
_LLVMPREFIX=$(llvm-config-18 --prefix)
LLVM_SYS_181_PREFIX="${_LLVMPREFIX}" LLVM_SYS_180_PREFIX="${_LLVMPREFIX}" \
CARGO_INCREMENTAL=1 cargo build --release -j 24 -p nyash-rust --features "$LLVM_FEATURE" >/dev/null
else
# llvm-harnessデフォルトはLLVM_SYS_180_PREFIX不要
CARGO_INCREMENTAL=1 cargo build --release -j 24 -p nyash-rust --features "$LLVM_FEATURE" >/dev/null
fi
echo "[2/4] Emitting object (.o) via LLVM backend ..."
# Default object output path under target/aot_objects
mkdir -p "$PWD/target/aot_objects"
stem=$(basename "$INPUT")
stem=${stem%.nyash}
OBJ="${NYASH_LLVM_OBJ_OUT:-$PWD/target/aot_objects/${stem}.o}"
if [[ "${NYASH_LLVM_SKIP_EMIT:-0}" != "1" ]]; then
rm -f "$OBJ"
COMPILER_MODE=${NYASH_LLVM_COMPILER:-harness}
case "$COMPILER_MODE" in
crate)
# Use crates/nyash-llvm-compiler (ny-llvmc): requires pre-generated MIR JSON path in NYASH_LLVM_MIR_JSON
if [[ -z "${NYASH_LLVM_MIR_JSON:-}" ]]; then
# Autoemit MIR JSON via nyash CLI flag
mkdir -p tmp
NYASH_LLVM_MIR_JSON="tmp/nyash_crate_mir.json"
echo " emitting MIR JSON: $NYASH_LLVM_MIR_JSON" >&2
./target/release/nyash --emit-mir-json "$NYASH_LLVM_MIR_JSON" --backend mir "$INPUT" >/dev/null
fi
echo " using ny-llvmc (crate) with JSON: $NYASH_LLVM_MIR_JSON" >&2
cargo build --release -p nyash-llvm-compiler >/dev/null
# Optional schema validation when explicitly requested
if [[ "${NYASH_LLVM_VALIDATE_JSON:-0}" == "1" ]]; then
if [[ -f tools/validate_mir_json.py ]]; then
if ! python3 -m jsonschema --version >/dev/null 2>&1; then
echo "[warn] jsonschema not available; skipping schema validation" >&2
else
echo " validating MIR JSON schema ..." >&2
python3 tools/validate_mir_json.py "$NYASH_LLVM_MIR_JSON" || {
echo "error: MIR JSON validation failed" >&2; exit 3; }
fi
fi
fi
if [[ "${NYASH_LLVM_EMIT:-obj}" == "exe" ]]; then
echo " emitting EXE via ny-llvmc (crate) ..." >&2
# Ensure NyRT is built (for libnyrt.a)
if [[ ! -f crates/nyrt/target/release/libnyrt.a && "${NYASH_LLVM_SKIP_NYRT_BUILD:-0}" != "1" ]]; then
( cd crates/nyrt && cargo build --release -j 24 >/dev/null )
fi
NYRT_DIR_HINT="${NYASH_LLVM_NYRT:-crates/nyrt/target/release}"
./target/release/ny-llvmc --in "$NYASH_LLVM_MIR_JSON" --out "$OUT" --emit exe --nyrt "$NYRT_DIR_HINT" ${NYASH_LLVM_LIBS:+--libs "$NYASH_LLVM_LIBS"}
echo "✅ Done: $OUT"; echo " (runtime may require nyash.toml and plugins depending on app)"; exit 0
else
./target/release/ny-llvmc --in "$NYASH_LLVM_MIR_JSON" --out "$OBJ"
fi
;;
esac
if [[ "$COMPILER_MODE" == "harness" ]]; then
if [[ "${NYASH_LLVM_FEATURE:-llvm}" == "llvm-inkwell-legacy" ]]; then
# Legacy path: do not use harness (LLVM_SYS_180_PREFIX needed)
_LLVMPREFIX=$(llvm-config-18 --prefix)
NYASH_LLVM_OBJ_OUT="$OBJ" LLVM_SYS_181_PREFIX="${_LLVMPREFIX}" LLVM_SYS_180_PREFIX="${_LLVMPREFIX}" \
./target/release/nyash --backend llvm "$INPUT" >/dev/null || true
else
# Harness path (Python llvmlite - LLVM_SYS_180_PREFIX不要)
NYASH_LLVM_OBJ_OUT="$OBJ" NYASH_LLVM_USE_HARNESS=1 \
./target/release/nyash --backend llvm "$INPUT" >/dev/null || true
fi
fi
fi
if [[ ! -f "$OBJ" ]]; then
echo "error: object not generated: $OBJ" >&2
echo "hint: you can pre-generate it (e.g. via --run-task smoke_obj_*) and set NYASH_LLVM_SKIP_EMIT=1" >&2
exit 3
fi
if [[ "${NYASH_LLVM_ONLY_OBJ:-0}" == "1" ]]; then
echo "[3/4] Skipping link: object generated at $OBJ (NYASH_LLVM_ONLY_OBJ=1)"
exit 0
fi
echo "[3/4] Building NyRT static runtime ..."
if [[ "${NYASH_LLVM_SKIP_NYRT_BUILD:-0}" == "1" ]]; then
echo " Skipping NyRT build (NYASH_LLVM_SKIP_NYRT_BUILD=1)"
else
# Use 24 threads for parallel build
( cd crates/nyrt && cargo build --release -j 24 >/dev/null )
fi
# Ensure output directory exists
mkdir -p "$(dirname "$OUT")"
echo "[4/4] Linking $OUT ..."
cc "$OBJ" \
-L target/release \
-L crates/nyrt/target/release \
-Wl,--whole-archive -lnyrt -Wl,--no-whole-archive \
-lpthread -ldl -lm -o "$OUT"
echo "✅ Done: $OUT"
echo " (runtime requires nyash.toml and plugin .so per config)"