强制WASM增量构建

结论:INI和解释器WASM构建已改为对象、依赖和命令指纹驱动的增量编译,并将所有构建必须增量写入项目规则。
This commit is contained in:
2026-06-08 05:05:17 +08:00
parent caa35820cd
commit 09304115ef
4 changed files with 203 additions and 13 deletions

View File

@@ -3,17 +3,44 @@ set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
OUT_DIR="$ROOT_DIR/runtime/ui/ini-panel"
BUILD_DIR="$ROOT_DIR/build/wasm/ini-panel"
OBJ_DIR="$BUILD_DIR/obj"
emcc \
-std=c++20 \
source "$ROOT_DIR/tools/wasm_incremental_build_lib.sh"
mkdir -p "$OUT_DIR" "$BUILD_DIR" "$OBJ_DIR"
TARGET="linuxcnc_ini_wasm"
: > "$BUILD_DIR/$TARGET.stdout.log"
: > "$BUILD_DIR/$TARGET.stderr.log"
COMMON_FLAGS=(
-std=c++20
-O2
-I"$ROOT_DIR/runtime/core/shims"
-I"$ROOT_DIR/vendor/linuxcnc/src"
-I"$ROOT_DIR/vendor/linuxcnc/src/rtapi"
-I"$ROOT_DIR/vendor/linuxcnc/src/emc"
)
SOURCES=(
"$ROOT_DIR/vendor/linuxcnc/src/emc/ini/inifile.cc"
"$ROOT_DIR/runtime/core/linuxcnc_wrap/linuxcnc_ini_wasm.cpp"
)
OBJECTS=()
for source in "${SOURCES[@]}"; do
obj="$(source_object_path "$source" "$ROOT_DIR" "$OBJ_DIR")"
OBJECTS+=("$obj")
compile_wasm_object "$TARGET" "$source" "$obj" "$BUILD_DIR" "${COMMON_FLAGS[@]}"
done
link_wasm_module \
"$TARGET" \
"$OUT_DIR/linuxcnc_ini.js" \
"$BUILD_DIR" \
-O2 \
-I"$ROOT_DIR/runtime/core/shims" \
-I"$ROOT_DIR/vendor/linuxcnc/src" \
-I"$ROOT_DIR/vendor/linuxcnc/src/rtapi" \
-I"$ROOT_DIR/vendor/linuxcnc/src/emc" \
"$ROOT_DIR/vendor/linuxcnc/src/emc/ini/inifile.cc" \
"$ROOT_DIR/runtime/core/linuxcnc_wrap/linuxcnc_ini_wasm.cpp" \
-o "$OUT_DIR/linuxcnc_ini.js" \
"${OBJECTS[@]}" \
-s MODULARIZE=1 \
-s EXPORT_ES6=1 \
-s ENVIRONMENT=web,node \

View File

