2010-04-26 72 views
44

有沒有一種方法可以在目標主體內重新分配Makefile變量值?更改目標主體內部的Makefile變量值

我所試圖做的是添加一些額外的標誌用於調試編譯:

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

test: clean debug_compile_flag compile compile_test 

debug_compile: 
    $(ERLCFLAGS) += -DTEST 

所以,如果我調用測試目標,我想清理我的環境中,增加一些新的標誌(像-DTEST),再次編譯整個代碼(第一個源代碼,然後是測試模塊)。

我不想複製/粘貼代碼用於編譯一些新的標誌集,因爲有很多邏輯放在這裏和那裏。

是否有一些簡單的方法來重新定義變量值,以便我可以重用現有的代碼?

+0

的可能重複[定義使在規則的執行時間變量(http://stackoverflow.com/questions/1909188 /界定,使變量 - 在規則,執行時間) – 2015-04-15 07:30:03

回答

-5

編輯:正如在other answer中的Beta所解釋的,這是可能的。


不,在Makefile中沒有辦法做到這一點。但是,您可以更改make命令行上的變量值。如果你重寫你的Makefile如下:

ERLCFLAGS += $(ERLCFLAGSADDED) 

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

test: clean compile compile_test 

然後,你可以調用化妝用執行你的測試:

make ERLCFLAGSADDED=-DTEST test 
+0

是啊,我解決了如你所說,在debug_compile運行submake問題: ERLC_FLAGS = $(ERLC_DEBUG_FLAGS)$(MAKE)編譯 謝謝! – paulgray 2010-04-26 09:39:14

+0

哦,是的,太好了。我沒有想到這個子調用。 – 2010-04-26 11:36:02

+0

如果您想要使用不同的標誌值多次運行目標,則子圖調用仍然有用。請參閱下面評論中引用的文檔。 – ntc2 2013-09-20 00:00:16

58

是的,有一個簡單的方法來做到這一點,並沒有重新運行製作。使用target-specific variable value

test: clean debug_compile 

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

在這裏保證執行順序嗎?或者可以讓-j2搞砸了嗎? – Marenz 2011-05-29 19:46:33

+2

[文檔](http://www.gnu.org/software/make/manual/make。html#Target_002dspecific):「請注意,一個給定的先決條件最多隻能在每次調用make時構建一次,如果同一個文件是多個目標的先決條件,並且每個目標對同一個目標具有不同的值 - 那麼要構建的第一個目標將導致構建該先決條件,並且先決條件將繼承第一個目標的目標特定值,並忽略來自其他任何目標的特定於目標的值。 – ntc2 2013-09-19 22:34:01

38

另一個答案就在這裏:Define make variable at rule execution time

對於懶惰的,你可以有這樣的規則下(FLAGDEBUG是我的變量):

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

只爲我工作的版本,謝謝! – Raphael 2013-05-07 08:39:26

+1

我有很多'$(eval xxx)'的問題,有很多奇怪的副作用。它看起來不像「真正」的Makefile變量賦值。 – Cyan 2017-02-02 23:59:29

+0

我有一個'eval'函數的問題 - 我的變量爲空值,因爲用eval定義的變量在目標執行開始時獲取它的值,而不是到達此行時。例如,如果您在目標的開頭創建了一些文件,然後嘗試使用'eval FILES = $(shell ls)'填充某個變量,則您的FILES變量將爲空 – 2017-06-05 13:31:58

0

我想在makefile中添加一個目標來運行測試,這意味着重新編譯源代碼帶有一些調試標誌。伊恩的回答:https://stackoverflow.com/a/15561911/是唯一的解決方案。

這是我想出了一個Makefile文件,運行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)