Круговая зависимость Makefile

Вот мой Makefile:

.PHONY: all homework1
CFLAGS= -g -O0 -Wall -Werror -Wno-unused-function
LDFLAGS= -lm

all : homework1

homework1 : program.tab.o program.lex.o
%.o : %.c
    gcc -o$@ -c $(CFLAGS) $<
%.lex.c : %.lex %.tab.h
    flex -o$@ $<
%.tab.c %.tab.h : %.y
    bison --verbose -o$@ -d $<

Всякий раз, когда я пытаюсь скомпилировать, я получаю предупреждение make: Circular program.lex <- program.lex.o dependency dropped. Я не вижу, как program.lex вообще зависит от program.lex.o в make-файле. Я вижу, что дерево зависимостей имеет глубину около 4 слоев, но оно не выглядит круглым.

Как я могу улучшить свой make-файл?


person Mike    schedule 09.09.2010    source источник
comment
Мало того, что ваш вопрос помечен как домашнее задание (никто вас об этом не спрашивает), так еще и ваш исполняемый файл называется домашним заданием. Просто наблюдение! Без комментариев :D   -  person Rahul    schedule 09.09.2010
comment
Это домашнее задание. Конечно, домашнее задание — написать файлы flex и bison, а не makefile. Makefile должен быть легкой частью: P   -  person Mike    schedule 09.09.2010
comment
Makefiles никогда не бывает легким, по моему опыту.   -  person reinierpost    schedule 11.10.2010


Ответы (4)


Карп @aaa прав, это неявное правило, но это не одно из правил LEX, потому что они строят N.c или N.r из N.l, а это правило строит N из N.o. Мне это кажется похожим на правило «Связывание одного объектного файла», описанное в info (make) Catalogue of Rules. Переименование файлов .lex в файлы .l решит эту проблему.

Кроме того: работая с flex, я не думаю, что вам действительно нужен файл .tab.h для сборки исходного кода лексера. Попробуйте это вместо этого:

%.l.c: %.l
    flex -o$@ $<
program.l.o: program.tab.h

Это добавит дополнительную зависимость к program.l.o.

person Jack Kelly    schedule 09.09.2010
comment
Спасибо! Устраняет проблему. Хотел бы я знать все эти неявные правила. Вы не знаете, могу ли я их отключить? - person Mike; 09.09.2010
comment
@Mike: gnu.org/software/make/manual /make.html#Catalogue-of-Rules — это каталог всех правил. make -r будет работать без неявных правил, но я не помню, работает ли это как параметр в переменной MAKEFLAGS или его нужно указывать в командной строке. - person Jack Kelly; 10.09.2010

Проблема в том, что в Make (ну, во всяком случае, в GNUMake) есть неявное правило для связывания одного объектного файла для сборки исполняемого файла. В вашем make-файле ничего не сказано о том, как собрать program.lex, поэтому Make прибегает к неявному правилу сборки из program.lex.o.

Поскольку ваш макет, по-видимому, зависит от наличия program.lex для начала, вы можете подавить неявное правило, добавив собственное правило для program.lex (которое ничего не делает):

program.lex:;
person Beta    schedule 09.09.2010
comment
Хороший трюк, чтобы заставить замолчать неявное правило. Я не видел этого раньше. - person Jack Kelly; 09.09.2010

запустите make с -d:

Considering target file `all'.
 File `all' does not exist.
  Considering target file `homework1'.
   File `homework1' does not exist.
    Considering target file `program.lex.o'.
     File `program.lex.o' does not exist.
     Looking for an implicit rule for `program.lex.o'.
     Trying pattern rule with stem `program.lex'.
     Trying implicit prerequisite `program.lex.c'.
     Found an implicit rule for `program.lex.o'.
      Considering target file `program.lex.c'.
       Looking for an implicit rule for `program.lex.c'.
       Trying pattern rule with stem `program'.
       Trying implicit prerequisite `program.lex'.
       Found an implicit rule for `program.lex.c'.
        Considering target file `program.lex'.
         Looking for an implicit rule for `program.lex'.
         Trying pattern rule with stem `program.lex'.
         Trying implicit prerequisite `program.lex.o'.
         Found an implicit rule for `program.lex'.
make: Circular program.lex <- program.lex.o dependency dropped.

есть правило неявной ссылки, которое вызывается, а не lex, который я изначально указал

избавиться от расширений ".lex.*"

person Anycorn    schedule 09.09.2010
comment
Нет - это правило пытается связать программы, созданные из одного объектного файла. - person Jack Kelly; 09.09.2010

Моя немедленная реакция заключалась в том, что вам нужно действие после правила, которое говорит homework1: program.tab.o program.lex.o:

 homework1:  program.tab.o program.lex.o
         ${CC} -o $@ program.tab.o program.lex.o ${LDFLAGS}

Однако, поскольку вы также отметили homework1 как .PHONY, возможно, вы еще не готовы связать программу. Но ваша проблема воспроизводится...

Обычно исходный код для Lex (или Flex) хранится в файле .l, а не в файле .lex, поэтому я изменил make-файл на:

.PHONY: all homework1
CFLAGS= -g -O0 -Wall -Werror -Wno-unused-function
LDFLAGS= -lm

all : homework1

homework1 : program.tab.o program.lex.o

%.o : %.c
    gcc -o $@ -c $(CFLAGS) $<
%.lex.c : %.l %.tab.h
    flex -o $@ $<
%.tab.c %.tab.h : %.y
    bison --verbose -o $@ -d $<

Предупреждающее сообщение исчезает. (Сначала я создал вашу среду, используя «touch program.lex program.y», затем я переместил program.lex в program.l).

Тем не менее, я все еще не совсем уверен, что происходит в сломанной версии, но, вероятно, это вращается вокруг неявных правил, предложенных @Beta.

person Jonathan Leffler    schedule 09.09.2010
comment
Поломка в сломанной версии связана с правилом связывания одного объектного файла (foo.o -> foo). - person Jack Kelly; 09.09.2010