Как мне прочитать исходные файлы из каталога и создать объектные файлы в другой папке в make-файле? - PullRequest
0 голосов
/ 11 июля 2020

У меня есть следующие исходные файлы:

% ls 
data_lexicon.c  data_lexicon.h  lex.l           makefile

И следующий make-файл:

% cat makefile
CC              = cc
CFLAGS          = -Wall -std=c89
LDFLAGS         = -ll
OBJFILES        = lex.o data_lexicon.o
TARGET          = lexical_analyzer_1

all:            $(TARGET) lex.c

lex.c:          lex.l data_lexicon.h
                lex -olex.c lex.l

$(TARGET):      $(OBJFILES)
                $(CC) $(CFLAGS) -o $(TARGET) $(OBJFILES) $(LDFLAGS)

clean:
                rm -f $(OBJFILES) lex.c $(TARGET)

Если я это сделаю make all я получу:

% ls 
data_lexicon.c          data_lexicon.o          lex.l
lexical_analyzer_1      data_lexicon.h          lex.c
lex.o                   makefile

Пока все хорошо.

Однако я хотел бы переместить исходные файлы (data_lexicon. c, data_lexicon.h, lex.l) в папку src и сгенерировать промежуточные файлы (data_lexicon .o lex. c, lex.o) в папку obj.

Я создаю обе папки, но не понимаю, как должен быть настроен файл makefile.

Я использую программу make FreeBSD, поэтому чем более портативным будет решение, тем лучше.

1 Ответ

1 голос
/ 11 июля 2020

Однако я хотел бы переместить исходные файлы (data_lexicon. c, data_lexicon.h, lex.l) в папку sr c и сгенерировать промежуточные файлы (data_lexicon.o lex. c, lex.o) в папку obj.

Меня никогда не перестает удивлять, как люди настаивают на дополнительной работе для себя. Вы, конечно, можете делать то, что описываете, но это потребует написания явных правил для объектных файлов.

Однако, прежде всего, вы должны понимать, что make сам по себе ничего не знает о каталогах. (Традиционный make в любом случае не знает. GNU make и, возможно, другие знают о них немного .) То есть он не имеет никакого смысла в различных каталогах, по которым он разрешает имена файлов. . Скорее, каждое имя цели разрешается относительно рабочего каталога make. Если вы хотите сослаться на что-то в подкаталоге, вы должны это сказать. Для начала:

OBJFILES        = obj/lex.o obj/data_lexicon.o

То же самое касается целевых и обязательных имен в правилах:

obj/lex.c:      src/lex.l src/data_lexicon.h
                lex -o$@ src/lex.l

Это также одна из причин отдать предпочтение автоматическим c переменным make, таким как как $@ в приведенном выше правиле, представляющем имя создаваемой цели.

В настоящее время ваш make-файл полагается на встроенное правило make для создания объектных файлов из соответствующих C исходных файлов, но «соответствующий» означает, что имена цели и предварительных условий идентичны , включая любые компоненты пути, за исключением суффиксов (.c vs .o). У вас больше не будет этой корреспонденции для data_lexicon.o, поэтому вам нужно будет написать явное правило для ее построения. Эта часть оставлена ​​в качестве упражнения.

...