Makefiles, сборка исходного кода из другой папки с файлами obj в подпапку текущей? - PullRequest
3 голосов
/ 11 ноября 2011

Фон

Я застрял на этом некоторое время, поэтому очень надеюсь, что кто-то может помочь! У меня есть массив папок с исходным кодом C / C ++, которые являются общим кодом для нескольких проектов, и еще несколько папок (со стороны других), которые содержат сами проекты.

Когда я строю проект, я хочу иметь возможность включать sources.mk из внешней папки, и чтобы объекты для этих включенных источников помещались в подпапку каталога проекта, чтобы не загромождать общую папку. с объектно-ориентированными объектами (каждый проект может иметь разные флаги, оптимизацию и т. д.)

В качестве примера приведем структуру папок:

source/common.mk
source/common/stuff/aaa.c
source/common/stuff/sources.mk
source/projects/thing/main.c
source/projects/thing/Makefile

Makefile в проектах / штуках будет включать в себя ../../common/stuff/sources.mk, чтобы получить список источников в этой папке (для добавления в список источников, уже находящихся в Makefile), и будет включите ../../common.mk, чтобы получить правила для создания .o из .c.

Источникам в sources.mk предшествует относительный путь между Makefile и sources.mk следующим образом:

THIS_TOP := $(dir $(lastword $(MAKEFILE_LIST)))
SOURCES_C += $(THIS_TOP)/aaa.c

Я хочу, чтобы все объекты входили в (каталог, в который я встраиваюсь) / objdir /, предпочтительно с подпапками на основе пути от источника, например ::

cd projects/thing; make

должно создать:

projects/thing/objdir/main.o
projects/thing/objdir/common/stuff/aaa.o

Итак, я составляю список объектных файлов и удаляю ../ из относительного пути следующим образом:

__OBJECTS=$(SOURCES_C:.c=.o) $(SOURCES_CPP:.cpp=.o)
_OBJECTS = $(subst ../,,$(__OBJECTS))
OBJECTS = $(patsubst %,$(OBJDIR)/%,$(_OBJECTS))

Пока все хорошо, верно? Но ...

Этот лот составляет список того, как именно я хочу, чтобы мои объекты создавались, никаких проблем там нет. Я могу создать objdir и его подпапки на основе содержимого списка, и я могу предоставить этот список в качестве зависимости от конечного исполняемого файла. Если бы объекты были на самом деле там, я был бы в порядке!

У меня проблема в том, что я не могу придумать правило (перейти на common.mk) для создания этого локального .o из удаленного .c! Я попробовал второе расширение, чтобы попытаться создать правило, которое ищет в списке файлов .c тот, который соответствует требуемому .o, но не может это сделать из-за отсутствия нескольких подстановочных знаков в фильтр ...

.SECOND_EXPANSION:
$(OBJDIR)/%.o: $$(filter %$$(addsuffix .c,$$(subst .o,,$$(notdir $$@))),$$(SOURCES_C))
    $(CC) -o $@ $< $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(WARNINGS) $(DEPGENFLAGS)

Я действительно рву волосы на этом ... Кто-нибудь справился с чем-то подобным? Если ничего не помогает, я просто собираю их как статические библиотеки (библиотеки уже создаются в подкаталоге папки проекта так, как я хочу), но так как это создает дополнительные make-файлы для поддержки, я бы действительно хотел этого избежать.

Любая помощь с благодарностью!

Спасибо

Олли

Ответы [ 2 ]

0 голосов
/ 11 ноября 2011

Вы пробовали vpath?

Я бы попробовал написать что-то вроде

vpath %.c <path/to/source/common/relative/to/your/objdir/common>

Я не уверен, что это будет работать, потому что% -patternэто может быть файл с указанием его пути, полученный из сложного правила .o: .c, которое вы используете.

Другой возможный подход заключается в предоставлении двух различных неявных правил для создания $(OBJDIR)/common/%.o и $(OBJDIR)/%.o с помощьютот же рецепт:

COMPILE_C = $(CC) -o $@ $< $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(WARNINGS) $(DEPGENFLAGS)

$(OBJDIR)/common/%.o : <relative/path/to/source/common>/%.c
    $(COMPILE_C)
$(OBJDIR)/%.o : ../%.c
    $(COMPILE_C)
0 голосов
/ 11 ноября 2011

Я почесал голову над вашей проблемой и в конце концов решил, что невозможно сделать то, что вы хотите, с одним единственным шаблоном .o:.c. Вы должны полагаться на одно шаблонное правило для библиотеки каталога.

Мое предложение будет определять правило шаблона в каждом файле sources.mk, в котором будут использоваться две переменные, которые будут предоставлены main Makefile:

TOPDIR = ../..
OBJDIR = objdir

С правилом шаблона, определенным в файле sources.mk следующим образом:

$(OBJDIR)/$(THIS_TOP)/*.o: $(TOPDIR)/$(THIS_TOP)/*.c
    $(CC) -o $@ $< $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(WARNINGS) $(DEPGENFLAGS)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...