Define Rules Only When Files Exist

5 views
Skip to first unread message

gar...@garretthopper.com

unread,
Aug 21, 2019, 10:05:42 PM8/21/19
to Shake build system
In Make it's fairly simple to define rules which will only match when a certain file exists:
submodules := $(patsubst %/Makefile,%,$(wildcard */Makefile))

.PHONY: $(submodules)
$(submodules):
$(MAKE) -C $@
It might not make sense in a Shake based system, but I'm trying to define a rule that can only build 'modules' which are folder that contain a `module.cfg` file. (And which will then parse the file to build the module.)
I've done some reading, and it sounds like Shake may not be suited to this modular style of build where each subfolder in a monorepo defines its own build process and the dependencies between these modules is defined in `*.cfg` files?

I've been playing with using `(?>)` to do this, however it doesn't allow `IO`, so I can't have it check that the `module.cfg` file exists.

If someone can point me in the right direction for structuring a large monorepo build based on Shake, that'd be great. I've had a lot of trouble finding even simple examples out there—let alone a monorepo with modular builds.

Do most people just define all rules in a single build, or do they try to split it up into individual folders next to the code?

Ryan Gonzalez

unread,
Aug 21, 2019, 11:13:40 PM8/21/19
to gar...@garretthopper.com, Shake build system
You can use liftIO to convert IO to Action: http://hackage.haskell.org/package/shake-0.18.3/docs/Development-Shake.html#v:liftIO

However, Shake already has an Action variant of System.Directory's doesFileExist: http://hackage.haskell.org/package/shake-0.18.3/docs/Development-Shake.html#v:doesFileExist

--
You received this message because you are subscribed to the Google Groups "Shake build system" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shake-build-sys...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/shake-build-system/a1b23fd7-a636-409a-aaaa-584cfc66adfb%40googlegroups.com.

Neil Mitchell

unread,
Aug 22, 2019, 2:13:37 AM8/22/19
to Ryan Gonzalez, gar...@garretthopper.com, Shake build system
Hi Garrett,

Generally in Make you define both the rules, and the specific content
about the files, in the Makefile. In Shake, if you go the route of
more composable descriptions (as quite a few people have done) you
would usually specify the executable rules in the single Shake rule,
but have the specific data only in module.cfg. I gave a talk about
this pattern at https://ndmitchell.com/#shake_09_oct_2015 (video at
https://skillsmatter.com/skillscasts/6548-defining-your-own-build-system-with-shake).
There is also a module
https://hackage.haskell.org/package/shake-0.18.3/docs/Development-Shake-Config.html
that makes some pieces a bit easier if you follow a particular style
(but none of its wired in, so feel free to go your own way.

Usually to build a module, I'd do something like:

"**/*.o" %> \out -> do
let mod = getModuleLocationFromOutput out
metadata <- loadModuleInfo mod
buildRule metadata out

Where loadModuleInfo could be an oracle - and then the metadata can be
tracked and cached.

Thanks, Neil
> To view this discussion on the web, visit https://groups.google.com/d/msgid/shake-build-system/CAO41-mMKCTrKp-oidHyYT7nagT3zLnWRmQgXKn%3DjzH0vLHqvqQ%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages