【问题标题】:How to generate multiple executable files in one Makefile?如何在一个 Makefile 中生成多个可执行文件?
【发布时间】:2017-08-22 08:51:15
【问题描述】:

我的目录包含2 源文件:a.cb.c。我想从a.cbb.c 生成可执行文件a。现在我只能想出一种写Makefile的方法:

all:  
    gcc -o a a.c
    gcc -o b b.c

好像有点别扭,有没有更好的方法?

【问题讨论】:

  • 这有什么尴尬的?
  • 只是觉得有点多余,不知道有没有更好的方法。
  • 这不仅仅是尴尬,它完全否定了make的概念。同样的事情可以通过一个简单的 shell 脚本来实现。

标签: makefile gnu-make


【解决方案1】:

答案很好,但我认为您需要了解make 的工作原理:

make 的基本功能是如有必要从输入文件创建输出文件。 make 通过比较时间戳决定什么是必要的:如果任何输入文件比从它创建的输出文件新,则执行该输出文件的配方。

这意味着只有一个名为all的规则,这个规则总是被执行(除非你碰巧有一个最近的文件实际上调用all--为了防止这种行为,您必须将all 列为.PHONY 目标,即实际上并不创建文件的目标)。你原来的 Makefile 相当于一个简单的 shell 脚本,所以它不能正确使用make

您的 Makefile 的最小“正确”版本应如下所示:

all: a b

a: a.c
    gcc -o a a.c

b: b.c
    gcc -o b b.c

.PHONY: all

所以,all 是“假的”,它依赖于 aba 仅在 a.c 更改时重建,b 仅在 b.c 更改时重建。

在一个真实的项目中,你的程序可能不仅仅是由一个源文件构成的,在这种情况下,你真的可以利用make:让它构建目标文件 的翻译单元,因此只有更改的 部分 才会真正重建。对于你的小例子来说,这有点过头了,但可以例如看起来像这样:

a_OBJS:= a.o
b_OBJS:= b.o

all: a b

a: $(a_OBJS)
    gcc -o$@ $^

b: $(b_OBJS)
    gcc -o$@ $^

%.o: %.c
    gcc -c -o$@ $<

clean:
    rm -f *.o

.PHONY: all clean

您只需将更多目标文件添加到 a_OBJSb_OBJS 即可在您的构建中包含新的翻译单元。 模式规则 %.o: %.c 将匹配它们。还有很多要发现的,我建议从 GNU make manual 开始。

【讨论】:

    【解决方案2】:

    我认为以下方法更好:

    all: a b
    a: a.c
      gcc -o a a.c
    b: b.c
      gcc -o b b.c
    

    在您的版本中,make all始终运行两次 gcc,无论 a.cb.c 是否被修改。在此版本中,gcc 将仅在必要时运行。

    当然你可以使用一些魔法(for-loop 或类似的)来创建规则,但我认为我的方法和你的方法之间的区别很明显。

    【讨论】:

    • 可以使用魔法,但是对于 makefile,我通常觉得简单和明确比聪明和难以理解更好(在 makefile 中,'clever' 和“太聪明了一半”太薄了)。模式规则(%: %.cgcc -o $@ $&lt;)在这里是合理的,因为它强调对称性。
    【解决方案3】:

    对我来说

    all:
        gcc -o a a.c
        gcc -o b b.c
    

    看起来不错。 或者可能是以下更好的控制

    all: a b
    
    a: a.c
        gcc -o a a.c
    
    b: b.c
        gcc -o b b.c
    
    clean:
        -rm a b
    

    一个鲜为人知的不带makefile的编译技巧

    make a    #run cc -o a a.c by make or
    make b    #run cc -o b b.c by make
    

    或者同时生成ab

    make a b
    

    make 在这里使用隐式规则,就像魔术一样。 但更喜欢指定规则的生成文件

    【讨论】:

    • make amake b 不起作用。你没有任何规则如何创建a。试试看吧:)
    • 我试过了。应该工作,这就是神奇的部分。使期望 a.cb.c 存在并运行隐式规则。在这种情况下不需要makefile
    猜你喜欢
    • 2018-11-14
    • 2017-10-12
    • 1970-01-01
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-23
    • 1970-01-01
    相关资源
    最近更新 更多