makefile中的变量相关目标

makefile中的变量相关目标,makefile,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

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

所以,我创建了如下的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
之前调用
makeclean
,以获得特定的实现。但是这增加了构建时间(我可以多次为一个实现运行测试),而且不是很舒服

我可以将此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
CC=g++
FLAGS=-Wall-O2
CFLAGS=-c$(标志)
I_PATH=implementation1.cpp
C|u PATH:=$(shell echo-n$(I|u PATH)| md5sum | awk'{print.implementation_uu2;substr($$1,0,10)“.o”;})
全部:强制实例
强制重新链接:
触摸-c$(c_路径)
实例:instance.cpp$(C_路径)
$(CC)$(FLAGS)instance.cpp$(C_PATH)-o$@
$(C_路径):$(I_路径)
$(CC)$(CFLAGS)$<-o$@
清洁:
-rm.实施*
-rm实例
在这里,我创建了
I_PATH
依赖对象文件(将路径散列到实现中),此外,每次运行
make
时,都会强制将
instance.cpp
与对象文件重新链接


但是,
make
中可能有某种机制来修复这种行为?或者我可以用不同的方法实现相同的目标?

为每个编译的
.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
或其他任何东西。)

是的,这很有意义-简单而好的解决方案。你能建议另一种重新链接的方式吗?或者我的方法可以接受吗?下一种情况需要重新链接:
make IMPL\u O=i1.O
make IMPL\u O=i2.O
make IMPL\u O=i1.O
-在第三次调用中,make不会跟踪更改,也不会重建任何内容。如果只是删除文件并重新创建它是不可接受的,如果参数发生变化,可以使用以前使用
md5sum
所做的一些操作来强制重做。。。。或者,您可以类似地为每个编译的工件指定一个唯一的名称,该名称反映了它嵌入的实现。