Linux环境基础开发工具使用篇(二) gcc/g++ 与 make/makefile

目录

一、Linux编译器 gcc/g++

基本定位:

程序的翻译过程

1.编程语言/编译器的自举过程

2.程序翻译的过程

(1)翻译过程理论

(2)翻译过程实操

(3)详解链接过程

总结

 二、自动化构建代码 make/Makefile

Makefile 内容模板

自动化构建与清理演示

.PHONY 修饰的伪目标表示总是被执行的含义:

1.现象

2.文件的acm时间

3.总是被执行的含义

make/Makefile的自动推导能力

Makefile 的一些语法细节

三、Linux第一个小程序---进度条

1.缓冲区

2.回车换行

版本一:简单原理版本​编辑

版本二:实际工程实践版本

版本三:美化版本


一、Linux编译器 gcc/g++

基本定位:

1.我们已经能够使用vim在Linux下写代码了,接下来编译代码就要靠gcc/g++了,gcc/g++是Linux下的编译器,gcc只能编译C语言代码,不能编译C++代码,而g++既可以编译C语言代码,也可以编译C++代码

2.C源文件后缀是.c,  C++源文件后缀是 .cpp / .cc / .cxx,  没有区别,只是使用习惯不同~

3.gcc/g++编译源文件可以指定形成的可执行程序的名称

4.如果用gcc编译c源文件报错,则采用 gcc test.c -std=c99

程序的翻译过程

1.编程语言/编译器的自举过程

早期只有二进制语言,后来人们觉得太麻烦了,于是发明了汇编语言,而机器只认识二进制语言,于是需要把汇编语言翻译成二进制语言,机器才能识别,因此人们用二进制语言写了一个简单的二进制编译器,把汇编翻译成了二进制,从此之后,就可以用汇编语言写一个编译器(编译器也是软件),叫做汇编编译器;

之后又出现了C/C++语言,人们用汇编语言写了一个简单的C/C++编译器,把C/C++语言翻译成汇编语言,汇编编译器再把汇编语言翻译成二进制语言,从此就可以用C/C++写编译器了,叫做C/C++编译器,这个过程叫做语言/编译器的自举过程

2.程序翻译的过程
(1)翻译过程理论

翻译过程就指的是将我们写的C/C++语言代码,翻译成机器可以认识的二进制语言的过程, 中间经历了下面四个阶段;之所以要经历好几个阶段,而不是从c语言直接到二进制文件,就是因为历史是这么发展过来的,我们可以站在巨人的肩膀上!

预处理

        变化: code.c -> code.i    预处理完之后还是c语言

        具体行为:

               a.头文件展开

               b.宏替换

               c.去注释

               d.条件编译

编译  

        变化: code.i -> code.s    C语言变成了汇编语言

汇编

        变化: code.s -> code.o   汇编语言变成了可重定位二进制文件

链接

        变化: code.o -> a.out      二进制文件变成可执行程序

(2)翻译过程实操

gcc code.c -o mybin  这样会一次性把预处理,编译,汇编,链接的工作全部做完,不便于我们观察每个阶段,因此我们给gcc 后面带上不同选项,就可以让程序翻译到指定阶段就停下来~

指令操作

        预处理  gcc -E code.c -o code.i

        编译      gcc -S code.i  -o code.s

        汇编      gcc -c  code.s -o code.o

        链接      gcc code.o -o a.out

①预处理: 

gcc -E code.c -o code.i

-E就是告诉gcc,翻译工作做到预处理完,就停下来,不要继续往后了!

-o就是指定生成的目标文件的名称

展开头文件,去注释,宏替换

图中已说明了头文件展开的本质就是拷贝头文件内容到源文件中, 因此linux系统肯定会去特定的路径下搜索头文件,进而拿到头文件内容~

条件编译

可以看到,通过条件编译,我们就可以实现对代码的动态裁剪

现实中有很多的软件都有专业版/社区版,只是功能有所差异,如果维护两份代码的话成本太高,因此可以通过条件编译选择性保留某些功能,这样就只需要一份源代码了~

②编译

gcc -S code.i  -o code.s

③汇编

④链接

ps: 直接vim code.o 或者 vim a.out 是乱码,我们可以采用 od 查看二进制文件

小贴士:二进制文件不具有可执行功能

(3)详解链接过程

·对库的理解

我们在c语言中已经学过了不少库函数,库函数本质就是有一些高频并且需要被人大量使用的函数,有人帮我们把他们实现好了,我们就无需再实现,只需要调用即可,这样的话既提高了效率,又减少了bug的产生,而这批库函数就是以库的形式呈现给我们的

ldd 指令 查看一个可执行程序所依赖的第三方库的信息

我们的代码+头文件+库文件 = 可执行程序

所以安装开发环境本质就是下载并安装头文件和库文件到开发环境的指定路径下,一定要被编译器自己能够找到!

·库的分类

libc.so.6。 库一般以lib开头,so 表明是库的类别是动态库, 6是版本号,一个库真正的名字是去掉前后缀,所以 libc.so.6 其实就是c标准库

