remake is a small command line helper that lets you build and test your project on a remote machine, while you keep editing locally on your own workstation.
The typical scenario is a developer working on a macOS arm64 laptop, with the real target environment being a Linux x86_64 server. Instead of manually uploading files, SSHing in, and re-running make, you can run a single command:
remakeIt synchronises your working directory to the remote host with rsync, then runs the build and tests directly on that machine. You see the output in your local terminal as if everything was happening on your laptop.
This version adds two important features:
- By default
remakeperforms both build and test (sync → build → test). - The configuration can define multiple remote targets, selected with
-t.
- Project-local configuration with a
.remake.conffile - Syncs the current project directory to a remote path using
rsync - Streams output from remote build and test commands back to your terminal
- Simple subcommands:
remake→ sync + build + testremake build→ sync + build onlyremake test→ sync + build + testremake run <command...>→ sync + run an arbitrary command
- Multiple remotes, selected by name with
-t target - Minimal dependencies:
rsync,ssh, and a C compiler
The goal is to keep this tool small, predictable, and easy to understand.
You need a POSIX-like system with ssh and rsync installed. On most Linux and BSD systems they are already available. On macOS they come preinstalled.
Build remake:
cc -Wall -Wextra -O2 -o remake remake.cOr use the Makefile:
makeThen move the remake binary somewhere on your $PATH:
sudo mv remake /usr/local/bin/remake looks for a file named .remake.conf starting from the current directory and walking upward until it reaches /. This lets you run remake from any subdirectory inside the project.
A simple configuration covering a single remote might look like this:
[remote]
host = staging.example.com
user = deploy
path = /srv/myproject
[sync]
exclude = .git,node_modules,build
[commands]
build = make -j4
test = ./run-testsYou can define more than one remote by adding extra sections of the form [remote:name]. The plain [remote] section is treated as the default target.
For example:
[remote]
host = staging.example.com
user = deploy
path = /srv/myproject
[remote:prod]
host = prod.example.com
user = deploy
path = /srv/myproject
[sync]
exclude = .git,node_modules,build
[commands]
build = make -j4
test = ./run-testsIn this setup:
remakeorremake testuses the default remote, defined by[remote].remake -t prod testuses the[remote:prod]configuration.
Remote entries are identified by their names:
[remote]is equivalent to[remote:default].[remote:staging]defines a target calledstaging.[remote:prod]defines a target calledprod.
Each remote entry requires:
-
host
Hostname or IP address of the remote machine. -
path
Directory on the remote machine where the project will be synced and commands will be executed.
Optional:
user
SSH user. If omitted, the local username is used.
exclude
Optional comma-separated list of patterns to pass torsync --exclude.
Example:.git,node_modules,build,*.o.
-
build
Required when you useremake,remake build, orremake test. This is the command that will be run to build your project on the remote server. -
test
Required when you useremakeorremake test. This is the command that will be run after a successful build, typically your test suite.
Basic usage with a single remote:
remakeThis is equivalent to:
remake testThe sequence is:
- Synchronise the current directory to the configured remote path using
rsync -az --delete. - Run the
buildcommand from the[commands]section on the remote server. - If the build succeeds, run the
testcommand.
To only build without running tests:
remake buildTo build and test explicitly:
remake testTo sync and run a custom command without using the predefined build and test entries:
remake run ./myserver --config server.confWhen you define multiple remotes, select which one to use with -t:
remake -t staging
remake -t prod test
remake -t prod run ./myserver --config prod.confIn each case, remake will:
- Look up the
[remote:staging]or[remote:prod]section. - Sync the current directory to its
path. - Run the requested commands there.
0if sync and all requested commands succeed.- Non-zero if
rsyncfails, if the configuration is missing required values, or if any remote command exits with a non-zero code. 1for simple usage or configuration errors.
This makes remake usable from scripts or as part of a larger automation workflow.
Imagine you have a C project you edit on macOS, and a Linux server named ssh-server.net where you want to build and run it.
Project structure:
myproject/
.remake.conf
Makefile
src/
tests/
.remake.conf:
[remote]
host = ssh-server.net
user = remote_user
path = /path/myproject
[remote:prod]
host = prod-server.net
user = remote_user
path = /path/myproject
[sync]
exclude = .git,build,*.o
[commands]
build = make -j4
test = ./run-testsFrom your laptop:
cd myproject
remakeYou might see something like:
[remake] syncing to crypto@ssh-server.net:/path/myproject
[remake] sync complete
[remake] === BUILD (make -j4) ===
cc -O2 -Wall -c src/main.c -o build/main.o
cc -O2 -Wall -c src/util.c -o build/util.o
cc -o build/myserver build/main.o build/util.o
[remake] BUILD done
[remake] === TEST (./run-tests) ===
[ RUN ] test_parse_config
[ OK ] test_parse_config
[ RUN ] test_connection
[ OK ] test_connection
[remake] TEST done
Later, when you are ready to exercise the production machine more directly:
remake -t prod testThe same project tree is synced and exercised against the production remote configuration.
remakeassumes thatsshandrsyncare installed and in your PATH.- Authentication is up to your normal SSH setup. It works best with SSH keys rather than passwords.
- The configuration format is intentionally kept small and direct.