Modifier la valeur de la variable Makefile dans le corps cible
Existe-t-il un moyen de réaffecter la valeur de la variable Makefile à l'intérieur du corps cible?
Ce que j'essaie de faire est d'ajouter des drapeaux supplémentaires pour la compilation de débogage:
%.erl: %.beam
$(ERLC) $(ERLFLAGS) -o ebin $<
test: clean debug_compile_flag compile compile_test
debug_compile:
$(ERLCFLAGS) += -DTEST
Donc, si j'Invoque Test target, je voudrais nettoyer mon environnement, ajouter de nouveaux drapeaux (comme -DTEST aux existants), compiler à nouveau le code entier (premières sources, puis modules de test).
Je ne veux pas copier / coller le code pour compiler avec de nouveaux drapeaux définis depuis il y a beaucoup de logique mis ici et là.
Existe-t-il un moyen facile de redéfinir la valeur de la variable afin que je puisse réutiliser le code existant?
4 réponses
Edit: Comme expliqué par la Bêta dans le autre réponse, c'est possible.
Non. Il n'y a aucun moyen de le faire dans le Makefile. Vous pouvez cependant modifier la valeur d'une variable sur la ligne de commande make
. Si vous réécrivez votre Makefile comme suit:
ERLCFLAGS += $(ERLCFLAGSADDED)
%.erl: %.beam
$(ERLC) $(ERLCFLAGS) -o ebin $<
test: clean compile compile_test
Ensuite, vous pouvez appeler make pour effectuer vos tests en utilisant:
make ERLCFLAGSADDED=-DTEST test
Oui, il y a un moyen facile de le faire, et sans relancer Make. Utilisez une valeur variable spécifique à la cible :
test: clean debug_compile
debug_compile: ERLCFLAGS += -DTEST
debug_compile: compile compile_test;
Une autre réponse est ici: Define make variable au moment de l'exécution de la règle.
Pour les paresseux, vous pouvez avoir des règles comme suit (FLAG
et DEBUG
sont mes variables):
.DBG:
$(eval FLAG += $(DEBUG))
Je voulais ajouter une cible dans un makefile pour exécuter des tests, ce qui impliquait de recompiler le code source avec des indicateurs de débogage. La réponse de Ian: https://stackoverflow.com/a/15561911/ était la seule solution qui a fonctionné.
Voici le Makefile que j'ai trouvé, qui garantit l'ordre d'exécution lors de l'exécution de make tests
:
TARGET = a.out
CC = g++
GENERIC_F = -Wall -Wextra -I. -Idoctest/doctest/
CFLAGS = -O0 -std=c++11 $(GENERIC_F)
DEBUG_MODE = -DDEBUG
LINKER = g++
LFLAGS = $(GENERIC_F) -lm
SRCDIR = src
OBJDIR = build
BINDIR = bin
SOURCES = $(wildcard $(SRCDIR)/*.cc)
INCLUDES = $(wildcard $(SRCDIR)/*.h)
OBJECTS = $(SOURCES:$(SRCDIR)/%.cc=$(OBJDIR)/%.o)
rm = rm -f
.PHONY: clear_screen tests extend_cflags
$(BINDIR)/$(TARGET): $(OBJECTS) $(INCLUDES)
$(LINKER) $(OBJECTS) $(LFLAGS) -o $@
@echo -e "Linking complete!\n"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cc $(INCLUDES)
@mkdir -p $(OBJDIR) $(BINDIR)
$(CC) $(CFLAGS) -c $< -o $@
@echo -e "Compiled "$<" successfully!\n"
.PHONY: clean
clean:
@$(rm) $(OBJECTS)
@echo "Cleanup complete!"
.PHONY: remove
remove: clean
@$(rm) $(BINDIR)/$(TARGET)
@echo "Executable removed!"
clear_screen:
@clear
extend_cflags:
$(eval CFLAGS += $(DEBUG_MODE))
tests: | remove extend_cflags $(BINDIR)/$(TARGET) clear_screen
@$(BINDIR)/$(TARGET)