首页 文章

如何实现记住上一个构建目标的Makefile?

提问于
浏览
6

假设你有一个带有两个伪目标的Makefile,'all'和'debug' . 'debug'目标用于构建与'all'相同的项目,除了一些不同的编译开关(例如-ggdb) . 由于目标使用不同的编译开关,如果在两者之间切换,显然需要重建整个项目 . 但GNUmake自然不会认识到这一点 .

所以,如果你输入 make all ,你就会得到

Building ...
...

然后,如果你输入 make debug ,你就得到了

make: Nothing to be done for `debug'.

所以我的问题是: how do you implement a clean solution in the Makefile to notice that the last build used a different pseudo-target, or different compile switches, than the one you want currently? 如果它们不同,Makefile会重建所有内容 .

3 回答

  • 2

    唯一干净的解决方案是将差异纳入目标名称 . 例如 . 您可以定义变量 $(DEBUG) 并在依赖于编译步骤的所有目标中始终使用它 .

  • 1

    将构建产品放入不同的目录树(同时保留源的一个副本) . 这样,您始终只是从最新版本进行简短编译,无论是调试还是发布(甚至是其他版本) . 也没有混淆的可能性 .

    EDIT

    上面的草图 .

    src := 1.c 2.c 3.c
    bare-objs := ${src:%.c=%.o}
    release-objs := ${bare-objs:%=Release/%}
    debug-objs := ${bare-objs:%=Debug/%}
    
    Release/prog: ${release-objs}
    Debug/prog: ${debug-objs}
    
    ${release-objs}: Release/%.o: %.c # You gotta lurve static pattern rules
        gcc -c $< -o $@
    
    ${debug-objs}: Debug/%.o: %.c
        gcc -c $< -o $@
    
    Release/prog Debug/prog:
        gcc $^ -o $@
    
    .PHONY: all
    all: Release/prog ; echo $@ Success
    
    .PHONY: debug
    debug: Debug/prog ; echo $@ Success
    

    (免责声明:未经测试,甚至未经过制作 . )

    你去吧它甚至 -j 安全所以你可以做 make -j5 all debug . 有很多明显的锅炉板只是为了整理而哭泣 .

  • 0

    保持对象文件的变体集(如在bobbogo的解决方案中)可能是最好的方法,但如果由于某种原因您不想这样做,您可以使用空文件作为标记,以指示您上次构建可执行文件的方式:

    %-marker:
            @rm -f $(OBJECTS) *-marker
            @touch $@
    
    debug: GCCFLAGS += -ggdb
    
    debug: SOMEOTHERFLAG = WHATEVER
    
    all debug: % : %-marker
            @echo making $@
            @$(MAKE) -S GCCFLAGS='$(GCCFLAGS)' SOMEOTHERFLAG='$(SOMEOTHERFLAG)' main
    

    这个想法还有其他变种;你可以有一个包含标志设置的小文件,makefile将构建它,并且 include . 这将是聪明的,但并不比这更清洁 .

相关问题