本文 Makefile 代码定义了如何编译一组 C 源文件(加减乘除)以生成一个静态库和一个使用该静态库的可执行程序。提供了详细的工程源码示例,并配有详细的解释。
- 工程源码目录
.
├── Makefile
├── add.c
├── add.h
├── div.c
├── div.h
├── main.c
├── multi.c
├── multi.h
├── sub.c
└── sub.h - 源码内容
Makefile
CC=gcc
CFLAGS=-Wall -g
LIBRARY=libmath.a
PROGRAM=main
PROGRAM_SRC=main.c
LIB_SRC=add.c div.c multi.c sub.c
all: main
$(PROGRAM): $(PROGRAM_SRC:.c=.o) $(LIBRARY)
$(CC) $(CFLAGS) -c $(PROGRAM_SRC)
$(CC) $(CFLAGS) main.o -L. -lmath -o $(PROGRAM)
$(LIBRARY): $(LIB_SRC:.c=.o)
$(CC) $(CFLAGS) -c $(LIB_SRC)
ar rcs $(LIBRARY) $(LIB_SRC:.c=.o)
clean:
rm -f *.o $(PROGRAM) $(LIBRARY)
- 变量定义
- CC=gcc: 指定编译器为 gcc。
- CFLAGS=-Wall -g: 设置编译选项,-Wall 表示开启警告信息,-g 表示包含调试信息。
- LIBRARY=libmath.a: 定义静态库的输出文件名为 libmath.a。
- PROGRAM=main: 定义可执行程序的输出文件名为 main。
- PROGRAM_SRC=main.c: 指定主程序的源文件为 main.c。
- LIB_SRC=add.c div.c multi.c sub.c: 列出静态库的所有源文件。
- 规则定义
- all: main: 定义默认目标为 main,即运行 make 命令时,默认会构建 main 目标。
- $(PROGRAM): $(PROGRAM_SRC:.c=.o) $(LIBRARY): 定义 main 目标的依赖项,包括主程序的 .o 文件和静态库 libmath.a。
- $(CC) $(CFLAGS) -c $(PROGRAM_SRC): 编译 main.c 生成 main.o。
- $(CC) $(CFLAGS) main.o -L. -lmath -o $(PROGRAM): 链接 main.o 和静态库 libmath.a,生成可执行文件 main。
- $(LIBRARY): $(LIB_SRC:.c=.o): 定义静态库的依赖项,即所有源文件对应的 .o 文件。
- $(CC) $(CFLAGS) -c $(LIB_SRC): 编译所有静态库源文件生成 .o 文件。
- ar rcs $(LIBRARY) $(LIB_SRC:.c=.o): 使用 ar 工具将 .o 文件打包成静态库 libmath.a。
- clean: 清理规则,删除所有 .o 文件、可执行文件 main 和静态库 libmath.a。
- 使用
- 运行 make 来构建项目。
- 运行 ./main 来执行程序。
- 运行 make clean 来清理编译产生的文件。
add.c
#include "add.h"
int add(int a, int b) {
return a + b;
}
add.h
#ifndef ADD_H
#define ADD_H
int add(int a, int b);
#endif // ADD_H
div.c
#include "div.h"
int div(int a, int b) {
if (b == 0) {
return 0; // 避免除数为零的情况
}
return a / b;
}
multi.h
#include "multi.h"
int multi(int a, int b) {
return a * b;
}
multi.h
#ifndef MULTI_H
#define MULTI_H
int multi(int a, int b);
#endif // MULTI_H
sub.c
#include "sub.h"
int sub(int a, int b) {
return a - b;
}
sub.h
#ifndef SUB_H
#define SUB_H
int sub(int a, int b);
#endif // SUB_H