Создание make-файла
Поэтому мне нужно создать make-файл, который будет генерировать приложение, описанное ниже, и убедиться, что каждый сгенерированный файл имеет свое собственное правило.
Для make-файла: первый инструмент - это flex, который принимает файл с именем spec.l
и генерирует файл с именем lex.yy.c
, Другой инструмент под названием Bison ожидает файл calledspec.y
и сгенерирует файл spec.tab.c
, Если бизон вызывается с использованием директив -vd
также будет создан файл с именем spec.tab.h
(что необходимо при компиляции lex.yy.c). Два файла C могут быть скомпилированы в объектные файлы и затем связаны вместе с библиотеками yacc (-ly) и lex (-ll) для генерации компилятора (a.out
, Описанный вами make-файл должен генерировать следующие команды, если вы начинали только с spec.l и spec.y:
flex spec.l
bison -vd spec.y
gcc -c lex.yy.c
gcc -c spec.tab.c
gcc spec.tab.o lex.yy.o -ly -ll
я не уверен, с чего начать с этой проблемой
редактировать: что у меня есть
compiler: spec.tab.o lex.yy.o
gcc spec.tab.o lex.yy.o -ly –ll
lex.yy.c: spec.l
flex spec.l
spec.tab.c: spec.y
bison -vd spec.y
spec.tab.o: spec.tab.c
gcc -c spec.tab.c
lex.yy.o: lex.yy.c spec.tab.h
gcc –c lex.yy.c
clean:
rm –f *.c *.o a.out
1 ответ
Вы должны рассказать марке о зависимостях. Например, lex.yy.c
зависит от spec.l:
lex.yy.c: spec.l
flex spec.l
Первая строка сказать lex.yy.c
зависит от spec.l
, Второй рассказывает, как создать обновленную версию lex.yy.c
когда spec.l
новее. Мы в значительной степени повторяем этот шаблон с другими файлами. В случае calledspec.y
, у нас есть два результата, которые получены из одного и того же ввода / команды. По крайней мере, с помощью GNU make вы можете указать это следующим образом:
spec.tab.c spec.tab.h: calledspec.y
bison -vd calledspec.y
Затем вы в значительной степени повторяете процесс для зависимостей .o
(или же .obj
и т. д.) файлы на заголовках и C-файлы:
lex.yy.o: lex.yy.c spec.tab.h
$(cc) -c lex.yy.c
И последнее замечание: если вы не укажете иное, make создаст первую цель, указанную в make-файле, поэтому вы обычно хотите расположить ее сначала по конечному исполняемому файлу, а затем по другим целям:
parser: lex.yy.o y.tab.o
$(cc) -o parser lex.yy.o y.tab.o
lex.yy.o: lex.yy.c spec.tab.h
$(cc) -c lex.yy.c
И так далее. Это относится только к целям, но не к макросам, поэтому вы обычно видите несколько вещей, таких как:
cflags = -O2
... в начале файла make. Затем строки, которые вызывает компилятор, будут использовать это, что-то вроде:
lex.yy.o: lex.yy.c spec.tab.h
$(cc) $(cflags) -c lex.yy.c
И когда это выполняется, cflags
макрос будет расширен, поэтому выполняемая команда gcc -O2 -c lex.yy.c
(и это предопределяет cc
к имени компилятора, который он обычно ожидает использовать, поэтому Microsoft делает его равным cl
GNU to gcc
, так далее.)