Dake is a distributed build system that extends traditional Makefiles to work seamlessly across multiple machines. It allows you to assign build targets to different hosts, automatically handle dependency fetching, and run remote builds with minimal overhead. The system is designed to be fully compatible with standard Makefile syntax while enabling transparent distribution.
In classic Make-based workflows, all build commands execute on a single host, even if you have multiple machines available. Dake changes that: it introduces lightweight daemons that communicate over the network and cooperatively build your project.
Each daemon can compile a subset of targets, share built artifacts, and synchronize dependencies with others. The developer writes a regular Makefile, annotating only which targets belong to which node. Everything else, distribution, fetching, caching, linking, is handled automatically.
Each machine participating in the distributed build must have Dake installed.
First, clone the repository and build it in release mode:
git clone https://github.com/yourusername/dake.git
cd dake
cargo build --releaseThe executable will be generated at:
target/release/dake
Copy it to a directory in your PATH:
sudo cp target/release/dake /usr/local/bin/You can check that it is installed correctly:
dake --versionOn every host that will participate in the distributed build, start the Dake daemon:
dake daemonBy default, the daemon listens for incoming connections on port 1808. You can launch it manually in a terminal or start it in the background:
nohup dake daemon > dake.log 2>&1 &Repeat this step on each machine that will be part of the distributed network.
A distributed Makefile looks almost identical to a standard one. You only need to define which nodes correspond to which working directories, and assign targets to them.
#!ROOT_DEF 172.0.0.2 = /project
#!ROOT_DEF 172.0.0.3 = /project
main: main.o a.o b.o
$(CC) -o main main.o a.o b.o
main.o: main.c
$(CC) -c main.c -o main.o
a.o[172.0.0.2]: a.c
$(CC) -c a.c -o a.o
b.o[172.0.0.3]: b.c
$(CC) -c b.c -o b.o#!ROOT_DEF 172.0.0.2 = /projectdefines that172.0.0.2corresponds to the daemon working in/projecton its host.a.o[172.0.0.2]means that targeta.owill be built remotely by the daemon running on172.0.0.2.- You can use a DNS name to specify the target host, and optionally append |path to define the project directory directly on that host.
- Dependencies are automatically fetched when required, and all commands use standard Makefile syntax.
Copy all project files (the Makefile and sources) to the working directory of each node, as specified in your root definitions.
For the example above, you would place these files on both hosts under /project:
/project/
├── Makefile
├── main.c
├── a.c
└── b.cOnce the daemons are running and all nodes contain the project files, start the build from any node:
dakeDake will:
- Parse the Makefile.
- Resolve all node definitions.
- Dispatch build commands to the appropriate hosts.
- Fetch remote build artifacts when needed.
- Link the final binary locally.
After the build completes, you can run the resulting executable as usual:
./mainExpected output:
sum = 3
Once you are done, stop all daemons manually:
pkill dakeOr, if you have set them up as services:
sudo systemctl stop dakeDake enables you to:
- Write standard Makefiles with minimal extensions.
- Build across multiple machines automatically.
- Reuse your existing toolchains and compilers.
- Keep the setup simple and reproducible.
All you need is to:
- Build Dake on each host.
- Launch
dake daemoneverywhere. - Write a Makefile with node annotations.
- Run
dakefrom any node.
And that’s it, your builds are now distributed.