Commit Graph
53 Commits
Author SHA1 Message Date
milner b3a2340a22 fix(build): handle assembly and reject sources meowc cannot compile 2022-07-25 11:49:47 +00:00
milner 84fae96b16 refactor(lib): delete the code nothing reaches 2022-07-24 18:55:09 +00:00
milner 5f81ab227d feat(run): run blocks for commands the build does not produce 2022-07-21 16:25:46 +00:00
milner 7d6aaeb5eb feat(exec): spill long command lines into response files 2022-07-20 17:50:41 +00:00
milner b8d3b7ebb1 feat(link): drive output names and link flags from the object format 2022-07-18 07:56:15 +00:00
milner 3b38d20522 feat(tools): record an editor demo of the header fan-out
Adds a recording harness for the Emacs session alongside the terminal one, and
the capture it produces: a declaration added to rt_scene.h, the fourteen
translation units across four targets that the depfiles put downstream of it,
and the link steps that do not rerun because the objects come back byte
identical.

Both harnesses waited on xdotool search --sync for their window, which blocks
indefinitely rather than failing when the window never appears, so a recording
that went wrong hung instead of exiting. Replaced with a bounded poll.
2022-07-16 18:01:52 +00:00
milner 2a2f8d976d feat(toolchain): cross compile through target triples and sysroots
A triple is set with --target or a target field in the toolchain block, and
everything derived from it follows: platform, arch and the conditionals built
on them come from the triple rather than uname, so a build file can branch on
the platform it is building for instead of the one it is running on.

Tools are taken from the triple prefix when a matching toolchain is installed
(x86_64-w64-mingw32-gcc, -ar, -ranlib) and otherwise the host compiler is
invoked with --target, which covers clang without a prefixed toolchain. An
explicit cc, cxx, ar or ranlib in the build file always wins over the derived
one. --sysroot adds --sysroot to both the compile and link lines.

Each triple gets its own build directory and probe cache under builddir, so a
host tree and a cross tree do not invalidate each other and neither reruns the
other's checks. Probes never execute what they compile, sizeof included, so the
configure stage needed no changes to work against a foreign target.

Executables and shared libraries now take the extension the target platform
uses. Without that the graph expected bin/app while mingw wrote bin/app.exe,
and the link step repeated on every build.

Verified against x86_64-w64-mingw32, which produces a PE32+ binary, and
aarch64-linux-gnu through clang, which produces AArch64 objects.
2022-07-16 01:16:10 +00:00
milner ff4e5c20dc fix(sched): kill running actions when meowc is interrupted
Ctrl-C killed meowc and left every compiler it had spawned running, still
holding CPU and still about to write into the build directory. There were no
signal handlers at all.

SIGINT and SIGTERM now cancel the same way a build failure does, and the run
returns cleanly so the cache is still written and the exit status is 130. A
second signal falls through to the default handler, so an unresponsive child
cannot trap the user.

Signalling a single pid was not enough: a compiler driver spawns its own
children, and those were reparented to init and survived. Each action is now
placed in its own process group with setsid, and cancellation signals the group,
which also makes the existing failure path reach grandchildren. Unix.wait is
retried on EINTR so a signal arriving mid-wait is not fatal.
2022-07-15 14:41:20 +00:00
milner 7502fcd7dd feat(sched): cancel in-flight actions when a build fails
Only new spawns were held back after a failure, so every action already running
was allowed to finish even though its output would be discarded. The scheduler
now sends SIGTERM to the remaining children on the first failure, and reports
them separately rather than counting a process it killed as a failure of its
own. Partial outputs are removed and their cache entries dropped, so the next
run starts clean.

Under -k the existing behaviour is kept, since keeping going is the point.

