本文旨在介绍,如何从零开始写Makfile,实现多文件、多目标、多级目录的代码编译。
目录
5、编译lib & 编译bin & 执行可执行文件 & 清除编译产物
一、Makefile基础
1、编写c代码
编写一个简单的main.c就行
#include <unistd.h>
#include <stdio.h>
int main(void)
{
printf("Hello world!\n");
return 0;
}
2、编写Makefile
同级目录下创建一个文件,名称为Makefile(建议文件名称就固定为Makefile)
Makefile的基础编写规则,我都写在下面的注释里面了^_^
# 在Makfile中,以'#'作为注释开头,不支持多行注释
#Makfile最朴素的用法就是,指定依赖文件,指定文件依赖关系,指定生成规则(如何将依赖文件转换成目标文件)
# 指定编译器
CC = gcc
# Makefile中,通常需要指定一个目标文件名词,即下面的变量 TARGET,后面可以借用 $(TARGET) 来获取 TARGET 的值
TARGET = main
#指定用于生成目标文件的依赖文件如下,目标文件是可执行文件,所以依赖文件应该是一个对象文件(.o文件)
#我们可以借助一个变量OBJS来指代它,后面可以使用 $(OBJS) 来获取变量 OBJS 的值
OBJS = main.o
#同样,生成对象文件(.o文件),也需要相应的源文件(.c或.cpp文件)
SRC = main.c
##指定编译选项,用于gcc编译
# 选项[-Wall]表示 将打印全部告警信息,[-g]表示 支持gdb调试,[-c]表示 只编译源文件但不链接,[-o]表示 指定输出的目标文件名称
CFLAGS = -Wall -g -c
# 需要指定一定的规则来生成目标文件,使用冒号指定依赖关系
# 下面一行gcc命令是生成规则(若要在makefile中执行命令,行首必须以tab键开头)
# 变量 $@ 指代冒号前面的参数,变量 $^ 指代冒号后面的所有参数
$(TARGET) : $(OBJS)
$(CC) -o $@ $^
$(OBJS) : $(SRC)
$(CC) -o $@ $(CFLAGS) $^
# 通常会在 Makfile 结尾处编写一个clean规则用于清除我们的中间文件和目标文件
# .PHONY 表示冒号后面的标签名 clean 是一个伪目标(只执行clean的命令,但不会生成一个名叫“clean”的目标文件)
.PHONY:clean
# 在命令前面加一个'@'符号,则只会执行命令,而不在终端打印出命令本身
clean:
$(RM) $(TARGET)
@echo "Clean target files done."
$(RM) $(OBJS)
@echo "Clean object files done."
3、编译 & 执行 & 清除编译产物
终端下执行命令make可以执行编译工作,执行make clean可以清除掉编译产物。
如果你的Makefile文件叫其他名称,可以使用 -f 参数指定文件名
现在就简单完成了一个Makefile的编译工程,可以通过make命令实现c代码的编译工作
二、多个依赖文件编译
通常来讲,我们编写的大型工程文件,代码都不可能放在同一个文件中,所以搭建如下图所示的一个代码结构

1、编写一个头文件public.h
#ifndef PUBLIC_H__
#define PUBLIC_H__
void tool1(void);
#endif
2、编写一个新的c文件main_lib.c
代码内容如下
#include <unistd.h>
#include <stdio.h>
#include "public.h"
void tool1(void)
{
printf("This is tool1.\n");
return;
}
3、修改main.c
修改main函数,使其能够调用main_lib.c中的函数
#include <unistd.h>
#include <stdio.h>
#include "public.h"
int main(void)
{
printf("Hello world!\n");
tool1();
return 0;
}
4、修改Makefile
##指定源文件
# 使用

本文详细介绍如何从零开始编写Makefile,实现多文件、多目标、多级目录的代码编译。涵盖基础设置、多文件编译、多目标编译、静态库打包与链接及多层目录递归编译等内容。

1724

被折叠的 条评论
为什么被折叠?



