上文我们已经学习了vim
编辑器的相关操作和使用,已经可以在Linux
下编写代码了,有了代码就需要编译运行,此时就需要用到Linux
中的编译工具gcc/g++
了,其中gcc
是C语言
的编译器,g++
是C++
的编译器,下面我们一起来学习一下吧
下面以gcc
为例来进行讲解,学会了gcc
,g++
也自然不在话下,这两个编译器的选项都是通用的,上手比较简单
将代码编译链接生成可执行程序,默认生成可执行文件a.out
gcc/g++ 源文件
当然也可以通过-o
选项,来生成指定的可执行文件
-o 目标文件
:生成指定目标文件
gcc/g++ -o 目标文件 源文件
gcc/g++ 源文件 -o 目标文件
注意:-o
选项后必须跟要生成的目标文件,这个选项放在源文件前面或者后面都是可以的
在之前说到过,程序的翻译分为:预处理、编译、汇编、链接四个阶段,下面我们就通过gcc
的学习来具体看看每个阶段都做了些什么
首先是预处理,主要功能包括包括宏定义,文件包含,条件编译,去注释等,经过预处理后文件的后缀为.i
通过-E
选项,可以使编译器在执行完预处理后停下来,配合-o
生成指定文件
gcc/g++ -E 源文件 -o 目标文件(.i)
第二步是编译,在这个阶段gcc/g++
会对代码进行语法分析、词法分析、语义分析、符号汇总等,然后将合法的代码转为汇编代码,经过编译后文件的后缀为.s
通过-S
选项,可以使编译器在执行完编译后就停下来,配合-o
生成指定文件
-S 源文件 -o 目标文件(.s) //也可以直接从.i文件开始执行
第三步是汇编,这个阶段是将汇编代码转化为二进制,并生成符号表,也就是把编译阶段生成的.s
文件转成目标文件,经过汇编后的文件后缀为.o
符号表相当于每个函数独自的地址,在Linux
中,C语言的符号表通常是 _函数名
,如 _Add
,C++的符号表通常为 _Z函数名长度+函数名+参数1+参数2
通过 -c
选项,可以使 编译器在执行完汇编阶段后就停下来,配合-o
生成指定文件
gcc/g++ -c 源文件 -o 目标文件(.o) //也可以从.i/.s文件开始执行
二进制文件是elf
格式,用vim
直接查看是乱码,可以用readelf
工具查看,没有的可以自行下载
最后一步是链接,这个阶段会进行合并段表,符号表的合并和重定位等操作,会将程序运行所需的各种函数链接起来,包括与库函数的链接,Linux
中一般是动态链接,链接后生成可执行文件,默认为a.out
,也可以自己指定
gcc/g++ 源文件 -o 目标文件 //也可以从.i/.s/.c文件开始执行
以上就是gcc/g++
的全部讲解和操作了,希望对各位有帮助
每种编程语言都有自己的库,比如c语言的stdio
、stdlib
等,我们在调用库函数时,就是在调用标准库中的函数,Linux下C语言的标准库都在/usr/include
路径下,这个文件就是C语言的动态库
动态库中的内容是被所有程序共享的,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so
”,如 libc.so.6
就是动态库。gcc
在编译时默认使用动态库。完成了链接之后,gcc
就可以生成可执行文件
Linux中默认使用动态链接,通过指令ldd
可以列出一个程序所需要的动态链接库(动态链接库也称共享链接库)
ldd 文件名 //查看文件链接情况
这里libc.so.6
就是动态链接的标志,其中lib
是前缀,.so
是后缀,去掉前后缀,最终为c
,即为文件最终调用的库
file命令查看文件详细信息
file 文件名 //查看文件的详细信息
动态链接主要依赖不同函数在库中的位置信息进行调用,只有一份代码库,比较节省空间
举个生活中的例子帮助记忆:
静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a,如果想采用 静态链接的方式编译程序,需要在编译时加上 -static
选项”
没有静态库可以自行下载
yum install -y glibc-static //下载C语言静态库
yum install -y glibc-static libstdc++-static //下载c++语言静态库
静态库名称为libXXX.a
,其中lib是前缀,.a是后缀,去掉前后缀,就是最终调用的库
由于静态链接是直接讲所需代码拷贝到程序中,所以最终生成的文件相对动态链接会大很多
接着上面的例子:
总结
优缺点
动态库优点
动态库缺点
静态库优点
静态库缺点
make
命令和Makefike
文件是配合使用的,Makefile
文件中用来编写任务,任务由依赖关系
+ 依赖方法
组成
那么什么是依赖关系和依赖方法呢?
比如源文件myfile.c
,通过gcc test.c -o myfile
命令编译后生成mytfile
文件,此时两个文件之间的依赖关系为 myfile:myfile.c
,而依赖方法就是 gcc myfile.c -o myfile
然后将依赖关系和依赖方法写入Makefile文件中
编写完成后,我们就得到了一个基本的自动化任务,输入 make myfile
就可以直接编译 myfile.c
文件,生成 myfile
注意:任务刷新策略
touch
源文件就行了,两种行为都会修改文件的最近修改时间,使源目标文件不是最新时间直接输入 make
指令时,会默认执行 Makefile
中的第一个自动化任务,当任务成功执行后,不再继续执行后续任务
而使用make 任务名
,则可以调用Makefile
文件中的任意任务,这里的任务名就是依赖关系中:
左侧的名字
.PHONY
是 Makefile
文件中的一个关键字,用于对某对象生成伪目标,这样可以无视任务刷新策略,重复执行任务
.PHONY
关键字,对于源文件编译来说,没什么意义,一般是用来修饰 clean
任务,生成清理任务,实现如下
小知识:make
指令的工作原理是去 Makefile
文件中查找任务执行,设计者为了保证适用性,命名为Makefile
和makefile
都是可以的
当普通用户想去执行某些操作时,会提示权限不够,需要使用root
身份,比如一个简单的下载软件操作,就有些麻烦了,为了解决这一情况,可以使用sudo
进行提权,也就是暂时借助root
的身份去完成某个命令
sudo 命令
当遇到权限拒绝的场景时,只需要使用sudo 命令
,然后输入密码,就可以暂时root
的身份无视权限完成指令了,这里不需要输入root
密码,而是输入普通用户的密码,这样可以做到保护root
的情况下执行指令
普通用户默认是没有赋予提权权限的,还是需要切到root
用户下进行配置
配置步骤:
root
用户下/etc/sudoers
文件//root用户下
vim /etc/sudoers //进入配置文件,按照下图修改即可
退出底行模式的时候需要使用wq!
指令,这是因为是系统级配置文件所以修改需要慎重,所以必须强制修改
Linux开发工具gcc/g++,到这里就介绍结束了,本篇文章对你由帮助的话,期待大佬们的三连,你们的支持是我最大的动力!
文章有写的不足或是错误的地方,欢迎评论或私信指出,我会在第一时间改正