@@ -7,8 +7,16 @@ WRAP_DIR="$ROOT_DIR/runtime/core/linuxcnc_wrap"
SHIM_DIR="$ROOT_DIR/runtime/core/shims"
INCLUDE_DIR="$ROOT_DIR/runtime/core/include"
OUT_DIR="$ROOT_DIR/build/wasm/core"
BUILD_DIR="$OUT_DIR"
OBJ_DIR="$BUILD_DIR/obj"
mkdir -p "$OUT_DIR"
source "$ROOT_DIR/tools/wasm_incremental_build_lib.sh"
mkdir -p "$OUT_DIR" "$OBJ_DIR"
TARGET="linuxcnc_interp_wasm"
: > "$BUILD_DIR/$TARGET.stdout.log"
: > "$BUILD_DIR/$TARGET.stderr.log"
COMMON_FLAGS=(
-std=c++20
@@ -62,11 +70,24 @@ INTERP_CORE_SOURCES=(
"$VENDOR_DIR/src/emc/ini/inifile.cc"
)
emcc \
"${COMMON_FLAGS[@]}" \
SOURCES=(
"${INTERP_CORE_SOURCES[@]}" \
"$WRAP_DIR/linuxcnc_interp_wasm.cpp" \
-o "$OUT_DIR/linuxcnc_interp.js" \
)
OBJECTS=()
for source in "${SOURCES[@]}"; do
obj="$(source_object_path "$source" "$ROOT_DIR" "$OBJ_DIR")"
OBJECTS+=("$obj")
compile_wasm_object "$TARGET" "$source" "$obj" "$BUILD_DIR" "${COMMON_FLAGS[@]}"
done
link_wasm_module \
"$TARGET" \
"$OUT_DIR/linuxcnc_interp.js" \
"$BUILD_DIR" \
-O2 \
"${OBJECTS[@]}" \
-s MODULARIZE=1 \
-s EXPORT_ES6=1 \
-s ENVIRONMENT=web,node \

View File

@@ -0,0 +1,139 @@
#!/usr/bin/env bash
write_command_file() {
local file="$1"
shift
printf '%q\n' "$@" > "$file"
}
command_matches() {
local file="$1"
shift
local tmp
tmp="$(mktemp)"
write_command_file "$tmp" "$@"
if [[ -f "$file" ]] && cmp -s "$tmp" "$file"; then
rm -f "$tmp"
return 0
fi
rm -f "$tmp"
return 1
}
depfile_newer_than() {
local depfile="$1"
local output="$2"
[[ -f "$depfile" ]] || return 0
local deps
deps="$(tr '\\\n' ' ' < "$depfile" | sed -e 's/^[^:]*://')"
local dep
for dep in $deps; do
if [[ -f "$dep" && "$dep" -nt "$output" ]]; then
return 0
fi
done
return 1
}
object_needs_rebuild() {
local obj="$1"
local depfile="$2"
local cmdfile="$3"
shift 3
[[ -f "$obj" ]] || return 0
command_matches "$cmdfile" "$@" || return 0
depfile_newer_than "$depfile" "$obj" && return 0
return 1
}
link_needs_rebuild() {
local output="$1"
local cmdfile="$2"
shift 2
[[ -f "$output" ]] || return 0
command_matches "$cmdfile" "$@" || return 0
local arg
for arg in "$@"; do
if [[ -f "$arg" && "$arg" -nt "$output" ]]; then
return 0
fi
done
return 1
}
source_object_path() {
local source="$1"
local root_dir="$2"
local obj_dir="$3"
local relative="${source#"$root_dir"/}"
if [[ "$relative" == "$source" ]]; then
relative="$(basename "$source")"
fi
relative="${relative//\//__}"
printf '%s/%s.o' "$obj_dir" "${relative%.*}"
}
compile_wasm_object() {
local target="$1"
local source="$2"
local obj="$3"
local build_dir="$4"
shift 4
local stdout_log="$build_dir/$target.stdout.log"
local stderr_log="$build_dir/$target.stderr.log"
local depfile="$obj.d"
local cmdfile="$obj.cmd"
local cmd=(emcc "$@" -MMD -MP -MF "$depfile" -c "$source" -o "$obj")
mkdir -p "$(dirname "$obj")"
if ! object_needs_rebuild "$obj" "$depfile" "$cmdfile" "${cmd[@]}"; then
printf 'up to date: %s\n' "$source" >> "$stdout_log"
return 0
fi
printf 'compile: %s\n' "$source" >> "$stdout_log"
if "${cmd[@]}" >> "$stdout_log" 2>> "$stderr_log"; then
write_command_file "$cmdfile" "${cmd[@]}"
return 0
fi
return 1
}
link_wasm_module() {
local target="$1"
local output="$2"
local build_dir="$3"
shift 3
local stdout_log="$build_dir/$target.stdout.log"
local stderr_log="$build_dir/$target.stderr.log"
local cmdfile="$build_dir/$(basename "$output").cmd"
local wasm_output="${output%.js}.wasm"
local cmd=(emcc "$@" -o "$output")
if [[ -f "$output" && ! -f "$wasm_output" ]]; then
printf 'missing paired wasm output: %s\n' "$wasm_output" >> "$stdout_log"
rm -f "$output"
fi
if ! link_needs_rebuild "$output" "$cmdfile" "${cmd[@]}"; then
printf 'up to date: %s\n' "$output" >> "$stdout_log"
return 0
fi
printf 'link: %s\n' "$output" >> "$stdout_log"
if "${cmd[@]}" >> "$stdout_log" 2>> "$stderr_log"; then
write_command_file "$cmdfile" "${cmd[@]}"
return 0
fi
return 1
}