On a graph with three six-second generators alongside one translation unit that
fails immediately, -j4 now returns in 0.12 s rather than 6.03 s.
2022-07-15 04:18:43 +00:00
milner b11c6e9f72 fix(cli): detect the core count on systems without /proc/cpuinfo
The default job limit read /proc/cpuinfo and silently fell back to four
anywhere that file is absent, so macOS and the BSDs ran at a fraction of the
available parallelism. Falls back to getconf _NPROCESSORS_ONLN before the
constant.
2022-07-14 18:24:39 +00:00
milner bf81a54bc2 perf(cache): memoise file digests and invalidate them on write
A header included by fourteen translation units was hashed once per dependent,
and every built action hashed its inputs twice: once to decide it was stale and
again to store the new key. Digests are now memoised for the run, and the
scheduler drops the entries for an action's outputs and depfile once it
finishes, so a freshly written file is never read from the memo.
2022-07-12 08:44:33 +00:00
milner bee445b66a feat(tools): add a reproducible terminal capture harness
Records on a throwaway Xvfb display at fixed geometry, drives the session with
xdotool, and quantises through a per-clip palette so the terminal's colours
survive instead of dithering.
2022-07-11 02:30:42 +00:00
milner 9678f30767 feat(examples): add the C++ benchmark and three test targets
A C++ consumer of the C archives, plus maths, scene and image tests driven by
meowc test.
2022-07-10 04:57:31 +00:00
milner 61836941e7 feat(examples): add the render binary and its argument handling
Scene, dimensions, sample count and thread count from the command line, with
defaults read out of the generated config header.
2022-07-07 21:07:20 +00:00
milner 6b6a16be04 feat(examples): generate scene translation units from .scene files
scenegen.py compiles each scene into a C source and header, driven by a rule
block with per-input stem expansion.
2022-07-07 12:27:02 +00:00
milner 9a29cc7b93 feat(examples): add a zlib backed PNG encoder
Real PNG output through deflate, which is what makes the pkg-config
dependency load bearing rather than merely declared.
2022-07-06 16:04:09 +00:00
milner a1173c73b6 feat(examples): add the image buffer and a PPM writer
RGB framebuffer with tone mapping, and PPM output for the path where zlib is
unavailable.
2022-07-04 09:14:34 +00:00
milner 13409a1e8b feat(examples): add shading, the threaded render loop and two scenes
Lambertian and metal shading with recursive bounces, a row-claiming loop
across worker threads, and the studio and rings scene files.
2022-07-02 12:49:50 +00:00
milner 09d072a658 feat(examples): add the scene representation, camera and intersection
Sphere and plane records, camera ray generation from field of view and aspect
ratio, and the nearest-hit search across the scene.
2022-07-02 02:41:00 +00:00
milner f313b97363 feat(examples): add vector maths and an xorshift RNG
vec3 operations and a per-thread random stream, the leaf library everything
else in the example depends on.
2022-06-30 11:37:33 +00:00
milner 816b1ee594 feat(examples): add the raytracer build file and core header
Nine targets: two translation units generated from scene files, a C++
consumer, a shared object built from the same sources as the archives, and an
optional zlib dependency.
2022-06-30 00:29:57 +00:00
milner a845c628e3 feat(examples): extend hello with a second translation unit and a test
Gives the archive more than one member and gives meowc test something to run.
2022-06-28 01:49:34 +00:00
milner d71c538eef feat(examples): add a hello project with a library and a consumer
Smallest project that exercises the whole pipeline: one static library and one
executable that links against it.
2022-06-26 15:32:31 +00:00
milner 26ea32d8d1 feat(cli): add argument parsing and command dispatch
Handles attached flag forms such as -j4 and -Dname=value, dispatches the
subcommands, and prints one aligned line per completed action with a summary.
2022-06-25 17:08:00 +00:00
milner 5560658db7 feat(scaffold): generate a project that builds and tests unmodified
Writes a build file, a library, a binary and a test, wired so build and test
both pass immediately after init.
2022-06-25 01:39:44 +00:00
milner 694370f2db feat(watch): rebuild when a tracked input changes
Snapshots the modification times of every graph input and re-runs the
scheduler on change.
2022-06-23 12:20:02 +00:00
milner 1713944e56 feat(testrun): build and run test targets, reporting pass or fail
Runs each test binary, captures its exit status, and reports per-test timing
alongside an aggregate line.
2022-06-23 03:23:45 +00:00
milner 38dbe2b8ee feat(install): copy installable outputs under a prefix
Destinations come from each target's install field, the executable bit is
preserved, and a dry run prints the plan without touching anything.
2022-06-21 02:23:23 +00:00
milner 12111f2b55 feat(dot): emit Graphviz source for the action graph
Nodes coloured by action kind, with a targets-only mode for graphs too large
to read in full.
2022-06-19 01:08:42 +00:00
milner 597c5b0d75 feat(compdb): write compile_commands.json for clangd
One entry per translation unit with directory, arguments and file, taken from
the compile actions already in the graph.
2022-06-17 19:15:48 +00:00
milner b6a41fda7b feat(sched): dispatch ready actions under a job limit
Checks each node's key at the moment it becomes ready rather than up front,
because an input may have been produced by a node that ran seconds earlier.
This is what gives early cutoff.
2022-06-15 20:17:47 +00:00
milner 9097815563 feat(build): lower resolved targets into graph actions
Emits compile, archive, shared-link and link actions per target, and applies
-fPIC to anything reachable from a shared target.
2022-06-13 08:04:17 +00:00
milner e42fbc8c57 feat(dep): source header edges from compiler depfiles
Parses -MMD -MF output, unfolding line continuations, so the include set comes
from the compiler rather than from hand-maintained declarations.
2022-06-12 22:24:06 +00:00
milner 8fa9b6ba4f feat(cache): key actions on content, argv and the real input set
Digests every input plus the exact argument vector into one key, persisted
under the build directory. Staleness becomes a content question rather than a
timestamp comparison.
2022-06-12 01:49:31 +00:00
milner df3abecf6a feat(graph): derive edges from which node produces which file
Indexes producers by output path, so a generator and the compile consuming its
output are connected without being declared. Detects duplicate producers and
reports dependency cycles by path.
2022-06-09 14:01:08 +00:00
milner fcb544fd65 feat(resolve): lower surviving blocks into targets and rule instances
Expands globs, resolves use edges between targets, propagates inherited
includes, and instantiates a rule once per matched input.
2022-06-08 10:43:20 +00:00
milner c680a70e1c feat(eval): evaluate statements in written order
Expands variables top to bottom, runs checks as they are reached and evaluates
conditionals against results already established. Written order is the
semantics, not an implementation detail.
2022-06-06 11:35:41 +00:00
milner 0259325381 feat(configh): generate a guarded C header from probe results
Emits the project name and the HAVE_ and SIZEOF_ defines from what the probes
actually found, behind an include guard derived from the output path.
2022-06-05 22:51:52 +00:00
milner 301ce7eab5 feat(probe): detect headers, functions, symbols, sizeof and pkg-config
Compiles and links throwaway programs to answer each check, and shells out to
pkg-config for cflags and libs. Results are memoised on the toolchain.
2022-06-03 09:35:23 +00:00
milner 8581f2e931 feat(exec): spawn subprocesses and capture stdout and status
Argv-vector execution with no shell in the path, so arguments containing
spaces or quotes need no escaping.
2022-06-01 08:37:55 +00:00
milner 0cef03d6b0 feat(parse): parse the grammar with recursive descent
Turns tokens into the AST, and consults suggest at each failure point so an
unknown declaration or field offers the nearest valid name.
2022-05-30 01:11:45 +00:00
milner eec988b452 feat(ast): model statements, blocks and nested conditionals
Keeps written order, so a later branch can observe the result of a check that
appeared earlier in the file.
2022-05-29 08:59:55 +00:00
milner 125376f53f feat(lexer): tokenise build files with a span on every token
Words, strings, braces and comments, each carrying its source range, so an
error points at the offending token rather than the whole line.
2022-05-27 13:59:46 +00:00
milner a864f5e7a8 feat(types): define resolved project, target and rule records
Targets carry sources, includes, flags and uses; rule instances carry resolved
inputs and outputs. This is the shape every later stage consumes.
2022-05-26 00:17:18 +00:00
milner d182750a9f feat(suggest): rank near-miss names by edit distance
Levenshtein with a cutoff, returning the closest valid name at a position, or
nothing when no candidate is close enough.
2022-05-25 15:17:54 +00:00
milner 4040f5a404 feat(json): emit JSON with correct control-character escaping
So generated output survives paths containing spaces, quotes or backslashes.
2022-05-23 21:14:56 +00:00
milner 9f4871b1e5 feat(glob): expand source patterns without shelling out
Matches *, ? and ** against directory entries directly, so src/**/*.c
resolves identically regardless of the shell.
2022-05-21 21:37:43 +00:00
milner e9f7f2c7dd feat(fs): add recursive mkdir, whole-file IO and mtime reads
Path joining, read, write, is_dir and mtime, used by every later stage that
touches disk.
2022-05-21 12:14:44 +00:00
milner 14377f6794 feat(ident): normalise names into C macro identifiers
Uppercases, replaces non-alphanumerics with underscores, and derives the
HAVE_X and SIZEOF_X forms the generated header uses.
2022-05-20 03:45:44 +00:00
milner e26d8344da feat(diag): render errors with a caret and the offending line
Formats file:line:col, re-reads the source to print the line, underlines the
span and leaves a slot for a suggestion.
2022-05-18 08:54:32 +00:00