C - Makefile 在头文件更改后编译,但更改不生效

C - Makefile compiles after header file changes, but changes dont take effect

我在这个程序中有 3 个文件,lab4.c、functions.h、functions.c

lab4.c调用了一个函数multiply(),其原型在functions.h中,定义在functions.c中。 Multiply 然后使用了 functions.c 中的多个其他函数。我拥有的唯一包含在 lab4.c 中,包括 functions.h,我还需要更多吗?我遇到的问题如下所述

lab4:

#include <stdio.h>
#include <stdlib.h>
#include "functions.h"
int main(void) {
...
}

functions.h:

#ifndef FUNCTIONS
#define FUNCTIONS

void divideByPowerOf2(unsigned int* a, int power);
void multiplyByPowerOf2(unsigned int* a, int power);
...
#endif /* FUNCTIONS */

functions.c:

void divideByPowerOf2(unsigned int* a, int power){
    *a >>= power;
}
void multiplyByPowerOf2(unsigned int* a, int power){
    *a <<= power;
}
...

目前,我的 makefile 如下所示:

生成文件:

#Makefile

all: lab4

lab4: lab4.o functions.o functions.h
    gcc -Wall -o lab4 lab4.o functions.o

lab4.0: lab4.c
    gcc -c lab4.c

functions.o: functions.c
    gcc -c functions.c

现在,当我更改头文件时,这将重新编译,但更改实际上并没有生效。例如,如果我将头文件更改为

#ifndef FUNCTIONS
#define FUNCTIONS

void divideByPowerOf2(unsigned int* a, int power);
//void multiplyByPowerOf2(unsigned int* a, int power);
...
#endif /* FUNCTIONS */

程序仍然运行良好。我假设我可能搞砸了将文件与 include 和所有内容链接在一起,因为这通常会让我感到困惑。例如,functions.c 是否需要引用任何内容? functions.h 是否需要对 .c 文件的任何引用?我如何让它正常工作,以便如果我更改头文件,它会重新编译并实际使用新的头文件

感谢您的帮助!

首先,这里有一个错字:

lab4.0: lab4.c

应该是

lab4.o: lab4.c

那么,你的 function.h 应该在 source => object dependency 行上,而不是在 object => executable 行上,否则,如果你更改 .h 文件,它只会重新 links 无需重建 .o 文件:它没有任何改变。

此外,使用 -Wall 很好,但是你必须在编译文件时使用它,而不是在 link 可执行文件时使用它,否则你会错过实际的编译警告 ( -Wall 仅在 link 阶段是非常无用的)。

例如,-Wall 标志会告诉您注释原型会生成 "implicit declaration" 警告(这可能导致函数的 call/return 值不正确)。使用 -Werror 更有效,它将警告转化为错误,因此您不能忽略警告。

您的 makefile 应如下所示:

all: lab4

CFLAGS = -Wall

lab4: lab4.o functions.o
    gcc -o lab4 lab4.o functions.o

lab4.o: lab4.c functions.h
    gcc $(CFLAGS) -c lab4.c

functions.o: functions.c functions.h
    gcc $(CFLAGS) -c functions.c

请注意,如果您只有 2 个源文件并且它们足够小,您甚至可能无法仅通过 运行:

使用 make 文件
gcc -Wall -o lab4 lab4.c functions.c

在脚本中。如果你有太多/大的源文件,那将不适用,因为它每次都会重建所有内容。