Donnerstag, 10. Oktober 2013

GNU Make as templating engine (???)

Hello visitors!

So this is already my second post about GNU Make I am writing within two weeks! My intention this time is to describe how you can get all the power of the Makefile-parser into any usual, build-related file.

To give you a better image of what I wanted to achieve originally and why, let me give you this scenario:
Imagine you are starting to work on yet another c/c++ program for GNU and you are trying to use as much basic project stuff as possible from your previous project. You are copying over makefiles, licenses, other textfiles and launching scripts. After that, you alter the name of the last project everywhere to match your new one's - which is pretty inconvenient if done by hand. You know: These project specific strings occuring in standard files all over the place should be kept at only one place, namely your build system's configuration file.

In my last article I was calling this build system configuration file for make "defs.mk". Now the question is: How will we get the definitions from there into our text files?

With the help of the standard *nix tools "cat", "sed" and "printf" I managed to write a small copy-over routine for make which performs make's variable expansion on the text files we want to reuse in the future. Here is the code:

 DOCFILES        = $(DOCSRCDIR)/LICENSE.txt $(DOCSRCDIR)/README.txt  
 DOCDESTS    = $(subst $(DOCSRCDIR),$(DISTDIR),$(DOCFILES))  
 .PHONY    = all  
 all: $(DOCDESTS)  
 $(DISTDIR)/%: $(DOCSRCDIR)/%  
 # Get the file's contents into "DOCCONTENT". Don't forget to escape "#"  
 # by using sed -e 's/\#/\\&/g' and also get rid of troublesome newlines  
 # (replaced with \n which is re-translated by printf later)  
 # http://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n  
     @$(eval DOCCONTENT := $(shell cat $^ | sed -e ':a;N;$$!ba;{s/\#/\\&/g;s/\n/\\n/g}'))  
     @printf "$(DOCCONTENT)" > $@  

By reading the document into the makefile variable "DOCCONTENT" all currently set variables are being expanded (replaced) in the script before we write it back to its destination. DISTDIR is hereby our distributiable package folder.

Inside the document we are also able to use make's inbuilt functions, such as $(wildcard and even $(shell. This is a bit risky though, since almost everything can be done this way. At least noone will complain about lacking features, though :)

I hope this can be helpful for you!
Regards

Keine Kommentare:

Kommentar veröffentlichen

Thanks for spending time on giving me feedback. I really appreciate it :)