Я работал над созданием файла Makefile с несколькими конфигурациями (который поддерживает отдельные цели' debug 'и' release '), и столкнулись со странной проблемой, которая, похоже, является ошибкой в GNU make.
Кажется, что GNU make неправильно расширяет целевые переменные, когда на эти переменные ссылаются в неявном правиле. Вот упрощенный Makefile, который показывает эту проблему:
all:
@echo specify configuration 'debug' or 'release'
OBJS := foo.o bar.o
BUILDDIR = .build/$(CONFIG)
TARGET = $(addprefix $(BUILDDIR)/,$(OBJS))
debug: CONFIG := debug
release: CONFIG := release
#CONFIG := debug
debug: $(TARGET)
release: $(TARGET)
clean:
rm -rf .build
$(BUILDDIR)/%.o: %.c
@echo [$(BUILDDIR)/$*.o] should be [$@]
@mkdir -p $(dir $@)
$(CC) -c $< -o $@
При указании цели «отладка» для параметра CONFIG устанавливается значение «отладка», а BUILDDIR и TARGET также расширяются должным образом. Однако в неявном правиле построения исходного файла из объекта$ @ раскрывается, как будто CONFIG не существует.
Вот результат использования этого Makefile:
$ make debug
[.build/debug/foo.o] should be [.build//foo.o]
cc -c foo.c -o .build//foo.o
[.build/debug/bar.o] should be [.build//bar.o]
cc -c bar.c -o .build//bar.o
Это показывает, что BUILDDIR расширяется нормально, но в результате получается $ @ is not. If I then comment out the target variable specification and manually set CONFIG := debug (the commented line above), I get what I would expect:
$ make debug
[.build/debug/foo.o] should be [.build/debug/foo.o]
cc -c foo.c -o .build/debug/foo.o
[.build/debug/bar.o] should be [.build/debug/bar.o]
cc -c bar.c -o .build/debug/bar.o
I've tested this with both make-3.81 on Gentoo and MinGW, and make-3.82 on Gentoo. All exhibit the same behavior.
I find it difficult to believe that I would be the first to come across this problem, so I'm guessing I'm probably just doing something wrong -- but I'll be honest: I don't see how I could be. :)
Are there any make gurus out there that might be able to shed some light on this issue? Thanks!