举例说明Linux下make命令及makefile

举例说明Linux下make命令及makefile

笔者这几天正在学习linux基础,前几天碰到了make指令,以及如何编写makefile文件,听了老师的视频在自己写又总是报错,最后经过多次尝试和查阅资料终于解决了问题,下面给大家看一下我做的一道题目:

编写一个拥有main_jj.c,fun_jj.c ,head_jj.h的makefile工程,fun_jj实现一个求和函数,main_jj调用求和函数并将结果打印出来,头文件声明求和函数。若在main_jj中修改两个加数后,观察make命令的执行情况。

那么我就以这个题目为例,给大家介绍一下Linux下的make指令和makefile文件,如果各位大佬觉得我写的有不妥之处,欢迎大家在评论区留言,我会努力改正,给大家呈现最好的内容。

注意:笔者用的是Ubuntu18.04版本的,别的版本也大同小异。

首先我们来编写函数,为了不干扰主目录下面的文件和目录,我在主目录下新建了一个名为test的目录(mkdir test),下面我用ls命令查看了主目录下的内容,新建成功。

在这里插入图片描述
然后我进入到test目录里面(cd test),新建了四个文本文件(touch main_jj.c fun_jj.c head_jj.h makefile),分别是main_jj.c,fun_jj.c ,head_jj.h,makefile,然后再用ls命令查看,新建成功。

在这里插入图片描述然后开始编辑文本文件main_jj.c,fun_jj.c ,head_jj.h,可以用vim编辑器,或者直接用gedit命令,下面是我写好并已经保存在文件里的内容:

//main_jj.c
#include<stdio.h>
int main()
{
 int a=2,b=3;
 fun(a,b);
 return 0;
}
//fun_jj.c
void fun(int a,int b)
{
 printf("a = %d\nb = %d\na + b = %d\n",a,b,a+b);
}
//head_jj.h
void fun(int a,int b);

下面来到了最重要的写makefile文件的时候了,我写的makefile文件的内容如下,咱们一句一句来解释。

my_result:fun_jj.o main_jj.o head_jj.h
 gcc fun_jj.o main_jj.o head_jj.h -o my_result
fun_jj.o:fun_jj.c
 gcc fun_jj.c -c
main_jj.o:main_jj.c
 gcc main_jj.c -c
clear:
 rm -f *.o

首先我们要知道,在写makefile文件的时候,有的行前面会空上一截,注意,这一截要用Tab键,不能用空格代替。

第一行中的my_result是我为程序编译后产生的可执行文件的文件名

看前两行:
my_result:fun_jj.o main_jj.o head_jj.h
gcc fun_jj.o main_jj.o head_jj.h -o my_result
这两行是说my_result这个文件是由fun_jj.o main_jj.o head_jj.h这三个文件产生的可执行文件,是怎么产生的呢?
噢!原来是执行gcc fun_jj.o main_jj.c head_jj.h -o my_result这一条命令产生的!

那么问题来了:

Ubuntu说:我怎么知道你这个fun_jj.o是怎么来的?快告诉我!
我:好吧!我告诉你fun_jj.o文件是fun_jj.c编译但不链接来的!,fun_jj.c你直接在当前目录下自己找,找不到的话就报错告诉我,你只要乖乖的按我的指令做就好了,记住了,我给你的指令是:gcc fun_jj.c -c
Ubuntu说:好吧,我执行gcc fun_jj.c -c了,哇,我生成了fun_jj.o!!!太神奇了,不可思议,我要继续执行指令gcc fun_jj.o main_jj.o head_jj.h -o my_result了。咦?这个 main_jj.o我也不知道怎么来的!
我:你怕不是个傻子吧!

在这里插入图片描述

我:我再告诉你一遍,同理,main_jj.o文件是main_jj.c编译但不链接来的!给你的指令是:gcc fun_jj.c -c
Ubuntu说:懂了懂了,谢谢!

通过我和Ubuntu的对话,大家应该知道,makefile文件里的内容就是告诉Ubuntu应该怎么做的,这个题目里面有一个我觉得很怪异的地方,就是文件head_jj.h,他只是一个函数的声明,我试过,如果把makefile文件的内容写成下面这个,结果是一样的:

my_result:fun_jj.o main_jj.o
 gcc fun_jj.o main_jj.o -o my_result
fun_jj.o:fun_jj.c
 gcc fun_jj.c -c
main_jj.o:main_jj.c
 gcc main_jj.c -c
clear:
 rm -f *.o

所以我觉得这个文件可写可不写,我们还是暂时把它写上吧。

写完了各个相互关联的语句之后,我们来看看最后的语句:
clear:
rm -f *.o
这两条语句,从rm -f *.o就可以看出,它是删除以.o结尾的文件,这个指令方便我们删去以.o结尾的指令,只需要执行make clear就行了。

下面俺来演示一下,现在命令行输入:

zhaole@zhaole-virtual-machine:~/test$ make my_result
gcc fun_jj.c -c
fun_jj.c: In function ‘fun’:
fun_jj.c:3:2: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
  printf("a = %d\nb = %d\na + b = %d\n",a,b,a+b);
  ^~~~~~
fun_jj.c:3:2: warning: incompatible implicit declaration of built-in function ‘printf’
fun_jj.c:3:2: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’
gcc main_jj.c -c
main_jj.c: In function ‘main’:
main_jj.c:5:2: warning: implicit declaration of function ‘fun’ [-Wimplicit-function-declaration]
  fun(a,b);
  ^~~
gcc fun_jj.o main_jj.o head_jj.h -o my_result

