一、本节概要
本专栏所有内容围绕Makefile官方文档进行刨析,给出详细具体示例做辅助理解手撕Makefile官方手册
二、Makefile中的变量
1、没有使用变量的makefile
现在有main.c
a.c
b.c
a.h
b.h
五个文件,以下是不使用变量的makefile完整示例:
all: main.o a.o b.o
gcc -o program main.o a.o b.o
main.o: main.c a.h b.h
gcc -c main.c -o main.o
a.o: a.c a.h
gcc -c a.c -o a.o
b.o: b.c b.h
gcc -c b.c -o b.o
clean:
rm -f program main.o a.o b.o
以下是构建的文件及其内容:
main.c:
#include <stdio.h>
#include "a.h"
#include "b.h"
int main() {
printf("This is main.c\n");
printf("Including files: a.h, b.h\n");
print_a();
print_b();
return 0;
}
a.c:
#include <stdio.h>
#include "a.h"
void print_a() {
printf("This is a.c\n");
printf("Including file: a.h\n");
}
b.c:
#include <stdio.h>
#include "b.h"
void print_b() {
printf("This is b.c\n");
printf("Including file: b.h\n");
}
a.h:
#ifndef A_H
#define A_H
void print_a();
#endif
b.h:
#ifndef B_H
#define B_H
void print_b();
#endif
这样,主程序 main.c
通过引用头文件 a.h
和 b.h
,分别调用了 a.c
中的 print_a()
函数和 b.c
中的 print_b()
函数。每个文件中都有相应的打印语句,以输出对应的文件名和所包含的文件。
2、使用变量的makefile
CC = gcc
CFLAGS = -c
TARGET = program
OBJS = main.o a.o b.o
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) -o $(TARGET) $(OBJS)
main.o: main.c a.h b.h
$(CC) $(CFLAGS) main.c -o main.o
a.o: a.c a.h
$(CC) $(CFLAGS) a.c -o a.o
b.o: b.c b.h
$(CC) $(CFLAGS) b.c -o b.o
clean:
rm -f $(TARGET) $(OBJS)
在这个示例中,使用了三个变量来存储常用的编译器、编译选项和目标文件名。CC
存储编译器名称,CFLAGS
存储编译选项,TARGET
存储目标文件名。OBJS
是一个宏定义,用于存储所有的目标文件。
通过使用这些变量,可以方便地管理和修改编译器、选项和目标文件名,以提高代码的可维护性。
请注意,在这个示例中,为了引用这些变量,需要将它们放在 $()
中。例如,$(CC)
表示引用 CC
变量的值。
使用变量可以使 Makefile 更加灵活,可以根据需要自由地更改和调整编译和链接的命令。同时也可以减少代码的重复,提高代码的可读性。