Files
Hao Zheandzhiheng.liu f0445e0cce docs(build): repair contributor guidance and maintenance tooling (#3551)
* docs: fix broken links and anchors across READMEs and guides

Sweep findings: D-10, D-11, D-12, D-13, D-14, D-15. Restore valid documentation targets and stable cross-page anchors.

(cherry picked from commit e3504d633d)

* docs: correct contributor and release references

Reconstruct the factual parts of draft #3397 against current upstream: use the supported setup wizard, align the repository tree and workflow names with tracked files, document current release paths, and repair the bug-bounty link. Excludes install-policy and subjective content rewrites.

Based-on: b332e19e40
Based-on: c89afb17f2
Co-authored-by: zhiheng.liu <zhiheng.liu@bytedance.com>

* build: propagate recipe failures and align CMake minimum

Keep build failures visible, use isolated temporary extraction paths, and enforce the native build's CMake 3.15 floor across all contributor guides. CMake version parsing accepts prerelease and vendor suffixes.

Based-on: 8943a12285
Co-authored-by: zhiheng.liu <zhiheng.liu@bytedance.com>

* fix(scripts): surface backfill enumeration failures

Preserve the safety fix from draft #3415 while retaining legacy no-op arguments for existing operational scripts. Deprecated arguments now remain parse-compatible, advertise their status in help, and emit explicit warnings when used.

Based-on: 5516d96048
Co-authored-by: zhiheng.liu <zhiheng.liu@bytedance.com>

---------

Co-authored-by: zhiheng.liu <zhiheng.liu@bytedance.com>
2026-07-28 18:11:33 +08:00

187 lines
8.2 KiB
Makefile

# Makefile for OpenViking
# Variables
PYTHON ?= python3
SETUP_PY := setup.py
OV_CLI_DIR := crates/ov_cli
# Dependency Versions
MIN_PYTHON_VERSION := 3.10
MIN_CMAKE_VERSION := 3.15
MIN_RUST_VERSION := 1.91.1
MIN_GCC_VERSION := 9
MIN_CLANG_VERSION := 11
# Output directories to clean
CLEAN_DIRS := \
build/ \
dist/ \
*.egg-info/ \
openviking/bin/ \
openviking/lib/ \
openviking/web_studio/dist/ \
$(OV_CLI_DIR)/target/ \
src/cmake_build/ \
.pytest_cache/ \
.coverage \
htmlcov/ \
**/__pycache__/
.PHONY: all build clean help check-pip check-deps
.PHONY: build-cli build-studio
all: build
help:
@echo "Available targets:"
@echo " build - Build ragfs-python and C++ extensions using setup.py"
@echo " build-cli - Build Rust CLI (ov) in development mode (fast) and copy to openviking/bin/"
@echo " build-studio - Build web-studio SPA and copy into openviking/web_studio/dist/"
@echo " clean - Remove build artifacts and temporary files"
@echo " check-deps - Check if required dependencies (Rust, CMake, etc.) are installed"
@echo " help - Show this help message"
check-pip:
@if command -v uv > /dev/null 2>&1 && uv pip --help > /dev/null 2>&1; then \
echo " [OK] uv pip found"; \
elif $(PYTHON) -m pip --version > /dev/null 2>&1; then \
echo " [OK] pip found"; \
else \
echo "Error: Neither uv pip nor pip found for $(PYTHON)."; \
echo "Try fixing your environment by running:"; \
echo " uv sync # if using uv"; \
echo " or"; \
echo " $(PYTHON) -m ensurepip --upgrade"; \
exit 1; \
fi
check-deps:
@echo "Checking dependencies..."
@# Python check
@$(PYTHON) -c "import sys; v=sys.version_info; exit(0 if v.major > 3 or (v.major == 3 and v.minor >= 10) else 1)" || (echo "Error: Python >= $(MIN_PYTHON_VERSION) is required."; exit 1)
@echo " [OK] Python $$( $(PYTHON) -V | cut -d' ' -f2 )"
@# CMake check
@command -v cmake > /dev/null 2>&1 || (echo "Error: CMake is not installed."; exit 1)
@CMAKE_VER=$$(cmake --version | head -n1 | awk '{print $$3}'); \
if ! $(PYTHON) -c "import re, sys; parse=lambda v: tuple(int(x) for x in re.match(r'^[0-9]+(?:\.[0-9]+)*', v).group().split('.')); raise SystemExit(0 if parse(sys.argv[1]) >= parse(sys.argv[2]) else 1)" "$$CMAKE_VER" "$(MIN_CMAKE_VERSION)"; then \
echo "Error: CMake >= $(MIN_CMAKE_VERSION) is required. Found $$CMAKE_VER"; exit 1; \
fi; \
echo " [OK] CMake $$CMAKE_VER"
@# Rust check
@command -v rustc > /dev/null 2>&1 || (echo "Error: Rust is not installed."; exit 1)
@RUST_VER=$$(rustc --version | awk '{print $$2}'); \
$(PYTHON) -c "import sys; parse=lambda v: tuple(int(x) for x in v.split('.')); raise SystemExit(0 if parse(sys.argv[1]) >= parse(sys.argv[2]) else 1)" "$$RUST_VER" "$(MIN_RUST_VERSION)" || (echo "Error: Rust >= $(MIN_RUST_VERSION) is required. Found $$RUST_VER"; exit 1); \
echo " [OK] Rust $$RUST_VER"
@# C++ Compiler check
@if command -v clang++ > /dev/null 2>&1; then \
CLANG_VER_FULL=$$(clang++ --version | head -n1 | grep -oE "[0-9]+\.[0-9]+\.[0-9]+" | head -n1); \
CLANG_VER=$$(echo $$CLANG_VER_FULL | cut -d. -f1); \
if [ $$CLANG_VER -lt $(MIN_CLANG_VERSION) ]; then echo "Error: Clang >= $(MIN_CLANG_VERSION) is required. Found $$CLANG_VER_FULL"; exit 1; fi; \
echo " [OK] Clang $$CLANG_VER_FULL"; \
elif command -v g++ > /dev/null 2>&1; then \
GCC_VER_FULL=$$(g++ -dumpversion); \
GCC_VER=$$(echo $$GCC_VER_FULL | cut -d. -f1); \
if [ $$GCC_VER -lt $(MIN_GCC_VERSION) ]; then echo "Error: GCC >= $(MIN_GCC_VERSION) is required. Found $$GCC_VER_FULL"; exit 1; fi; \
echo " [OK] GCC $$GCC_VER_FULL"; \
else \
echo "Error: C++ compiler (GCC or Clang) is required."; exit 1; \
fi
build: check-deps check-pip build-studio
@echo "Cleaning stale ragfs-python native artifacts from project .venv..."
@if [ -x .venv/bin/python ]; then \
.venv/bin/python -c 'import sysconfig; from pathlib import Path; roots = {Path(sysconfig.get_path("platlib")), Path(sysconfig.get_path("purelib"))}; removed = []; [removed.append(path) or path.unlink() for root in roots if root.exists() for path in root.rglob("*") if path.is_file() and path.name.startswith("ragfs_python") and path.suffix in {".so", ".pyd", ".dylib"}]; print(" [OK] removed stale ragfs artifacts from .venv" if removed else " [OK] no stale ragfs artifacts found in .venv")'; \
else \
echo " [SKIP] project .venv not found; skip ragfs native cleanup"; \
fi
@echo "Starting build process via setup.py..."
$(PYTHON) $(SETUP_PY) build_ext --inplace
@if command -v uv > /dev/null 2>&1 && uv pip --help > /dev/null 2>&1; then \
echo " [OK] uv pip found, use uv pip to install..."; \
uv pip install -e .; \
else \
echo " [OK] pip found, use pip to install..."; \
$(PYTHON) -m pip install -e .; \
fi
@echo "Building ragfs-python (Rust RAGFS binding) into openviking/lib/..."
@set -e; \
MATURIN_CMD=""; \
if command -v maturin > /dev/null 2>&1; then \
MATURIN_CMD=maturin; \
elif command -v uv > /dev/null 2>&1 && uv pip --help > /dev/null 2>&1; then \
uv pip install maturin; \
MATURIN_CMD=maturin; \
fi; \
if [ -n "$$MATURIN_CMD" ]; then \
RAGFS_TMPDIR=$$(mktemp -d); \
EXTRACT_SCRIPT=$$(mktemp); \
trap 'rm -f "$$EXTRACT_SCRIPT"; rm -rf "$$RAGFS_TMPDIR"' 0; \
(cd crates/ragfs-python && $$MATURIN_CMD build --release --out "$$RAGFS_TMPDIR" 2>&1); \
mkdir -p openviking/lib; \
rm -f openviking/lib/ragfs_python*.so openviking/lib/ragfs_python*.pyd openviking/lib/ragfs_python*.dylib; \
echo "import zipfile, glob, shutil, os, sys" > "$$EXTRACT_SCRIPT"; \
echo "whls = glob.glob(os.path.join('$$RAGFS_TMPDIR', 'ragfs_python-*.whl'))" >> "$$EXTRACT_SCRIPT"; \
echo "assert whls, 'maturin produced no wheel'" >> "$$EXTRACT_SCRIPT"; \
echo "with zipfile.ZipFile(whls[0]) as zf:" >> "$$EXTRACT_SCRIPT"; \
echo " for name in zf.namelist():" >> "$$EXTRACT_SCRIPT"; \
echo " bn = os.path.basename(name)" >> "$$EXTRACT_SCRIPT"; \
echo " if bn.startswith('ragfs_python.abi3.') and (bn.endswith('.so') or bn.endswith('.pyd')):" >> "$$EXTRACT_SCRIPT"; \
echo " dst = os.path.join('openviking', 'lib', bn)" >> "$$EXTRACT_SCRIPT"; \
echo " with zf.open(name) as src, open(dst, 'wb') as f: f.write(src.read())" >> "$$EXTRACT_SCRIPT"; \
echo " os.chmod(dst, 0o755)" >> "$$EXTRACT_SCRIPT"; \
echo " print(f' [OK] ragfs-python: extracted {bn} -> {dst}')" >> "$$EXTRACT_SCRIPT"; \
echo " sys.exit(0)" >> "$$EXTRACT_SCRIPT"; \
echo "print('[Warning] No ragfs_python abi3 .so/.pyd found in wheel')" >> "$$EXTRACT_SCRIPT"; \
echo "sys.exit(1)" >> "$$EXTRACT_SCRIPT"; \
$(PYTHON) "$$EXTRACT_SCRIPT"; \
rm -f "$$EXTRACT_SCRIPT"; \
rm -rf "$$RAGFS_TMPDIR"; \
trap - 0; \
else \
echo " [SKIP] maturin not found, ragfs-python (Rust binding) will not be built."; \
echo " Install maturin to enable: uv pip install maturin"; \
fi
@echo "Build completed successfully."
clean:
@echo "Cleaning up build artifacts..."
@for dir in $(CLEAN_DIRS); do \
if [ -d "$$dir" ] || [ -f "$$dir" ]; then \
echo "Removing $$dir"; \
rm -rf $$dir; \
fi \
done
@find . -name "*.pyc" -delete
@find . -name "__pycache__" -type d -exec rm -rf {} +
@echo "Cleanup completed."
# Web Studio target
build-studio:
@set -e; \
if [ "$$OV_SKIP_STUDIO_BUILD" = "1" ]; then \
echo " [SKIP] web-studio build disabled by OV_SKIP_STUDIO_BUILD=1"; \
elif [ -f openviking/web_studio/dist/index.html ]; then \
echo " [OK] web-studio bundle already present"; \
elif ! command -v npm > /dev/null 2>&1; then \
echo " [SKIP] npm not found; install Node.js to enable /studio"; \
elif [ ! -f web-studio/package.json ]; then \
echo " [SKIP] web-studio source not found"; \
else \
echo "Building web-studio (Vite SPA)..."; \
(cd web-studio && npm ci && npm run build -- --base="/studio/"); \
mkdir -p openviking/web_studio; \
rm -rf openviking/web_studio/dist; \
cp -r web-studio/dist openviking/web_studio/dist; \
echo " [OK] web-studio bundle copied to openviking/web_studio/dist/"; \
fi
# Rust CLI targets
build-cli:
@echo "Building Rust CLI (ov) in development mode..."
@cd $(OV_CLI_DIR) && cargo build
@mkdir -p openviking/bin
@cp target/debug/ov openviking/bin/ov
@chmod +x openviking/bin/ov
@echo " [OK] CLI built at target/debug/ov"
@echo " [OK] CLI copied to openviking/bin/ov"