再用ll命令查看一下(这里用ll更好,因为ll可以看到文件最后一次修改的时间)

总用量 44
drwxr-xr-x  2 zhaole zhaole 4096 223 21:28 ./
drwxr-xr-x 18 zhaole zhaole 4096 223 20:33 ../
-rw-r--r--  1 zhaole zhaole   75 221 19:06 fun_jj.c
-rw-r--r--  1 zhaole zhaole 1592 223 21:28 fun_jj.o
-rw-r--r--  1 zhaole zhaole   23 221 19:21 head_jj.h
-rw-r--r--  1 zhaole zhaole   69 221 20:00 main_jj.c
-rw-r--r--  1 zhaole zhaole 1440 223 21:28 main_jj.o
-rw-r--r--  1 zhaole zhaole  177 223 21:28 makefile
-rwxr-xr-x  1 zhaole zhaole 8368 223 21:28 my_result*

果然,生成了.o文件

我们再打开my_result查看:

zhaole@zhaole-virtual-machine:~/test$ ./my_result
a = 2
b = 3
a + b = 5

此时我们改变main_jj.c里面a,b的值:

//main_jj.c
#include<stdio.h>
int main()
{
 int a=11,b=9;
 fun(a,b);
 return 0;
}

再重复上面的指令:

zhaole@zhaole-virtual-machine:~/test$ make my_result
gcc main_jj.c -c
main_jj.c: In function ‘main’:
main_jj.c:5:2: warning: implicit declaration of function ‘fun’ [-Wimplicit-function-declaration]
  fun(a,b);
  ^~~
gcc fun_jj.o main_jj.o head_jj.h -o my_result
zhaole@zhaole-virtual-machine:~/test$ ./my_result
a = 11
b = 9
a + b = 20

显然,a,b的值更新了,再用ll命令查看一下:

zhaole@zhaole-virtual-machine:~/test$ ll
总用量 44
drwxr-xr-x  2 zhaole zhaole 4096 223 22:00 ./
drwxr-xr-x 18 zhaole zhaole 4096 223 20:33 ../
-rw-r--r--  1 zhaole zhaole   75 221 19:06 fun_jj.c
-rw-r--r--  1 zhaole zhaole 1592 223 21:28 fun_jj.o
-rw-r--r--  1 zhaole zhaole   23 221 19:21 head_jj.h
-rw-r--r--  1 zhaole zhaole   70 223 21:59 main_jj.c
-rw-r--r--  1 zhaole zhaole 1440 223 22:00 main_jj.o
-rw-r--r--  1 zhaole zhaole  177 223 21:28 makefile
-rwxr-xr-x  1 zhaole zhaole 8368 223 22:00 my_result*

敲黑板!!!

大家看两次ll命令main_jj.c,main_jj.o,my_result这三个文件的修改时间变了,而我只修改了main_jj.c中参数的值,出现这样的原因是因为Ubuntu会检测到和main_jj.c的修改时间是在main_jj.o之后的,就说明在生成main_jj.o之后,main_jj.c有改变了,所以说,也要修改main_jj.o。而在执行gcc fun_jj.o main_jj.o -o my_result的时候,Ubuntu又发现main_jj.o最后一次修改的时间在my_result之后,所以又对my_result进行了修改。

大家可以发现,使用makefile给我们免去了很多繁琐的步骤。

下面我们在不修改数值的情况下,第三次执行make my_result:

zhaole@zhaole-virtual-machine:~/test$ make my_result
make: “my_result”已是最新。
zhaole@zhaole-virtual-machine:~/test$ ./my_result
a = 11
b = 9
a + b = 20

显示已是最新!再用ll命令查看一下:

zhaole@zhaole-virtual-machine:~/test$ ll
总用量 44
drwxr-xr-x  2 zhaole zhaole 4096 223 22:00 ./
drwxr-xr-x 18 zhaole zhaole 4096 223 20:33 ../
-rw-r--r--  1 zhaole zhaole   75 221 19:06 fun_jj.c
-rw-r--r--  1 zhaole zhaole 1592 223 21:28 fun_jj.o
-rw-r--r--  1 zhaole zhaole   23 221 19:21 head_jj.h
-rw-r--r--  1 zhaole zhaole   70 223 21:59 main_jj.c
-rw-r--r--  1 zhaole zhaole 1440 223 22:00 main_jj.o
-rw-r--r--  1 zhaole zhaole  177 223 21:28 makefile
-rwxr-xr-x  1 zhaole zhaole 8368 223 22:00 my_result*

显然,时间没有改变。

下面,我们来演示一下make clear的作用:

zhaole@zhaole-virtual-machine:~/test$ make clear
rm -f *.o
zhaole@zhaole-virtual-machine:~/test$ ll
总用量 36
drwxr-xr-x  2 zhaole zhaole 4096 223 22:12 ./
drwxr-xr-x 18 zhaole zhaole 4096 223 20:33 ../
-rw-r--r--  1 zhaole zhaole   75 221 19:06 fun_jj.c
-rw-r--r--  1 zhaole zhaole   23 221 19:21 head_jj.h
-rw-r--r--  1 zhaole zhaole   70 223 21:59 main_jj.c
-rw-r--r--  1 zhaole zhaole  177 223 21:28 makefile
-rwxr-xr-x  1 zhaole zhaole 8368 223 22:00 my_result*

发现.o文件全部都没有了,makefile再一次给我们提供了方便!

好了,今天就写到这了,欢迎在评论区对不当的地方进行指正,一起进步。

对了,原创不易,最后如果觉得本文对你有帮助的话,请:
在这里插入图片描述

  • 22
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值