2016-06-23 2 views
0

Я узнаю больше о make-файлах и наткнулся на пример, который я не совсем понимаю. Что происходит в чистом виде? Он принудительно удаляет все объектные файлы в/obj, но после этого я теряюсь. Я знаю, что он также удаляет exe-файл, но как это переводится в коде?Что происходит в этом чистом?

IDIR =../include 
CC=gcc 
CFLAGS=-I$(IDIR) 

ODIR=obj 
LDIR =../lib 

LIBS=-lm 

_DEPS = hellomake.h 
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) 

_OBJ = hellomake.o hellofunc.o 
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ)) 


$(ODIR)/%.o: %.c $(DEPS) 
     $(CC) -c -o [email protected] $< $(CFLAGS) 

../hellomake: $(OBJ) 
     gcc -o [email protected] $^ $(CFLAGS) $(LIBS) 

.PHONY: clean 

clean: 
     rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 
+0

Не похоже, что он удаляет «hellomake». – melpomene

+0

'$ (INCDIR)' похоже, что он должен быть '$ (IDIR)', потому что 'INCDIR' не определен нигде. – melpomene

+0

Что происходит в '* ~ core $ (INCDIR)/* ~', если он не удаляет hellomake? – user256017

ответ

2

Давайте посмотрим на линии

rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 

Первое, make делает это расширение $(...) переменных, что приводит к:

rm -f obj/*.o *~ core /*~ 

Последняя часть, скорее всего, ошибка: INCDIR является не определено, поэтому оно ничего не меняется. Вы имели в виду $(IDIR)?

Второе, что делает make, выполняет итоговую строку через /bin/sh -c .... Оболочка расширяет такие вещи, как подстановочные знаки.

Предположим, что объектные файлы в obj: hellomake.o и hellofunc.o. Затем obj/*.o становится obj/hellofunc.o obj/hellomake.o.

*~ соответствует всем файлам в текущей директории, заканчивающейся ~. Почему у вас такой файл? Потому что, когда вы используете emacs для редактирования файла foo, он по умолчанию оставит backup copy under foo~. Таким образом, это предназначено для удаления резервных файлов emacs.

core - это то, что вы обычно получаете, когда включаете core dumps, и программа, с которой вы запускаете аварийные ситуации (и вы не используете systemd). Его можно использовать для отладки аварии.

Последний шаблон выглядит так, как будто он соответствует файлам резервных копий emacs в INCDIR, но поскольку он не работает, он пытается найти файлы резервных копий в корневом каталоге, /. Обычно нет файлов в /, не говоря уже о резервных копиях emacs.

Если шаблон не соответствует файлам, поведение оболочки по умолчанию заключается в том, чтобы оставить его нерасширенным. Таким образом, последняя часть (/*~), вероятно, остается как есть. Давайте предположим, что у вас нет резервных копий файлов в текущем каталоге либо, так *~ также оставили в покое:

rm -f obj/hellofunc.o obj/hellomake.o *~ core /*~ 

Эта линия проходит rm, передавая ей массив строк в качестве аргументов:

{ "rm", "-f", "obj/hellofunc.o", "obj/hellomake.o", "*~", "core", "/*~" } 

rm (следующее соглашение) сканирует свои аргументы для строк, начинающихся с -, которые он обрабатывает как параметры. В этом случае есть один вариант: f. f («force») сообщает rm, чтобы не спрашивать о файлах, на которые у вас нет прав на запись; просто удалите их в любом случае. Он также подавляет ошибки, такие как те, которые вы обычно пытаетесь удалить не существующие файлы. (В частности, у вас, вероятно, нет файла, который буквально называется *~.)

Таким образом, все, что удаляет

  • объектные файлы в obj/
  • core в текущем каталоге
  • файлы
  • Emacs резервного копирования в текущем каталоге
  • EMACS файлы резервных копий в / (который, вероятно, дон 't существуют, и если они существуют, у вас, вероятно, нет разрешений на удаление)

при игнорировании любых ошибок.

+0

Действительно хороший ответ .. –

Смежные вопросы