Как мне сделать простой в обновлении make-файл? - PullRequest
1 голос
/ 26 октября 2011

Мой make-файл выглядит примерно так:

FOO_OBJECT_FILES := $(OBJDIR)/Foo.cpp.o
BAR_OBJECT_FILES := $(OBJDIR)/Bar.cpp.o $(OBJDIR)Bar.c.o
ALL_OBJECT_FILES := $(FOO_OBJECT_FILES) $(BAR_OBJECT_FILES)

$(BINDIR)/Foo.a: $(FOO_OBJECT_FILES)
    # Rules for making a static library out of Foo's object files go here.

$(BINDIR)/Bar.a: $(BAR_OBJECT_FILES)
    # This uses the exact same command sequence as the previous rule.

$(BINDIR)/All.a: $(ALL_OBJECT_FILES)
       # Ditto.

# ...

Когда (не , если ) добавлено больше целей в проект, разработчику придется обновить как минимум три вещи:

  1. Список объектных файлов новой цели
  2. Список всех объектных файлов
  3. Цели для создания новой цели, даже если она использует те же правила, что идругие

Есть ли способ упростить этот процесс, или я застрял с ним?

Я пытался использовать правила подстановочных знаков, но похоже, что они не работают с макросами.

$(BINDIR)/%.a: $(%_OBJECT_FILES)
    # ...

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

OBJECT_FILES_Foo: $(OBJDIR)/Foo.cpp.o
OBJECT_FILES_Bar: $(OBJDIR)/Bar.cpp.o $(OBJDIR)Bar.c.o
OBJECT_FILES_All: FOO_OBJECT_FILES BAR_OBJECT_FILES

$(BINDIR)/%.a: OBJECT_FILES_%
    # This rule can't see into the object file lists to use them to build.

Нет лучшего способа?

Ответы [ 3 ]

1 голос
/ 27 октября 2011

Вероятно, есть много способов сделать это. Одним из таких способов является следующее. Все, что нужно сделать для новой цели - это добавить ее имя в список модулей и дать список зависимостей для нее.

BINDIR := bin
OBJDIR := obj

MODULES := Foo Bar

Foo_OBJS := $(OBJDIR)/Foo.cpp.o
Bar_OBJS := $(OBJDIR)/Bar.cpp.o $(OBJDIR)/Bar.c.o

#####################################################
#                                                   #
#   Nothing below here should need to be altered.   #
#                                                   #
#####################################################

All_OBJS := $(foreach mod, $(MODULES),$($(mod)_OBJS))

define rule
$(BINDIR)/$(1).a: $($(1)_OBJS)
    @echo
    @echo 'Target: $$@'
    @echo 'Deps  : $$^'
endef

$(foreach lib, All $(MODULES), $(eval $(call rule,$(lib))))

###########################################
#                                         #
# The next part is just here for testing. #
#                                         #
###########################################

.PHONY: all
all: $(foreach lib, All $(MODULES),$(BINDIR)/$(lib).a)

%.o:
    @echo Making $@
1 голос
/ 27 октября 2011

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

1 голос
/ 27 октября 2011

Вы не можете много делать с 1 и 2, это произвольные вещи, которые Make не может вывести. Вы можете немного улучшить 3:

$(BINDIR)/%.a:
    # commands for making a static library

# adding a new target:
QUARTZ_OBJECT_FILES := $(OBJDIR)/Quartz.cpp.o $(OBJDIR)Arbitrary.o
ALL_OBJECT_FILES += $(QUARTZ_OBJECT_FILES) 
$(BINDIR)/Quartz.a: $(QUARTZ_OBJECT_FILES)

Вы можете использовать шаблон, чтобы уменьшить эти три строки до одной:

$(eval $(call template, QUARTZ_OBJECT_FILES, $(OBJDIR)/Quartz.cpp.o $(OBJDIR)Arbitrary.o))

но стоит ли оно того?

...