user744629
user744629

Reputation: 2041

trailing whitespace in Makefile variable

The Makefile:

#there is a whitespace after "/my/path/to"
FOO = "/my/path/to"
BAR = "dir"

INCLUDE_DIRS = $(FOO)/$(BAR) "/another/path"

INCLUDES = $(foreach dir,$(INCLUDE_DIRS),-I$(dir))

all:
     @echo $(INCLUDES)

With Gnu make I expect my $(INCLUDES) to be:

-I/my/path/to/dir -I/another/path

However, if the line

FOO = "/my/path/to"

ends with a whitespace (which is a common "mistake"), variable FOO will contains the whitespace, and the resulting INCLUDES will contains three directories (the two firsts beeing the first one splitted):

-I/my/path/to -I/dir -I/another/path

The only solution I found is to use the strip function:

FOO = $(strip "/my/path/to" )

But isn't there a more natural syntax, or any way to avoid this pitfall?

Upvotes: 2

Views: 5880

Answers (2)

user744629
user744629

Reputation: 2041

Based on Eldar Abusalimov solution, here is a function that can be used in a loop to check multilple directories for whitespace:

FOO = /my/path
BAR = to # <- a space!
BAZ = dir

# $(call assert-no-whitespace,DIRECTORY)
define assert-no-whitespace
  $(if $(word 2,[$($1)]),$(error There is a whitesapce inside variable '$(1)', please correct it),)
endef

CHECK_FOR_WHITESPACE = \
  FOO \
  BAR 

$(foreach dir,$(CHECK_FOR_WHITESPACE),$(call assert-no-whitespace,$(dir)))

all:
  @echo $(FOO)/$(BAR)/$(BAZ)

Upvotes: 2

Eldar Abusalimov
Eldar Abusalimov

Reputation: 25523

First of all, note that there probably shouldn't be double quotes around the paths. In your example I guess the value of $(FOO)/$(BAR) would be "/my/path/to"/"dir" instead of expected /my/path/to/dir.

Answering to your question, generally speaking, no. Concatenating two values preserves whitespaces, so if you want to write $(FOO)/$(BAR) is up to you to guarantee that both $(FOO) and $(BAR) are single words with no leading or trailing whitespaces. strip function is good enough to remove the latter (if any).

However you can treat one of these variables as a list and write something like $(FOO:%=%/$(BAR)) and this will work fine. But personally I would prefer to check the value of FOO (either fixing it or failing with an error if it is bad) and then use it as usual, for example:

FOO = /my/path/to # <- a space!
BAR = dir

...

ifneq ($(word 2,[$(FOO)]),)
  $(error There is a whitespace inside the value of 'FOO')
endif

Upvotes: 3

Related Questions