使用动态目标名称

时间:2014-02-05 18:09:10

标签: makefile gnu-make

我知道我可以在makefile中的目标中使用自动变量$@来检索当前目标的名称。现在我想知道是否有可能有一个看起来像这样的makefile:...

$@:
    g++ $@ && ./a.out

我们的想法是,键入make test.cpp应运行g++ test.cpp && ./a.out,而make main.cpp应运行g++ main.cpp && ./a.out

我看到通配符可能与我的问题密切相关。但是,像这样的makefile:

*.cpp:
    g++ $@ && ./a.out

确实创建了适当的目标,但是使用这样的makefile运行make test.cpp会产生make: >>test.cpp<< is already up-to-date - 而不进行编译。

2 个答案:

答案 0 :(得分:4)

您描述的行为是您想要从制作系统中获得的行为,这就是为什么它被许多人所喜爱并且如此好地扩展。

make test.cpp不起作用,因为您想要的是make a.out

尝试从一个简单但正确的makefile开始,并根据您的需要进行演变

要触发编辑,请移除test.o并说出make test.o,或说touch test.cpp,然后再说make test.o。如果您不想要中间对象文件(我告诉您 - 您确实需要它们),您可以应用上述建议,将test.o替换为a.out

您正在尝试推送 : - )

正如@MadScientist在他的评论中提醒的那样,GNU Make的一个有用功能是一组庞大的默认规则,当你不需要对每一步都进行精细控制时,可以节省相当多的样板。

答案 1 :(得分:0)

在尝试制作Go程序时,我也有类似的需求。我通过将目标设置为*解决了我的问题。

此外,您还需要传递.PHONY指令以过滤出要处理的文件,否则需要输入make: 'clock1' is up to date,因为我的makefile目录中已经有clock1的文件夹。

GO_BUILD = go build
GO_BIN ?= $(shell go env GOPATH)/bin
PROG = $(GO_BIN)/$@

*:
    $(GO_BUILD) -o $(PROG) ./$@/*.go
    ls -al $(PROG)
test:
    @echo ${GO_BIN}

.PHONY: clock1 clock2 countdown*

运行make命令:

$ make clock1   
go build -o /data/go/bin/clock1 ./clock1/*.go
ls -al /data/go/bin/clock1
-rwxr-xr-x  1 Terry  staff  3013840 Sep 25 16:53 /data/go/bin/clock1

$ make clock2 
go build -o /data/go/bin/clock2 ./clock2/*.go
ls -al /data/go/bin/clock2
-rwxr-xr-x  1 Terry  staff  3177296 Sep 25 16:53 /data/go/bin/clock2

$ make countdown1
go build -o /data/go/bin/countdown1 ./countdown1/*.go
ls -al /data/go/bin/countdown1