web-dev-qa-db-fra.com

makefile est manquant separator

D'accord, je suis coincé là-dessus et je n'ai aucune idée de ce que je fais mal. Tout se passait bien en travaillant sur un makefile plus compliqué, mais tout à coup, j'ai eu l'erreur "Missing separator". J'ai pu l'isoler dans un scénario très simple:

test.mk

define Push_dir
$(info ${1})
endef

define pop_dir
$(info ${1})
endef

define include_submake
$(call Push_dir,${1})
$(call pop_dir,${1})
endef

Simple

include test.mk

INITIAL_SUBMAKE:= includeme.mk
$(call include_submake,${INITIAL_SUBMAKE})

process:
    @echo Processed...

Et la sortie:

C:\project>make -f Simple process
includeme.mk
includeme.mk
Simple:4: *** missing separator.  Stop.

includeme.mk n'existe pas réellement. Je n'ai aucune idée de ce qui ne va pas ici, j'ai essayé une multitude de choses. Si j'entoure l'appel à include_submake dans info comme suit:

$(info $(call include_submake,${INITIAL_SUBMAKE}))

L'erreur de séparateur manquante disparaît. De plus, si dans le include_submake définir, je n’appelle que l’une des fonctions, cela fonctionne bien. De plus, si j'appelle directement les fonctions au lieu de les appeler include_submake, cela fonctionne également:

include test.mk

INITIAL_SUBMAKE:= includeme.mk
$(call Push_dir,${INITIAL_SUBMAKE})
$(call pop_dir,${INITIAL_SUBMAKE})

process:
    @echo Processed...


C:\project>make -f Simple process
includeme.mk
includeme.mk
Processed...

Je sens que je néglige quelque chose de fondamental ici. Merci de votre aide.

15
ThePosey

L'erreur missing separator est due à une valeur de retour non vide de include_submake, qui correspond à un caractère de saut de ligne dans votre cas. Make autorise uniquement les caractères d'espacement (c'est-à-dire un espace ou une tabulation) dans une expression qui n'est pas supposée faire partie d'une règle ou d'une autre directive.

Réécrivez vos fonctions en utilisant plain-old Effectuez une affectation de variable et l'erreur devrait disparaître:

Push_dir = \
    $(info $1)

pop_dir = \
    $(info $1)

include_submake = \
    $(call Push_dir,$1) \
    $(call pop_dir,$1)

UPD .: define vs assignation de variable simple

Répondre à une question du premier commentaire. Personnellement, je préférerais utiliser la directive define dans plusieurs cas.

Utilisation de la fonction eval

Comme le suggère le GNU Make manual, la directive define est très utile en conjonction avec la fonction eval . Exemple tiré du manuel (c'est moi qui souligne):

 PROGRAMS = serveur client 
 
 Server_OBJS = server.o serveur_priv.o server_access.o 
 Server_LIBS = protocole privé 
 
 Client_OBJS = client.o client_api.o client_mem.o 
 client_LIBS = protocole 
 
# Tout ce qui suit est générique
 
. PHONY: tous 
 Tous: $ (PROGRAMMES) 
 
définir PROGRAM_template
 $ (1): $$ ($ (1) _OBJS) $$ ($ (1) _LIBS:% = - l%) 
 ALL_OBJS + = $$ ($ (1) _OBJS ) 
endef
 
 $ (pour chaque programme, $ (PROGRAMMES), $ (eval $ (appelez PROGRAM_template, $ (prog)))) 
 
 $ (PROGRAMMES): 
 $ (LINK.o) $ ^ $ (LDLIBS) -o $ @ 
 
 Clean: 
 Rm -f $ (ALL_OBJS) $ (PROGRAMMES) 

Modèles de générateur

Les variables verbatim conviennent parfaitement aux cas où vous souhaitez générer un fichier à partir de GNU Make. Par exemple, envisagez de générer un fichier d’en-tête basé sur certaines informations de Makefile.

# Args: 
 # 1. Identifiant d'en-tête.définir header_template
/* Ce fichier est généré par GNU Make $ (MAKE_VERSION). */
 
 # ifndef $ (inclusion_guard) 
 # définir $ (inclusion_guard) 
 
 $ (foreach inc, $ ($ 1.includes) , 
 # include <$ (inc) .h>) 
 
/* Autre chose ... */
 
 # endif/* $ (inclusion_guard) */
 
endef# 1. Identifiant unique d'en-tête.
 inclusion_guard =\
 __GEN_ $ 1_H 
 
# Échappement Shell.
 sh_quote =\
 '$ (subst', '""', $ 1) '
 
 foo.includes: = bar baz 
 
 HEADERS: = foo.h 
 
 $ (HEADERS):% .h: 
 @Printf "% s" $ (appel sh_quote, $ (appel header_template , $ (* F))) & gt $ @ 

Syntaxe de fabrication étendue

Dans notre projet, nous utilisons notre propre système de construction appelé Mybuild , et il est entièrement implémenté au dessus de GNU Make. En tant que hacks de bas niveau que nous avons utilisés pour améliorer la syntaxe médiocre du langage intégré de Make, nous avons développé un script spécial qui permet d’utiliser une syntaxe étendue pour les définitions de fonctions. Le script lui-même est écrit dans Make aussi, il s’agit donc d’une sorte de méta-programmation dans Make.

En particulier, on peut utiliser des fonctionnalités telles que:

  • Définir des fonctions multilignes sans avoir besoin d'utiliser une barre oblique inverse
  • Utilisation de commentaires dans les fonctions (dans plain-old Les commentaires Make ne peuvent apparaître qu'en dehors des directives d'affectation de variable)
  • Définition de macros personnalisées telles que $(assert ...) ou $(lambda ...)
  • Inlining fonctions simples comme $(eq s1,s2) (vérification d'égalité de chaîne)

Ceci est un exemple de la façon dont une fonction peut être écrite en utilisant la syntaxe étendue. Notez que cela devient une fonction Make valide et peut être appelé comme d'habitude après un appel à $(def_all).

# Inverse la liste spécifiée. 
 # 1. La liste 
 # Retour: 
 # La liste avec ses éléments dans l’ordre inverse.définir l'inverse# Commencez par la liste vide.
 $ (pli, 1 $, 
 
 # Ajoute chaque nouvel élément (2 $) à 
 # Le résultat des calculs précédents.$ (lambda 2 $ 1 $)) 
endef
 $ (def_all) 

En utilisant ces nouvelles fonctionnalités, nous avons pu implémenter des choses vraiment cool (enfin, au moins pour Make :-)), notamment:

  • Couche orientée objet avec allocation dynamique d'objet, héritage de classe, invocations de méthode, etc.
  • Moteur d'exécution de l'analyseur LALR pour les analyseurs générés par GOLD Parser Builder
  • Bibliothèque de modélisation avec prise en charge de l’exécution des modèles générés avec EMF

N'hésitez pas à utiliser n'importe quelle partie de le code dans vos propres projets!

20
Eldar Abusalimov

J'ai rencontré le même problème. J'ai inséré 'tab', supprimé 'tab', réinséré pour en être sûr. Même message d'erreur.

Mais, j'ai fait tout cela à l'intérieur de XCodem qui, à ma grande surprise, a inséré des espaces blancs, pas "\ t". Une fois que j'ai utilisé un éditeur différent, ces erreurs «fantômes» ont disparu.

HTH ... 

0
Heikki