- Notifications
You must be signed in to change notification settings - Fork23
Build system in D, Python, Ruby, Javascript or Lua
License
atilaneves/reggae
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
A (meta) build system with multiple front (D, Python, Ruby,Javascript, Lua) and backends (make, ninja, tup, custom).
Detailed API documentation can be foundhere.
Do we really need another build system? Yes.
On the frontend side, take CMake. CMake is pretty awesome. CMake'slanguage, on the other hand, is awful. Many other build systems usetheir own proprietary languages that you have to learn to be able touse them. I think that using a good tried-and-true general purposeprogramming language is better, with an API that is declarative asmuch as possible.
On the backend, it irks me that wanting to use tup means tying myselfto it. Wouldn't it be nice to describe the build in my language ofchoice and be able to choose between tup and ninja as an afterthought?
I also wanted something that makes it easy to integrate differentlanguages together. Mixing D and C/C++ is usually a bit painful, forinstance. In the future it may include support for other staticallycompiled languages. PRs welcome!
reggae is really a flexible DAG describing API that happens to be goodat building software.
- Multiple frontends: write readable and concise build descriptions inD,Python,Ruby,JavaScriptorLua. 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 withouthaving 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 codecommands (as opposed to shell commands) are only supported by thebinary backend, and due to tup's nature dub support and a few otherfeatures are not available. When using the tup backend, simple isbetter.
The recommended backend is ninja. If writing build descriptions in D,the binary backend is also recommended.
Pick a language to write your description in and place a file calledreggaefile.{d,py,rb,js,lua}
at the root of your project.
In one of the scripting languages, a global variable with the typereggae.Build
must exist with any name. Also, the relevantlanguage-specific package can be installed using pip, gem, npm orluarocks to install the reggae package (reggae-js for npm). This isnot required; the reggae binary includes the API for all scriptinglanguages.
In D, a function calledreggaeBuild
must exist that returns aBuild
object. Normally this function isn't written by hand but byusing thebuild template mixin.
From the the build directory, runreggae [-b <ninja|make|tup|binary>] /path/to/your/project
. You can now build your project using theappropriate command (ninja, make, tup, or ./build respectively).
The API is documentedelsewhere and the best examplescan be found in thefeature tests. To build a simple helloapp in C/C++ with a build description in Python:
fromreggaeimport*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 theexecutable
high-level convenience rule. For custom behaviourthe 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:
fromreggaeimport*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.
The easiest dub integration is to run reggae with a directorycontaining a dub project as parameter. That will create a build systemwith a default target that would do the same as "dub build" but probablyfaster. An optionalut
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 buildcd buildreggae ..# 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 informationin areggaefile.d
build description file. A simple example for buildingproduction and unittest binaries concurrently is this:
import reggae;alias main = dubBuild!(CompilerFlags("-g -debug"));alias ut = dubBuild!(Configuration("unittest"));mixin build!(main, ut);
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.
To build reggae, you will need a D compiler. The dmd referencecompiler is recommended. Reggae can build itself. To bootstrap,either use dub (dub build) or theincluded bootstrap script. Call it without argumentsformake
or with one to choose another backend, such asninja
. This will create areggae
binary in abin
directory thencall itself to generate the "real" build system with the requestedbackend. The reggae-enabled build includes a unit test binary.
About
Build system in D, Python, Ruby, Javascript or Lua