Giter Site home page Giter Site logo

atilaneves / reggae Goto Github PK

View Code? Open in Web Editor NEW
181.0 8.0 22.0 2.43 MB

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

License: BSD 3-Clause "New" or "Revised" License

Ruby 1.01% D 85.86% Shell 0.25% C++ 0.48% Python 1.80% Lua 7.81% JavaScript 0.93% Gherkin 1.21% Makefile 0.01% Batchfile 0.06% CMake 0.32% C 0.26%
d scripting-language tup ninja cmake python lua javascript dlang dlanguage build-tool build-system make makefile makefile-generation ruby meta-buildtool

reggae's Introduction

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 called reggaeBuild must exist that returns a Build object. 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.

reggae's People

Contributors

alexandrumc avatar atilaneves avatar benjaminschaaf avatar blackedder avatar burner avatar dependabot[bot] avatar drug007 avatar geod24 avatar john-colvin avatar johschmitz avatar kinke avatar rjframe avatar skoppe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reggae's Issues

Allow compiling dub projects in other directories than root

I had been building my project with Meson, but it stopped compiling due to a Meson bug. I thought that I could use Reggae instead, but I have Qt/C++ project in a root directory and my D project symlinked to subprojects/d-library so I can't use dubDefaultTarget. What about adding an optional argument to dubDefaultTarget for using a different root? I know that dub supports --root flag in the command line, so this should be possible.

Predefined file names can conflict with others

I run reggae in dir with cmake project and there is conflict between build dir, where cmake builds and build file generated by reggae. Using build name looks to be not comfortable, should be the way to avoid such conflicting.

Can't build with recent compilers

With ldc 1.13.0 (dmd frontent 2.083.1) and dmd 2.084.0 I get this error

reggae 0.6.3: building configuration "executable"...
/home/john/.dub/packages/reggae-0.6.3/reggae/payload/reggae/build.d(343,22): Error: template reggae.build.Target.getLanguage.any!((a) => a._outputs.length && (reggae.rules.common.getLanguage(a._outputs[0]) == language)).any cannot deduce function from argument types !()(const(Target[])), candidates are:
/usr/include/dlang/dmd/std/algorithm/searching.d(171,10):        reggae.build.Target.getLanguage.any!((a) => a._outputs.length && (reggae.rules.common.getLanguage(a._outputs[0]) == language)).any(Range)(Range range) if (isInputRange!Range && is(typeof(unaryFun!pred(range.front))))
/usr/bin/dmd failed with exit code 1.

Fails for excel-d v0.5.5

The default configuration on Linux has no targets, so trying to get the target name from it fails with a range error on configToDubFino["default"].targetName since there are no packages.

doesnt compile on windows

Fetching unit-threaded 0.7.28 (getting selected version)...
Performing "debug" build using dmd for x86.
reggae 0.5.13: building configuration "executable"...
payload\reggae\rules\common.d(307,9): Error: static assert "Can only create static libraries on Posix"
dmd failed with exit code 1.

[Question] How does Reggae _work_? Internal documentation please

I want to make a Reggae-like project. I really like the way the current one works, with the single import reggae; pulling in a whole build system that you can use, but there's a problem. I'm looking at the source, and I cannot tell where does Reggae start working up. It's not with the mixin build!(...); or a custom Build function, but some default code that executes when importing Reggae, that starts of the chain of functions that actually do stuff. Could you please explain (somewhere) how thing whole thing works? What does Reggae do with the reggaefile.d, how does the file work, etc. etc.

Improve clarity of "magic" rules

Currently higher level rules like dubMainTarget or dCompile are overly magical in both naming and implementation. It would improve learning curve a lot if reggae defined standard naming rules for higher level targets and separated their implementations in dedicated package/modules. Former would help to guess needed names without referring to documentaiton all the time, latter would provide nice examples of how one can define own higher level rules.

It is also worth noting that it isn't really important to go for shorter names for such symbols. Build systems are usually written once but read / maintained very often, as such, reading clarity and unambiguity takes absolute priority.

Support for D code in target actions

As discussed at DConf, I want to be able to define this snippet:

const fooObj = Target("foo.o", "dmd -c -offoo.o foo.d", [Target("foo.d")]);

as a D function instead:

@Target("foo.o", "foo.d")
void fooObj()
{
    import std.process;
    enforce(execute([ "dmd", "-c", "-of" ~ ThisTarget, ThisDeps ]).status == 0);
}

This is generally not necessary for simple rules like this but becomes more important once you start manipulate with paths and strings in your rules - this is very hard to define in cross-platform way by shell calls.

AFAIR you have confirmed that generation of ninja/make backend would still be possible with this feature as reggae can compile such functions into separate binaries during the backend generation step. It is hard to say how complicated it can be without diving deep into reggae sources.

Cannot build on Debian Sid with ldc2

I just pull 52b43dc which is tag: v0.5.16, and tried to build using Ninja and ldc2:

|> (export DMD=ldc2 ; bash -x ./bootstrap.sh ninja)
+ set -euo pipefail
+ '[' ninja '!=' '' ']'
+ BACKEND=ninja
+ COMP=ldc2
+ rm -rf bin
+ echo 'Compiling reggae'
Compiling reggae
+ ldc2 -ofbin/reggae -Isrc -Ipayload -Jpayload/reggae src/reggae/json_build.d src/reggae/reggae.d src/reggae/reggae_main.d src/reggae/dub/interop.d src/reggae/dub/json.d payload/reggae/backend/binary.d payload/reggae/backend/make.d payload/reggae/backend/ninja.d payload/reggae/backend/package.d payload/reggae/backend/tup.d payload/reggae/options.d payload/reggae/reflect.d payload/reggae/config.d payload/reggae/build.d payload/reggae/types.d payload/reggae/sorting.d payload/reggae/dependencies.d payload/reggae/range.d payload/reggae/buildgen.d payload/reggae/package.d payload/reggae/ctaa.d payload/reggae/file.d payload/reggae/rules/c_and_cpp.d payload/reggae/rules/common.d payload/reggae/rules/d.d payload/reggae/rules/dub.d payload/reggae/rules/package.d payload/reggae/core/package.d payload/reggae/core/rules/package.d payload/reggae/dub/info.d
+ cd bin
+ echo 'Running boostrapped reggae with backend ninja'
Running boostrapped reggae with backend ninja
+ ./reggae -b ninja --dc=ldc2 ..
[Reggae] Writing reggae source files
[Reggae] Writing reggae configuration
[Reggae] Writing dub configuration
[Reggae] Compiling metabuild binary dcompile
[Reggae] Compiling metabuild binary build.o
Couldn't execute ./dcompile --objFile=build.o --depFile=reggaefile.dep ldc2 -I/home/Checkouts/Git/Reggae -Isrc -g -debug /home/Checkouts/Git/Reggae/reggaefile.d src/reggae/config.d src/reggae/options.d src/reggae/buildgen_main.d src/reggae/buildgen.d src/reggae/build.d src/reggae/backend/package.d src/reggae/backend/binary.d src/reggae/package.d src/reggae/range.d src/reggae/reflect.d src/reggae/dependencies.d src/reggae/types.d src/reggae/ctaa.d src/reggae/sorting.d src/reggae/file.d src/reggae/rules/package.d src/reggae/rules/common.d src/reggae/rules/d.d src/reggae/rules/c_and_cpp.d src/reggae/core/package.d src/reggae/core/rules/package.d src/reggae/backend/ninja.d src/reggae/backend/make.d src/reggae/backend/tup.d src/reggae/dub/info.d src/reggae/rules/dub.d
in /home/Checkouts/Git/Reggae/bin/.reggae:
Could not compile with args:
ldc2 -I/home/Checkouts/Git/Reggae -Isrc -g -debug /home/Checkouts/Git/Reggae/reggaefile.d src/reggae/config.d src/reggae/options.d src/reggae/buildgen_main.d src/reggae/buildgen.d src/reggae/build.d src/reggae/backend/package.d src/reggae/backend/binary.d src/reggae/package.d src/reggae/range.d src/reggae/reflect.d src/reggae/dependencies.d src/reggae/types.d src/reggae/ctaa.d src/reggae/sorting.d src/reggae/file.d src/reggae/rules/package.d src/reggae/rules/common.d src/reggae/rules/d.d src/reggae/rules/c_and_cpp.d src/reggae/core/package.d src/reggae/core/rules/package.d src/reggae/backend/ninja.d src/reggae/backend/make.d src/reggae/backend/tup.d src/reggae/dub/info.d src/reggae/rules/dub.d -ofbuild.o -c
ldc2: Unknown command line argument '-debug'.  Try: '/usr/bin/ldc2 -help'
ldc2: Did you mean '-d-debug'?


