我有一个小项目用于测试,我想将解决方案的不同实现链接到测试。
所以,我创建了看起来像这样的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.o
,make
无法理解某些内容发生了变化而且没有重建项目。
当然,我可以在运行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
中有一些机制来修复这种行为?或者我可以通过不同的方法实现相同的目标?
答案 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
或其他什么。)