【问题标题】:make with dynamic target names使用动态目标名称制作
【发布时间】:2014-03-02 08:18:36
【问题描述】:

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

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

这个想法是输入make test.cpp 应该运行g++ test.cpp && ./a.outmake main.cpp 应该运行g++ main.cpp && ./a.out

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

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

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

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

    您描述的行为是您希望从 make 系统中获得的行为,这就是为什么它受到许多人的喜爱并且可以很好地扩展。

    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 的一个有用功能是大量的默认规则,当您不需要对每个步骤进行精细控制时,它们可以节省相当多的样板文件。

    【讨论】:

    • 要完全完整,这个答案应该指出 make 有一组内置的 隐式规则 可以让它了解如何从 @987654331 构建 .o @ 文件,以及各种其他类型的源文件。此外,您可以定义自己的隐式规则或覆盖内置规则,如果它们不满足您的需要。标准 make 支持 后缀规则,这是一种有限形式的隐式规则,而 GNU make 支持 模式规则,这是一种更强大的形式。您可以通过 Google 查找这些术语以了解它们以及如何指定它们。
    • @MadScientist - 我同意自动规则在一定程度上很有用,但是在构建比测试应用程序更简单的东西时,您最好完全控制
    • 使用隐式规则绝不会放弃对任何事物的任何控制。而且,在任何比测试应用程序更简单的构建系统中,它们绝对是避免大量冗余冗余的关键。有些人更喜欢静态模式规则,但我个人认为没有什么大的优势。
    • @MadScientist - 我添加了关于默认规则的注释,我什至在我的一个旧项目中找到了一个示例 makefile(答案中的链接)。
    • 也许当您说“自动规则”时,您的意思是默认或内置的隐式规则,而不是一般的隐式规则?确实,内置规则有时不能满足您的需求,这就是您可以(或许应该)重新定义它们的原因。但是,它们很好地可变化,因此您通常只需设置CCCFLAGSCXXCXXFLAGSCPPFLAGS 等,一切都会很好。
    【解决方案2】:

    我在尝试制作 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
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-19
      • 1970-01-01
      • 2022-11-15
      • 1970-01-01
      • 1970-01-01
      • 2017-08-20
      • 2018-09-01
      • 1970-01-01
      相关资源
      最近更新 更多