#makefile #build #programmatically #variables #prelude #would #hook

build makemake

Library for building Makefiles programmatically

3 releases

0.1.4 Sep 18, 2024
0.1.3 Jul 6, 2024
0.1.2 Jul 1, 2024
0.1.1 Jun 30, 2024
0.1.0 Jun 30, 2024

#198 in Build Utils

Download history 54/week @ 2024-08-24 3/week @ 2024-08-31 136/week @ 2024-09-14 45/week @ 2024-09-21 19/week @ 2024-09-28 3/week @ 2024-10-12 1/week @ 2024-10-19 38/week @ 2024-11-02 10/week @ 2024-11-09 16/week @ 2024-11-16 2/week @ 2024-11-23

66 downloads per month

LGPL-3.0-or-later

38KB
961 lines

makemake

CI CodeFactor

makemake is a rust library for building Makefiles programmatically. Traits allow makemake functions to take in pretty much any type as an argument - you can set the value of a variable to a string, a function, or even another variable, without needing .into()s everywhere. There's also a helper expr! macro for building more complex expressions.

Although version-agnostic, makemake does support GNU make features. If you intend your Makefiles to be extremely portable (although even macOS comes with GNU make), avoid those features as you would when writing Makefiles by hand.

Usage

Run this command in your rust project root:

cargo add makemake

You can find the crate on crates.io.

Then, you can add

use makemake::prelude::*;

to appropriate files.

Example

Let's build a Makefile for a C project.

let mut makefile = Makefile::new();

We'll want variables for the source files, object files, compiler, and flags.

let src = makefile.assign("SRC", Function::wildcard([expr!("src/*.c")]));
let obj = makefile.assign("OBJ", Substitution::new(src, ".c", ".o"));
let cc = makefile.assign_without_overwrite(
    "CC",
    Function::shell("which gcc || which clang")
);
let cflags = makefile.append("CFLAGS", "-std=c99 -Wall -Wextra");
let target = makefile.assign("TARGET", "main");

Next, we'll define the rule to create the target.

makefile.rule(target).dep("main.c").dep(obj).cmd(expr!(
    cc;
    cflags;
    "-o";
    makefile.target_var();
    makefile.deps_var()
));

In the expr! macro, use ; to separate arguments by spaces and , to put them directly adjacent.

Finally, we can print the resultant Makefile.

print!("{}", makefile.build());

Indeed, we can use our Makefile to build an example project.

cargo run --example c_project > examples/Makefile
cd examples
make && ./main

The actual example (c_project.rs in the examples/ directory) also comes with a make clean!

Setting Up Git Hooks

After cloning the repository, run the following script to set up the hooks:

/bin/sh setup_hooks.sh

License

This project is licensed under the LGPL License, a copy of which is available in this directory.

Dependencies

~1.2–1.8MB
~42K SLoC