rix
rix

Reputation: 93

Get parent dir, grandparent dir and so on in gnu make?

I have a variable path, for example this path from $(shell pwd):

C:\a\b\c\d\e\f

what i want to get is this and save it in a variable:

C:\a\b\c\d\e
C:\a\b\c\d
C:\a\b\c
C:\a\b
C:\a
C:\

how to do it in gnu make? And how to stop if there is no more parent (reached C:)

Upvotes: 0

Views: 577

Answers (1)

bobbogo
bobbogo

Reputation: 15493

Ok, I'm going to switch into posix path mode. No appologgies. Life is too short to mess around with windows paths when cygwin is available. (I will note though that $(dir) recognises backslashes.)

So, a function.

You just spit out the argument, and then call the function again but this time with the last path component snipped off. Something like

parents = $1 $(call parents,$(dir $1))

First problem: $(dir a/b/c/d) returns a/b/c/. Fine, except that $(dir /a/b/c/) just gives you a/b/c/ again. You need to strip that final slash before the call:

parents = $1 $(call parents,$(patsubst %/,%,$(dir $1)))

OK. Problem now is this recursive call never terminates the sequence.

We need to stop calling parents once $1 has no slashes in it. Several methods come to mind. One way is to transliterate / into  (that's the job of $(subst …)), then stop if the resulting number of words ($(words …)) is 1 ($(filter …)):

parents = \
  $1 \
  $(if $(filter-out,1,$(words $(subst /, ,$1))), \
    $(call parents,$(patsubst %/,%,$(dir $1))))

(Hope I've got that nesting right.) Giving:

$ cat Makefile
parents = \
  $1 \
  $(if $(filter-out 1,$(words $(subst /, ,$1))), \
    $(call parents,$(patsubst %/,%,$(dir $1))))

$(error [$(call parents,/a/b/c/d/e/f)])


$ make
Makefile:6: *** [/a/b/c/d/e/f  /a/b/c/d/e  /a/b/c/d  /a/b/c  /a/b  /a ].  Stop.

:-)

Footnote: Dunno what you are trying to achieve, but I reckon there is probably a more make-like way of doing it!

Upvotes: 1

Related Questions