目录
[1. 语言的发展](#1. 语言的发展)
[1.1 语言和编译器自举的过程](#1.1 语言和编译器自举的过程)
[1.2 程序翻译的过程:](#1.2 程序翻译的过程:)
[2. 动静态库的理解](#2. 动静态库的理解)
[1. 快速上手使用](#1. 快速上手使用)
[2. makefile/make执行顺序的理解](#2. makefile/make执行顺序的理解)
前言
了解完vim编辑器的使用,接下来就可以尝试写一写代码啦,本期我将会向大家介绍Linux环境下,gcc/g++的使用方法,以及一些使用技巧。
gcc/g++的使用
在此之前我们需要先了解一下语言的发展,以便于我们更好的理解程序编译的过程。
1. 语言的发展
编程语言的发展历程:
- 二进制
- 汇编
- C语言诞生
- C++、python、Java ...
1.1 语言和编译器自举的过程
二进制 ------>用二进制写汇编编译器,然后就可以通过汇编语言,编写汇编语言的编译器,使用汇编语言编写C语言编译器,再用C语言编写C语言的编译器......不断向后迭代
1.2 程序翻译的过程:
预处理:
-
头文件展开
-
去注释
-
宏替换
-
条件编译
gcc -E code.c -o code.i
从现在开始进行程序的翻译过程,当预处理做完的时候,就停下来
-E预处理
-o 生成指定临时文件(.i文件)
gcc code.c -o code.exe -D N=1
-D 指定值
Linux环境下,我们可以给编译器不同的宏值,来进行对代码的裁减
编译:
-
C语言转换为汇编语言
gcc -S code.i -o code.s
从现在开始进行程序的翻译,当编译做完的时候,就停下来
汇编:
-
汇编语言翻译成二进制(可重定位目标二进制文件)
gcc -c code.s -o code.o
-c汇编做完就停下来
链接:
生成.o文件以后并不能执行(即使有可执行权限)
gcc -o code code.o
-o 指定生成的文件
2. 动静态库的理解
查看文件链接的库:
ldd + [可执行文件]
也就是C标准库
库分为两类:
|-----|-------|---------|
| 平台 | Linux | Windows |
| 动态库 | .so | .dll |
| 静态库 | .a | .lib |
平台要支持开发,就必须提前在系统中安装 语言的标准头文件+库文件
动静态库本质就是文件
动态库:在程序运行时被加载到内存中,程序可以共享同一个库文件
**优点:**比较节省资源,不会出现太多重复代码
**缺点:**对库的以来较强,一旦库文件丢失,使用该库的程序都无法运行
静态库:将自己需要的代码拷贝到自己的可执行程序中,程序运行时不需要额外的库文件(导致可执行文件较大)
**优点:**不依赖库,同类型平台中都可以直接运行使用
**缺点:**可执行程序体积比较大,比较浪费资源
使用静态库编译代码:
gcc -o [指定文件名] code.c -static
查看Linux系统中是否有静态库:
ls /lib64/libc.a
显示没有文件就没有安装(一般情况下,系统默认都不会安装)
Centos 7 yum 安装静态库 指令:
sudo yum install -y glibc-static libstdc++-static
安装成功之后可以再次使用上述指令进行验证
Linux项目自动化构建工具-make/makefile
- make 是一个命令
- makefile 是一个文件
makefile文件保存的是依赖关系和依赖方法
1. 快速上手使用
-
编写一个code.c文件
-
手动创建一个名为Makefile的文件(文件名必须是Makefile)
打开文件输入进行写入:
执行make指令就可以自动将代码进行编译
什么是依赖关系和依赖方法
举个例子:
我们与父母,我们和父母之间就是依赖关系,没有生活费时,我们找父母要生活费,打电话给父母确认依赖关系,向父母要生活费就是具体的依赖方法。
依赖关系:为什么帮你?
依赖方法:怎么帮?
语法:
当我们不修改项目的代码时多次执行make就会出现这种情况:
清理掉项目生成的可执行文件即可,可以对一个项目编译,那我们也要对一个项目进行清除,如何清除?
只需在第一个目标文件下边重新添加一个:
依赖方法:删除文件
使用:
make + 目标文件
那为什么mybin
就可以不指明目标文件?
Makefile
和make
形成文件的时候,默认是从上到下扫描makefile
文件,默认形成第一个目标文件
在重复执行的时候,会显示当前的目标文件已经是最新的,那make
和makefile
是如何知道可执行程序是比较新的呢?
这个其实是通过对比时间比起来的,只要可执行程序的最近修改时间比所有源文件的最近修改时间新,说明它就是最新的!
stat指令可以查看文件的相关时间
其中:
- Modify是修改文件内容的时间
- Change是文件属性改变的时间
它们有什么不同?
文件 = 内容 + 属性
- Modify对应的是文件内容修改
- Change对应的是文件属性修改
但是在修改文件的内容时,我们会发现Change也会发生改变,这是因为我们在修改文件内容时,文件的大小(文件属性)也会发生改变。
Access:在访问一定次数时才会进行更新(为了提高工作效率),在日常操作中,会大量的访问文件,访问频次远超于Modify和Change
知识补充:
touch命令还可以对文件**acm
**(是Access、Change、Modify缩写)的时间进行刷新,不存在的文件它会进行创建
为了解决多次执行时不进行操作的问题,可以使用.PHONY:修饰
#
.PHONY:修饰mybin目标文件,成为一个伪目标,总是被执行
注意:.PHONY一般都是修饰clean操作的
这样就可以连续重复的执行
这个机制是Linux中为了防止同个程序被反复编译。
例如:在日常工作中,一个项目有很多代码,makefile文件中存放了许多程序的编译指令,编译一次可能就要二十多分钟,如果哪个模块出了问题进行了修改,调试效果时,如果都重新编译,就要编译二十多分钟,所以为了提高效率,在Linux中,只有被修改后才可以重新编译并且只会对修改的部分进行重新编译、链接。
2. makefile/make
执行顺序的理解
它的执行过程也是一个类似递归的过程(先进后出),先进入执行,直到找到最终的文件,然后开始逆向执行
make/makefile的用法还有很多,这里就不再进行深入介绍,本文只是对make/makefile一些基本常见的内容进行介绍
总结
本文介绍的gcc/g++以及make/makefile都是在日常工作中常用的工具,make和makefile用于自动化构建过程,特别是在大型项目中。熟悉和掌握这些工具的基本用法对于软件开发人员来说也是非常重要的,以上便是本文的全部内容,最后感谢阅读!