如何让Makefile重新编译已更改的文件?

Pit*_*kos 58 c makefile recompile

我一直在努力让make只编译已经编辑过的文件.但是我没有太大成功,所有文件都被重新编译.有人能解释一下为什么吗?

我的文件是:

main.c
a_functions.c
Run Code Online (Sandbox Code Playgroud)

其中main.c包含main.ha_functions.c包含

这是我的makefile:

CC=gcc
CFLAGS=-Wall -I. -c
EXEC_FILE=program1


all: program

a_functions.o: a_functions.c
a_functions.c: a.h
main.o: main.c
main.c: main.h

objects: a_functions.c main.c
    $(CC) a_functions.c main.c $(CFLAGS)

program: a_functions.o main.o
    $(CC) a_functions.o main.o -o $(EXEC_FILE)
Run Code Online (Sandbox Code Playgroud)

根据建议更改makefile似乎有同样的问题::

all: program

a_functions.o: a_functions.c a.h
    gcc a_functions.c -c

main.o: main.c main.h
    gcc main.c -c

program: a_functions.o main.o
    gcc a_functions.o main.o -o program1
Run Code Online (Sandbox Code Playgroud)

Bet*_*eta 75

您正在讨论的具体问题 - program1即使没有任何更改,也要进行重建(通过重新链接对象) - 在此规则中:

program: a_functions.o main.o
    gcc a_functions.o main.o -o program1
Run Code Online (Sandbox Code Playgroud)

此规则的目标是program,并且Make假定它是一个文件.但由于没有这样的文件,每次运行Make时,Make认为需要重建此文件,并执行规则.我建议这个:

program1: a_functions.o main.o
    gcc a_functions.o main.o -o program1
Run Code Online (Sandbox Code Playgroud)

或者更好,这个:

program1: a_functions.o main.o
    gcc $^ -o $@
Run Code Online (Sandbox Code Playgroud)

或者更好的是:

$(EXEC_FILE): a_functions.o main.o
    $(CC) $^ -o $@
Run Code Online (Sandbox Code Playgroud)

(并且不要忘记更改all规则以匹配.)

其他几点:

  1. 正如@paxdiablo指出的那样,

    a_functions.o: a_functions.c a.h
    main.o: main.c main.h
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将这些对象链接在一起是没有意义的,除非一个(可能main.o)中的某个东西在另一个(可能)中调用某些东西a_functions.o,所以我希望看到这样的依赖:

    main.o: a.h
    
    Run Code Online (Sandbox Code Playgroud)

    所以我怀疑你有一些错位的声明.

  3. 你宣布一个objects规则,但从不引用它.所以你永远不会真正使用它; Make使用默认规则%.o: %.c.我建议这个:

    OBJECTS = a_functions.o main.o
    $(OBJECTS): %: %.c
        $(CC) $< $(CFLAGS) -o $@
    
    Run Code Online (Sandbox Code Playgroud)

    (在这种情况下,您可以更改$(EXEC_FILE): a_functions.o main.o$(EXEC_FILE): $(OBJECTS).)或者只是这样:

    %.o: %.c
        $(CC) $< $(CFLAGS) -o $@
    
    Run Code Online (Sandbox Code Playgroud)


pax*_*blo 12

不确定这是否导致您的具体问题,但两行:

a_functions.c: a.h
main.c: main.h
Run Code Online (Sandbox Code Playgroud)

肯定是错的,因为通常没有命令根据它包含的头重新创建一个C文件.

C文件不依赖于它们的头文件,这些C文件创建的对象可以.

例如,a main.c:

#include <hdr1.h>
#include <hdr2.h>
int main (void) { return 0; }
Run Code Online (Sandbox Code Playgroud)

会是makefile这样的:

main.o: main.c hdr1.h hdr2.h
    gcc -c -o main.o main.c
Run Code Online (Sandbox Code Playgroud)

更改:

a_functions.o: a_functions.c
a_functions.c: a.h
main.o: main.c
main.c: main.h
Run Code Online (Sandbox Code Playgroud)

至:

a_functions.o: a_functions.c a.h
main.o: main.c main.h
Run Code Online (Sandbox Code Playgroud)

(假设a_functions.c包含a.hmain.c包含main.h)并再试一次.

如果上述假设是错误的,您将不得不告诉我们哪些C文件包含哪些标题,以便我们可以告诉您正确的规则.


如果您的争论是makefile即使在这些更改之后仍在构建所有内容,您需要查看两件事.

第一个是ls -l所有相关文件的输出,以便您可以查看它们具有的日期和时间.

第二个是来自的实际输出make.输出make -d将特别有用,因为它显示make用于确定要执行的操作的文件和日期.


在调查方面,make似乎按照以下成绩单正常工作:

=====
pax$ cat qq.h
#define QQ 1
=====
pax$ cat qq.c
#include "qq.h"
int main(void) { return 0; }
=====
pax$ cat qq.mk
qq: qq.o
        gcc -o qq qq.o

qq.o: qq.c qq.h
        gcc -c -o qq.o qq.c
=====
pax$ touch qq.c qq.h
=====
pax$ make -f qq.mk
gcc -c -o qq.o qq.c
gcc -o qq qq.o
=====
pax$ make -f qq.mk
make: `qq' is up to date.
Run Code Online (Sandbox Code Playgroud)

  • 对象不会被重新编译.它只是重新链接的program1. (2认同)