Linux的编译器-gcc/g++
基本概念:gcc是专门用来编译c语言的,g++可以编译c++或c语言
问题一:gcc有时候为什么不能编译带有for循环的c语言源文件?
答:gcc版本过低会不支持for循环等c99标准下的内容
解决方式:gcc 源文件名 -std=c99(-std=c99是为了让gcc支持c99中的语法)
此外,gcc还可以指定编译生成的可执行程序文件名:gcc -o 自定义名称 源文件 -std=c99
问题二:gcc中c++源文件的后缀是什么?
答:.cc、.cpp、.cxx,不能
问题三:gcc能编译c++的源文件文件吗?
答:不能,c++的源文件只能由g++来编译
指令:g++ -o my.exe test.cc -std=c++11
此外,g++也支持编译c语言的源文件,所以:g++ -o my.exe test.c -std=c99
问题四:如何查看自己是否拥有g++?如何安装g++?
答:g++ --version查看g++版本,sudo yum install -y gcc-g++指令进行g++的安装
再次理解程序的翻译过程
过程 | gcc命令 | 说明 |
预处理 | gcc -E test.c -o test.i | 宏替换、去注释、头文件展开、条件编译 |
编译 | gcc -S test.i -o test.s | 将源代码翻译成汇编语言 |
汇编 | gcc -c test.s -o test.o | 汇编语言变为机器码,生成目标文件 |
链接 | gcc test.c -o my.exe | 目标文件和库函数结合,生成形成可执行程序 |
- -E:从现在开始进行程序的翻译,预处理完成就停下
- -S:从现在开始进行程序的编译,编译完成就停下
- -c:从现在开始进行程序的翻译,汇编完成就停下
1、gcc -E test.c -o test.i:将源文件预处理后的结果放入test.i文件
2、gcc -S test.i -o test.s:将test.i文件编译后的结果放入test.s文件
3、gcc -c test.s -o test.o:将汇编语言转换为机器码,然后放入test.o文件
动态链接和静态链接
基本概念:两种不同的链接方式,用于将程序中使用的函数库与程序本身结合起来
动态链接:
- 特点:告诉了程序目标库的地址,使用该库中的内容时回去该库中调用
- 优点:节省资源
- 缺点:多个程序共享动态库,一旦动态库缺失,所有动态链接这个库的程序都无法执行了
静态链接:
- 特点:在编译时就把库中的方法拷贝到程序中,之后就不再与库产生任何联系了
- 优点:浪费资源
- 缺点:一旦形成与库无关
在Linux系统中,.so
文件是动态链接库 .a
文件是静态库,且默认情况下linux不会安装静态库
Linux项目自动化构建工具-Makefile
主要组成部分:依赖关系 + 依赖方法
注意事项:
1、make是指令、makefile是文件,它还可以写成Makefile
2、默认情况下,make指令会从上至下读取目标文件,并优先生成第一个目标文件
3、目标文件:后的内容是一个文件列表,文件列表可以为空,如果列表中的多文件会以test1.c test2.c test3.c一个文件隔一个空格的方式存放
4、程序会根据依赖关系执行依赖方法
5、.PHONY:xxx,xxx对应的方法总是要被执行的
6、依赖方法前总要有一个tab留出空间
7、mekefile/make会自动根据文件中的依赖关系,进行自动推导,帮助我们执行所有相关的依赖方法
常见功能:
1、将test.c编译成mytest:
2、清除编译后的无用文件:
问题一:为什么makefile对最新的可执行程序,默认不重新形成?
答:提高编译效率
问题二:如何做到问题一?
答:
问题三:makefile怎么知道我的程序要被编译了?
答:对比,可执行文件的最新修改时间和源文件的最近修改时间,谁更新?
~over~