Skip to content

Repository files navigation

Open Make (omake)

This is an open implementation of make, striving to be simple, portable, and fast.

To avoid clashing with your system's make, this project is built as omake by default, but if this project is ever used as the default implementation of make in a system, then it should be named make (to follow the same convention as bmake and gmake).

Installation

You can install with Cargo: cargo install omake. In the future, I may consider packaging this project for other repos such as Homebrew or the AUR.

Project Goals

This project is in its infancy, so I may find out later that some or all of the project goals are impossible to achieve. Regardless, in order of importance, here are the project goals:

  1. Portable makefiles and makefiles generated by tools like CMake should behave correctly.
  2. Support as many commonly-used BSD and GNU make extensions as possible.
  3. Be capable of building the Linux kernel.
  4. Be really fast.
  5. If we decide to implement new extensions, they should be opt-in to retain backwards compatibility. We should avoid this unless there are serious performance improvements.
  6. Possibly the hardest: don't turn into a backwards-incompatible competing standard. As uninspired as it may seem, I just want an implementation of make that works on Linux and FreeBSD (and macOS); that's it.

1.0 release will probably happen when this project can build the Linux kernel.

Note that due to implementation details (and especially during the initial development phase this project is in), it's possible certain features are inadvertently added. Users should probably not rely on those and they may even qualify as bugs. I hope to get everything ironed out before the 1.0 release to avoid (as stated in Goal #6) building an incompatible competing standard. There are already other build systems, I don't actually want to make another one.

Working list of things that I plan on leaving out of this implementation intentionally:

  1. Remaking makefiles from RCS/SCCS. I see no need to support this.

Development

To build and run:

cargo build
cargo run -- -f Makefile     # run against a makefile (args after `--`)

The toolchain is pinned to nightly via rust-toolchain.toml (only so rustfmt can wrap over-long comments) and installs automatically; the code itself still builds on stable.

Build-time Configuration

Like the BSD makes, omake will grow a few OS-specific paths — chiefly the system makefile directory where sys.mk and the built-in rules live (bmake's _PATH_DEFSYSPATH, /usr/share/mk on NetBSD and FreeBSD). Rather than hard-code one OS, these are centralized as build-time constants, each overridable through an OMAKE_* environment variable read at compile time with option_env! and defaulting to NetBSD's value:

// One module holds these; NetBSD defaults, overridable at build time.
pub const DEFAULT_SYSPATH: &str = match option_env!("OMAKE_DEFAULT_SYSPATH") {
    Some(path) => path,
    None => "/usr/share/mk",
};

A packager targeting a different layout sets the override in the build environment (or pins it in .cargo/config.toml):

OMAKE_DEFAULT_SYSPATH=/opt/pkg/share/mk cargo build --release

Planned constants and their NetBSD defaults: system makefile dir /usr/share/mk, system makefile name sys.mk, object-dir prefix /usr/obj, default shell dir /bin, temp dir /tmp. These are tracked in TODO.md; none are wired up yet (omake does not read sys.mk today).

Before Committing

cargo fmt                   # nightly rustfmt, wraps comments at 100 columns
cargo clippy --all-targets  # the baseline is zero warnings — keep it clean
cargo test                  # fast unit + system tests, no external dependencies

Repository Layout

  • src/lib/ — the library (parsing + execution). Start here:
    • makefile.rs — the parser and the Makefile type (directives, includes, conditionals, .for).
    • makefile/rule_map.rs — rules, the build graph, recipe execution, implicit/pattern rules.
    • expand.rs — variable/function expansion ($(...), GNU functions, BSD : modifiers).
    • vars.rs — the variable store and origins; makeflags.rsMAKEFLAGS (de)serialization; compat.rs — the --compat={gnu,bsd} diagnostic-output emulation; glob.rs, logger.rs.
  • src/bin/main/ — the CLI: args.rs (clap) and _main.rs (wiring, the restart loop).
  • tests/system_tests.rs + tests/scenarios/ (directory-per-scenario), and tests/conformance/ (the GNU/bmake suites; see its README). TODO.md (gitignored) tracks the remaining work, split into GNU and BSD sections.

Dependencies are kept minimal on purpose.

Testing

Unit tests live alongside the code where they are feasible. The bulk of coverage is the system test suite under tests/scenarios/: each scenario is a directory with a makefile, a mod.rs, and any fixture files. mod.rs invokes the system_test_cases! macro, which runs the built omake against that makefile with the given arguments and checks stdout/stderr — and the resulting directory contents — against the expected values. These are fast and need no external tools:

cargo test  # unit + system tests

Conformance Suites

Beyond the hand-written scenarios, tests/conformance/ runs omake against the real upstream test suites of GNU make and BSD make (vendored on demand at a pinned commit). Both do exact golden-file comparison, so the runners use --compat={gnu,bsd} to match that make's diagnostic output and measure real behavioral gaps rather than format noise. Current pass rates:

Suite Version omake --compat
GNU make 4.4.1 717 / 1337
BSD make 20230711 117 / 396

The scores are pinned as a regression gate: two #[ignore]d tests shell out to the runners, so the normal cargo test loop stays fast and dependency-free. To also run the gate, un-ignore them:

cargo test -- --include-ignored   # also runs the conformance regression gate (~6 min)

See tests/conformance/README.md for the runner scripts, their prerequisites (perl, bmake, first-time network), how to read the results, and why a plain-omake score would be lower but meaningless (output-format noise, not mis-run makefiles).

About

An open implementation of make.

Resources

Stars

20 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages