reggae icon indicating copy to clipboard operation
reggae copied to clipboard

dub + Ninja: Phony targets don't work properly

Open kinke opened this issue 3 years ago • 4 comments

For some little dub test project, the following reggaefile.d:

import reggae;

alias buildTarget = dubDefaultTarget!(); // dub build
alias testTarget = dubTestTarget!();     // dub test (=> ut[.exe])
mixin build!(buildTarget, optional!testTarget);

yields the following (fine) build.ninja:

include rules.ninja
# Automatically generated by reggae version 0.5.24+
# Do not edit by hand
build .reggae\objs\dub$ with$ spaces.exe.objs\dev\test\my$ source_modc.obj: _dcompile C$:\dev\test\my$ source\modc.d C$:\dev\test\my$ source\my$ module.d C$:\dev\test\my$ source\other_module.d
  includes = -IC:\dev\test "-IC:\dev\test\my source"
  flags = "-L/LIBPATH:my libs" -d-debug -g -w -oq -od=.dub/obj -version=Have_dub_with_spaces

build dub$ with$ spaces.exe: _dlink .reggae\objs\dub$ with$ spaces.exe.objs\dev\test\my$ source_modc.obj
  flags = "-L/LIBPATH:my other libs" "-L/LIBPATH:my libs" -g

build .reggae\objs\ut.exe.objs\dev\test\my$ source_modc.obj: _dcompile C$:\dev\test\my$ source\modc.d C$:\dev\test\my$ source\my$ module.d C$:\dev\test\my$ source\other_module.d
  includes = -IC:\dev\test "-IC:\dev\test\my source"
  flags = "-L/LIBPATH:my libs" -d-debug -g -w -oq -od=.dub/obj -version=Have_dub_with_spaces -unittest

build ut.exe: _dlink .reggae\objs\ut.exe.objs\dev\test\my$ source_modc.obj
  flags = "-L/LIBPATH:my other libs" "-L/LIBPATH:my libs" -g

build build.ninja: _rerun | C$:\Users\IEUser\AppData\Local\dub\packages\reggae-master\reggae\bin\reggae.exe C$:\dev\test\reggaefile.d C$:\dev\test\dub.sdl C$:\dev\test\dub.selections.json
  pool = console

default dub$ with$ spaces.exe

With a more advanced reggaefile.d:

import reggae;

alias buildTarget = dubDefaultTarget!(); // dub build
alias testTarget = dubTestTarget!();     // dub test (=> ut[.exe])

alias defaultTarget = phony!("default", "", buildTarget);

version (Windows) {
    // Windows: extra `ut` convenience alias for `ut.exe`
    alias utTarget = phony!("ut", "", testTarget);
    mixin build!(optional!buildTarget, optional!testTarget,
                 defaultTarget, optional!utTarget);
} else {
    mixin build!(optional!buildTarget, optional!testTarget, defaultTarget);
}

I was expecting the following additions/changes on Windows:

build default: phony dub$ with$ spaces.exe
  pool = console

build ut: phony ut.exe
  pool = console

default default

But alas, this is what's generated:

include rules.ninja
# Automatically generated by reggae version 0.5.24+
# Do not edit by hand
build .reggae\objs\dub$ with$ spaces.exe.objs\dev\test\my$ source_modc.obj: _dcompile C$:\dev\test\my$ source\modc.d C$:\dev\test\my$ source\my$ module.d C$:\dev\test\my$ source\other_module.d
  includes = -IC:\dev\test "-IC:\dev\test\my source"
  flags = "-L/LIBPATH:my libs" -d-debug -g -w -oq -od=.dub/obj -version=Have_dub_with_spaces

build dub$ with$ spaces.exe: _dlink .reggae\objs\dub$ with$ spaces.exe.objs\dev\test\my$ source_modc.obj
  flags = "-L/LIBPATH:my other libs" "-L/LIBPATH:my libs" -g

build .reggae\objs\ut.exe.objs\dev\test\my$ source_modc.obj: _dcompile C$:\dev\test\my$ source\modc.d C$:\dev\test\my$ source\my$ module.d C$:\dev\test\my$ source\other_module.d
  includes = -IC:\dev\test "-IC:\dev\test\my source"
  flags = "-L/LIBPATH:my libs" -d-debug -g -w -oq -od=.dub/obj -version=Have_dub_with_spaces -unittest

build ut.exe: _dlink .reggae\objs\ut.exe.objs\dev\test\my$ source_modc.obj
  flags = "-L/LIBPATH:my other libs" "-L/LIBPATH:my libs" -g

build .reggae\objs\default.objs\dev\test\my$ source_modc.obj: _dcompile C$:\dev\test\my$ source\modc.d C$:\dev\test\my$ source\my$ module.d C$:\dev\test\my$ source\other_module.d
  includes = -IC:\dev\test "-IC:\dev\test\my source"
  flags = "-L/LIBPATH:my libs" -d-debug -g -w -oq -od=.dub/obj -version=Have_dub_with_spaces

build .reggae\objs\default.objs\dub$ with$ spaces.exe: _dlink .reggae\objs\default.objs\dev\test\my$ source_modc.obj
  flags = "-L/LIBPATH:my other libs" "-L/LIBPATH:my libs" -g

