Compare commits

..
10 Commits
15 changed files with 348 additions and 11 deletions

No files matched your search

Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
+5
View File
@@ -1,6 +1,8 @@
open Meow open Meow
open Types open Types
let version = "0.1.0"
let usage = let usage =
String.concat "\n" String.concat "\n"
[ [
@@ -35,6 +37,7 @@ let usage =
" -v print each command as it finishes"; " -v print each command as it finishes";
" -q only print warnings and errors"; " -q only print warnings and errors";
" --no-color plain output"; " --no-color plain output";
" --version print the version and exit";
] ]
let cores_from_cpuinfo () = let cores_from_cpuinfo () =
@@ -120,6 +123,7 @@ let parse_args argv =
| "-q" :: r -> fl.quiet <- true; go r | "-q" :: r -> fl.quiet <- true; go r
| "--no-color" :: r -> Style.enabled := false; go r | "--no-color" :: r -> Style.enabled := false; go r
| ("-h" | "--help") :: _ -> print_endline usage; exit 0 | ("-h" | "--help") :: _ -> print_endline usage; exit 0
| ("-V" | "--version") :: _ -> print_endline ("meowc " ^ version); exit 0
| (("-f" | "-j" | "-C" | "-D" | "--prefix" | "--target" | "--sysroot") as o) :: [] -> | (("-f" | "-j" | "-C" | "-D" | "--prefix" | "--target" | "--sysroot") as o) :: [] ->
Diag.error "%s needs a value" o Diag.error "%s needs a value" o
| a :: r when String.length a > 2 && String.sub a 0 2 = "-j" -> | a :: r when String.length a > 2 && String.sub a 0 2 = "-j" ->
@@ -531,6 +535,7 @@ let cmd_compdb () =
let cmd_watch names = let cmd_watch names =
let round () = let round () =
Cache.reset ();
let p = configure () in let p = configure () in
with_config_header p; with_config_header p;
let t0 = Unix.gettimeofday () in let t0 = Unix.gettimeofday () in
+4
View File
@@ -36,6 +36,10 @@ let digest_file p =
let forget p = Hashtbl.remove digests p let forget p = Hashtbl.remove digests p
(* The memo saves re-hashing a header that half the project includes, so it is
only ever valid for one build. A watch loop runs many in one process. *)
let reset () = Hashtbl.reset digests
let key ~cmd ~inputs = let key ~cmd ~inputs =
let b = Buffer.create 256 in let b = Buffer.create 256 in
Buffer.add_string b cmd; Buffer.add_string b cmd;
+18 -6
View File
@@ -103,10 +103,16 @@ let platform_vars env plat arch =
("unix", if plat = "windows" || plat = "bare" || plat = "wasm" then "false" else "true"); ("unix", if plat = "windows" || plat = "bare" || plat = "wasm" then "false" else "true");
] ]
(* A build file that says "cc cc" means the default compiler, not the host one,
so the triple prefix still wins over a generic name. Anything more specific,
a path or a particular compiler, is what the author asked for and is kept. *)
let generic name =
List.mem (Filename.basename name) [ "cc"; "gcc"; "clang"; "c++"; "g++"; "clang++"; "ar" ]
let derive_cross env explicit = let derive_cross env explicit =
let tc = env.tc in let tc = env.tc in
let t = tc.target in let t = tc.target in
let set k = Hashtbl.mem explicit k in let chosen k current = Hashtbl.mem explicit k && not (generic current) in
let prefixed n = t ^ "-" ^ n in let prefixed n = t ^ "-" ^ n in
let have_prefixed = Exec.which (prefixed "gcc") || Exec.which (prefixed "cc") in let have_prefixed = Exec.which (prefixed "gcc") || Exec.which (prefixed "cc") in
let tc = let tc =
@@ -115,18 +121,24 @@ let derive_cross env explicit =
let pick n alt = if Exec.which (prefixed n) then prefixed n else prefixed alt in let pick n alt = if Exec.which (prefixed n) then prefixed n else prefixed alt in
{ {
tc with tc with
cc = (if set "cc" then tc.cc else pick "gcc" "cc"); cc = (if chosen "cc" tc.cc then tc.cc else pick "gcc" "cc");
cxx = (if set "cxx" then tc.cxx else pick "g++" "c++"); cxx = (if chosen "cxx" tc.cxx then tc.cxx else pick "g++" "c++");
ar = (if set "ar" then tc.ar else prefixed "ar"); ar = (if chosen "ar" tc.ar then tc.ar else prefixed "ar");
} }
in in
(* Whatever compiler we ended up with, it has to be aimed at the triple, or a
cross build quietly produces host binaries in a cross directory. *)
let targeted =
let base = Filename.basename tc.cc and n = String.length t in
String.length base > n && String.sub base 0 n = t
in
let xflags = let xflags =
(if have_prefixed then [] else [ "--target=" ^ t ]) (if targeted then [] else [ "--target=" ^ t ])
@ (if tc.sysroot = "" then [] else [ "--sysroot=" ^ tc.sysroot ]) @ (if tc.sysroot = "" then [] else [ "--sysroot=" ^ tc.sysroot ])
in in
let tc = { tc with xflags } in let tc = { tc with xflags } in
let tc = let tc =
if set "builddir" || Filename.basename tc.builddir = t then tc if Hashtbl.mem explicit "builddir" || Filename.basename tc.builddir = t then tc
else { tc with builddir = Filename.concat tc.builddir t } else { tc with builddir = Filename.concat tc.builddir t }
in in
env.tc <- tc; env.tc <- tc;
+7 -4
View File
@@ -2,8 +2,8 @@ open Ast
open Types open Types
let target_fields = let target_fields =
[ "srcs"; "include"; "use"; "cflags"; "cxxflags"; "ldflags"; "define"; "pkg"; "install"; [ "srcs"; "exclude"; "include"; "use"; "cflags"; "cxxflags"; "ldflags"; "define"; "pkg";
"soname"; "args" ] "install"; "soname"; "args" ]
let rule_fields = [ "inputs"; "outputs"; "use"; "command"; "description" ] let rule_fields = [ "inputs"; "outputs"; "use"; "command"; "description" ]
let install_fields = [ "files"; "to" ] let install_fields = [ "files"; "to" ]
@@ -138,9 +138,12 @@ let sources_of ~extra ((b : block), base) (t : target) =
if pats = [] then if pats = [] then
Diag.error ~span:b.nspan ~hint:"add a line like: srcs src/*.c" "%s %s declares no srcs" Diag.error ~span:b.nspan ~hint:"add a line like: srcs src/*.c" "%s %s declares no srcs"
b.kind b.bname; b.kind b.bname;
let expand ps = List.concat_map (fun p -> Glob.expand_with ~extra (Eval.under base p)) ps in
(* a glob is the natural way to say srcs, and then there is always the one file
that has to come back out of it *)
let dropped = expand (texts (get b "exclude")) in
let files = let files =
List.concat_map (fun p -> Glob.expand_with ~extra (Eval.under base p)) pats expand pats |> List.filter (fun f -> not (List.mem f dropped)) |> List.sort_uniq compare
|> List.sort_uniq compare
in in
if files = [] then if files = [] then
Diag.error ~span:b.nspan Diag.error ~span:b.nspan
+55
View File
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
source "$(dirname "${BASH_SOURCE[0]}")/record-lib.sh"
GEOMETRY=${GEOMETRY:-1280x720}
SRC=${SRC:-$HOME/projects/abnormal}
OUT="$ROOT/assets/compiler.mp4"
WORK=$(mktemp -d)
cp -a "$SRC" "$WORK/abnormal"
rm -rf "$WORK/abnormal/build" "$WORK/abnormal/gen"
mkdir -p "$WORK/bin"
ln -sf "$ROOT/meowc" "$WORK/bin/meowc"
start_xvfb "$GEOMETRY"
kitty \
--config "$HOME/.config/kitty/kitty.conf" \
-o remember_window_size=no \
-o "initial_window_width=${GEOMETRY%x*}" \
-o "initial_window_height=${GEOMETRY#*x}" \
-o confirm_os_window_close=0 \
--directory "$WORK/abnormal" \
-- bash --noprofile --norc >/dev/null 2>&1 &
sleep 3
for _ in $(seq 30); do
xdotool search --onlyvisible --class kitty >/dev/null 2>&1 && break
sleep 1
done
xdotool search --onlyvisible --class kitty windowactivate >/dev/null 2>&1 || true
xdotool type --delay 10 -- 'export PS1="expr $ " PATH='"$WORK"'/bin:$PATH; clear'
xdotool key Return
sleep 1
start_capture "$GEOMETRY" "$WORK/compiler.mkv"
send_line 'cat programs/poly.expr programs/folded.expr' 2.2
send_line 'meowc build' 4
send_line 'meowc test' 4
send_line 'clear' 0.6
send_line './build/bin/vm --list' 3.5
send_line './build/bin/vm poly 5' 3.5
send_line 'objdump -d -M intel --no-show-raw-insn build/bin/vm | sed -n "/prog_folded/,/ret/p"' 3
send_line 'objdump -d -M intel --no-show-raw-insn build/bin/vm | sed -n "/prog_poly/,/ret/p"' 4.5
stop_capture
LIMIT=${LIMIT:-29.5}
raw=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$WORK/compiler.mkv")
speed=$(python3 -c "print(max(1.0, $raw / $LIMIT))")
ffmpeg -v error -y -i "$WORK/compiler.mkv" -an -vf "setpts=PTS/$speed" \
-c:v libx264 -crf 20 -preset slow -pix_fmt yuv420p -movflags +faststart "$OUT"
echo "raw ${raw}s, sped up ${speed}x"
rm -rf "$WORK"
echo "wrote $OUT"
+24 -1
View File
@@ -5,6 +5,7 @@ set -euo pipefail
ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
FONT=${FONT:-JetBrainsMono Nerd Font Mono} FONT=${FONT:-JetBrainsMono Nerd Font Mono}
FPS=${FPS:-12} FPS=${FPS:-12}
DELAY=${DELAY:-42}
start_xvfb() { start_xvfb() {
local geometry=$1 local geometry=$1
@@ -41,12 +42,34 @@ stop_capture() {
send_line() { send_line() {
local text=$1 pause=${2:-0.9} local text=$1 pause=${2:-0.9}
xdotool type --delay 42 -- "$text" xdotool type --delay "$DELAY" -- "$text"
sleep 0.35 sleep 0.35
xdotool key Return xdotool key Return
sleep "$pause" sleep "$pause"
} }
# Fixed sleeps race a build that takes longer than expected, and the keystrokes
# land in the middle of its output. PROMPT_COMMAND appends a byte every time the
# shell draws a prompt, so the recorder can wait for the command to actually end.
wait_prompt() {
local before=$1 limit=${2:-600}
for _ in $(seq "$limit"); do
[ "$(wc -c <"$PROMPT_FILE" 2>/dev/null || echo 0)" != "$before" ] && return 0
sleep 0.1
done
}
run_line() {
local text=$1 settle=${2:-0.8}
local before
before=$(wc -c <"$PROMPT_FILE" 2>/dev/null || echo 0)
xdotool type --delay "$DELAY" -- "$text"
sleep 0.35
xdotool key Return
wait_prompt "$before"
sleep "$settle"
}
to_gif() { to_gif() {
local src=$1 out=$2 fps=${3:-11} local src=$1 out=$2 fps=${3:-11}
local palette=${src%.mkv}.png local palette=${src%.mkv}.png
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
source "$(dirname "${BASH_SOURCE[0]}")/record-lib.sh"
GEOMETRY=${GEOMETRY:-1280x720}
SRC=${SRC:-$HOME/projects/abnormal}
OUT="$ROOT/assets/pipeline.mp4"
WORK=$(mktemp -d)
PROMPT_FILE="$WORK/prompt"
cp -a "$SRC" "$WORK/abnormal"
rm -rf "$WORK/abnormal/build" "$WORK/abnormal/gen"
mkdir -p "$WORK/bin"
ln -sf "$ROOT/meowc" "$WORK/bin/meowc"
start_xvfb "$GEOMETRY"
kitty \
--config "$HOME/.config/kitty/kitty.conf" \
-o remember_window_size=no \
-o "initial_window_width=${GEOMETRY%x*}" \
-o "initial_window_height=${GEOMETRY#*x}" \
-o confirm_os_window_close=0 \
--directory "$WORK/abnormal" \
-- bash --noprofile --norc >/dev/null 2>&1 &
sleep 3
for _ in $(seq 30); do
xdotool search --onlyvisible --class kitty >/dev/null 2>&1 && break
sleep 1
done
xdotool search --onlyvisible --class kitty windowactivate >/dev/null 2>&1 || true
xdotool type --delay 10 -- 'export PS1="expr $ " PROMPT_COMMAND="printf . >> '"$PROMPT_FILE"'" PATH='"$WORK"'/bin:$PATH; clear'
xdotool key Return
sleep 1
start_capture "$GEOMETRY" "$WORK/pipeline.mkv"
run_line 'meowc build' 1.4
run_line 'meowc test' 1.4
run_line './build/bin/vm --list' 2.6
run_line './build/bin/vm poly 5' 2.6
run_line 'clear' 0.4
run_line 'touch *.ml *.scm *.c programs/*.expr' 0.5
run_line 'meowc build' 1.8
run_line 'sed -i s/no.encoding/bad.operator/ back.ml' 0.5
run_line 'meowc build' 1.8
run_line 'sed -i "s/(halt 0)/(halt 0) (nop 0)/" ops.scm' 0.5
run_line 'meowc build' 2.2
stop_capture
LIMIT=${LIMIT:-45}
raw=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$WORK/pipeline.mkv")
speed=$(python3 -c "print(max(1.0, $raw / $LIMIT))")
ffmpeg -v error -y -i "$WORK/pipeline.mkv" -an -vf "setpts=PTS/$speed" \
-c:v libx264 -crf 20 -preset slow -pix_fmt yuv420p -movflags +faststart "$OUT"
echo "raw ${raw}s, sped up ${speed}x"
rm -rf "$WORK"
echo "wrote $OUT"
+58
View File
@@ -0,0 +1,58 @@
#!/usr/bin/env bash
source "$(dirname "${BASH_SOURCE[0]}")/record-lib.sh"
GEOMETRY=${GEOMETRY:-1280x720}
SRC=${SRC:-$HOME/projects/xmm0club/rackvm}
OUT="$ROOT/assets/rackvm.mp4"
WORK=$(mktemp -d)
PROMPT_FILE="$WORK/prompt"
cp -a "$SRC" "$WORK/rackvm"
rm -rf "$WORK/rackvm/build" "$WORK/rackvm/.git"
mkdir -p "$WORK/bin"
ln -sf "$ROOT/meowc" "$WORK/bin/meowc"
start_xvfb "$GEOMETRY"
kitty \
--config "$HOME/.config/kitty/kitty.conf" \
-o remember_window_size=no \
-o "initial_window_width=${GEOMETRY%x*}" \
-o "initial_window_height=${GEOMETRY#*x}" \
-o confirm_os_window_close=0 \
--directory "$WORK/rackvm" \
-- bash --noprofile --norc >/dev/null 2>&1 &
sleep 3
for _ in $(seq 30); do
xdotool search --onlyvisible --class kitty >/dev/null 2>&1 && break
sleep 1
done
xdotool search --onlyvisible --class kitty windowactivate >/dev/null 2>&1 || true
xdotool type --delay 10 -- 'export PS1="rackvm $ " PROMPT_COMMAND="printf . >> '"$PROMPT_FILE"'" PATH='"$WORK"'/bin:$PATH; clear'
xdotool key Return
sleep 1
start_capture "$GEOMETRY" "$WORK/rackvm.mkv"
run_line 'meowc targets' 2.2
run_line 'meowc build' 1.8
run_line 'meowc test' 1.8
run_line 'meowc run check' 2.2
run_line 'meowc --prefix /tmp/stage install' 2.2
run_line 'clear' 0.4
run_line 'touch src/*.c include/*.h tests/*.c' 0.5
run_line 'meowc build' 2.0
run_line 'echo "void rackvm_unused_decl(void);" >> include/rackvm.h' 0.5
run_line 'meowc build' 2.6
stop_capture
LIMIT=${LIMIT:-45}
raw=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$WORK/rackvm.mkv")
speed=$(python3 -c "print(max(1.0, $raw / $LIMIT))")
ffmpeg -v error -y -i "$WORK/rackvm.mkv" -an -vf "setpts=PTS/$speed" \
-c:v libx264 -crf 20 -preset slow -pix_fmt yuv420p -movflags +faststart "$OUT"
echo "raw ${raw}s, sped up ${speed}x"
rm -rf "$WORK"
echo "wrote $OUT"
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
source "$(dirname "${BASH_SOURCE[0]}")/record-lib.sh"
GEOMETRY=${GEOMETRY:-1280x720}
EXAMPLE="$ROOT/examples/raytracer"
OUT="$ROOT/assets/showcase.mp4"
WORK=$(mktemp -d)
PROMPT_FILE="$WORK/prompt"
cp -a "$EXAMPLE" "$WORK/raytracer"
rm -rf "$WORK/raytracer/build" "$WORK/raytracer/gen" "$WORK/raytracer/out"
mkdir -p "$WORK/bin"
ln -sf "$ROOT/meowc" "$WORK/bin/meowc"
start_xvfb "$GEOMETRY"
kitty \
--config "$HOME/.config/kitty/kitty.conf" \
-o remember_window_size=no \
-o "initial_window_width=${GEOMETRY%x*}" \
-o "initial_window_height=${GEOMETRY#*x}" \
-o confirm_os_window_close=0 \
--directory "$WORK/raytracer" \
-- bash --noprofile --norc >/dev/null 2>&1 &
sleep 3
for _ in $(seq 30); do
xdotool search --onlyvisible --class kitty >/dev/null 2>&1 && break
sleep 1
done
xdotool search --onlyvisible --class kitty windowactivate >/dev/null 2>&1 || true
xdotool type --delay 10 -- 'export PS1="raytracer $ " PROMPT_COMMAND="printf . >> '"$PROMPT_FILE"'" PATH='"$WORK"'/bin:$PATH; clear'
xdotool key Return
sleep 1
start_capture "$GEOMETRY" "$WORK/showcase.mkv"
run_line 'meowc targets' 2.4
run_line 'meowc build' 1.6
run_line 'meowc test' 2.2
run_line 'clear' 0.4
run_line 'touch src/*/*.c include/*.h' 0.5
run_line 'meowc build' 2.0
run_line 'echo "void rt_scene_extra(void);" >> include/rt_scene.h' 0.5
run_line 'meowc build' 2.6
stop_capture
LIMIT=${LIMIT:-45}
raw=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$WORK/showcase.mkv")
speed=$(python3 -c "print(max(1.0, $raw / $LIMIT))")
ffmpeg -v error -y -i "$WORK/showcase.mkv" -an -vf "setpts=PTS/$speed" \
-c:v libx264 -crf 20 -preset slow -pix_fmt yuv420p -movflags +faststart "$OUT"
echo "raw ${raw}s, sped up ${speed}x"
rm -rf "$WORK"
echo "wrote $OUT"
+62
View File
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
source "$(dirname "${BASH_SOURCE[0]}")/record-lib.sh"
GEOMETRY=${GEOMETRY:-1280x720}
SRC=${SRC:-$HOME/projects/xmm0club/rackvm}
OUT="$ROOT/assets/watch.mp4"
WORK=$(mktemp -d)
cp -a "$SRC" "$WORK/rackvm"
rm -rf "$WORK/rackvm/build" "$WORK/rackvm/.git"
mkdir -p "$WORK/bin"
ln -sf "$ROOT/meowc" "$WORK/bin/meowc"
(cd "$WORK/rackvm" && PATH="$WORK/bin:$PATH" meowc -q build >/dev/null 2>&1)
tmux -L meowcrec kill-server 2>/dev/null || true
printf 'set -g status off\nset -g pane-active-border-style fg=colour240\nset -g pane-border-style fg=colour240\n' > "$WORK/tmux.conf"
start_xvfb "$GEOMETRY"
kitty \
--config "$HOME/.config/kitty/kitty.conf" \
-o remember_window_size=no \
-o "initial_window_width=${GEOMETRY%x*}" \
-o "initial_window_height=${GEOMETRY#*x}" \
-o confirm_os_window_close=0 \
--directory "$WORK/rackvm" \
-- bash --noprofile --norc >/dev/null 2>&1 &
sleep 3
for _ in $(seq 30); do
xdotool search --onlyvisible --class kitty >/dev/null 2>&1 && break
sleep 1
done
xdotool search --onlyvisible --class kitty windowactivate >/dev/null 2>&1 || true
xdotool type --delay 10 -- 'export PS1="rackvm $ " PATH='"$WORK"'/bin:$PATH; clear; tmux -L meowcrec -f '"$WORK"'/tmux.conf new-session -s d'
xdotool key Return
sleep 2
xdotool type --delay 10 -- 'export PS1="rackvm $ " PATH='"$WORK"'/bin:$PATH; clear'
xdotool key Return
sleep 1
start_capture "$GEOMETRY" "$WORK/watch.mkv"
send_line 'meowc watch' 3
xdotool key ctrl+b; sleep 0.4; xdotool key percent; sleep 1.2
xdotool type --delay 10 -- 'export PS1="rackvm $ " PATH='"$WORK"'/bin:$PATH; clear'
xdotool key Return
sleep 1
send_line 'echo "void rackvm_probe(void);" >> include/rackvm.h' 6
send_line 'sed -i /rackvm_probe/d include/rackvm.h' 6
send_line 'touch src/*.c include/*.h' 4
stop_capture
LIMIT=${LIMIT:-45}
raw=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$WORK/watch.mkv")
speed=$(python3 -c "print(max(1.0, $raw / $LIMIT))")
ffmpeg -v error -y -i "$WORK/watch.mkv" -an -vf "setpts=PTS/$speed" \
-c:v libx264 -crf 20 -preset slow -pix_fmt yuv420p -movflags +faststart "$OUT"
echo "raw ${raw}s, sped up ${speed}x"
rm -rf "$WORK"
echo "wrote $OUT"