bin.name: build.o, bin.cmd: ./dcompile --objFile=build.o --depFile=reggaefile.dep ldc2 -I/home/Checkouts/Git/Reggae -Isrc -g -debug /home/Checkouts/Git/Reggae/reggaefile.d src/reggae/config.d src/reggae/options.d src/reggae/buildgen_main.d src/reggae/buildgen.d src/reggae/build.d src/reggae/backend/package.d src/reggae/backend/binary.d src/reggae/package.d src/reggae/range.d src/reggae/reflect.d src/reggae/dependencies.d src/reggae/types.d src/reggae/ctaa.d src/reggae/sorting.d src/reggae/file.d src/reggae/rules/package.d src/reggae/rules/common.d src/reggae/rules/d.d src/reggae/rules/c_and_cpp.d src/reggae/core/package.d src/reggae/core/rules/package.d src/reggae/backend/ninja.d src/reggae/backend/make.d src/reggae/backend/tup.d src/reggae/dub/info.d src/reggae/rules/dub.d

Building projects depending on dub

As I understand it, reggae won't currently build more complex dub projects like vibe-d because it doesn't implement the full dub build rules. Please correct me if I am wrong (and if you can show logic to build one of the vibe-d examples using reggae that would be great).

That's fine because one can just build them separately, set the import paths so the project is found, and static link to the library files. However dub projects put the source files in different locations (sometimes its source, sometimes src, sometimes deimos, and sometimes there is an additional degree of nesting). One can't read the file system at compile time.

Is there a way to do what I want? Use reggae to build my own projects - these being composed of multiple static libraries and some source files depending on them, but also everything depending on some code.dlang.org modules, including, but not only vibe-d.

Thanks.

Laeeth.

Default executable name from dubTestTarget can be confusing

By default the unittests are written into an ut executable which could be confusing to a new user.

Maybe calling it unittest or runtest would be more obvious to what it is.

Alternatively calling it APPLICATION_NAME-test by default would be more dub compatible and easier to migrate to for dub users. The dubDefaultTarget right now emits the same executable name as dub after all

[Minor] Do not show stack trace in some cases

If I do run reggae without backend specified it tries to run but failed with message:

Running ../../.dub/packages/reggae-0.5.17/reggae/bin/reggae 
[Reggae] Writing reggae source files
[Reggae] Writing reggae configuration
[Reggae] Writing dub configuration
[Reggae] Compiling metabuild binary dcompile
[Reggae] Compiling metabuild binary build.o
[Reggae] Compiling metabuild binary buildgen
[Reggae] Running the created binary to generate the build
Couldn't execute the produced buildgen binary:
object.Exception@src/reggae/buildgen.d(119): A backend must be specified with -b/--backend
----------------
??:? void reggae.buildgen.doOneBuild(reggae.build.Build, const(reggae.options.Options), immutable(char)[][]) [0x5b7654a8]
??:? void reggae.buildgen.doBuild(reggae.build.Build, const(reggae.options.Options), immutable(char)[][]) [0x5b765339]
??:? void reggae.buildgen.doBuildFor!("reggaefile").doBuildFor(const(reggae.options.Options), immutable(char)[][]) [0x5b765af4]
??:? _Dmain [0x5b76519a]
??:? _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv [0x5b80d483]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x5b80d3ab]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() [0x5b80d428]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x5b80d3ab]
??:? _d_run_main [0x5b80d317]
??:? main [0x5b7652a1]
??:? __libc_start_main [0x1e73c1c0]

Program exited with code 1

I'm sure stacktrace is excessive here. Is there a way to strip stacktrack from exception message (in ReggaeMain template for example)? Or do not add it to.

Add API docs

I'm hopeful for this tool. Please generate some API documentation to make it more convenient to assess its value.

Cannot bootstrap with latest version

Running ./bootstrap.sh ninja fails with the following message:

