• Stars
    star
    183
  • Rank 210,154 (Top 5 %)
  • Language
    D
  • License
    BSD 3-Clause "New...
  • Created almost 10 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Build system in D, Python, Ruby, Javascript or Lua

Reggae

Actions Status Coverage

A (meta) build system with multiple front (D, Python, Ruby, Javascript, Lua) and backends (make, ninja, tup, custom).

Detailed API documentation can be found here.

Why?

Do we really need another build system? Yes.

On the frontend side, take CMake. CMake is pretty awesome. CMake's language, on the other hand, is awful. Many other build systems use their own proprietary languages that you have to learn to be able to use them. I think that using a good tried-and-true general purpose programming language is better, with an API that is declarative as much as possible.

On the backend, it irks me that wanting to use tup means tying myself to it. Wouldn't it be nice to describe the build in my language of choice and be able to choose between tup and ninja as an afterthought?

I also wanted something that makes it easy to integrate different languages together. Mixing D and C/C++ is usually a bit painful, for instance. In the future it may include support for other statically compiled languages. PRs welcome!

reggae is really a flexible DAG describing API that happens to be good at building software.

Features

  • Multiple frontends: write readable and concise build descriptions in D, Python, Ruby, JavaScript or Lua. Your choice!
  • Multiple backends: generates build systems for make, ninja, tup, and a custom binary backend
  • Like autotools, no dependency on reggae itself for people who just want to build your software. The --export option generates a build system that works in the root of your project without having to install reggae on the target system
  • Flexible low-level DAG description DSL in each frontend to do anything
  • High-level DSL rules for common build system tasks for C, C++ and D projects
  • Automatic header/module dependency detection for C, C++ and D
  • Automatically runs itself if the build description changes
  • Out-of-tree builds - no need to create binaries in the source tree
  • User-defined variables like CMake in order to choose features before compile-time
  • dub integration for D projects

Not all features are available for all backends. Executable D code commands (as opposed to shell commands) are only supported by the binary backend, and due to tup's nature dub support and a few other features are not available. When using the tup backend, simple is better.

The recommended backend is ninja. If writing build descriptions in D, the binary backend is also recommended.

Usage

Pick a language to write your description in and place a file called reggaefile.{d,py,rb,js,lua} at the root of your project.

In one of the scripting languages, a global variable with the type reggae.Build must exist with any name. Also, the relevant language-specific package can be installed using pip, gem, npm or luarocks to install the reggae package (reggae-js for npm). This is not required; the reggae binary includes the API for all scripting languages.

In D, a function with return type Build must exist with any name. Normally this function isn't written by hand but by using the build template mixin.

From the the build directory, run reggae [-b <ninja|make|tup|binary>] /path/to/your/project. You can now build your project using the appropriate command (ninja, make, tup, or ./build respectively).

Quick Start

The API is documented elsewhere and the best examples can be found in the feature tests. To build a simple hello app in C/C++ with a build description in Python:

from reggae import *
app = executable(name="hello", src_dirs=["."], compiler_flags="-g -O0")
b = Build(app)

Or in D:

import reggae;
alias app = executable!(ExeName("hello"), Sources!(["."]), Flags("-g -O"));
mixin build!app;

This shows how to use the executable high-level convenience rule. For custom behaviour the low-level primitives can be used. In D:

import reggae;
enum mainObj  = Target("main.o",  "gcc -I$project/src -c $in -o $out", Target("src/main.c"));
enum mathsObj = Target("maths.o", "gcc -c $in -o $out", Target("src/maths.c"));
enum app = Target("myapp", "gcc -o $out $in", [mainObj, mathsObj]);
mixin build!(app);

Or in Python:

from reggae import *
main_obj = Target("main.o",  "gcc -I$project/src -c $in -o $out", Target("src/main.c"))
maths_obj = Target("maths.o", "gcc -c $in -o $out", Target("src/maths.c"))
app = Target("myapp", "gcc -o $out $in", [mainObj, mathsObj])
bld = Build(app)

These wouldn't usually be used for compiling as above, since the high-level rules take care of that.

