在 Ubuntu 环境下,使用 Makefile 可以帮助自动化编译过程,尤其是在项目包含多个源文件时。 下面是一个简单的示例,展示如何使用 Makefile 编译一个 C 项目,其中 main.c 调用了 test1.c 中的函数。
1. 创建源文件
首先,创建两个源文件:main.c 和 test1.c,以及一个头文件 test1. h。
test1.h
#ifndef TEST1_H
#define TEST1_H
// 声明函数
void test1_function();
#endif
test1.c
#include <stdio.h>
#include "test1.h"
// 定义函数
void test1_function() {
printf("This is a function from test1.c\n");
}
main.c
#include <stdio.h>
#include "test1.h"
int main() {
printf("Main program\n");
test1_function(); // 调用 test1.c 中的函数
return 0;
}
2. 创建 Makefile
在项目目录下创建一个名为 Makefile 的文件,并输入以下内容:
# 定义编译器和编译选项
CC = gcc
CFLAGS = -Wall -g
# 定义源文件和目标文件
SOURCES = main.c test1.c
OBJECTS = $(SOURCES:.c=.o)
EXECUTABLE = my_program
# 默认目标(当直接输入 `make` 时执行)
all: $(SOURCES) $(EXECUTABLE)
# 链接目标
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $^ -o $@ #链接
# 编译规则(将.c文件编译为.o文件)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@ #汇编
# 清理生成文件
clean:
rm -f $(OBJECTS) $(EXECUTABLE)
总共4个文件,分别是:
解释说明
OBJECTS
作用:自动生成对应的目标文件(.o 文件)列表。
语法:$(SOURCES:.c=.o) 表示将 SOURCES 中所有 .c 后缀的文件替换为 .o 后缀。
示例:
makefile
OBJECTS = $(SOURCES:.c=.o)
展开结果:如果 SOURCES = main.c test1.c,则 OBJECTS 展开为 main.o test1.o。
关键规则解释
all: $(EXECUTABLE)
默认目标,当运行 make 时会尝试构建 $(EXECUTABLE)。
$(EXECUTABLE): $(OBJECTS)
链接规则,将所有目标文件(main.o 和 test1.o)链接成可执行文件 my_program。
%.o: %.c
模式规则,将每个 .c 文件编译为对应的 .o 文件。
clean
清理规则,删除所有目标文件和可执行文件。
3. 使用 Makefile 进行编译和运行
1)编译程序:
在终端中导航到包含 Makefile 的目录,然后运行以下命令:
make
这将自动编译 main.c 和 test1.c,并生成可执行文件 my_program。
生成了’‘main.o ‘’ ,’'test1.o ‘’ , ‘‘my_program’’
2)运行程序:
编译成功后,可以直接运行生成的可执行文件:
./my_program
输出:
Main program
This is a function from tsr.c
3) 清理生成文件:
如果需要清理生成的目标文件和可执行文件,可以运行以下命令:
make clean
|
4. 关键说明
Makefile 的作用:
自动化编译过程,减少手动输入命令的麻烦。
支持多文件编译,只需在 SOURCES 变量中列出所有源文件即可。
提供清理功能,方便重新编译
。
编译选项:
-Wall:启用所有警告信息,帮助发现潜在问题。
-g:生成调试信息,便于使用 gdb 进行调试。
扩展性:
如果项目包含更多源文件,只需在 SOURCES 变量中列出所有文件即可,Makefile 会
自动处理依赖关系。
对于更复杂的项目,可以考虑使用 CMake 等构建工具。