2010-07-16 131 views
12

我不熟悉makefiles,但用於簡單的。現在,我手頭有一項任務。Makefile - 根據目標更改變量值

我需要編譯和鏈接測試應用程序與不同的庫和不同的包含路徑基於給定的目標。如果target爲TARGET1,則在編譯期間與LIB1鏈接幷包含INCLUDEPATH1。同樣,如果給定的目標是TARGET2,則在CFLAGS中使用INCLUDEPATH2編譯並與LIB2鏈接。

%.o: %.c 
    @echo [CC] $< ... 
    $(CC) $(CFLAGS) -o $*.o $< 

現在我有一個規則編譯我的測試應用程序。現在,如何根據目標改變CFLAGS。

回答

27

如果您正在使用GNU製作,您可以使用target-specific variables

target1: CFLAGS = -IINCLUDEPATH1 
target1: LDLIBS = -lLIB1 

target2: CFLAGS = -IINCLUDEPATH2 
target2: LDLIBS = -lLIB2 

all: target1 target2 

target1: target1.o misc.o 
target2: target2.o 

但是這不工作相當以及你想:如果目標1TARGET2份額一些源文件,你需要安排他們每個編譯兩次,並命名爲不同的.o文件 - 這將使你的生成文件更加複雜。

另外,如果你鍵入make target1然後-IINCLUDEPATH1將傳播到misc.c的編制,根據需要。但是,如果輸入make misc.o,則無法知道這最終是以目標1爲目標,並且編譯misc.c將不會獲得特殊的$ CFLAGS值(儘管它會得到全局值,如果有的話)。

所以這只是在簡單情況下才有用。但是,也許你的情況非常簡單。

+1

哇,我不知道特定於目標的變量會傳播到隱式規則! – 2010-07-16 12:34:29

+0

偉大的建議。儘管我一直在寫Makefiles太久,不知何故,我從來沒有意識到這個功能。 – 2016-07-29 11:51:04

1

我不認爲你可以根據目標改變變量。假設你調用

make TARGET1 TARGET2 

CFLAGS然後有什麼價值?

在這種情況下,您可以使用非模式規則來區分目標。

TARGET1: a.c 
    @echo [CC] $< ... 
    $(CC) -I INCLUDEPATH1 ... 

TARGET2: a.c 
    @echo [CC] $< ... 
    $(CC) -I INCLUDEPATH2 ... 

爲了減少重複,你也可以使用變量和 「functions」。然後,您可以在不同的規則中重用您的模式規則的正文。

define compile_cmd 
    @echo [CC] $< ... 
    $(CC) -I $1 -l$2 $(CFLAGS) 
endef 

TARGET1: a.c 
    $(call compile_cmd,INCLUDEPATH1,LIB1) -o [email protected] $< 

TARGET2: a.c 
    $(call compile_cmd,INCLUDEPATH2,LIB2) -o [email protected] $< 

%.o: %.c 
    $(call compile_cmd,INCLUDEPATH_DEFAULT,LIB_DEFAULT) -o [email protected] $< 

這將使一個很好的和靈活的makefile,以滿足您的需求。