D projects and dub integration

The easiest dub integration is to run reggae with a directory containing a dub project as parameter. That will create a build system with a default target that would do the same as "dub build" but probably faster. An optional ut target corresponds to the unittest executable of "dub test". For example:

# one-time setup (assuming the current working dir is a dub project,
# i.e., contains a dub.{sdl,json} file):
mkdir build
cd build
reggae ..

# equivalent to "dub build":
ninja
# equivalent to "dub test -- <args>":
ninja ut && ./ut <args>
# build both default and unittest targets in parallel:
ninja default ut

For advanced use cases, reggae provides an API to use dub build information in a reggaefile.d build description file. A simple example for building production and unittest binaries concurrently is this:

import reggae;
alias main = dubDefaultTarget!(CompilerFlags("-g -debug"));
alias ut = dubConfigurationTarget!(Configuration("unittest"));
mixin build!(main, ut);

Scripting language limitations

Build written in one of the scripting languages currently:

  • Can only detect changes to the main build description file (e.g. reggaefile.py), but not any other files that were imported/required
  • Cannot use the binary backend
  • Do not have access to the dub high-level rules

These limitations are solely due to the features not having been implemented yet.

Building Reggae

To build reggae, you will need a D compiler. The dmd reference compiler is recommended. Reggae can build itself. To bootstrap, either use dub (dub build) or the included bootstrap script. Call it without arguments for make or with one to choose another backend, such as ninja. This will create a reggae binary in a bin directory then call itself to generate the "real" build system with the requested backend. The reggae-enabled build includes a unit test binary.

More Repositories

1

cmake-ide

Use Emacs as a C/C++ IDE
Emacs Lisp
714
star
2

dpp

Directly include C headers in D source code
D
229
star
3

unit-threaded

Advanced unit test framework for D
D
121
star
4

cerealed

Powerful binary serialisation library for D
D
91
star
5

automem

C++-style automatic memory management smart pointers for D
D
85
star
6

mqtt

MQTT broker written in D, using vibe.d
D
58
star
7

fearless

Safe concurrency in D (`shared` made easier)
D
50
star
8

mqttcpp

MQTT broker in C++11
C++
41
star
9

premock

Mock C functions using the preprocessor
C++
32
star
10

python-dpp-nanomsg

Automagically call nanomsg from Python with 2 lines of D code
Makefile
31
star
11

tardy

Runtime polymorphism without inheritance (structs, ints, classes, ...)
D
25
star
12

concepts

Concepts for d
D
22
star
13

mqtt_rs

MQTT broker in Rust
Rust
22
star
14

genomego

Multi-threaded Genetic Algorithms library for Go.
Go
21
star
15

ac-dcd

Auto completion for Emacs using DCD: the D completion daemon
Emacs Lisp
20
star
16

nogc

Utilities to write `@nogc` code
D
17
star
17

unencumbered

Enencumbered allows Cucumber to support step definitions written in D
D
15
star
18

flycheck-dmd-dub

flycheck and DCD dub support to enable D IDE features in Emacs
Emacs Lisp
14
star
19

mirror

Run and compile time reflection for D
D
10
star
20

libclang

libclang binding / wrapper for D
D
8
star
21

pythagoras

Pythagorean triples
D
8
star
22

cmake_modules

Modules for CMake
6
star
23

monty

Python C API for D
D
4
star
24

kwargs

Mimic keyword function arguments with types
D
4
star
25

genomed

Genetic Algorithms library for D
D
4
star
26

mqtt_hs

MQTT broker in Haskell
Haskell
4
star
27

dtest

Utility executable to be used with unit-threaded
D
3
star
28

felix

Category theory types inspired from Haskell
D
2
star
29

cereal

C++
1
star
30

scheme_hs

Write yourself a Scheme in Haskell
Haskell
1
star
31

test_allocator

D
1
star
32

all-dub-packages

Utility to get all dub packages that still build
D
1
star
33

unit-thread

C++
1
star
34

ldc-xcompile-windows

Scripts and tips to cross-compile D source files into Windows binaries from Linux using LDC
Shell
1
star