Ваш макрос getobj
выглядит так, как будто вы хотите объявить правило (target: prerequisites
).Но использование, которое вы пытаетесь использовать, выглядит так, как будто вы пытаетесь присвоить результат его расширения переменной, что на самом деле не имеет смысла.
Итак, давайте проигнорируем правило просмотра и сосредоточимся на вашей цели (насколько я понимаю): определите макрос, который получает basename
каждого слова, которое ему передано, и заменяет его на $(OBJDIR)/<basename>.o
.Вы были почти там:
getobj = $(patsubst %,$(OBJDIR)/%.o,$(basename $(1)))
должен сделать это, где $(1)
- это параметр макроса, список слов, разделенных пробелами.И вы вызываете его с помощью call
make-функции :
TESTHNF_OBJS2 = $(call getobj,$(TESTHNF_CPPS) $(TESTHNF_CS))
call
make-функция заменяет $(1)
на параметр $(TESTHNF_CPPS) $(TESTHNF_CS)
в определении getobj
и возвращает результат.В вашем случае это эквивалентно:
TESTHNF_OBJS2 = $(patsubst %,$(OBJDIR)/%.o,$(basename $(TESTHNF_CPPS) $(TESTHNF_CS)))
Когда TESTHNF_OBJS2
будет расширен, результат будет:
objects/testhnf.o objects/timings.o ... objects/lip.o
Вернуться к просмотру правила.Если вместо этого вам нужно создать правило make:
<basename>: $(OBJDIR)/<basename>.o
для каждого <basename>
в вашем списке, плюс определить переменную TESTHNF_OBJS
, в которой перечислены все соответствующие объектные файлы, то вы можете использовать комбинациюforeach
, eval
и call
.Но все немного сложнее, потому что make один раз расширяет параметр eval
, создает экземпляр результата как конструкцию make и расширяет ее еще раз при синтаксическом анализе как любые обычные конструкции make.Таким образом, двойное расширение иногда следует избегать путем удвоения знаков $
;это не ваш случай, но лучше помнить об этом при использовании подобных вещей.
OBJDIR = objects
TESTHNF_CPPS = testhnf.cpp timings.cpp LongModular.cpp VeryLong.cpp VeryLongModular.cpp squfof.cpp
TESTHNF_CS = mt19937int.c lip.c
TESTHNF_OBJS :=
# $(1): basename of one source file
define getobj
$(1): $(OBJDIR)/$(1).o
TESTHNF_OBJS += $(OBJDIR)/$(1).o
endef
$(foreach b,$(basename $(TESTHNF_CPPS) $(TESTHNF_CS)),$(eval $(call $(b))))
clean:
rm -f $(TESTHNF_OBJS)
Поскольку все это довольно сложно, а преимущества довольно малы, вероятно, лучше придерживаться более простогоконструкции, которые легче понять и поддерживать:
OBJDIR := objects
TESTHNF_CPPS := testhnf.cpp timings.cpp LongModular.cpp VeryLong.cpp VeryLongModular.cpp squfof.cpp
TESTHNF_CS := mt19937int.c lip.c
BASENAMES := $(basename $(TESTHNF_CPPS) $(TESTHNF_CS))
TESTHNF_OBJS := $(addprefix $(OBJDIR)/,$(addsuffix .o,$(BASENAMES)))
$(BASENAMES): %: $(OBJDIR)/%.o
clean:
rm -f $(TESTHNF_OBJS)
Правило статическое правило .