2010-04-26 7 views
44

Czy istnieje sposób na ponowne przypisanie wartości zmiennej Makefile wewnątrz obiektu docelowego?Zmiana wartości zmiennej Makefile wewnątrz obiektu docelowego

Co staram się zrobić to dodać jakieś dodatkowe flagi dla debugowania kompilacji:

%.erl: %.beam 
    $(ERLC) $(ERLFLAGS) -o ebin $< 

test: clean debug_compile_flag compile compile_test 

debug_compile: 
    $(ERLCFLAGS) += -DTEST 

Więc jeśli modlę Test cel chciałbym oczyścić moje środowisko, dodać kilka nowych flag (jak -DTEST do istniejących), skompiluj cały kod jeszcze raz (pierwsze źródła, następnie moduły testowe).

Nie chcę kopiować/wklejać kodu do kompilacji z nowymi ustawionymi flagami, ponieważ tu i tam jest dużo logiki.

Czy istnieje prosty sposób na ponowne zdefiniowanie wartości zmiennej, aby ponownie wykorzystać istniejący kod?

+0

możliwy duplikat [Zdefiniuj uczynić zmienną w czasie wykonywania reguła] (http://stackoverflow.com/questions/1909188/definiować-make-zmienny-at-reguły-wykonanie-time) –

Odpowiedz

-5

Edytuj: Jak wyjaśniono w Beta w other answer, jest to możliwe.


Nie. Nie ma sposobu, aby zrobić to w pliku Makefile. Można jednak zmienić wartość zmiennej w wierszu polecenia make. Jeśli przepisać Makefile następująco:

ERLCFLAGS += $(ERLCFLAGSADDED) 

%.erl: %.beam 
    $(ERLC) $(ERLCFLAGS) -o ebin $< 

test: clean compile compile_test 

Następnie można wywołać make wykonywać swoje testy przy użyciu:

make ERLCFLAGSADDED=-DTEST test 
+0

Yeah, I rozwiązać problem, jak sugerowano, bieganie submake w debug_compile: ERLC_FLAGS = $ (ERLC_DEBUG_FLAGS) $ (MAKE) skompilować Thanks ! – paulgray

+0

O tak, świetnie. Nie myślałem o tym submake inwokacji. –

+0

Inwokacja submenu jest nadal przydatna, jeśli chcesz uruchomić cel wiele razy z różnymi wartościami flag. Zobacz dokumenty, które zacytowałem w komentarzu poniżej. – ntc2

58

Tak, tam jest łatwym sposobem, aby to zrobić, a nie ponowne uruchomienie Marka. Użyj target-specific variable value:

test: clean debug_compile 

debug_compile: ERLCFLAGS += -DTEST 
debug_compile: compile compile_test; 
+2

Czy zagwarantowana jest tutaj kolejność wykonania? Czy może make -j2 podkręca rzeczy? – Marenz

+2

[Dokumenty] (http://www.gnu.org/software/make/manual/make.html # Target_002dspecific): "Należy pamiętać, że dany warunek wstępny zostanie zbudowany tylko raz na wywołanie make, jeśli ten sam plik jest warunkiem wstępnym wielu celów, a każdy z tych celów ma inną wartość dla tego samego obiektu docelowego. specyficzna zmienna, wówczas pierwszy cel, który ma zostać zbudowany, spowoduje, że ten wstępny obiekt zostanie zbudowany, a warunek wstępny odziedziczy wartość specyficzną dla celu z pierwszego celu, ignorując wartości specyficzne dla celu z innych celów. " – ntc2

38

Inna odpowiedź jest tutaj: Define make variable at rule execution time.

dla leniwych, można mieć zasady, takie jak następujące (FLAG i DEBUG są moje zmienne):

.DBG: 
    $(eval FLAG += $(DEBUG)) 
+2

Tylko wersja, która działała dla mnie, dzięki! – Raphael

+1

Mam wiele problemów z '$ (eval xxx)', z tonami dziwnych efektów ubocznych. Wydaje się, że nie działa tak dobrze jak "prawdziwe" przypisanie zmiennej Makefile. – Cyan

+0

Miałem problem z funkcją 'eval' - otrzymałem puste wartości dla moich zmiennych, ponieważ zmienna zdefiniowana za pomocą eval pobiera jej wartość na początku wykonywania celu, a nie po osiągnięciu tej linii. Na przykład, jeśli tworzysz jakieś pliki na początku celu, a później próbujesz wypełnić pewną zmienną za pomocą 'eval FILES = $ (shell ls)', twoje pliki FILES var będą puste –

0

chciałem dodać cel w makefile, aby przeprowadzić testy, które domniemanych rekompilacji kodu źródłowego z niektórymi flagami debugowania. Odpowiedź Iana: https://stackoverflow.com/a/15561911/ było jedynym rozwiązaniem, które działało.

Oto Makefile wymyśliłem, co gwarantuje kolejność wykonywania, gdy uruchomiony 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 [email protected] 
    @echo -e "Linking complete!\n" 

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cc $(INCLUDES) 
    @mkdir -p $(OBJDIR) $(BINDIR) 
    $(CC) $(CFLAGS) -c $< -o [email protected] 
    @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) 
Powiązane problemy