make se plaint "séparateur manquant (vous vouliez dire TAB?)"

10

En essayant d'installer le som_pak-3.1-NAcMoS.tar.gzfichier, j'ai utilisé les commandes ci-dessous:

$ tar xvf som_pak-3.1-NAcMoS.tar.gz
$ cd som_pak-3.1
$ cp makefile.unix makefile
$ make
$ cd ..
$ ln -s som_pak-3.1 $NACMOS_HOME/som_pak

Mais lors de l'exécution de la makecommande, j'obtiens l'erreur suivante:

* séparateur manquant (vouliez-vous dire TAB au lieu de 8 espaces?). Arrêtez.

  • Quelqu'un peut-il me dire la raison de l'erreur?
  • Y a-t-il des packages à inclure avec cela?
Rincy Raphael
la source
1
D'où avez-vous téléchargé ce fichier?
Gilles 'SO- arrête d'être méchant'

Réponses:

15

L'erreur que vous rencontrez:

*** séparateur manquant (vouliez-vous dire TAB au lieu de 8 espaces?). Arrêtez.

Signifie que le makefilecontient des espaces au lieu de Tab. L' makeutilitaire est notoirement difficile à utiliser Spaceau lieu de Tab. Il est donc probable que le makefilecontient Spaceau début des strophes de règles dans le fichier.

Exemple

Disons que j'ai les 3 .cfichiers suivants:

Bonjour c
char *
hello() 
{
  return "Hello";
}
world.c
char *
world() 
{
  return "world";
}
main.c :
#include <stdio.h>

/* Prototypes. */
char *hello();
char *world();

int
main(int argc, char *argv[]) 
{
    printf("%s, %s!\n", hello(), world());
    return 0;
}    

Dites que j'ai ce qui suit Makefile:

# The executable 'helloworld' depends on all 3 object files
helloworld: main.o hello.o world.o
        cc -o helloworld main.o hello.o world.o # Line starts with TAB!

# Build main.o (only requires main.c to exist)
main.o: main.c
        cc -c main.c # Line starts with TAB!

# Build hello.o (only requires hello.c to exist)
hello.o: hello.c
        cc -c hello.c # Line starts with TAB!

# Build world.o (only requires world.c to exist)
world.o: world.c
        cc -c world.c # Line starts with TAB!

#  Remove object files, executables (UNIX/Windows), Emacs backup files, 
#+ and core files
clean:
        rm -rf  *.o helloworld *~ *.core core # Line starts with TAB!

Maintenant, nous essayons de construire une cible

Quand je l'exécute contre la cible helloworld:

$ make helloworld
makefile:3: *** missing separator (did you mean TAB instead of 8 spaces?).  Stop.

Semble familier?

Résoudre le problème

Vous pouvez résoudre ce problème en modifiant les caractères Spacesréels Tab. J'avais l'habitude vimde réparer mon dossier. Ouvrez-le simplement:

$ vim makefile

Et puis exécutez cette commande dans:

:%s/^[ ]\+/^I/

REMARQUE: ^I est un caractère spécial. La frappe ^suivie de Isera interprétée différemment de Ctrl+ V- Ctrl+ I.

Cela remplacera toutes les lignes commençant par 1 ou plus Spacespar un réel Tab.

Maintenant, quand je réexécute ma helloworldcible:

$ make helloworld
cc -c main.c # Line starts with TAB!
cc -c hello.c # Line starts with TAB!
cc -c world.c # Line starts with TAB!
cc -o helloworld main.o hello.o world.o # Line starts with TAB!

Références

slm
la source
J'obtiens un motif d'erreur E486 introuvable lorsque j'essaie d'utiliser cette commande vim
Daniel Jacobson
@DanielJacobson - si vous avez un nouveau Q, veuillez le demander, les commentaires ne sont pas destinés à poser de nouvelles questions.
slm
^ Je viens de créer ^ I dans le fichier lui-même au lieu de l'onglet
Dim
1

Comme l'autre réponse l'a suggéré, les Makefiles ont besoin de caractères de tabulation, pas d'espaces. J'ai mon .vimrcjeu pour remplacer automatiquement tous les onglets par des espaces, je dois donc définir manuellement le paramètre inverse dans les Makefiles individuels. La vimcommande que j'utilise est la suivante:

:%s/^[ ]\+/\t/g
Emily Herbert
la source
J'utilise cette modeline (première ligne dans Makefile)# vim: set noet:
Michael D.
0

Remarque: La bonne façon de résoudre ce problème particulier consiste à corriger le Makefile de sorte que chaque ligne d'action de chaque recette soit mise en retrait à l'aide d'un caractère de tabulation unique, puis à soumettre un correctif pour cela aux développeurs d'origine.

Il s'agit d'un vilain hack, qui fonctionne avec les versions récentes de GNU make(si le problème est que le Makefile utilise des espaces plutôt que des tabulations, de manière cohérente):

make '.RECIPEPREFIX+='

Cela définira le GNU spécial make variable.RECIPEPREFIX sur un seul espace. Cette variable, depuis GNU make3.82 ou plus (2007), contrôle le caractère utilisé pour préfixer les lignes d'action des recettes. Si la variable est vide (comme c'est par défaut), des tabulations sont utilisées.

Exemple,

$ cat Makefile
all:
  echo hello
$ make '.RECIPEPREFIX+='
echo hello
hello

Exemple, montrant son utilisation avec >(en définissant la variable à l'intérieur du Makefile dans ce cas):

$ cat Makefile
.RECIPEPREFIX = >
all:
> echo hello
$ make
echo hello
hello

Voir également:

Kusalananda
la source