Could not compile with args:
dmd -version=Have_reggae -m64 -g -debug -w -cov -unittest -I/home/elronnd/code/reggae -I/home/elronnd/code/reggae/payload -I/home/elronnd/code/reggae/src -J/home/elronnd/code/reggae/payload/reggae /home/elronnd/code/reggae/payload/reggae/backend/binary.d /home/elronnd/code/reggae/payload/reggae/backend/make.d /home/elronnd/code/reggae/payload/reggae/backend/ninja.d /home/elronnd/code/reggae/payload/reggae/backend/package.d /home/elronnd/code/reggae/payload/reggae/backend/tup.d /home/elronnd/code/reggae/payload/reggae/build.d /home/elronnd/code/reggae/payload/reggae/buildgen.d /home/elronnd/code/reggae/payload/reggae/config.d /home/elronnd/code/reggae/payload/reggae/core/package.d /home/elronnd/code/reggae/payload/reggae/core/rules/package.d /home/elronnd/code/reggae/payload/reggae/ctaa.d /home/elronnd/code/reggae/payload/reggae/dependencies.d /home/elronnd/code/reggae/payload/reggae/dub/info.d /home/elronnd/code/reggae/payload/reggae/file.d /home/elronnd/code/reggae/payload/reggae/options.d /home/elronnd/code/reggae/payload/reggae/package.d /home/elronnd/code/reggae/payload/reggae/path.d /home/elronnd/code/reggae/payload/reggae/range.d /home/elronnd/code/reggae/payload/reggae/reflect.d /home/elronnd/code/reggae/payload/reggae/rules/c_and_cpp.d /home/elronnd/code/reggae/payload/reggae/rules/common.d /home/elronnd/code/reggae/payload/reggae/rules/d.d /home/elronnd/code/reggae/payload/reggae/rules/dub.d /home/elronnd/code/reggae/payload/reggae/rules/package.d /home/elronnd/code/reggae/payload/reggae/sorting.d /home/elronnd/code/reggae/payload/reggae/types.d /home/elronnd/code/reggae/src/reggae/dub/interop.d /home/elronnd/code/reggae/src/reggae/dub/json.d /home/elronnd/code/reggae/src/reggae/from.d /home/elronnd/code/reggae/src/reggae/io.d /home/elronnd/code/reggae/src/reggae/json_build.d /home/elronnd/code/reggae/src/reggae/reggae.d /home/elronnd/code/reggae/src/reggae/reggae_main.d -of.reggae/objs/ut.objs/home/elronnd/code/reggae/payload/reggae/backend.o -c
/home/elronnd/code/reggae/tests/utils.d(4): Error: module `unit_threaded` is in file 'unit_threaded.d' which cannot be read
import path[0] = /home/elronnd/code/reggae
import path[1] = /home/elronnd/code/reggae/payload
import path[2] = /home/elronnd/code/reggae/src
import path[3] = /usr/include/dlang/dmd

Linking to c from dub build

I am trying to get reggae working for https://github.com/cairoD/cairoD but get linking errors when trying the separate unittest build.

My reggaefile.d looks as follows:

import reggae;
alias main = dubDefaultTarget!();
alias ut = dubConfigurationTarget!(ExeName("ut"), Configuration("unittest-minimal"));
mixin build!(ut);

This works fine if I use mixin build!(main), but fails on mixin build!(ut). It seems because it doesn't link correctly to libcairo, even though libcairo is specified as "libs" in the dub.json configuration. Top of the errors:

