reggae
reggae copied to clipboard
dub + Ninja: Phony targets don't work properly
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
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.
I dunno - the fact that Windows has an extra .exe
is its own thing? I'd probably type ninja ut.exe && ut
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.
Ugh, Windows. You're right, of course.