[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

tricks in GNU make

From: Michael Mounteney
Subject: tricks in GNU make
Date: Wed, 6 Aug 2003 21:07:59 +0100
User-agent: KMail/1.5

This message is not specific to GNU make on Win-32 but it might be especially 
useful on that platform, since I offer a method of circumventing restricted 
command line length.  A side-effect of my method is the ability to perform 
arithmetic in macros.

From time to time the enquiry is made:  `how can I pass a long list of 
arguments to a command in Windows, since that platform only allows `short' 
command lines ?'  Here is one suggestion.

Generally the user wants a method of breaking up a long macro and iteratively 
passing it in chunks to the command.  However, make is a functional language 
and therefore iteration is meaningless in it.  In fact, in the course of 
devising this message, I realised more and more the similarity of make and 
Haskell in thier approach to programming.  Make is even less efficient at 
arithmetic, in my method, as we will see.

What my approach does is break a long macro into a fixed number of parts, here 

First, an example macro that we want to break up.

biglist=one two three four five six seven eight nine ten eleven twelve 
thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty

Then, five `utility' macros, the first three being functions.

multiply=$(foreach I,$(1),$(2:%=$(I)%))
stripzero=$(patsubst 0%,%,$(1))
generate=$(call stripzero,$(call stripzero,$(call multiply,$(1),$(call 
forwards:=$(call generate,0 1 2 3 4 5 6 7 8 9)
backwards:=$(call generate,9 8 7 6 5 4 3 2 1 0)

Here's (some of) the arithmetic.  Add more to taste:

plus=$(word $(2),$(wordlist $(1),99999,$(wordlist 3,99999,$(forwards))))
gt=$(filter $(2),$(wordlist $(1),99999,$(forwards)))

Very clever.  Now to break up that big list of names:

tagged=$(join $(wordlist 1,$(words $(1)),$(patsubst %,1: 2: 3:,$(1))),$(1))
untag=$(patsubst $(1):%,%,$(filter $(1):%,$(2)))

Calculate this once, for efficiency:

taglist:=$(call tagged,$(biglist))

Right, now show off the fancy effects.

        @echo $(call plus,4,7)
        @echo $(if $(call gt,4,7),is,is not)
        @echo $(if $(call gt,7,4),is,is not)
        @echo $(taglist)
        @echo $(call untag,1,$(taglist))
        @echo $(call untag,2,$(taglist))
        @echo $(call untag,3,$(taglist))

If you want to e-mail me directly about this, substitute landcroft for 
wrandyke.demon in the reply address.

I hope the above helps someone.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]