Maxim Sloyko
Maxim Sloyko

Reputation: 15876

Joining elements of a list in GNU Make

In my makefile I have a variable with a list of directories, like this:

DIRS = /usr /usr/share/ /lib

Now, I need to create PATH variable from it, which is basically the same, but uses semicolon as a separator:

PATH = /usr:/usr/share/:/lib

How do I do that? I mean, how do I join elements of DIRS list with semicolons, instead of spaces?

Upvotes: 32

Views: 19370

Answers (3)

Dave Dopson
Dave Dopson

Reputation: 42716

Cleanest Form (that I can find):

classpathify = $(subst $(eval ) ,:,$(wildcard $1))
cp = a b c d/*.jar

target:
    echo $(call classpathify,$(cp))
# prints a:b:c:d/1.jar:d/2.jar

Notes:

  • Turning it into a pseudo-function makes the intention clearer than doing a bunch of arcane string manipulation inline.
  • Note the trailing space after eval: $(eval ). Without this, make interprets $(eval) as a variable rather than calling the eval function. If the trailing space is omitted, you could replace eval with some_undefined_variable and the text replacement will still happen. However, if you run make with the --warn-undefined-variable flag, you'll get a warning that eval or some_undefined_variable is undefined.
  • I included the $(wildcard) function because you almost always use these two together when specifying a classpath
  • Make sure not to put any extra spaces in after the commas or you will get something like "::a:b:c:d:e".

Upvotes: 18

Eric Melski
Eric Melski

Reputation: 16810

You can use the $(subst) command, combined with a little trick to get a variable that has a value of a single space:

p = /usr /usr/share /lib
noop=
space = $(noop) $(noop)

all:
        @echo $(subst $(space),:,$(p))

Upvotes: 43

tanghao
tanghao

Reputation: 71

You use ':' as separator, so you are on Linux. Consider using bash tool chain to replace continuous spaces by single colon

PATH := $(shell echo $(DIRS) | sed "s/ \+/:/g")

Upvotes: 3

Related Questions