поместите все объектные файлы в один каталог для распределенных источников в make-файле - PullRequest
0 голосов
/ 24 октября 2018

Мой исходный код не централизован.Я хочу поместить все мои объекты в один каталог ./build/obj.

Вот то, что у меня есть до сих пор

ROOT=.

BUILDDIR=$(ROOT)/build
BINDIR=$(BUILDDIR)/bin
OBJDIR=$(BUILDDIR)/obj
CC=$(XCOMPILE)gcc
BIN=my-reader

CFLAGS+=\
        -Wall \
        -Wextra \
        -Werror \
        -pedantic \
        -std=gnu11 \
        $(INCLUDE)

SRCDIRS+=\
         $(ROOT)/src \
         $(ROOT)/../../folder0/folder01/src \
         $(ROOT)/../../folder0/folder02/src \
         $(ROOT)/../../folder1/folder03/folder04/i2c/src \
         $(ROOT)/../../folder1/folder03/folder04/spi/src \
         $(ROOT)/../../folder1/folder03/folder04/system/src \
         $(ROOT)/../../folder2/folder03/folder04/chip-1-api/src \
         $(ROOT)/../../folder2/folder03/folder04/chip-2-api/src

DEPDIRS+=\
         $(SRCDIRS)

SRC+=$(shell find $(SRCDIRS) -type f -name "*\.c")
DEP+=$(shell find $(DEPDIRS) -type f -name "*\.h")

OBJ=$(patsubst %.c, $(OBJDIR)/%.o, $(SRC))
INCLUDE=$(foreach d, $(DEP),-I $(dir $d))

test:
    echo $(SRC)

all: CFLAGS+=-O3
all: _all

debug: CFLAGS+=-ggdb
debug: CPPFLAGS+=-DDEBUG
debug: _all

_all: $(BINDIR) $(BINDIR)/$(BIN)

$(BINDIR)/$(BIN): $(OBJ) | $(BINDIR)
    $(CC) $(CPPFLAGS) $(CFLAGS) $^ -o $@

$(BINDIR):
    mkdir -p $@

$(OBJDIR)/%.o: %.c $(DEP)
    $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@

.PHONY: clean
clean:
    rm -rf $(BUILDDIR)

Это не совсем подходит для меня, поскольку создает некоторые файлы и каталоги, в которых находится make-файл.Что я действительно хочу, чтобы все .o файлы были в ./build/obj.Я провожу несколько дней, пытаясь выяснить, есть ли общий способ сделать это, но, похоже, его нет.Насколько я понимаю, для того, чтобы поместить все мои файлы в каталог ./build/obj, мне нужно создать конкретную цель для каждого из них, что противоречит цели использования универсального make-файла.Кто-нибудь знает, возможно ли то, что я пытаюсь сделать?Я видел людей, которые генерировали файлы .dep (в которых были свои цели), а затем включали их в make-файлы.К сожалению, я не знаю, как это сделать.Буду признателен за любую помощь в этом.

1 Ответ

0 голосов
/ 24 октября 2018

Это очень просто, с использованием VPATH .Во-первых, вы должны убедиться, что ваша переменная OBJS содержит то, что вы хотите построить.В настоящее время у вас есть это:

OBJ=$(patsubst %.c, $(OBJDIR)/%.o, $(SRC))

, что неверно, потому что SRC содержит пути типа ./../../folder0/folder02/src/foobar.c, что означает, что после patsubst вы получите пути типа ./build/obj/./../../folder0/folder02/src/foobar.o, что явно не то, что выхочу.Используйте вместо этого:

OBJ = $(patsubst %.c, $(OBJDIR)/%.o, $(notdir $(SRC)))

, который для каждого исходного файла somepath/foobar.c, независимо от значения somepath , даст вам ./build/obj/foobar.o, что вам нужно.

Затем сохраните правило, которое создает этот .o из файла .c.Наконец, используйте VPATH, чтобы указать make, где искать исходные файлы, если они не существуют в локальном каталоге:

VPATH = $(SRCDIRS)

Это все, что вам нужно сделать.

Я должен отметить, чтоваш INCLUDES немного сломан: у вас будет огромное количество дубликатов каталогов, добавленных с -I.Вместо этого:

INCLUDE=$(foreach d, $(DEP),-I $(dir $d))

Вы должны использовать:

INCLUDE = $(addprefix -I,$(sort $(dir $(DEP)))

Функция sort также будет уникальной, и вам не понадобится foreach, потому что большинство функций ввозьмите несколько слов и оперируйте всеми ними.

В качестве последнего замечания вы должны использовать := вместо =, это будет намного более эффективным.То, как вы пишете здесь каждый раз, когда эти переменные раскрываются, будет перезапускать операции find и т. Д. Вставьте echo find 1>&2; в вызовы shell функций перед find и посмотрите, сколько раззапустите ...

О, тогда действительно последнее замечание: при настройке этого параметра теперь каждый отдельный исходный файл будет перестраиваться при каждом изменении любого заголовочного файла (вы добавили $(DEPS) в качестве предварительного условия для$(OBJDIR)/%.o цель).Может быть, это то, что вы хотите, но это необычно.

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