Flake is a build system that aims to replace Make. Flake is a small, portable, standalone executable and a general purpose build system. Like Make, Flake has a slight bias towards its own implementation language. It is distributed with build rules for C/C++ and Lua. In conjunction with Clang or GCC, it can generate a standalone executable with a single command-line invocation.
- 
Flake does not invent its own programming language. It reuses Lua.
We chose Lua because it is simple, safe, portable and well-documented.
 - 
Automatic parallelization.
For example, consider the following build description.
return c.program { c.object 'a.c', c.object 'b.c', }
Flake recognizes that the program depends on 2 objects and that the objects are independent of each other. It therefore builds the objects in parallel. The C build rules have no special handling for this. Builders are only serialized with the output of one is the input of another.
 - 
Build steps can have dependencies on dependency generators.
return c.program(c.dependencies 'main.c')
 - 
Flake build scripts do not specify dependencies between files.
You will not see this:
%.o: %.c clang -c -o $@ $<
Flake dependencies are created implicitly. Builders return a handle to any file that needs to be created. Passing this handle to another function implies a dependency.
local obj = c.object 'a.c' return c.program(obj)
 - 
Names for intermediary files are automatically generated.
 - 
Flake uses lexical scoping to track dependencies. No global variables.
No globals means that you can share build libraries between teams without concern for naming conflicts.
 - 
Scales cleanly to multi-project builds.
local mylib = flake.importBuild '../mylib' return c.program { 'main.c', mylib.contents['mylib.a'] }
Flake builds subprojects in the context of the subproject's directory. Flake detects when relative paths are passed to/from the subproject and automatically adjusts the paths. In the example above, the subproject builds
./mylib.a, but the top-level project sees../mylib/mylib.a. No need forabspath()noise. 
$ make -C flake
$ export PATH=$PWD/flake/out/release:$PATH$ cat hello.c
#include <stdio.h>
int main() {
  printf("Hello, World!\n");
  return 0;
}$ flake --silent c run hello.c
Hello, World!$ cat hello.lua
print 'Hello, World!'$ flake --silent lua run hello.lua
Hello, World!$ cat build.lualocal system = require 'system'
local c      = require 'c'
local lua    = require 'lua'
return system.directory {
  path = 'out',
  contents = {
    ['hello-c']   = c.program{'hello.c'},
    ['hello-lua'] = lua.program{'hello.lua'},
  },
}$ flake build.luaflake [OPTIONS]... [FILE [TARGET [TARGET_PARAMS]]]
Build the 'main' target from 'build.lua' in the current directory.
$ flakeBuild the 'test' target from 'build.lua' in the current directory.
$ flake build.lua testBuild the 'main' target from 'foo.lua' in the current directory.
$ flake foo.luaBuild the 'main' target from 'build.lua. in the 'bar' directory.
$ flake -C barThe Flake build system would not exist without the following contributions: