Подавить вывод ошибок правил - PullRequest
10 голосов
/ 13 августа 2010

У меня есть правило, которое создает каталог

bin:
    -mkdir $@

Однако после первого создания каталога я получаю следующий вывод:

mkdir bin
mkdir: cannot create directory `bin': File exists
make: [bin] Error 1 (ignored)

Есть ли способ, которым я могу запустить правило, только если каталог не существует, или подавить вывод, когда каталог уже существует?

Ответы [ 6 ]

17 голосов
/ 16 апреля 2012

Другой способ подавить вывод make: error ... (ignored) состоит в добавлении || true к команде, которая может завершиться ошибкой.Пример с grep, который проверяет ошибки в файле журнала LaTeX:

undefined:
  @grep -i undefined *.log || true

Без || true, make жалуется, когда grep не находит совпадений.

Это работает для всех командне только MKDIR;вот почему я добавил этот ответ.

8 голосов
/ 24 августа 2010

Традиционный способ обработки каталога - использовать файл штампа, от которого зависит и который создает каталог в качестве побочного эффекта.Удалите файл штампа при создании distclean или любой другой вашей «действительно чистой» цели:

bin/.dirstamp:
    mkdir -p $(DIRS)
    touch $@

bin/foo: bin/.dirstamp
    $(MKFOO) -o $@

distclean:
    rm -rf bin

Причина этого заключается в следующем: при создании / удалении файла в bin mtimeсодержащей директории обновляется.Если цель зависит от bin, то при следующем запуске make она будет воссоздавать ненужные файлы.

8 голосов
/ 13 августа 2010

Ошибка уже игнорируется лидирующей '-' в командной строке. Если вы действительно хотите потерять сообщения об ошибках от mkdir, используйте перенаправление ввода / вывода:

bin:
    -mkdir bin 2> /dev/null

Вы все равно получите предупреждение "ignore" из make, поэтому, возможно, лучше использовать опцию mkdir, которая не вызывает сбой, когда цель уже существует, то есть -p опция:

MKDIR_P = mkdir -p

bin:
    ${MKDIR_P} $@

Параметр -p фактически создает все каталоги, которые отсутствуют в данных путях, поэтому он может создать несколько каталогов за один вызов, но побочным эффектом является то, что он не генерирует ошибку для уже существующих каталогов. , Это предполагает реализацию POSIX-ih mkdir; старые машины могут не поддерживать его (хотя это уже давно стало стандартом).

0 голосов
/ 20 августа 2010

Make предполагает, что первая цель является целью по умолчанию.Если это ваш полный make-файл, то он всегда должен пытаться переделать цель по умолчанию, которая является bin.Вставьте следующие строки в начало вашего make-файла:

all: bin
.PHONY: all
0 голосов
/ 14 августа 2010

Ну, я закончил с этой конструкцией, может быть, кто-то найдет ее полезной или может прокомментировать:

BINDIR = .
TMPDIR = tmp
OUTDIRS = $(BINDIR) $(TMPDIR)
$(OUTDIRS):
    @test -d $@ || mkdir $@
0 голосов
/ 13 августа 2010

Ваше правило не должно выполняться, если его цель не существует или устарела из-за его зависимостей.Другими словами, вы никогда не должны сталкиваться с этой ошибкой.

[Пример добавления]

[max@truth tmp]$ ls -la
total 20
drwxr-xr-x.  2 max users 4096 Aug 14 21:11 .
drwx------. 80 max max   4096 Aug 14 18:25 ..
-rw-rw-r--   1 max max     38 Aug 14 21:11 Makefile
[max@truth tmp]$ cat Makefile 
.PHONY: all
all: bin

bin:
    mkdir $@

[max@truth tmp]$ make
mkdir bin
[max@truth tmp]$ ls -la
total 24
drwxr-xr-x.  3 max users 4096 Aug 14 21:11 .
drwx------. 80 max max   4096 Aug 14 18:25 ..
drwxrwxr-x   2 max max   4096 Aug 14 21:11 bin
-rw-rw-r--   1 max max     38 Aug 14 21:11 Makefile
[max@truth tmp]$ make
make: Nothing to be done for `all'.
[max@truth tmp]$ make
make: Nothing to be done for `all'.

От чего зависит ваша папка?Является ли ваша папка фальшивой мишенью?

...