Reputation: 20686
Let's say you have a variable in a makefile fragment like the following:
MY_LIST=a b c d
How do I then reverse the order of that list? I need:
$(warning MY_LIST=${MY_LIST})
to show
MY_LIST=d c b a
Edit: the real problem is that
ld -r some_object.o ${MY_LIST}
produces an a.out
with undefined symbols because the items in MY_LIST
are actually archives, but in the wrong order. If the order of MY_LIST
is reversed, it will link correctly (I think). If you know a smarter way to get the link order right, clue me in.
Upvotes: 16
Views: 6006
Reputation: 342
GNU Make version 4.4 adds the new function $(let ...)
. The manual offers the following macro which can be used for reversing the order of words
reverse = $(let first rest,$1,\
$(if $(rest),$(call reverse,$(rest)) )$(first))
all: ; @echo $(call reverse,d c b a)
Upvotes: 1
Reputation: 1088
An improvement to the GNU make solution:
reverse = $(if $(wordlist 2,2,$(1)),$(call reverse,$(wordlist 2,$(words $(1)),$(1))) $(firstword $(1)),$(1))
Upvotes: 7
Reputation: 1663
Playing off of both Ben Collins' and elmarco's answers, here's a punt to bash which handles whitespace "properly"1
reverse = $(shell printf "%s\n" $(strip $1) | tac)
which does the right thing, thanks to $(shell)
automatically cleaning whitespace and printf
automatically formatting each word in its arg list:
$(info [ $(call reverse, one two three four ) ] )
yields:
[ four three two one ]
1...according to my limited test case (i.e., the $(info ...)
line, above).
Upvotes: 2
Reputation:
A solution in pure GNU make:
default: all
foo = please reverse me
reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1))
all : @echo $(call reverse,$(foo))
Gives:
$ make
me reverse please
Upvotes: 25
Reputation: 476
You can also define search groups with ld:
ld -r foo.o -( a.a b.a c.a -)
Will iterate through a.a, b.a, and c.a until no new unresolved symbols can be satisfied by any object in the group.
If you're using gnu ld, you can also do:
ld -r -o foo.o --whole-archive bar.a
Which is slightly stronger, in that it will include every object from bar.a regardless of whether it satisfies an unresolved symbol from foo.o.
Upvotes: 5
Reputation: 20686
Doh! I could have just used a shell script-let:
(for d in ${MY_LIST}; do echo $$d; done) | tac
Upvotes: 6