Makefile:为什么在依赖项中放入.o而不是.c?

时间:2014-08-18 02:38:34

标签: makefile

在本教程中:http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/

我不明白他为什么在Makefile1中使用.c依赖项而在Makefile2中使用.o依赖项。你能不能把.o和.c放在gcc中?使用.o?

有什么好处

2 个答案:

答案 0 :(得分:2)

1)它正好在教程中:"通过将对象文件 - hellomake.o和hellofunc.o - 放在依赖列表和规则中,make知道它必须首先单独编译.c版本,然后构建可执行文件hellomake。" 不严格正确,但你可以看到作者的意思。

2)你可以这样做,但你应该知道这两种方法实际上做了什么。另外,比较:

gcc -o hellomake hellomake.c hellofunc.c -I.

gcc -o hellomake hellomake.o hellofunc.o

第二次使用中不需要-I.;编译器无法使用它并将忽略它。 (是的,我知道教程中的命令使用它 - 作者错了。)

3)我所知道的最大优点是能够保留目标文件(foo.o),以避免以后不必要的重新编译;可能还有其他人。

答案 1 :(得分:2)

我猜Beta已经消除了你的大部分疑问。

我想为What's the advantage of using .o?

添加一些更基本的要点

在构建项目时,构建最终二进制文件有两个步骤

  1. 编译 - 编译器语法检查和其他编译条件。此阶段将生成.o个文件作为输出
  2. 链接 - 将映射函数调用。上述步骤中创建的所有.o都将链接以生成最终二进制文件
  3. 但为什么要使用两个步骤?

    对于一个小型项目而言,它并不重要,但是当项目变大时,很难将所有文件放在单个gcc行下。甚至更难映射依赖文件等。

    让我们使用implicit rules重写Makefile2以编译.c

    hellomake: hellomake.o hellofunc.o
         $(CC) -o hellomake hellomake.o hellofunc.o
    
    #Below rules will be provided by make implicit rules
    hellomake.o: hellomake.c
         $(CC) -c hellomake.c
    hellofunc.o: hellofunc.c
         $(CC) -c hellofunc.c
    

    现在假设您更改了文件hellofunc.c,那么只会重新编译hellofunc.o并且最终链接将会发生,而不是像Makefile1那样再次编译所有内容。 看起来似乎有很大的不同,但当你对一个大项目的单个文件进行更改时,时间复杂度就会很大。