makefile中的变量依赖目标

时间:2017-05-09 05:50:24

标签: makefile

我有一个小项目用于测试,我想将解决方案的不同实现链接到测试。

所以,我创建了看起来像这样的makefile

CC=g++
FLAGS=-Wall -O2
CFLAGS=-c $(FLAGS)
I_PATH=implementation1.cpp

all: instance

instance: instance.cpp .implementation.o
    $(CC) $(FLAGS) instance.cpp .implementation.o -o $@

.implementation.o: $(I_PATH)
    $(CC) $(CFLAGS) $(I_PATH) -o $@

clean:
    -rm .implementation*
    -rm instance

此处,I_PATH是解决方案实施的途径。我想测试通过命令行参数传递不同实现的不同解决方案:make I_PATH=implementation2.cpp

但是,由于我的所有实现都编译为同一个目标文件.implementation.omake无法理解某些内容发生了变化而且没有重建项目。

当然,我可以在运行make clean之前调用make进行特定实施。但是这会增加构建时间(我可以多次运行一个实现的测试)并且不太舒服。

我可以将这个makefile修复为:

CC=g++
FLAGS=-Wall -O2
CFLAGS=-c $(FLAGS)
I_PATH=implementation1.cpp
C_PATH := $(shell echo -n $(I_PATH) | md5sum | awk '{print ".implementation_" substr($$1, 0, 10) ".o";}')

all: force instance

force_relink: 
    touch -c $(C_PATH)

instance: instance.cpp $(C_PATH)
    $(CC) $(FLAGS) instance.cpp $(C_PATH) -o $@

$(C_PATH): $(I_PATH)
    $(CC) $(CFLAGS) $< -o $@

clean:
    -rm .implementation*
    -rm instance

在这里,我创建I_PATH依赖对象文件(获取实现路径的哈希值),并且每次instance.cpp运行时强制重新链接make和目标文件。

但也许make中有一些机制来修复这种行为?或者我可以通过不同的方法实现相同的目标?

1 个答案:

答案 0 :(得分:1)

为每个已编译的.o文件指定一个不同的名称,并且只是链接到您想要的已编译的.o文件会更有意义吗?

instance: instance.cpp $(IMPL_O)
    $(CC) $(FLAGS) $^ -o $@  # propably no need to override default rule

使用make IMPL_O=implementation2.o在您的问题中生成示例。

这样,每个文件的名称都能真实地显示其身份,而且您不必明确跟踪任何内容。

(显然,你可以将.o扩展名重构为Makefile本身,这样你就可以说IMPL=implementation2或其他什么。)