我不熟悉makefile,但习惯于简单的。现在,我手边有一项任务。
我需要根据给定目标编译和链接测试应用程序与不同的库和不同的包含路径。如果target是TARGET1,则在编译期间链接LIB1并包含INCLUDEPATH1。类似地,如果给定的目标是TARGET2,则在CFLAGS中使用INCLUDEPATH2进行编译并与LIB2链接。
%.o: %.c
@echo [CC] $< ...
$(CC) $(CFLAGS) -o $*.o $<
现在我有一个如上所述的规则来编译我的测试应用程序。现在,如何根据目标更改CFLAGS。
答案 0 :(得分:30)
如果您使用的是GNU Make,可以使用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
但是这并不像你想的那样好:如果 target1 和 target2 共享一些源文件,你需要安排它们到每个都被编译两次,并被编译为不同名称的.o文件 - 这将使你的makefile复杂化。
此外,如果您键入make target1
,则-IINCLUDEPATH1
将根据需要传播到 misc.c 的编译中。但是,如果您键入make misc.o
,则无法知道这最终将发送到 target1 ,并且 misc.c 的编译将不会获得特殊的$ CFLAGS值(虽然它会得到全局的,如果有的话)。
所以这只在简单的情况下才有用。但也许你的情况足够简单。
答案 1 :(得分: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 $@ $<
TARGET2: a.c
$(call compile_cmd,INCLUDEPATH2,LIB2) -o $@ $<
%.o: %.c
$(call compile_cmd,INCLUDEPATH_DEFAULT,LIB_DEFAULT) -o $@ $<
这将使一个足够好且灵活的makefile适合您的需求。