I'm trying to use a codegen tool for Go to automatically generate some code based on the contents of other go files. The codegen tool will get standard arguments which can be deduced from the name of the file its generating and the name of the file that it's parsing. If I were doing it all manually, it would look like:
foo-tool -name FooInterface -file foo/api.go
foo-tool -name BarInterface -file foo/api.go
foo-tool -name BingInterface -file foo/bing.go
foo-tool -name BazInterface -file foo/baz.go
But I don't want to do it manually, I want to use Make! So I tried to accomplish the same thing with a Makefile and a pattern rule.
foo_FooInterface.go : foo/api.go
foo_BarInterface.go : foo/api.go
foo_BingInterface.go : foo/bing.go
foo_BazInterface.go : foo/baz.go
foo_%.go : %.go
$(eval foo_name=$(subst mock_,,$(subst .go,,$(@F))))
build-foo -name $(foo_name) -file $<
In my mind, the first 3 rules would set up the dependency graph, and the pattern rule would tell Make what to do with the dependencies. But when I try running make foo_BarInterface.go
, I get make: Nothing to be done for foo_BarInterface.go
. I understand why this happens, because Make is expecting to match foo_FooInterface.go with FooInterface.go, but I don't want to restructure my project's files like that.
Is this possible, or do I need to do something like:
foo_FooInterface.go : foo/api.go
build-foo -name FooInterface -file foo/api.go
foo_BarInterface.go : foo/api.go
build-foo -name BarInterface -file foo/api.go
foo_BingInterface.go : foo/bing.go
build-foo -name BingInterface -file foo/bing.go
foo_BazInterface.go : foo/baz.go
build-foo -name BingInterface -file foo/baz.go
Which I really don't want to do, because new Interface
s will be added as the codebase grows, and I don't want to require people to type all of that every time.
Edit: I wouldn't mind specifying the rule manually every time, but I need a rule that collects all the generated files together, and I don't want to specify every foo_*.go in that one. Is there a way to say "This rule depends on all rules (not files) matching a pattern?" I was able to do
foo_files := $(shell grep 'foo_\w\+.go' Makefile | cut -d : -f1)
But this seems bad to me.
foo_FooInterface.go
, orfoo_FooInterface
, orFooInterface
, or what? – Betafoo_FooInterface.go
. The build-foo tool creates files with that name based on the-name FooInterface
argument. I guess I should have been more specific about that. – Lily Marafoo_*.go
files depends on a different set of prerequisite files, not justfoo/api.go
? If this is the case, can you show us an example closer to what you really need? – Dario