Features
-
Cross-platform: Windows is a first-class citizen - no dependency on a POSIX-compliant shell (or any shell). Werk files work on all platforms out of the box.
-
Simple language: Werk files are written in a simple and human-friendly language that's easy to understand. It is designed to be written by hand.
-
Task recipes: Real support for executing project scrips, similar to
just
recipes or.PHONY
Make targets. A command recipe will be run at most once perwerk
invocation. -
Build recipes: Files can be built from Make-like patterns, and rebuilt according to modification time.
-
Advanced outdatedness:
werk
does more than just compare file modification timestamps. Metadata is cached between runs to support additional sources of "outdatedness". -
Separate output directory: All files produces by
werk
are put in a separate output directory, which is always what you want. This is hard to achieve with Make. -
Globbing: Filesystem glob patterns work out of the box, and can be used reliably in dependencies.
werk
caches a hash of the glob result between builds, so file deletion is detected as a change. Globbing is based on theglobset
crate, which comes fromripgrep
. -
Paths can contain spaces: Make simply cannot deal.
-
Depfile support: Depfile output from C-like compilers such as
clang
,gcc
,cl
,glslc
, etc. are specially supported in build recipes. When a recipe contains adepfile
dependency, it is automatically built and included when evaluating the dependencies of that recipe. -
.gitignore support: The
ignore
crate is used to hide files fromwerk
. -
Dry-run: Pass
--dry-run
to diagnose the build process without generating any output. -
Concurrency: Build recipes and tasks run in parallel when possible.
-
(TODO) Autoclean: Werk is aware of which files it has generated, and can automatically clean them up from the output directory.
-
(TODO) Autowatch: Werk can be run in
--watch
mode, which waits for file changes and automatically rebuilds when any change is detected.
Limitations
-
Cross-platform: Paths and commands must work across all platforms.
werk
does not require a shell (likesh
orbash
), but that also means that common shell features are not available. The language provides cross-platform alternatives in most cases. -
Declarative: Very advanced build logic can be difficult to express. If the limited expression support in
werk
is insufficient (and can't be easily supported in the model), consider using a more advanced solution like GNU make, CMake, ninja-build, scons, cargo-script, etc. -
Separate output directory: It is not possible to put output files next to input files, and files in the output directory are assumed to be generated by
werk
. -
Multiple recipes matching the same pattern: As opposed to Make, build recipes are not disambiguated by their inputs. This means that for example it is not possible to have two recipes that match
%.o
, where one takes%.c
as input and the other takes%.cpp
as input.- Workaround 1: Define separate recipes
%.c.o
and%.cpp.o
to build the two kinds of source files with different output file extensions. - Workaround 2: Use capture patterns, so the build recipe pattern is
%.(c|cpp)
, and usematch
expressions to generate the correct compiler arguments based on the captured pattern{0}
, which will evaluate to either "c" or "cpp".
- Workaround 1: Define separate recipes
-
Multiple outputs from a single recipe: This is not supported. The typical example is a code generator that outputs both a header file and a source file, like
bison
. Note: This may be explicitly supported in the future.- Workaround: For the common case of a
bison
parser, define the recipe for the generatedparser.h
file, and add another recipe for theparser.c
file that has no commands, but just depends onparser.h
.
- Workaround: For the common case of a
-
Detailed parallelism control:
werk
currently does not support marking specific recipes as "non-parallel". The only way to control parallelism is by supplying the--jobs
command line parameter, which controls the number of worker threads.