2008-09-09 10 views
11

Disons que vous avez une variable dans un fragment de makefile comme ce qui suit:manière la plus simple d'inverser l'ordre des chaînes dans une variable make

MY_LIST=a b c d 

Comment inverser alors l'ordre de cette liste? J'ai besoin:

$(warning MY_LIST=${MY_LIST}) 

pour montrer

MY_LIST=d c b a 

Edit: le vrai problème est que

ld -r some_object.o ${MY_LIST} 

produit un a.out avec des symboles non définis parce que les éléments de MY_LIST sont en fait des archives, mais le mauvais ordre. Si l'ordre de MY_LIST est inversé, il se liera correctement (je pense). Si vous connaissez un moyen plus intelligent d'obtenir l'ordre de lien, indiquez-moi.

+0

drôle! J'espère que c'est juste pour l'avertissement :) – elmarco

Répondre

19

Une solution dans le plus pur GNU make:

par défaut: tous

foo = s'il vous plaît me inverser

inverse = $ (si $ (1), $ (appel inverse, $ (2 wordlist, $ (mots $ (1)), $ (1)))) $ (FirstWord $ (1))

tous: @echo $ (appel inverse, $ (foo))

donne:

$ font

me renverse s'il vous plaît

+1

Merci! Celui-ci a résolu mon problème exact, à savoir concaténer les PDF dans l'ordre de l'année dans l'ordre décroissant. :) –

2

Doh! Je aurais pu utiliser un script shell-let:

(for d in ${MY_LIST}; do echo $$d; done) | tac

+0

$ pour d dans un deux trois; fais écho $ d; fait tac trois deux un Superflous \ n. Mais c'est cool d'apprendre le tac. – elmarco

4

Vous pouvez également définir des groupes de recherche avec ld:

ld -r foo.o -(a.a b.a c.a -) 

aura-t-itérer aa, ba, et ca jusqu'à ce qu'aucun nouveaux symboles non résolus peut être satisfait par n'importe quel objet du groupe.

Si vous utilisez gnu ld, vous pouvez également faire:

ld -r -o foo.o --whole-archive bar.a 

est légèrement plus forte, en ce qu'elle comprendra tous les objets de bars.Un peu importe si elle satisfait un symbole non résolu de foo .o.

4

Une amélioration de la solution GNU make:

inverse = $ (si $ (wordlist 2 , 2, $ (1)), $ (appel inverse, $ (liste de mots 2, $ (mots $ (1)), $ (1))) $ (premier mot $ (1)), $ (1))

  • une meilleure condition d'arrêt, original utilise la chaîne vide perdre une fonction appel
  • ne pas ajouter un espace menant à la liste inversée, contrairement à l'original
1

Jouant sur des deux Ben Collins' et elmarco's réponses, voici un botté de dégagement pour bash qui gère les espaces "correctement"

reverse = $(shell printf "%s\n" $(strip $1) | tac) 

qui fait la bonne chose, grâce à $(shell) nettoyage automatique des espaces et printf formatant automatiquement chaque mot dans sa liste de arg:

$(info [ $(call reverse, one two three four ) ]) 

rendements:

[ four three two one ] 

... selon mon limité cas de test (c'est-à-dire la ligne $(info ...), ci-dessus).

Questions connexes