Dynamic target in make

I am new to make and am trying to use it to deploy some javascript files. For a long time I could hardly cope with the following problem without success.

My directory structure is as follows:

helpers/ foo/ foo.js test/ test1.js test2.js ... bar/ bar.js test/ test1.js test2.js ... other helpers... distrib/ files ready for distribution other stuff... 

My makefile should, among other things, create helpers. For each foo helper, I want to create the following files under the distribution: foo-version.js , foo-version-uncommented.js , foo-version-packed.js and foo-version-tests.zip . The first three are obtained by foo.js, respectively, in the form of a copy, by removing comments and running javascript minifier. I already have commands to complete these tasks.

The version number should be read in the comments of the file itself, which I can easily handle

 def version $(shell cat $1 | grep @version | sed -e"s/.*version *//") endef 

My problem is that targets like foo-version.js are dynamic since they depend on the version number that is read at run time make. I tried using templates, but I was not able to complete this work. The problem is that something like this will not work

 helpers := foo bar helpers: $(helpers) $(helpers): %: $(call version, %) 

because the second% is not extended in the macro call, but it is used literally.

I need to do make helpers to create all the helpers or make foo to create one. The second step is to delete all files under distrib with a lower version number. Any ideas how to do this?

As a side question: can a task like this be easier with another build tool? I am not an expert, and it can be a pain to learn something else.

+4
source share
2 answers

In GNU make, you can use the call and eval functions, usually in combination with foreach :

 %-version.js: %.js # your recipe here %-version-uncommented.js: %.js # your recipe here %-version-packed.js: %.js # your recipe here %-version-tests.zip: %.js # your recipe here versions_sfxs := .js -uncommented.js -packed.js -tests.zip helpers := $(shell ls $(HELPERSDIR)) define JS_template helpers: $(1)-version$(2) endef $(foreach h, $(helpers), \ $(foreach sfx, $(versions_sfxs), \ $(eval $(call JS_template,$(h),$(sfx)) \ ) \ ) 

This code is not tested, but it gives a general idea. Expect to have afternoon debugging using spaces, tabs, dollar icons, and backslashes, as in shell scripts. Search for make eval or something for more details and pointers.

+9
source

In the end, I decided to write my own PHPmake build tool . It has a syntax resembling standard makefiles, but it is already more powerful than standard makefiles, and it is easy to expand because the makefiles themselves are written in plain PHP.

No more debugging spaces, tabs, or dollar signs! :-)

-4
source

All Articles