yggdrasil/Makefile
xfy a4331bd813 feat(build): add FreeBSD x86_64 cross-compile support
方案 A(clang + lld + 本地 sysroot)。rustc 为 freebsd target 链接的系统库
(libc/libexecinfo/libgcc_s/libthr)及 sysinfo 依赖的 freebsd 专有库
(libkvm/libmemstat/libprocstat/libdevstat)需 FreeBSD 运行时,无法纯靠
clang+lld 无 sysroot 完成;故从 FreeBSD 15.1 base.txz 解出 crt 对象 + 系统库
到 .freebsd-sysroot/(gitignored,machine-local)。

- .cargo/config.toml: freebsd target 配置作为注释模板(sysroot 路径机器相关,
  不硬编码进仓库);linker 经 rustflags 的 -C linker=clang 设置,使 Makefile
  能用 CARGO_TARGET_*_RUSTFLAGS 环境变量整体注入。
- Makefile: 新增 freebsd-sysroot(幂等下载+解压 base.txz)与 build-freebsd
  (release server 二进制交叉编译)target。server 用 cargo 直出而非 dx CLI,
  因 dx 对该 target 的支持未经验证。
- .gitignore: 忽略 .freebsd-sysroot/。
- AGENTS.md: 补充构建命令说明。

实测 release 二进制 16MB,stripped ELF for FreeBSD 15.1,动态依赖均为
FreeBSD base 自带库(libc.so.7 libthr.so.3 libkvm.so.7 等)。
2026-07-01 13:40:00 +08:00

166 lines
7.3 KiB
Makefile
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.

