сделайте жалуется “недостающий разделитель (Вы имели в виду ВКЛАДКУ?)”

Попытайтесь делать это (использующий , заключите в фигурные скобки расширение и шарики):

rm -f {a..z}/*.pdf

или

rm -f [a-z]/*.pdf

если Ваше отсутствие оболочки функция расширения фигурной скобки.

Вопреки [a-z], {a..z} (также поддерживаемый ksh93), не a glob, это - расширение фигурной скобки, это расширилось (прежде чем globs) независимо от того, существуют ли файлы или нет. Это похоже rm -f a/*.pdf b/*.pdf..., независимо от того, существуют ли a, b... или нет. Также отметьте это вопреки [a-z] то, где диапазон может быть иждивенцем локали (как может включать é, ś...), {a..z} только работы с диапазонами байта (и надежно только в ASCII обозначьте буквами диапазоны и диапазоны числа),

(Мерси Stephane Chazelas для объяснений)

8
19.04.2017, 22:50
4 ответа

Ошибка, с которой вы столкнулись:

*** отсутствует разделитель (вы имели в виду TAB вместо 8 пробелов?). Стоп.

Означает, что make-файл содержит пробелы вместо табуляции. Утилита make , как известно, требовательна к использованию пробела вместо Tab . Так что вполне вероятно, что make-файл содержит пробел в начале разделов правил внутри файла.

Пример

Допустим, у меня есть следующие 3 файла .c :

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

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

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

Скажем, у меня есть следующий 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!

Теперь мы пытаемся создать цель

, когда я запускаю ее против цели helloworld :

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

Вы знакомы?

Устранение проблемы

Это можно исправить, заменив Пробелы фактическими символами табуляции . Я использовал vim для восстановления своего файла. Просто откройте его:

$ vim makefile

А затем запустите эту команду в пределах:

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

ПРИМЕЧАНИЕ: ^ I - специальный символ. Ввод ^ , за которым следует I , будет интерпретироваться иначе, чем Ctrl + V - Ctrl + I .

Это заменит все строки, начинающиеся с 1 или более пробелов , на фактическую табуляцию .

Теперь, когда я перезапускаю свой helloworld target:

$ 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!

Ссылки

12
27.01.2020, 20:10

Как было сказано в другом ответе, в файлах Makefile нужны символы табуляции, а не символы пробела. Мой .vimrcнастроен на автоматическую замену всех вкладок пробелами, поэтому мне приходится вручную устанавливать обратную настройку в отдельных файлах Makefile. Команда vim, которую я использую, выглядит следующим образом::

:%s/^[ ]\+/\t/g
3
27.01.2020, 20:10

Примечание. :Правильный способ решения этой конкретной проблемы состоит в том, чтобы исправить Makefile таким образом, чтобы каждая строка действия каждого рецепта имела отступ с использованием одного символа табуляции, а затем отправить исправление для него первоначальным разработчикам.

Это уродливый хак, который работает с последними версиями GNU make(, если проблема в том, что Makefile последовательно использует пробелы вместо табуляции):

make '.RECIPEPREFIX+='

Это установит специальную переменную GNU make.RECIPEPREFIXв один пробел. Эта переменная, начиная с GNU make3.82 или около того (2007 ), управляет символом, используемым для префикса строк действий в рецептах. Если переменная пуста (, как по умолчанию ), используются вкладки.

Пример,

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

Пример, показывающий его использование с>(установкой переменной внутри Makefile в этом случае):

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

См. также:

1
27.01.2020, 20:10

Проблема была в том,

.PHONY foo

И я должен был

.PHONY: foo

Я получаю эту ошибку,

❯ make foo
Makefile:1: *** missing separator.  Stop.
0
04.03.2021, 04:41

Теги

Похожие вопросы