Linux中 .so 是 动态库 ;.a 是 静态库,  ll /lib64/* 可以看到动态库很多,静态库比较少

windows中 xxxx.dll是动态库,YYYY.lib是静态库

·动静态库的概念

1.动态库是C/C++或者其他第三方提供的所有方法的集合,被所有程序以链接(动态链接)的方式,关联起来

动态链接  ---》 每个函数在被编译器编译形成库的时候都有地址,库中所有的函数,都有入口地址,所谓的动态链接,其实就是要把连接的库中的函数地址拷贝到我们可执行程序的特定位置

2. 静态库是C/C++或者其他第三方提供的所有方法的集合,被所有程序以拷贝的方式,将需要的代码,拷贝到自己的可执行程序中!

静态链接 ---》 静态库的存在是为了被拷贝

·动静态库的优缺点

·动态库

    优点:形成的可执行程序体积小, 节省资源(磁盘+内存)

         因为只需要拷贝函数地址,所以体积小,由于可执行程序文件,要被保存在磁盘上,所以节省磁盘空间,又因为程序在被运行的时候要先被加载到内存中,所以体积小的话也节省内存空间

    缺点:强依赖动态库,动态库没了,所有的依赖这个库的程序都无法运行了

·静态库

    优点:无视库,可以独立运行

    缺点:体积太大,浪费资源

·测试动静态库

默认情况下,云服务器是没有安装c静态库的,只有动态库,也就是说编译器默认链接的方式是动态链接,就是因为静态库的体积太大了!

总结

开发环境默认做以下几点:

1.下载开发环境 include, lib等

2.设置合理的查找路径

3.规定好形成可执行程序的链接方式

 二、自动化构建代码 make/Makefile

我们已经能够在vim中编写代码了,也能够用gcc/g++编译代码了,而linux还给我们提供了自动化构建代码和自动化清理的方案,具体含义如下:

make是一个命令,Makefile是一个在当前目录下存在的一个具有特定格式的文本文件

Makefile 内容模板

自动化构建与清理演示

其中,只写make会扫描Makefile中从上到下遇到的第一个目标文件,并执行依赖方法

.PHONY 修饰的伪目标表示总是被执行的含义:

1.现象

第一次make的时候可以编译,第二次make就编译不通过了

而当我修改了源文件code.c的内容之后又能够编译了,但是再编译又不行了~

说明了make/Makefile能够识别出文件新旧,如果是旧文件就不编译了,因为当源文件比较多的时候都重新编译太耗费时间了,会降低编译效率!但是make/Makefile是如何识别文件新旧的呢??是通过对比可执行程序mybin和源文件的时间来确定文件新旧的!

2.文件的acm时间

Access  文件最近被访问的时间(包括ls, cd, cat, vim等)

Modify   文件最近的内容修改时间

Change 文件最近的属性修改时间

①直接修改文件属性,Ctime变了,MTime一般不变

②改变文件内容,Mtime变化,ATime和CTime也联动式地变化(比如文件大小)

③访问文件,Atime有时变,有时不变

大多数情况下对一个文件最频繁的操作就是查看文件,而文件保存在磁盘上,访问磁盘的效率是表低下的,因此如果每次查看文件都要更改文件的Atime, 本质就是访问磁盘,减缓了操作系统效率,因此系统对于更改Atime添加了次数限制

3.总是被执行的含义

上面提到,make/Makefile 是通过对比源文件和可执行程序的时间来确定要不要编译,而这个时间就指的是Mtime, 如果源文件时间 < 可执行程序,说明这个源文件已经是最新编译过的,将不再重新编译,如果原文件时间 > 可执行程序,说明这个源文件是新创建的,还没有被编译过,因此要编译!

总是被执行的含义就是如果被.PHONY 修饰,依赖方法总是执行,不被任何情况拦截(比如文件时间的前后关系)

make/Makefile的自动推导能力

Makefile 的一些语法细节

1.让指定的依赖方法不回显

现在不想让执行的指令以及echo语句本身显示出来,只想让echo打印的内容显示出来,这时可以在依赖方法前面加@

2.变量/宏的替换

3.依赖关系的简写

当然也可以把上面两个语法细节结合起来写~

三、Linux第一个小程序---进度条

补充知识:

1.缓冲区

第一个程序:

第二个程序:

问题是第2个程序,执行流程肯定是顺序结构,先执行打印语句,但现象是先睡眠了两秒钟,说明打印出的内容只是暂时没有显示到屏幕上罢了,实际上打印的内容暂存在了缓冲区中,我们可以采用刷新缓冲区的方式来让打印内容立即显示到屏幕上!

而第一个程序之所以立马显示打印内容,是因为\n也是一种刷新缓冲区的方式,叫做行刷新!

2.回车换行

回车和换行其实是两个操作,不过C语言中的 \n 把两个操作都给做了,因此,如果我们只想回车(回到该行最开始) 而不到下一行, 可以用\r

倒计时程序

版本一:简单原理版本

版本二:实际工程实践版本

版本三:美化版本

  • 20
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux离线安装GCC和G++的步骤如下: 1. 下载GCC和G++的源代码包,可以从官方网站或镜像站点下载。 2. 解压源代码包,进入解压后的目录。 3. 执行configure命令,生成Makefile文件。命令格式为:./configure --prefix=/usr/local/gcc --disable-multilib。 4. 执行make命令,编译源代码。命令格式为:make -j4。 5. 执行make install命令,安装GCC和G++。命令格式为:make install。 6. 配置环境变量,将GCC和G++的路径添加到PATH环境变量中。可以在/etc/profile文件中添加以下内容: export PATH=/usr/local/gcc/bin:$PATH 7. 验证安装是否成功,执行gcc -v和g++ -v命令,查看版本信息。 以上就是Linux离线安装GCC和G++的步骤。 ### 回答2: Linux是一款开源的操作系统,因为其完备的开发工具和庞大的用户群体,它成为了众多开发者的首选。在Linux系统中,gcc和g这两个工具的安装是非常重要的,因为它们是编译和连接程序所必须的。如果你的系统没有连接到互联网,那么你需要进行离线安装。下面是一些步骤,帮助你离线安装gcc和g。 1. 获取安装包 首先需要获取gcc和g的安装包。通常,这些安装包可以从你的Linux发行版的仓库中获得。如果你无法通过互联网获取,你就需要从其他的渠道获取,例如从朋友的电脑或通过移动设备。安装包需要下载并存储在本地。 2. 安装前依赖 在Linux中,一些软件包的安装需要先安装其他的软件包或库,这些依赖的软件包需要在安装前安装。你需要检查你的Linux发行版提供了哪些依赖的软件包,然后将它们逐一地安装。 3. 安装gcc和g 下载好所有的依赖包之后,接下来就需要安装gcc和g了。在终端中,输入以下命令来安装gcc和g: ``` tar -xf gcc_版本号.tar.gz cd gcc_版本号 ./configure --prefix=/usr/local/gcc make make install ``` 以上命令解释: - tar命令解压缩安装包 - cd命令 进入gcc的目录下 - ./configure是运行configure脚本,用于检测系统环境。--prefix选项指定了安装的目录,在这里是/usr/local/gcc。 - make命令用于编译 - make install 用于安装 4. 配置环境变量 在安装完成后,需要设置环境变量,以便系统中任何地方都可以使用gcc和g。在终端中输入以下命令行: ``` echo "export PATH=/usr/local/gcc/bin:$PATH" >> ~/.bashrc source ~/.bashrc ``` 以上命令解释: - echo "export PATH=/usr/local/gcc/bin:$PATH" >> ~/.bashrc,该命令用来将路径/usr/local/gcc/bin加入环境变量中 - source ~/.bashrc 是用于读取.bashrc文件的变动,如果不这样做,改变环境变量是不起作用的。 这些步骤完成后,你的系统中就已经成功安装了gcc和g,你可以在终端中输入gcc或g的命令来验证安装是否成功了。如果你的系统不能连接到互联网,现在已经可以使用gcc和g来编译程序了。 ### 回答3: Linux是一种常用的操作系统,在开发过程中,经常需要使用gcc编译器和g++编译器来进行代码的编译和构建。但是在某些情况下,我们可能需要在没有网络连接的情况下安装这些工具。下面介绍一下在Linux系统中离线安装gcc和g++编译器的方法。 首先,我们需要准备好gcc和g++编译器版本的安装文件,可以从官方网站或者镜像网站下载对应版本的安装文件。下载完成后,将安装文件传输到Linux系统中,放在一个目录下,例如/opt/gcc。 接下来,我们需要安装依赖库和工具包。在Linux系统中,gcc和g++编译器需要依赖一些库和工具包,比如binutils、libmpc、libmpfr、libgmp、mpc-devel、mpfr-devel和gmp-devel等。在没有网络连接的情况下,我们需要手动安装这些依赖库和工具包。 通过以下命令安装依赖库和工具包: yum install -y gcc gcc-c++ binutils libmpc libmpfr libgmp mpc-devel mpfr-devel gmp-devel 安装完成后,我们可以开始离线安装gcc和g++编译器。 通过以下命令进入/opt/gcc目录: cd /opt/gcc 解压安装文件: tar -zxvf gcc-XX.X.tar.gz 进入解压后的目录: cd gcc-XX.X 创建一个目录,用于编译安装: mkdir build 进入build目录: cd build 通过以下命令配置并编译: ../configure --prefix=/opt/gcc --disable-multilib --enable-languages=c,c++ make make install 这个过程可能需要花费比较长的时间,具体时间取决于系统硬件配置和编译器版本。安装完成后,我们可以通过以下命令查看gcc和g++编译器版本: /opt/gcc/bin/gcc -v /opt/gcc/bin/g++ -v 至此,我们已经完成了Linux系统中离线安装gcc和g++编译器的过程。在没有网络连接的情况下,我们可以通过手动安装依赖库和工具包,并下载安装文件进行安装,来使用这些工具进行代码编译和构建。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值