build default: phony .reggae\objs\default.objs\dub$ with$ spaces.exe
  pool = console

build .reggae\objs\ut.objs\dev\test\my$ source_modc.obj: _dcompile C$:\dev\test\my$ source\modc.d C$:\dev\test\my$ source\my$ module.d C$:\dev\test\my$ source\other_module.d
  includes = -IC:\dev\test "-IC:\dev\test\my source"
  flags = "-L/LIBPATH:my libs" -d-debug -g -w -oq -od=.dub/obj -version=Have_dub_with_spaces -unittest

build .reggae\objs\ut.objs\ut.exe: _dlink .reggae\objs\ut.objs\dev\test\my$ source_modc.obj
  flags = "-L/LIBPATH:my other libs" "-L/LIBPATH:my libs" -g

build ut: phony .reggae\objs\ut.objs\ut.exe
  pool = console

build build.ninja: _rerun | C$:\Users\IEUser\AppData\Local\dub\packages\reggae-master\reggae\bin\reggae.exe C$:\dev\test\reggaefile.d C$:\dev\test\dub.sdl C$:\dev\test\dub.selections.json
  pool = console

default default

kinke avatar Jan 26 '21 14:01 kinke

After quite a bit of wrangling, I got it to do what I wanted:

import reggae;

alias buildTarget = dubDefaultTarget!(); // dub build
alias testTarget = dubTestTarget!();     // dub test (=> ut[.exe])

Target aliasTarget(string aliasName, alias target)()
{
    import std.algorithm: map;
    // Using leaf targets `$builddir/<raw output>` as dependencies
    // yields the expected relative target names for Ninja/make.
    return Target.phony(aliasName, "", Target(target.rawOutputs.map!(o => "$builddir/" ~ o), ""));
}

// Add a `default` convenience alias for the `dub build` target.
// Especially useful for Ninja (`ninja default ut` to build default & test targets in parallel).
alias defaultTarget = aliasTarget!("default", buildTarget);   

version (Windows) {
    // Windows: extra `ut` convenience alias for `ut.exe`
    alias utTarget = aliasTarget!("ut", testTarget);
    mixin build!(buildTarget, optional!testTarget, optional!defaultTarget, optional!utTarget);
} else {
    mixin build!(buildTarget, optional!testTarget, optional!defaultTarget);
}

=>

include rules.ninja
# Automatically generated by reggae version 0.5.24+
# Do not edit by hand
build .reggae\objs\dub$ with$ spaces.exe.objs\dev\test\my$ source_modc.obj: _dcompile C$:\dev\test\my$ source\modc.d C$:\dev\test\my$ source\my$ module.d C$:\dev\test\my$ source\other_module.d
  includes = -IC:\dev\test "-IC:\dev\test\my source"
  flags = "-L/LIBPATH:my libs" -m64 -debug -g -w -version=Have_dub_with_spaces

build dub$ with$ spaces.exe: _dlink .reggae\objs\dub$ with$ spaces.exe.objs\dev\test\my$ source_modc.obj
  flags = "-L/LIBPATH:my other libs" "-L/LIBPATH:my libs" -m64 -g

build .reggae\objs\ut.exe.objs\dev\test\my$ source_modc.obj: _dcompile C$:\dev\test\my$ source\modc.d C$:\dev\test\my$ source\my$ module.d C$:\dev\test\my$ source\other_module.d
  includes = -IC:\dev\test "-IC:\dev\test\my source"
  flags = "-L/LIBPATH:my libs" -m64 -debug -g -w -version=Have_dub_with_spaces -unittest

build ut.exe: _dlink .reggae\objs\ut.exe.objs\dev\test\my$ source_modc.obj
  flags = "-L/LIBPATH:my other libs" "-L/LIBPATH:my libs" -m64 -g

build default: phony dub$ with$ spaces.exe
  pool = console

build ut: phony ut.exe
  pool = console

build build.ninja: _rerun | C$:\dev\reggae\bin\reggae.exe C$:\dev\test\reggaefile.d C$:\dev\test\dub.sdl C$:\dev\test\dub.selections.json
  pool = console

default dub$ with$ spaces.exe

I think this is more or less how the default reggaefile.d for dub projects should look like - only performing the main build by default, but providing a handy OS-independent ut alias to include the tests (or building those exclusively). E.g., one could use ninja default ut && ./ut tests.ut as replacement for dub test -- tests.ut && dub build after running reggae once etc.

kinke avatar Jan 27 '21 01:01 kinke

I dunno - the fact that Windows has an extra .exe is its own thing? I'd probably type ninja ut.exe && ut

atilaneves avatar Jan 27 '21 11:01 atilaneves

I'd probably type ninja ut.exe && ut

I'm thinking about automation, where such platform differences are always a PITA. To be precise, I was wondering how we build the Symmetry SIL stuff, noted the explicit reggaefile.d files and that they only include the main build, and then thought that it's too bad the tests cannot be built with reggae that way (for devs), and was hence looking for a way to improve the default reggaefile.d for max flexibility and an IMO least-surprising default behavior.

If you agree, I'll open a PR to make this the default.

kinke avatar Jan 27 '21 13:01 kinke

Ugh, Windows. You're right, of course.

atilaneves avatar Jan 27 '21 15:01 atilaneves