I am writing a Shakefile with the aim of making it extensible with new Rules
. Its interface is a function mainFor :: Rules () -> IO ()
, the idea being that client projects would only need to define main = mainFor myCustomRules
to get the whole thing working. mainFor customRules
is defined as a bunch of Shake Rules
followed by a call to customRules
.
This works as long as the custom rules passed to mainFor
are for new targets.
However, some of my stock (non-custom) rules are basically of the form "run this big opaque proprietary external script with this input and hope for the best"; and there can be extra files used by the external script depending on its input. For example, imagine I have a rule of the following form:
"_build/output.bin" %> out -> do
need ["_build/script.scr", "_build/src/generated.src"]
runExternalScript
For a particular client project, maybe the generated source code contains references to another file _build/src/extrainput.src
. So in the custom rules passed to mainFor
, not only do I need extra rules for this file, but the existing rule should also be modified to mark that it need
s this input:
main = mainFor $ do
"_build/src/extrainput.src" %> \out -> do
generateExtraSrc
"_buld/output.bin" %> \out -> do
need ["_build/src/extrainput.src"]
but this, unsurprisingly, fails because both the stock rule in mainFor
and the second custom rule passed in the customRules
argument are for the same target. Note that I do not want to fully override the stock rule, only extend it to add the extra dependency.
There is currently no way to do this using Shake. The possibilities are:
FilePath -> Action ()
function, then define your own%>
that also applied that function to the output. It would only work with pre-selected extension points, but if you redefine%>
at the top of the file it can hit all your instances.shakeExtra
to store the state in some way.