2010-12-02 98 views
3

Arrière-plan. Je travaille sur un fichier spec qui doit traiter une liste de fichiers dans plusieurs scriptlets. DRY (ne vous répétez pas) m'a une fois défini la liste comme une macro qui est étendue dans les différents scripts d'aide. Maintenir la liste est une douleur car je n'ai pas vu un moyen d'éviter de mettre tous les fichiers sur la même ligne.Existe-t-il une syntaxe ou une astuce pour créer une macro de fichier de spécification RPM multiligne?

 
%define LIST \ 
a \ 
b 

donne une erreur

 
%define LIST a\ 
b\ 

donne une erreur aussi bien

 
%define LIST a 
%define LIST %LIST b 

échoue en raison d'une erreur de récursion

Répondre

0

Vous devez avoir au moins une partie de la valeur sur la première ligne, à savoir:

%define LIST a\ 
b\ 
c 

Cette définition de macro fonctionnera. Si vous envisagez de les utiliser en tant que commandes, c'est-à-dire quelque chose comme

%define DOSOMETHING rm file1\ 
rm file2\ 
rm file3 
... 
%build 
%DOSOMETHING 

cela ne fonctionnera pas. Les lignes dans les sections exécutables sont d'abord divisées en commandes séparées, ALORS les macros sont développées. C'est à dire. définir la macro fonctionnera, l'exécuter comme trois commandes séparées ne fonctionnera pas.

Si vous souhaitez exécuter 3 commandes séparées, il est plus facile de le faire comme

%define DOSOMETHING rm file1; rm file2; rm file3 
+1

La solution ci-dessus ne fonctionne pas pour moi, possible pourrait fonctionner pour d'autres versions de rpmbuild. Je reçois une erreur: erreur: ligne 31: balise inconnue: b \ Modifié la question pour refléter cela. –

2

Depuis que vous avez expliqué votre objectif un peu plus, nous allons essayer une approche différente. Essayez ceci dans votre fichier de spécification:

Source1:  flist 

%{expand:%global LIST %(cat %{SOURCE1})} 

Et ce dans le fichier Source1 (dans ce cas flist):

a \ 
b \ 
c 

J'ai testé avec rpm 4.4.6 puisque c'est la plus ancienne version disponible pour moi en ce moment.

+0

Cela ne fonctionne pas sur CentOS4, qui est en fin de vie et possède une ancienne version RPM. Malheureusement, c'est ce que le PO et le vôtre essayent vraiment de travailler. Bien que de loin, c'est le plus proche d'une solution. – chutz

1

Dans les définitions de macro, une barre oblique inverse de fin de ligne est supprimée et utilisée pour indiquer à RPM que la définition de macro se poursuit. Le caractère de nouvelle ligne est pas dépouillé (contrairement à un fichier make). Par conséquent, si vous construisez un script multiligne, les points-virgules ne sont pas nécessaires. Cela signifie également que si vous divisez une seule commande, vous devez utiliser les barres obliques inverses. Deux pour produire un backslash que le shell verra et un pour dire à rpmbuild de continuer à analyser la macro. Le shell supprimera le backslash qu'il voit, plus le retour à la ligne et cela donnera une commande sur deux lignes. Ouf !!

+0

% définir MAKE make \\\ nom = TODO \\\ aide \\\ – RzR

0

Si j'étais vous, je maintiendrais la liste dans un fichier source.

Contenu de %{_sourcedir}/LIST:

a 
b 
c 
d 

Dans le fichier de spécification:

%define process_files() \ 
    for i in %(cat %{_sourcedir}/LIST) 
    do \ 
     echo "process list of files here" \ 
    done 
1

Vous ne pouvez pas vraiment faire des macros multilignes dans un fichier de spécification de la façon dont vous pouvez dans votre fichier ~/.rpmmacros. Un peu idiot.

Je crée un sous-répertoire SPECS/inc/avec des fichiers spec qui agissent comme des macros multilignes utilisées par tous les paquets créés pour mon site. Au lieu d'utiliser des macros comme %foo, vous pouvez simplement faire %include inc/foo.spec. Vous pouvez également créer des raccourcis pour éviter la syntaxe include %global foo %include inc/foo.spec. Ensuite, cela fonctionne comme une macro multi-ligne.

Voici un exemple complet.

inc/env.spec

%global foo %include inc/foo.spec 
%global bar %include inc/bar.spec 
#Lots of other common things to all packages 

inc/foo.spec

a 
b 
c 
d 

Et puis dans mon fichier de spécification de package, mylib.spec:

%include inc/env.spec 

Name: mylib 
Version: X.Y 
#etc... 

%foo 
0

Cet exemple devrait travail:

cat file.spec 

%define MAKE make \\\ 
status=success \\\ 
#EOL 

%build 
${MAKE} 


cat Makefile 

status?=fail 
default: 
    echo "status=${status}"