GCC是一款编译器,原名为GNU C语言编译器(GNU C Compiler),GCC源于GNU项目,GNU是一个开发大量自由UNIX软件的集合,GNU意为“GNU's Not UNIX”,也就是说GNU不是UNIX。GCC从只能处理C语言到现在可以C++及更多编程语言,所以改名为GNU编译器套件(GNU Compiler Collection)。
ubuntu安装gcc时发生错误,原因未知,先解决,后查找原因。
解决办法:
1.查看进程中是否有apt-get,然后kill掉这个进程
但是结果显示不存在这个进程,不知道有没有人跟我有相同的情况,第一个方法不行的话,就换方法2解决吧。
2.删除锁文件
用sudo rm删除,先是安装了,然后又失败了。
从其他博主那得知得:出现了lock-frontend得时,先用 sudo rm /var/lib/dpkg/lock-frontend,再用 sudo rm /varlib/dpkg/lock, 最终安装成功。
出现这种情况的原因:
因为某些其他程序正在尝试更新 Ubuntu。当命令或应用程序更新系统或安装新软件时,它会锁定 dpkg 文件(Debian 软件包管理器)。
完成此锁定是为了使两个进程不会同时更改内容,因为这可能会导致不必要的情况和可能的系统损坏。
来源:[Solved] Could not get lock /var/lib/dpkg/lock Error in Ubuntu (itsfoss.com)
GCC的编译过程
1.预处理(pre-processing)
再这个过程中,展开宏定义,删除define,处理预编译。
gcc -E 1.c -o 1.i,用cat查看后缀为.i的文件,.i文件是生成的一个中间文件,查看这个文件你会发现这个文件很长。然后发现define被删除,宏进行了替换。注意预处理时不会检查语法错误。
2.编译(Compiling)
在这个阶段,gcc会把.i中间文件转化为汇编文件.s。
用cat查看,额。。看不懂,这是一种汇编代码。
3.汇编(Assembling)
汇编阶段,编译器把编译出来的结果汇编成具体CPU上的目标代码模块。输入汇编文件.s,输出机器语言.o。
此时的文件不能用文本编译器打开,可以用反编译objdump -D 1.o查看。依然看不懂,但是计算机可以。
4.链接(Linking)
链接阶段,把机器代码文件.o(也就是自己编译的代码由预处理,编译,汇编生成的.o)和系统的标准启动代码和库代码这3个部分合并成一个可执行文件。
总结:源代码转化为可执行文件是通过编译器的预处理生成.i中间文件,然后对中间文件进行编译生成.s汇编文件,然后编译器把编译出来的.s汇编文件汇编成具体CPU上的目标代码模块,变为.o机器语言。然后通过通过链接合并已编译的模块,最终生成可执行文件。
用gcc 直接对1.c进行编译,也会发现生成了1.o,1.s,1.i,也就是上述过程的结果,拆开来看是一样的。a.out是可执行程序
通常是用gcc 1.c -o 1将1.o,1.s,1.i合并并重命名为1,执行可执行文件1。因为如果要存储a.out,应该把它重命名。否则,该文件会被下一次编译程序时产生的新a.out文件替换。因为一旦链接为完整的可执行程序,就会将其删除。
1.gcc的文件类型约定
2.gcc的选项参数
程序库
所谓"程序库",简单说,就是包含了数据和执行码的文件。其不能单独执行,可以作为其它执行程序的一部分来完成某些功能。库的存在,可以使得程序模块化,可以加快程序的再编译,可以实现代码重用,可以使得程序便于升级。程序库可分静态库(static library)和共享库(shared object)。
静态库是在可执行程序运行前就已经加入到执行码中,成为执行程序的一部分;共享库, 是在执行程序启动时加载到执行程序中,可以被多个执行程序共享使用。
共享库(动态库): 会和调用者一起加载到内存,当执行调用语句时会从程序的调用位置跳转到共享库中运行,共享库要有执行权限。
静态库的内容更新后需要重新编译程序,使用静态库编译出的可执行文件会比共享库的要大,静态库在文件中静态展开,所以有多少文件就展开多少次,非常吃内存,100M 展开100次,就是1G,虽然运行速度快,但维护麻烦。
共享库使用方便,共享库如果发生变化不需要重新编译程序,使用它编译出的可执行文件比使用静态库要小,运行速度慢,但是省内存。
创建和使用静态库
ar rcs libmyname.a file1.o file2.o
libmyname.a时要创建的静态库名称,把目标代码.o文件加入到静态库中。然后用gcc把主函数和静态库链接生成可执行文件。
创建和使用共享库
gcc -shared -fPIC -o libmyname.so file1.c(或file1.o) file2.c
同样,先生成动态库然后将目标代码.o文件加入到动态库中,然后编译生成可执行文件。