2010-07-16 614 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,以满足您的需求。