140 lines
2.9 KiB
Bash
140 lines
2.9 KiB
Bash
#!/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
|
|
}
|