.PHONY: dev build build-linux build-freebsd freebsd-sysroot docker css css-watch clean build-editor build-editor-incremental build-lightbox build-lightbox-incremental build-core build-core-incremental build-codemirror build-codemirror-incremental highlight-css test doc doc-open start clippy fix
build:
@$(MAKE) build-editor
@$(MAKE) build-lightbox
@$(MAKE) build-core
@$(MAKE) build-codemirror
@$(MAKE) highlight-css
@tailwindcss -i input.css -o public/style.css --minify
@$(MAKE) doc
@dx build --release --debug-symbols=false
build-linux:
@$(MAKE) build-editor
@$(MAKE) build-lightbox
@$(MAKE) build-core
@$(MAKE) build-codemirror
@$(MAKE) highlight-css
@tailwindcss -i input.css -o public/style.css --minify
@dx build @client --release --debug-symbols=false --wasm-js-cfg false
@dx build @server --release --debug-symbols=false --target x86_64-unknown-linux-musl --wasm-js-cfg false --features server
@echo ""
@echo "Linux build complete! The server binary is at target/dx/yggdrasil/release/web/server"
@echo "Remember to deploy it alongside the target/dx/yggdrasil/release/web/public directory."
@echo "When running the server, ensure DIOXUS_ASSET_DIR is set or the public directory is in CWD."
# FreeBSD 15.1 base.txz 版本与下载源。sysroot 仅需 ./lib 与 ./usr/libcrt 对象 + 系统库)。
FREEBSD_VERSION ?= 15.1-RELEASE
FREEBSD_BASE_URL ?= https://download.freebsd.org/ftp/releases/amd64/amd64/$(FREEBSD_VERSION)/base.txz
FREEBSD_SYSROOT := $(CURDIR)/.freebsd-sysroot
# 下载并解压 FreeBSD base.txz 到 .freebsd-sysroot/供交叉链接crt 对象 + 系统库)。
# 幂等:若 sysroot 已存在则跳过下载。
freebsd-sysroot:
@if [ -d "$(FREEBSD_SYSROOT)/usr/lib" ] && [ -d "$(FREEBSD_SYSROOT)/lib" ]; then \
echo "FreeBSD sysroot already present at $(FREEBSD_SYSROOT)"; \
else \
echo "Downloading FreeBSD $(FREEBSD_VERSION) base.txz..."; \
curl -fL --retry 3 -o /tmp/freebsd-base.txz "$(FREEBSD_BASE_URL)"; \
mkdir -p "$(FREEBSD_SYSROOT)"; \
echo "Extracting crt objects and system libs..."; \
tar -xf /tmp/freebsd-base.txz -C "$(FREEBSD_SYSROOT)" ./lib ./usr/lib; \
rm -f /tmp/freebsd-base.txz; \
echo "FreeBSD sysroot ready at $(FREEBSD_SYSROOT)"; \
fi
# 交叉编译 FreeBSD x86_64 release server 二进制。
# 前置clang + lld 已装pacman -S clang lld、rustup target add x86_64-unknown-freebsd、
# `make freebsd-sysroot`。sysroot 路径经 CARGO_TARGET_*_RUSTFLAGS 注入,避免在
# .cargo/config.toml 里硬编码机器相关路径。server 二进制用 cargo 直出dx CLI 对该
# target 未经验证);前端 wasm 与静态资源与 build-linux 相同,不在此重复构建。
build-freebsd:
@$(MAKE) freebsd-sysroot
@SYSROOT="$(FREEBSD_SYSROOT)"; \
RUSTFLAGS_FREEBSD="-C linker=clang -C link-arg=--target=x86_64-unknown-freebsd -C link-arg=-fuse-ld=lld -C link-arg=--sysroot=$$SYSROOT -C link-arg=-L$$SYSROOT/usr/lib -C link-arg=-L$$SYSROOT/lib"; \
echo "Cross-compiling yggdrasil server for FreeBSD x86_64..."; \
CARGO_TARGET_X86_64_UNKNOWN_FREEBSD_RUSTFLAGS="$$RUSTFLAGS_FREEBSD" \
cargo build --release --target x86_64-unknown-freebsd --features server --bin yggdrasil
@echo ""
@echo "FreeBSD build complete! Server binary: target/x86_64-unknown-freebsd/release/yggdrasil"
@echo "Deploy it to FreeBSD 15+ alongside the static public/ directory."
@echo "Runtime needs (bundled in FreeBSD base): libc.so.7 libthr.so.3 libkvm.so.7 etc."
highlight-css:
@cargo run --bin generate_highlight_css
build-editor:
@echo "Building Tiptap editor..."
@cd libs/tiptap-editor && pnpm ci --include=dev && pnpm run build
@echo "Tiptap editor built."
# dev 用的增量构建:跳过 pnpm ci假设 node_modules 已存在),仅 vite build。
# 与 build-editor 分开,避免每次 make dev 都重装依赖。
build-editor-incremental:
@cd libs/tiptap-editor && pnpm run build
build-lightbox:
@echo "Building Lightbox..."
@cd libs/lightbox && pnpm install && pnpm run build
@echo "Lightbox built."
# dev 用的增量构建:跳过 pnpm ci假设 node_modules 已存在),仅 vite build。
build-lightbox-incremental:
@cd libs/lightbox && pnpm run build
build-core:
@echo "Building yggdrasil-core..."
@cd libs/yggdrasil-core && pnpm install && pnpm run build
@echo "yggdrasil-core built."
# dev 用的增量构建:跳过 pnpm install假设 node_modules 已存在),仅 vite build。
build-core-incremental:
@cd libs/yggdrasil-core && pnpm run build
build-codemirror:
@echo "Building CodeMirror editor..."
@cd libs/codemirror-editor && pnpm ci --include=dev && pnpm run build
@echo "CodeMirror editor built."
# dev 用的增量构建:跳过 pnpm ci假设 node_modules 已存在),仅 vite build。
build-codemirror-incremental:
@cd libs/codemirror-editor && pnpm run build
dev: build-editor-incremental build-lightbox-incremental build-core-incremental build-codemirror-incremental
@echo "Cleaning static/..."
@rm -rf static/
@echo "Building Tiptap editor (incremental)..."
@echo "Starting tailwindcss watch and dx serve..."
@tailwindcss -i input.css -o public/style.css --watch & \
TAILWIND_PID=$$!; \
trap 'kill $$TAILWIND_PID 2>/dev/null; exit' INT TERM EXIT; \
SSR_CACHE_SECS=0 dx serve --addr 0.0.0.0
css:
@tailwindcss -i input.css -o public/style.css
css-watch:
@tailwindcss -i input.css -o public/style.css --watch
test:
@cargo test
@cd libs/tiptap-editor && pnpm test
@cd libs/lightbox && pnpm test
@cd libs/yggdrasil-core && pnpm test
@cd libs/codemirror-editor && pnpm test
clippy:
@cargo clippy --all-targets --all-features -- -D warnings
fix:
@cargo fix --allow-dirty
# 只编译当前 crate 的文档(--no-deps 跳过依赖,--document-private-items
# 让纯 binary crate 的内部模块/私有项也进文档,否则页面基本是空的)。
# RUSTDOCFLAGS 把 rustdoc 的 --default-theme=ayu 透传过去——cargo doc 本身
# 无主题参数,但会把该环境变量转交给底层 rustdoc。注意它是默认值浏览器
# 若已记住上次的主题选择localStorage则不会被覆盖。
#
# 生成后拷贝到 public/doc/,让文档随 Dioxus 静态目录发布。先清空旧目录再
# 整体拷贝避免删除模块后残留旧文件。rustdoc 内部用相对路径引用资源
# (如 ../../static.files/),原样挂载不会断链。
#
# 额外生成 public/doc/index.html 重定向页Dioxus 在 dev 用
# nest_service("/doc", ServeDir) 托管该目录ServeDir 访问目录根时默认
# 返回 index.html。用 meta refresh + JS 跳转到真正的文档入口
# yggdrasil/index.html这样裸路径 /doc 也能直达文档,且不与 Dioxus 的
# /doc/* 路由冲突(手动注册 /doc 会在 merge 时 panic
doc:
@RUSTDOCFLAGS="--default-theme=ayu" cargo doc --no-deps --document-private-items
@rm -rf public/doc
@cp -r target/doc public/doc
@printf '<!DOCTYPE html><html><head><meta charset="utf-8"><meta http-equiv="refresh" content="0;url=yggdrasil/index.html"><title>Redirecting…</title></head><body><script>location.replace("yggdrasil/index.html")</script></body></html>' > public/doc/index.html
# 同 doc生成完自动用浏览器打开。
doc-open:
@RUSTDOCFLAGS="--default-theme=ayu" cargo doc --no-deps --document-private-items --open
docker:
@docker build -t yggdrasil .
clean:
@cargo clean
@rm -f public/style.css public/highlight.css
@rm -rf public/doc
@rm -rf uploads/.cache