【第二十一章】make

基础

Linux系统上真正识别的可执行文件是二进制程序,比如usr/bin/passwd这种。
用户一般用文本编辑器(比如vim)编写源代码,再通过编译器将源代码编译成操作系统能看懂的二进制程序,经过编译与链接后就能产生一个可以执行的二进制程序。
编译过程中会产生目标文件(.o结尾的文件),这是源代码(.c结尾的文件)经过编译后还未进行链接的中间文件。
总结一下就是:

  • 开放源代码: 即程序代码,人类写的程序语言,但是电脑不认识
  • 编译器:将程序代码“翻译”成就算是能看懂的语言
  • 目标文件:源代码经过编译后还未进行链接的中间文件
  • 可执行文件:经过编译器变成的二进制程序,计算机看得懂所以能执行
gcc -c hello.c
//仅将源代码编译为目标文件,但不产生二进制执行文件

gcc -O hello.c -c
//-O编译时根据操作环境给予最佳执行速度
//并且会生成hello.o这个文件

gcc -o hello hello.c
//-o后面跟着要输出的二进制文件名

gcc -o hello hello.c -Wall
//加入-Wall后程序编译更加严谨,会显示警告信息

单一程序

  1. 编写源代码
    在这里插入图片描述
  2. 用gcc编译源代码
    在这里插入图片描述
    如果不加上任何参数,则执行文件的文件名会被自动设置为a.out
  3. 最后测试
    在这里插入图片描述
    这里的./意思是当前目录下。如果不加./,系统会把我输入的东西当作一个命令执行,这将导致报错:找不到a.out这个命令;加上./将指明相对路径,系统就知道这不是个命令,所以会执行当前目录下的a.out。

换一种方式

现在生成一个目标文件进行其他操作,而且执行文件的文件名也不用默认的a.out。
加上-c选项编译出目标文件
在这里插入图片描述
再将目标文件链接后生成可执行文件hello(绿色的那个),再执行该文件
在这里插入图片描述
这里实际只有一个目标文件,没有突出链接的特点。给我一种不需要生成执行文件,用a.out就够了的感觉。其实不是,当有多个目标文件时就知道链接的重要性

主、子程序链接

接下来演示:
主程序:
在这里插入图片描述
主程序调用的函数
在这里插入图片描述

  1. 进行编译
    在这里插入图片描述
  2. 将两个目标文件链接成可执行文件thanks
    在这里插入图片描述
  3. 执行
    在这里插入图片描述

这里如果哪次更新了thank2.c的内容,则我只要重新编译该.c文件,再重新编译一个.o文件,最后重新和thank.o进行链接即可

调用外部函数库

在这里插入图片描述
这里新版gcc可以直接gcc sin.c,因为新版会主动帮你将需要的函数库放进来编译,所以只要加上#include <math.h>就行。
以前这样加入额外函数库:
在这里插入图片描述
-l表示加入某个函数库
-m表示加入的是libm.so这个函数库
-L表示在/lib和/lib64这两个目录下找我要的函数库

make

假设执行文件有3个源代码文件,f1.c、f2.c、main.c。
在这里插入图片描述
如果想让这个程序运行就要一个个的执行gcc -c然后gcc -o再链接。而且如果其中一个文件重新编译,还得再执行一遍上述操作。但是利用make可以自动执行该操作。

  1. 先写一个makefile文件
    在这里插入图片描述
  2. 执行make
    在这里插入图片描述

可以看到make自动将源文件进行了编译然后链接,最后生成了test执行文件。
如果最后再执行一遍make
在这里插入图片描述
会发现系统显示test已经是最新的了。

makefile的基本语法

(这里讲的比较简洁,深入学习看这里:跟我一起写Makefile

target : 目标文件1 目标文件2
【Tab】 gcc -o 欲建立的文件 目标文件1 目标文件2

target就是我们要建立的文件,目标文件是具有相关性的文件。注意命令行必须以【Tab】开头!
还可以编写clean操作将生成的执行文件和目标文件删除:
在这里插入图片描述
在这里插入图片描述
所以现在makefile里就有两个目标,分别是test和clean:想要建立test的话就执行make test,想清除文件就执行make clean。想先清除目标文件再编译test的话可以执行make clean test
在这里插入图片描述

使用变量

可以用变量简化makefile
在这里插入图片描述
和bash shell脚本呢的语法不太相同的几点是:

  1. 变量的变量内容以【=】隔开,同时两边可以有空格
  2. 变量左边不可以有【Tab】
  3. 变量欲变量内容在【=】两边不能有【:】
  4. 变量最好写成大写
  5. 运用变量时以${变量}或 $(变量)使用
  6. 在该shell里的环境变量可以被套用,比如CFLAGS
  7. 命令行模式也能设置变量

在gcc进行编译时会主动读取CFLAGS这个环境变量,所以我可以直接在shell中定义出这个环境变量,也能在makefile里定义,更可以在命令行中定义:
在这里插入图片描述
在makefile中:
在这里插入图片描述
在这里插入图片描述
如果CFLAGS 的内容在命令行中和环境变量中不相同,那以哪个方式输入的优先呢?环境变量使用的规则是这样的

  • make命令行后面加上的环境变量优先
  • makefile里面指定的环境变量第二
  • shell原本具有的环境变量第三
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值