Daniel
Daniel

Reputation: 1198

Defining rules in Makefile functions

I want to define a few similar rules, so I decided to try to define them inside of a function:

COMPILED_JS_FILES=$(COMPILED_JS_FILES) $(foreach m,$(notdir $(wildcard src/$(1)/*.$(2))),$(TARGET_DIR)/$(1)/$(m))


$(TARGET_DIR)/$(1)/%.$(2) : src/$(1)/%.$(2)
    $(CAT) $< > $@

endef

$(eval $(call COMPILE_JS,modules,js))
$(eval $(call COMPILE_JS,modules,jsm))
$(eval $(call COMPILE_JS,models,js))
$(eval $(call COMPILE_JS,firefox,js))
$(eval $(call COMPILE_JS,helpers,js))

However, the $< and $@ variables inside the rule evaluate to empty strings, presumably because they are being defined by the function that is running them, as opposed to being saved until the rule is evaluated.

I am curious about the answer to this question, but also into other reasonable solutions to this problem (other than restructuring the directory structure).

Upvotes: 1

Views: 992

Answers (2)

Daniel
Daniel

Reputation: 1198

I actually figured out the answer (in this case, I don't know about in general) - $$< and $$@. Furthermore $$(CAT) will delay the expansion of $(CAT) until the evaluation of the rule.

Upvotes: 1

thb
thb

Reputation: 14454

This is an old problem with makefiles. There really isn't a good, general way to get around it within Make, because you are right: the $< and $@ just are not available when you need them.

When I have a problem like this, I tend to write a support script outside Make. However, GNU Make does provide the .SECONDEXPANSION target, an obscure hack intended to make some tasks like yours possible to complete. You might investigate it, though my own experience is that .SECONDEXPANSION is not always a clean solution.

Upvotes: 0

Related Questions