我知道我可以在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
- 而不进行编译。
答案 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