由于在工作中接触到Makefile,需要对Makefile进行修改,由于本人Makefile为0基础,所以根据Makefile教程上手编写第一个Makefile,以此来熟悉Makefile。
编程环境:VMware Workstation 17 pro 镜像:Ubuntu20.04
目标:通过一个.h头文件将两个.c文件连接在一起,输出hello,world!
在测试目录下使用vim命令分别创建三个相关c语言文件:main.c、print.c、print.h
1.main.c
#include "print.h"
int main()
{
print();
return 0;
}
2.print.c
#include<stdio.h>
void print()
{
printf("hello,world!\n");
printf("I'm dh!\nAnd ");
printf("test succsess!\n");
}
3.print.h
#ifndef __print_H
#define __print_H
void print();
#endif
其中Makefile的格式为:
target : prerequisites... //依赖文件,可能含有多个,大多情况为.o文件
command //对依赖文件所进行的操作,一般是编译器的编译操作
prerequisite(target) : prerequisites //生成target的依赖文件所需的依赖文件
command
[label] :
[command]
根据格式编写Makefile文件:
abc : main.o print.o
cc -o abc main.o print.o
main.o : main.c print.h
cc -c main.c
print.o : print.c
cc -c print.c
clean :
rm main.o print.o
其中,abc即为生成的可运行程序target,main.o、print.o是abc的prerequisites依赖文件。
2、3、4、5行都与1、2行同理,clean就是[label]的实例,下面会讲到clean的用法。
至此,文件夹下所需的实操文件就齐全了。如下图所示
接下来直接在终端输入命令make,终端会输出以下信息
dh@ubuntu:~/testdir$ make
cc -c main.c
cc -c print.c
cc -o abc main.o print.o
接着文件夹下会出现abc、main.o与print.o文件
作为强迫症我会觉得main.o与print.o很多余,但是输入rm main.o print.o很麻烦,而且当类似文件很多时麻烦呈指数型加倍,所以就可以使用之前在Makefile中编写过的[label],命令行输入make clean即可执行rm main.o print.o
make clean即为rm main.o print.o替换版指令。除此之外还可以编写其他的命令作为Makefile中的[label]。执行完make clean后文件夹就会变成这样
最后在终端输入./abc即可执行hello,world程序。
反思:
1.在编写Makefile时发现一个问题,标准库如stdio.h需要加入到依赖条件中吗?
当我将标准库中的头文件加入到依赖条件中时发现,子依赖不知道如何添加,索性就直接不在依赖条件中添加标准库文件。结果也证明不需要添加标准库文件也可以正常运行,但是原理还需要研究。
2.将main.c文件中的#include "print.h"误写成#include <print.h>能否make成功?
由于include中的""与<>表示的文件寻址不同,make会产生报错,因为<>表示在系统库中寻找文件,但系统库中没有print.h这个文件,所以会报no such file or directory这个错误。
文章参考了陈皓大牛的《跟我一起写Makefile》