#build-system #ninja-build #programming-language #turtle #dynamic #outputs #content

build turtle-build

Ninja-compatible build system for high-level programming languages

31 releases

0.4.8 Dec 7, 2023
0.4.7 Oct 17, 2023
0.4.6 Jul 11, 2023
0.4.4 Nov 16, 2022
0.3.1 Feb 5, 2022

#57 in Build Utils

Download history 15/week @ 2024-07-26 46/week @ 2024-08-02 274/week @ 2024-08-09 40/week @ 2024-08-16 44/week @ 2024-08-23 85/week @ 2024-08-30 52/week @ 2024-09-06 17/week @ 2024-09-13 49/week @ 2024-09-20 203/week @ 2024-09-27 145/week @ 2024-10-04 76/week @ 2024-10-11 92/week @ 2024-10-18 20/week @ 2024-10-25 171/week @ 2024-11-01 167/week @ 2024-11-08

451 downloads per month

MIT/Apache

140KB
4K SLoC

Rust 3.5K SLoC // 0.0% comments Gherkin (Cucumber) 489 SLoC Shell 94 SLoC // 0.1% comments Ruby 1 SLoC

Turtle

GitHub Action crates.io License

Ninja-compatible build system for high-level programming languages written in Rust

Goals

  • Safe (no unsafe) and fast implementation of the Ninja build system in Rust
  • Modest, comprehensive, and customizable build/error outputs
    • Turtle never shows any information that is not understandable to end-users.
    • This is important for users of high-level programming languages who do not know how compilers and build systems work.

Turtle is originally written for the Pen programming language. Therefore, we support only dynamic dependencies but not C/C++ header dependencies currently. Your contribution is welcome! 😄

Install

cargo install turtle-build

Usage

turtle

For more information, see turtle --help.

Features

  • Ninja-compatible build file syntax and command line options 🥷
  • Content hash-based rebuild
  • Description-only outputs
    • Turtle never shows commands of build rules but only descriptions because the former is hard for end-users to digest.
  • Source mapping
    • Turtle maps outputs in error messages to source filenames defined as srcdep variables defined in build directives to make them understandable to end-users.
  • --log-prefix option
    • It changes log prefixes attached to every line of logs from Turtle itself (e.g. --log-prefix my-build-system for a log of my-build-system: build failed.)
  • --quiet option
    • It suppresses error messages from Turtle itself on expected build errors. This is useful when you are spawning Turtle as a child process of some higher-level build system.
  • Console output handling similar to Rust's Cargo
    • Turtle shows outputs of build jobs running currently at the bottom of logs. So it's easy to track what is going on during builds.

Compatibility with Ninja

Turtle aims to support full syntax of the Ninja build files. It also supports basic command line arguments but is not going to implement all the original options (e.g. -t option.)

Syntax

  • build statement
    • Explicit outputs
    • Explicit inputs
    • Implicit outputs
    • Implicit inputs
    • Order-only inputs
    • phony rule
  • rule statement
  • default statement
  • include statement
  • subninja statement
  • pool statement
  • Global variables
  • Build-local variables
  • in and out special variable

Command line arguments

  • -f custom build file option
  • -j job limit option
  • -k keep-going option
  • -C change-directory option

Others

  • Circular build dependency detection
  • Circular build file dependency detection
  • builddir special variable
  • Dynamic dependencies
    • Implicit inputs
    • Implicit outputs
    • Circular build dependency detection
  • C/C++ header dependencies
    • depfile option
    • deps option
  • Windows support

Technical notes

Something different from the traditional build systems and notable in Turtle is that it solves parallel builds similar to parallel graph reduction naturally, where you modify graph structures in parallel and reduce it into a solution, thanks to an ecosystem of futures and stackless coroutines in Rust.

Here is how parallel builds work in Turtle:

  1. Turtle spawns futures for all builds of default targets.
  2. Depending on builds' configuration, they spawn more futures or resolve their futures.
    • If they require some input targets to be built first, they spawn those builds for input targets all in parallel.
  3. Those futures are scheduled and run in parallel by an asynchronous runtime in Rust.
  4. Builds complete when all the futures are resolved.

Currently, Turtle uses a topological sort algorithm only to detect dependency cycles but not for scheduling of build jobs.

Turtle is powered by the following neat projects and others!

Similar projects

License

Dual-licensed under MIT and Apache 2.0.

Dependencies

~11–19MB
~251K SLoC