.reggae/dcompile --objFile=objs/ut.objs/home/edwin/.dub/packages/derelict-util-
2.0.4/source/derelict/util.o --depFile=objs/ut.objs/home/edwin/.dub/packages/de
relict-util-2.0.4/source/derelict/util.o.dep dmd  -I/home/edwin/Documents/code/
cairoD/src/ -I/home/edwin/.dub/packages/x11-1.0.9/source/ -I/home/edwin/.dub/pa
ckages/derelict-ft-1.0.2/source/ -I/home/edwin/.dub/packages/derelict-util-2.0.
4/source/ -I/home/edwin/Documents/code/cairoD/./  /home/edwin/.dub/packages/der
elict-util-2.0.4/source/derelict/util/exception.d /home/edwin/.dub/packages/der
elict-util-2.0.4/source/derelict/util/loader.d /home/edwin/.dub/packages/dereli
ct-util-2.0.4/source/derelict/util/sharedlib.d /home/edwin/.dub/packages/dereli
ct-util-2.0.4/source/derelict/util/system.d /home/edwin/.dub/packages/derelict-
util-2.0.4/source/derelict/util/wintypes.d /home/edwin/.dub/packages/derelict-u
til-2.0.4/source/derelict/util/xtypes.d
dmd -ofut  objs/ut.objs/home/edwin/Documents/code/cairoD/src/cairo/c.o objs/ut.
objs/home/edwin/Documents/code/cairoD.o objs/ut.objs/home/edwin/Documents/code/
cairoD/src/cairo.o objs/ut.objs/home/edwin/.dub/packages/x11-1.0.9/source/x11/e
xtensions.o objs/ut.objs/home/edwin/.dub/packages/x11-1.0.9/source/x11.o objs/u
t.objs/home/edwin/.dub/packages/derelict-ft-1.0.2/source/derelict/freetype.o ob
js/ut.objs/home/edwin/.dub/packages/derelict-util-2.0.4/source/derelict/util.o
objs/ut.objs/home/edwin/Documents/code/cairoD/src/cairo.o: In function `_D5cair
o5cairo14CairoException6__ctorMFE5cairo1c5cairo14cairo_status_tAyaiZC5cairo5cai
ro14CairoException':
/home/edwin/Documents/code/cairoD/src/cairo/xlib.d:(.text._D5cairo5cairo14Cairo
Exception6__ctorMFE5cairo1c5cairo14cairo_status_tAyaiZC5cairo5cairo14CairoExcep
tion+0x38): undefined reference to `cairo_status_to_string'
objs/ut.objs/home/edwin/Documents/code/cairoD/src/cairo.o: In function `_D5cair
o5cairo4Path7Payload6__dtorMFZv':
/home/edwin/Documents/code/cairoD/src/cairo/xlib.d:(.text._D5cairo5cairo4Path7P
ayload6__dtorMFZv+0x16): undefined reference to `cairo_path_destroy'
objs/ut.objs/home/edwin/Documents/code/cairoD/src/cairo.o: In function `_D5cair
o5cairo6Matrix6__ctorMFNcddddddZS5cairo5cairo6Matrix':
/home/edwin/Documents/code/cairoD/src/cairo/xlib.d:(.text._D5cairo5cairo6Matrix
6__ctorMFNcddddddZS5cairo5cairo6Matrix+0x4c): undefined reference to `cairo_mat
rix_init'

doesn't work with my libs

Make a simple little dub package:

dub.json

{
        "name": "dubtest",
        "dependencies": {
                "arsd-official:nanovega" : "*"
        }
}

source/app.d

import arsd.simpledisplay;
import arsd.nanovega;

void main () {
}

dub run works, doing nothing of course.

$ dub run reggae -- -b make

seems to work but then

$ make

spams undefined reference; it apparently didn't link in the library modules.

$  dub run reggae -- -b ninja
$ ninja
ninja: error: build.ninja:18: multiple rules generate .reggae/objs/dubtest.objs/home/me/.dub/packages/arsd-official-4.3.4/arsd-official.o [-w dupbuild=err]

Get Reggae into the Debian and Fedora distributions

Perhaps the people putting LDC into Debian and Fedora could be inveigled upon to add Reggae to their list so as to get it into those distributions?

Debian and I think Fedora have a policy they will only package things for which the toolchain for building is packaged.

-C option doesn't work with multiple build files

Say you take the rerun_itself.feature test but instead of running reggae -b ninja proj/ you run reggae -b ninja -C build/ linking will fail with the following error:

Couldn't execute dmd -ofbuildgen build.o
reggae_test/build/.reggae:
build.o:(.data.rel.ro+0x10): undefined reference to `_D3src8builddef12__ModuleInfoZ'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1

bin.name: buildgen, bin.cmd: dmd -ofbuildgen build.o

Same target built multiple times

Simple example:

import reggae;

const ao = objectFile(SourceFile("a.c"));
const bo = objectFile(SourceFile("b.c"));
const co = objectFile(SourceFile("c.c"));
const t1 = Target("b", "gcc -o$out $in", [ao, bo]);
const t2 = Target("c", "gcc -o$out $in", [ao, co]);
mixin build!(t1, t2);

a.c will be compiled twice, which is unnecessary.

cannot read uninitialized variable packages in CTFE

src/reggae/dub/info.d(233): Error: cannot read uninitialized variable packages in CTFE
src/reggae/rules/dub.d(43):        called from here: DubInfo().targetName()
src/reggae/dub/info.d(244): Error: cannot read uninitialized variable packages in CTFE
src/reggae/rules/dub.d(44):        called from here: DubInfo().mainLinkerFlags()

struggling to make a small test case, happens in a kaleidic package.

Can't set executable as dependency

This is a common use case for code generation, the code generation Target needs to depend on the tool used to generate the code.

And the executable() function is not usable at compile time

Minimize 3d party dependencies

If this tool is to be advertised as a standard build system for D, it needs to be able to build and run tests with minimal to no external dependencies. I know you love cucumber but this can easily become a contribution blocker if project is to be maintained as part of D-Programming-Language organization :)

Python support

For non-D developers, have a Python interface to reggae so build descriptions can be written in Python.

preBuildCommands only run once

So that if unit-threaded is generating the file for the unit tests, adding a new file does not cause the main file to be updated.

Support MethodInitializer syntax?

In DMD I added an interesting way to initialize "make rules" in build.d (https://github.com/dlang/dmd/blob/master/src/build.d). here's an example:

alias backend = makeRule!((builder, rule) => builder
    .name("backend")
    .target(env["G"].buildPath("backend").objName)
    .sources(sources.backend)
    .msg("(DC) BACKEND_OBJ")
    .command([
        env["HOST_DMD_RUN"],
        "-c",
        "-of" ~ rule.target,
        "-betterC"]
        .chain(flags["DFLAGS"], rule.sources).array)
);

If reggae were to support the same syntax, the following:

alias app = executable!(
    ExeName("example"),
    Sources!(cast(string[])null, Files("../../example.d")),
    Flags("-g -debug"),
    ImportPaths(["../src_hresult",
        "../src_cstring",
        "../../out/DerelictUtil/source",
        "../src_coreclr",
        "../src_clr",
        "../src_clrbridge",
        "../../out/dlibs/src",
    ])
);

could become:

alias app = executable!(e => e
    .ExeName("example")
    .Sources(cast(string[])null, Files("../../example.d"))
    .Flags("-g -debug")
    .ImportPaths(["../src_hresult",
        "../src_cstring",
        "../../out/DerelictUtil/source",
        "../src_coreclr",
        "../src_clr",
        "../src_clrbridge",
        "../../out/dlibs/src",
    ])
);
``

The code to support the syntax is here:

/** Initializes an object using a chain of method calls */
struct MethodInitializer(T) if (is(T == class)) // currenly only works with classes
{
    private T obj;
    auto ref opDispatch(string name)(typeof(__traits(getMember, T, name)) arg)
    {
        mixin("obj." ~ name ~ " = arg;");
        return this;
    }
}
/** Create an object using a chain of method calls for each field. */
T methodInit(T, alias Func, Args...)(Args args) if (is(T == class)) // currently only works with classes
{
    auto initializer = MethodInitializer!T(new T());
    Func(initializer, initializer.obj, args);
    initializer.obj.finalize();
    return initializer.obj;
}

It turned out to be a nice syntax/mechanism for build.d. It almost emulates named parameter semantics. It allows

  • configuration in any order
  • cross-referencing data between fields
  • no need to modify surrounding lines to add/remove new configuration (don't have to worry about the comma , character to separate function arguments)

Runtime reggae crash when using dub file with no targetType

Steps to reproduce:

[/tmp]$ mkdir test

[/tmp]$ cd test

[/tmp/test]$ dub init
Successfully created an empty project in '/tmp/test'.

[/tmp/test]$ # reggae commit 7a9da1f5a78b16e6383a59fc256dd3772a917ac7

[/tmp/test]$ reggae ./dub.sdl
Could not find /tmp/test/./dub.sdl/reggaefile.d

[/tmp/test]$ reggae -b binary .
[Reggae] Creating reggaefile.d from dub information
[Reggae] Writing reggae source files
core.exception.RangeError@/tmp/reggae/src/reggae/dub/json.d(50): Range violation
----------------
??:? _d_arraybounds [0x757d3f]
??:? reggae.dub.json.__array [0x754fcf]
/tmp/reggae/src/reggae/dub/json.d:50 pure @trusted std.json.JSONValue reggae.dub.json.byKey(std.json.JSONValue, const(immutable(char)[])) [0x7527cd]
/tmp/reggae/src/reggae/dub/json.d:15 @trusted reggae.dub.info.DubInfo reggae.dub.json.getDubInfo(immutable(char)[]) [0x752636]
/tmp/reggae/src/reggae/dub/interop.d:51 @safe reggae.dub.info.DubInfo reggae.dub.interop._getDubInfo(const(reggae.options.Options)) [0x749b9f]
/tmp/reggae/src/reggae/dub/interop.d:114 @safe void reggae.dub.interop.writeDubConfig(const(reggae.options.Options), std.stdio.File) [0x74a35c]
/tmp/reggae/src/reggae/reggae.d:332 void reggae.reggae.writeConfig(const(reggae.options.Options)) [0x6d784c]
/tmp/reggae/src/reggae/reggae.d:309 void reggae.reggae.writeSrcFiles(const(reggae.options.Options)) [0x6d7712]
/tmp/reggae/src/reggae/reggae.d:170 void reggae.reggae.createBuild(const(reggae.options.Options)) [0x6d5576]
/tmp/reggae/src/reggae/reggae.d:72 void reggae.reggae.run(reggae.options.Options) [0x6d4ade]
/tmp/reggae/src/reggae/reggae.d:52 _Dmain [0x6d882f]
??:? _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv [0x759e56]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x759d94]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() [0x759e12]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x759d94]
??:? _d_run_main [0x759cf1]
??:? main [0x6d892f]
??:? __libc_start_main [0x5469970f]

[/tmp/test]$ echo 'targetType "executable"' >> dub.sdl

[/tmp/test]$ reggae -b binary .
[Reggae] Writing reggae source files
[Reggae] Compiling metabuild binary .reggae/dcompile
[Reggae] Compiling metabuild binary build.o
[Reggae] Compiling metabuild binary build

[/tmp/test]$

dubConfigurationTarget doesn't work well with `unittest` configuration

This:

import reggae;
alias ut = dubConfigurationTarget!(ExeName("ut"), Configuration("unittest"), Flags("-g -debug -cov"));
mixin build!ut;

Doesn't work exactly like dub test. The reason is that dub test adds the -unittest flag to every file in the main package and the equivalent reggae build doesn't. Adding -unittest manually to Flags above makes it worse; in that case it only compiles all files (including dependencies) with the flag turned on, which can cause link errors and/or spending time running "foreign" unit tests.

$builddir not expanded when target is not builtin as dependency

In this example, $builddir in target liba is expanded,

import reggae;

const ao = objectFile(SourceFile("a.c"));
const liba = Target("$builddir/liba.a", "ar rcs liba.a a.o", [ao]);
const bo = objectFile(SourceFile("b.c"));
const co = objectFile(SourceFile("c.c"));
const t1 = Target("b", "gcc -o$out $in", [liba, bo]);
const t2 = Target("c", "gcc -o$out $in", [liba, co]);
mixin build!(t1, t2);

But in this example, it is not:

import reggae;

const ao = objectFile(SourceFile("a.c"));
const liba = Target("$builddir/liba.a", "ar rcs liba.a a.o", [ao]);
mixin build!(liba);

Can't bootstrap on a system without dmd

|> DMD=ldmd2 ./bootstrap.sh ninja
Compiling reggae
Running boostrapped reggae with backend ninja
[Reggae] Writing reggae source files
[Reggae] Writing reggae configuration
[Reggae] Writing dub configuration
[Reggae] Calling 'dub fetch' since getting the configuration failed
[Reggae] Fetching package with command 'dub fetch unit-threaded --version=0.7.11'
Could not write dub configuration, try 'dub upgrade': Error calling dub --annotate build --compiler=dmd --print-configs --build=docs:
Failed to invoke the compiler dmd to determine the build platform: /bin/sh: dmd: command not found


Error calling dub --annotate build --compiler=dmd --print-configs --build=docs:
Failed to invoke the compiler dmd to determine the build platform: /bin/sh: dmd: command not found

How to use environment variables/runtime reggaefiles

If I try to get an environment variable to use in my reggaefile, by using std.process.environment.get, I can't build it because the source for getenv is not available at compile-time. This could be remedied by providing some way to process reggae files without CTFE, which I'm not sure reggae currently supports, or provide some other way to access those env vars at compile-time. What do you suggest?

Either way, this project would really benefit from some examples. The written docs and unit tests cover many of the features, but nothing shows how to do things like some non-trivial examples.

Build on Debian Sid fails using DMD

I just pulled to pick up the lastest changes, I am now on 52b43dc which is tagged 0.5.16. I tried to do a bootstrap build with Ninja:

|> ./bootstrap.sh ninja
Compiling reggae
Running boostrapped reggae with backend ninja
[Reggae] Writing reggae source files
[Reggae] Writing reggae configuration
[Reggae] Writing dub configuration
[Reggae] Compiling metabuild binary dcompile
[Reggae] Compiling metabuild binary build.o
[Reggae] Compiling metabuild binary buildgen
[Reggae] Running the created binary to generate the build

[12/12] dmd -ofut  .reggae/objs/ut.objs/home/Checkouts/Git/Reggae/bin.o .reggae/objs/ut...me/users/russel/.dub/packages/unit-threaded-0.7.28/unit-threaded/source/unit_threaded.o
FAILED: ut 
dmd -ofut  .reggae/objs/ut.objs/home/Checkouts/Git/Reggae/bin.o .reggae/objs/ut.objs/home/users/russel/.dub/packages/unit-threaded-0.7.28/unit-threaded/source/unit_threaded.o
/usr/bin/ld: .reggae/objs/ut.objs/home/Checkouts/Git/Reggae/bin.o: SHT_GROUP section [index 26410] has no SHF_GROUP sections
/usr/bin/ld: .reggae/objs/ut.objs/home/Checkouts/Git/Reggae/bin.o: SHT_GROUP section [index 26411] has no SHF_GROUP sections
/usr/bin/ld: .reggae/objs/ut.objs/home/Checkouts/Git/Reggae/bin.o: SHT_GROUP section [index 26410] has no SHF_GROUP sections
/usr/bin/ld: .reggae/objs/ut.objs/home/Checkouts/Git/Reggae/bin.o: SHT_GROUP section [index 26411] has no SHF_GROUP sections
/usr/bin/ld: .reggae/objs/ut.objs/home/Checkouts/Git/Reggae/bin.o: SHT_GROUP section [index 26410] has no SHF_GROUP sections
/usr/bin/ld: .reggae/objs/ut.objs/home/Checkouts/Git/Reggae/bin.o: SHT_GROUP section [index 26411] has no SHF_GROUP sections
/usr/bin/ld: .reggae/objs/ut.objs/home/Checkouts/Git/Reggae/bin.o: SHT_GROUP section [index 26410] has no SHF_GROUP sections
/usr/bin/ld: .reggae/objs/ut.objs/home/Checkouts/Git/Reggae/bin.o: SHT_GROUP section [index 26411] has no SHF_GROUP sections
.reggae/objs/ut.objs/home/Checkouts/Git/Reggae/bin.o: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
Error: linker exited with status 1
ninja: build stopped: subcommand failed.

I get DMD from D-Apt:

|> which dmd
/usr/bin/dmd

|> dmd
DMD64 D Compiler v2.075.0
Copyright (c) 1999-2017 by Digital Mars written by Walter Bright

Support python 2 and 3

Some Linux distributions (e.g., Ubuntu) make the "python" executable refer to python 2 and "python3" is python 3; Others, like Arch, make "python" python 3 and "python2" python 2. I'd like to use v3 for my reggaefile in a project consistently but this requires some work...

What makes sense to me is to look for something like a "REGGAE_PYTHON" environment variable that points to the python path, and call python via that value; if the variable doesn't exist, just call "python" like reggae does now. I can export my python path, but this doesn't mess up anyone that doesn't care, and we don't try to guess anything.

I can do the work for this, but don't know how you'd want it done.

Implement binary/D backend

One of primary goals for going for D build system is to remove all build dependencies but D compiler / standard library. It should be possible to do full build without relying on ninja / make - initially it is ok to even be considerably slower than those.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.