Как скомпилировать .o файлы в другой каталог, используя makefile? - PullRequest
0 голосов
/ 08 июля 2019

У меня есть несколько исходных файлов в разных каталогах.Теперь я хочу скомпилировать их объекты в другой каталог.Как я могу это сделать?

Я пробовал это, но выдает ошибку

`SRCDIR = ${SRC}/unix/fs
SRCDIR = ${SRC}/share/ch
SRCDIR = ${SRC}/linux/fs
SRCDIR = ${SRC}/unix/ch
OBJDIR = ${HOME}/build/libverify`

OBJS = ${OBJDIR}/check_format.o
OBJS += ${OBJDIR}/check_code.o

$(CC) $(CFLAGS) -c -o $(OBJS) $(SRCDIR)

Он успешно создает один файл check_format.o, но выдает ошибку для другого .o файла

gcc: error: /home/build/libverify/check_code.o: No such file or directory

1 Ответ

0 голосов
/ 08 июля 2019

Вот очень простой пример с одним файлом src/main.cpp, скомпилированным в объектный файл в obj/main.o:

OBJDIR = obj
SRCDIR = src
OBJS = $(OBJDIR)/main.o

build: $(OBJS)

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
    gcc -c $< -o $@

Как и в вашем make-файле, вы указываете каталоги obj и src. Затем вы указываете объектный файл (файлы), который хотите создать, в переменной OBJS.

Но тогда вам нужна цель для вызова make. Make использует первую цель, с которой сталкивается, если вы не передаете параметр. Поэтому здесь я добавил build:, который зависит от OBJS. Поэтому, когда я запускаю make, он запускает цель build, а затем пытается построить каждый из элементов в OBJS.

Наконец, нам нужно шаблонное правило, которое говорит:

Такие вещи выглядят как obj/%.o (% - это подстановочный знак), они зависят от исходного файла src/%.cpp (замените .cpp на .c или .cxx или что-то еще). В теле правила мы добавляем нашу линию make.

gcc -c $< -o $@ где $ <- зависимость (исходный файл), а $ @ - цель (объектный файл). </p>

Примечание: Я не указываю список источников (SRCS), потому что они подразумеваются сопоставлением с шаблоном объекта. То есть если я хочу создать файл obj/test.o, то это зависит от существующего файла src/test.cpp - на основе введенного мной здесь шаблона-правила. Поэтому я могу изменить свой make-файл, добавив больше исходных файлов, выполнив:

OBJDIR = obj
SRCDIR = src
OBJS = $(OBJDIR)/main.o
OBJS += $(OBJDIR)/fred.o
OBJS += $(OBJDIR)/bob.o

$(info objs: $(OBJS))

build: $(OBJS)

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
    gcc -c $< -o $@

Выход из режима работы make:

$ make
objs: obj/main.o obj/fred.o obj/bob.o
gcc -c src/main.cpp -o obj/main.o
gcc -c src/fred.cpp -o obj/fred.o
gcc -c src/bob.cpp -o obj/bob.o

Примечание: Я добавил строку $(info objs: $(OBJS)), чтобы распечатать значение OBJS

UPDATE

Это просто простая версия, как иметь более одной исходной папки - но вы захотите продолжать улучшать ее, так как она довольно проста

OBJ_DIR = obj
SOURCES = src1/bob.cpp
SOURCES += src2/fred.cpp
SOURCES += src3/main.cpp

OUT_DIRS = $(sort $(dir $(SOURCES)))    

# Calculate the objects files - should be: 
#   obj/src1/bob.o
#   obj/src2/fred.o
#   obj/src3/main.o
OBJS = $(addprefix $(OBJ_DIR)/,$(addsuffix .0,$(basename $(pathsubst %,%,$(SOURCES)))))

$(info objs: $(OBJS))

build: $(OBJS)

# Now this rule also requres the object sub-dirs to be created first
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(OUT_DIRS)
    gcc -c $< -o $@

# Rule to create the object dir folders
$(OUT_DIRS):
    mkdir -p $@

примечание: Я не тестировал этот - но я объяснил, как должен формироваться список OBJS - он "должен" работать. Так что здесь мы все еще используем то же правило шаблона, но теперь мы включаем исходные подпапки в пути к объектам, чтобы шаблон все равно совпадал. Вы получите структуру каталогов внутри obj/, как описано в комментарии.

Вы можете увидеть, добавив немного, если «интеллект» в make-файл станет более сложным, но теперь вы можете добавлять исходные файлы в любое количество подпапок или подпапок и т. Д. ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...