【Linux】2.0 Linux环境和基本开发工具的使用

1.Linux系统软件安装

  • 源码安装
  • rpm安装包 -> 依赖关系问题
  • yum(初阶学习主要途径)

1.1Linux 软件包管理器 yum

基本指令: sudo yum install + 软件名称
作用:包管理器解决软件包下载,解决依赖关系,安装卸载等问题

首先我们还是举一个例子来解释这么使用yum安装软件
使用yum安装sl命令
[clx@VM-20-6-centos lesson_7_09]$ sl --首先我是调用sl命令
bash: sl: command not found          --我们发现系统里没有sl命令
[clx@VM-20-6-centos lesson_7_09]$ sudo yum install sl --安装过程中解压拷贝等
可能需要权限,所以先进行权限提升,然后通过指令yum install sl在yum服务器中查找实例指令
[sudo] password for clx: 
Loaded plugins: fastestmirror, langpacks
Repository base is listed more than once in the configuration
Repository updates is listed more than once in the configuration
Repository extras is listed more than once in the configuration
Repository centosplus is listed more than once in the configuration
Repository epel is listed more than once in the configuration
Repository epel-debuginfo is listed more than once in the configuration
Repository epel-source is listed more than once in the configuration
Determining fastest mirrors
base                                                                                                                                                           | 3.6 kB  00:00:00     
epel                                                                                                                                                           | 4.7 kB  00:00:00     
extras                                                                                                                                                         | 2.9 kB  00:00:00     
updates                                                                                                                                                        | 2.9 kB  00:00:00     
(1/3): updates/7/x86_64/primary_db                                                                                                                             |  16 MB  00:00:00     
(2/3): epel/x86_64/updateinfo                                                                                                                                  | 1.1 MB  00:00:03     
(3/3): epel/x86_64/primary_db                                                                                                                                  | 7.0 MB  00:00:23     
Resolving Dependencies
--> Running transaction check
---> Package sl.x86_64 0:5.02-1.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

======================================================================================================================================================================================
 Package                                 Arch                                        Version                                          Repository                                 Size
======================================================================================================================================================================================
Installing:
 sl                                      x86_64                                      5.02-1.el7                                       epel                                       14 k

Transaction Summary
======================================================================================================================================================================================
Install  1 Package

Total download size: 14 k
Installed size: 17 k
Is this ok [y/d/N]: y  --查找结束,找到sl,shell询问我们是否进行下载,输入y
Downloading packages:
sl-5.02-1.el7.x86_64.rpm                                                                                                                                       |  14 kB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : sl-5.02-1.el7.x86_64                                                                                                                                               1/1 
  Verifying  : sl-5.02-1.el7.x86_64                                                                                                                                               1/1 

Installed:
  sl.x86_64 0:5.02-1.el7                                                                                                                                                              

Complete!              --安装成功
[clx@VM-20-6-centos lesson_7_09]$ sl  --调用sl指令,会有一辆小火车跑出来
以上即是sl指令的yum安装过程

1.2yum安装扩展源

在日常使用中,因为不同软件所属国家不同,使用我们国内的网络下载国外服务器上的安装包网速会很慢,所以国内有一些机构将国外的服务器上的软件搬运进来,我们可以通过安装这些机构,从而扩大我们yum持有的软件包范围。获得更加良好的用户体验

安装扩展源

1.3yum查找安装删除软件包

查找语法: yum list | grep +软件包名称

首先打印处yum list(软件包列表)再通过管道进行查找
使用 yum list | grep lrzsz 查找lrzsz安装包
[clx@VM-20-6-centos lesson_7_09]$ yum list | grep lrzsz
Exiting on Broken Pipe
[clx@VM-20-6-centos lesson_7_09]$ yum list | grep lrzsz
Repository base is listed more than once in the configuration
Repository updates is listed more than once in the configuration
Repository extras is listed more than once in the configuration
Repository centosplus is listed more than once in the configuration
Repository epel is listed more than once in the configuration
Repository epel-debuginfo is listed more than once in the configuration
Repository epel-source is listed more than once in the configuration
lrzsz.x86_64                             0.12.20-36.el7                @os      

安装语法:sudo yum install 软件包名称 添加-y选项,系统就不会发出询问

[clx@VM-20-6-centos lesson_7_09]$ sudo yum install lrzsz  --下载安装包
Loaded plugins: fastestmirror, langpacks
Repository base is listed more than once in the configuration
Repository updates is listed more than once in the configuration
Repository extras is listed more than once in the configuration
Repository centosplus is listed more than once in the configuration
Repository epel is listed more than once in the configuration
Repository epel-debuginfo is listed more than once in the configuration
Repository epel-source is listed more than once in the configuration
Loading mirror speeds from cached hostfile
Resolving Dependencies
--> Running transaction check
---> Package lrzsz.x86_64 0:0.12.20-36.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

======================================================================================================================================================================================
 Package                                  Arch                                      Version                                             Repository                               Size
======================================================================================================================================================================================
Installing:
 lrzsz                                    x86_64                                    0.12.20-36.el7                                      base                                     78 k

Transaction Summary
======================================================================================================================================================================================
Install  1 Package

Total download size: 78 k
Installed size: 181 k
Is this ok [y/d/N]: y         --输入y
Downloading packages:
lrzsz-0.12.20-36.el7.x86_64.rpm                                                                                                                                |  78 kB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : lrzsz-0.12.20-36.el7.x86_64                                                                                                                                        1/1 
  Verifying  : lrzsz-0.12.20-36.el7.x86_64                                                                                                                                        1/1 

Installed:
  lrzsz.x86_64 0:0.12.20-36.el7                                                                                                                                                       

Complete!          -安装成功

删除语法:sudo yum remove 软件包名称

[clx@VM-20-6-centos lesson_7_09]$ sudo yum remove lrzsz --删除安装包lrzsz
Loaded plugins: fastestmirror, langpacks
Repository base is listed more than once in the configuration
Repository updates is listed more than once in the configuration
Repository extras is listed more than once in the configuration
Repository centosplus is listed more than once in the configuration
Repository epel is listed more than once in the configuration
Repository epel-debuginfo is listed more than once in the configuration
Repository epel-source is listed more than once in the configuration
Resolving Dependencies
--> Running transaction check
---> Package lrzsz.x86_64 0:0.12.20-36.el7 will be erased
--> Finished Dependency Resolution

Dependencies Resolved

======================================================================================================================================================================================
 Package                                  Arch                                      Version                                              Repository                              Size
======================================================================================================================================================================================
Removing:
 lrzsz                                    x86_64                                    0.12.20-36.el7                                       @os                                    181 k

Transaction Summary
======================================================================================================================================================================================
Remove  1 Package

Installed size: 181 k
Is this ok [y/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Erasing    : lrzsz-0.12.20-36.el7.x86_64                                                                                                                                        1/1 
  Verifying  : lrzsz-0.12.20-36.el7.x86_64                                                                                                                                        1/1 

Removed:
  lrzsz.x86_64 0:0.12.20-36.el7                                                                                                                                                       

Complete!                  --删除成功

> 注意:Centos系统中,只允许一个yum进行下载,不能有多个安装包同时进行下载

1.4lrzsz使用

作用:服务器之间的文件传输
Linux->Windows

使用sz指令
[clx@VM-20-6-centos lesson_7_09]$ sz test.cpp 将test.cpp传输到Windows中

Windows->Linux

rz -E指令
[clx@VM-20-6-centos lesson_7_09]$ rz -E   --然后就可以选择文件上传到当前目录

2.Linux开发工具

2.1Linux编译器-vim使用

功能:解决代码编写问题,本质是文本编辑器
三个常用模式:1.命令模式 2.插入模式 3.底行模式

命令->插入  a/i/o
命令->底行 shift + :
插入和底行->命令  Esc

2.2vim命令模式基本指令

shift + $/ shift + ^ 光标定位到行结尾/行开始
shift + g / gg      光标定位到文件结尾/开头
数字 + shift + g     光标定位到第几行开头
yy  复制一行
p   粘贴
数字 + yy 复制n行
数字 + p  粘贴n次
u   撤销
Ctrl + u 取消撤销
dd  删除光标所在行
数字 + dd 删除n行
数字 + dd + p 剪切
shift + ~ 大小写切换
w/b   按单词为单位跳转(到单词的开始)
e     按单词为单位跳转(到单词的结尾)
x/nx  删除光标处字符
shift + x / 数字 + shift + x 删除光标前面字符
r/nr  下面的操作直接替换光标所在字符/连续替换
shift + r 进入替换模式
h j(jump) k(king) l 左下上右
数字 + l 在当前行跳转n个字符
Ctrl + b 向上移动一页
Ctrl + f 向下移动一页
Ctrl + u 向上移动半页
Ctrl + d 向下移动半夜
yw   按单词为单位进行复制
数字 + yw 复制n个单词

2.3vim底行模式基本指令

set nonu 取消行号
set nu   调出行号
w/q/!     保存/退出/强制
!+ shell指令  不退出vim进行命令行的输入
vs + filename 分屏
Ctrl + w 光标在多屏幕之间切换

2.4简单的vim配置

配置文件位置/etc/vimrc,系统公共的vim配置文件,对所有用户有效
在每个用户的主目录下,都可以创建自己的.vimrc文件,若没有可以自己创建

前期学习不建议自己配置,最好上网直接下载成品,对Linux不太熟悉自己配置的话成本实在太高

3.Linux编译器-gcc/g++使用

3.1可执行程序生成的过程

  • 预处理(进行宏替换)-E
    主要功能:宏定义,文件包含,条件编译,去注释等
    主要对#开头的代码行进行处理

  • 编译(生成汇编)-S
    主要功能:编译器检查代码规范性、是否有语法错误,确定代码实际的工作。确认没有错误后将代码翻译成汇编语言

  • 汇编(生成机器可识别代码)-c

主要功能:生成机器可识别代码,生成的文件是可重定向的

  • 链接(生成可执行文件或者库文件)

3.2使用gcc实现程序生成过程

-o 选项 是将所得数据写入指定路径

[clx@VM-20-6-centos lesson_7_11]$ ll
total 4
-rw-rw-r-- 1 clx clx 147 Jul 11 09:28 test.c  --首先我们先创建一个test.c文件
[clx@VM-20-6-centos lesson_7_11]$ cat test.c
#include <stdio.h>
int main()
{
  printf("hello linux");
  printf("hello linux");
  printf("hello linux");
  printf("hello linux");
  return 0;
}

[clx@VM-20-6-centos lesson_7_11]$ ll
total 4
-rw-rw-r-- 1 clx clx 147 Jul 11 09:28 test.c

预处理 gcc -E 生成.i文件
[clx@VM-20-6-centos lesson_7_11]$ gcc -E test.c -o test.i
[clx@VM-20-6-centos lesson_7_11]$ ll
total 24
-rw-rw-r-- 1 clx clx   147 Jul 11 09:28 test.c
-rw-rw-r-- 1 clx clx 16945 Jul 11 09:39 test.i

编译 gcc -S   生成.s 文件
[clx@VM-20-6-centos lesson_7_11]$ gcc -S test.c -o test.s
[clx@VM-20-6-centos lesson_7_11]$ ll
total 28
-rw-rw-r-- 1 clx clx   147 Jul 11 09:28 test.c
-rw-rw-r-- 1 clx clx 16945 Jul 11 09:39 test.i
-rw-rw-r-- 1 clx clx   602 Jul 11 09:40 test.s

汇编 gcc -c   生成-o文件
[clx@VM-20-6-centos lesson_7_11]$ gcc -c test.c -o test.o
[clx@VM-20-6-centos lesson_7_11]$ ll
total 32
-rw-rw-r-- 1 clx clx   147 Jul 11 09:28 test.c
-rw-rw-r-- 1 clx clx 16945 Jul 11 09:39 test.i
-rw-rw-r-- 1 clx clx  1696 Jul 11 09:40 test.o
-rw-rw-r-- 1 clx clx   602 Jul 11 09:40 test.s
链接 gcc     生成可执行程序a.out 文件
[clx@VM-20-6-centos lesson_7_11]$ gcc test.c
[clx@VM-20-6-centos lesson_7_11]$ ll
total 44
-rwxrwxr-x 1 clx clx  8360 Jul 11 09:41 a.out
-rw-rw-r-- 1 clx clx   147 Jul 11 09:28 test.c
-rw-rw-r-- 1 clx clx 16945 Jul 11 09:39 test.i
-rw-rw-r-- 1 clx clx  1696 Jul 11 09:40 test.o
-rw-rw-r-- 1 clx clx   602 Jul 11 09:40 test.s

-E,-S,-c选项是指做到这一步就停下来。若不添加选项则默认直接生成可执行程序

3.3条件编译(了解)

[clx@VM-20-6-centos lesson_7_11]$ ll
total 4
-rw-rw-r-- 1 clx clx 129 Jul 11 09:49 test.c
[clx@VM-20-6-centos lesson_7_11]$ cat test.c   --创建一个test.c文件
#include <stdio.h>

int main()
{
# if OS          --OS我们并没有定义,编译器会默认其为假
  printf("Hello Centos!\n");
#else
  printf("Hello Windows!\n");
#endif

  return 0;
}
[clx@VM-20-6-centos lesson_7_11]$ gcc test.c     --生成可执行程序
[clx@VM-20-6-centos lesson_7_11]$ ./a.out
Hello Windows!                                   --条件判定为假
[clx@VM-20-6-centos lesson_7_11]$ rm a.out
[clx@VM-20-6-centos lesson_7_11]$ gcc test.c -D OS=1   --使用-D选项直接对条件OS进行赋值
[clx@VM-20-6-centos lesson_7_11]$ ll
total 16
-rwxrwxr-x 1 clx clx 8360 Jul 11 09:53 a.out
-rw-rw-r-- 1 clx clx  129 Jul 11 09:49 test.c
[clx@VM-20-6-centos lesson_7_11]$ ./a.out 
Hello Centos!                                         --条件判断为真

通过设置gcc的命令参数,来实现我们代码的条件编译。
以下是四个文件的样子。
.i文件和.c文件都是我们认识的c代码
.s文件则是汇编语言 .o文件则是输入给计算机执行的机器语言

在这里插入图片描述

3.4 理解链接

目标文件,只有函数调用,没有函数的实现。
链接的本质是将自己调用过程和具体的实现过程关联起来

如何查看自己的程序调用了哪些函数呢
我们可以使用ldd指令 + 可执行程序文件名称进行查看
[clx@VM-20-6-centos lesson_7_11]$ ll
total 44
-rw-rw-r-- 1 clx clx   129 Jul 11 10:05 test.c
-rw-rw-r-- 1 clx clx 16880 Jul 11 10:05 test.i
-rw-rw-r-- 1 clx clx  1505 Jul 11 10:05 test.o
-rwxrwxr-x 1 clx clx  8360 Jul 11 10:01 test.out
-rw-rw-r-- 1 clx clx   450 Jul 11 10:05 test.s
[clx@VM-20-6-centos lesson_7_11]$ ldd test.out
	linux-vdso.so.1 =>  (0x00007ffcf4572000)
	/$LIB/libonion.so => /lib64/libonion.so (0x00007fe339d86000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fe33989f000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007fe33969b000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fe339c6d000)

我们可以发现我们所调用的库的最后一个单词都是so
在【Centos】中 so -> 动态库 a-> 静态库

库的命名 lib + 库的名称 +.a/.so

3.5调用库函数原理

功能:减少开发的工作量,是软件分工的一种表现
库: 动态库(.so) 静态库(.a)
动态库原理:在我们编译阶段,调用的库函数处会保留其对应的符号,即生成一个占位符。在链接阶段,编译器通过这个占位符可以找到此函数所在库,以及此函数在库中的地址。最后将占位符改为库中此函数的起始地址,生成的可执行程序就可以通过地址来调用库函数。这就是目标文件和库链接生成可执行文件的原理
静态库原理:和动态库相同,调用的库函数处会生成相应的占位符。在链接阶段,编译器会找到库和目标库函数。然后将库中生成好的的可执行程序直接加载到我们的程序当中。完成库和目标文件的链接,生成一个可执行程序

3.6动态库和静态库的区别

引:代码通过编译器生成可执行程序要加入指令,会使文件的体积变大。可执行程序之间有部分代码逻辑是相同的,即可执行程序中有部分代码是相同的

我们先说结论

动态链接:
优点:节省空间(磁盘空间,内存空间),生成可执行程序体积小,加载速度快
缺点:运行时可移植比较差

1.节省磁盘空间
首先代码生成可执行程序中需要进行很多步骤,所以由一段代码生成的可执行程序比对应代码庞大。动态库里面记载的是库函数的实现指令所以相对于存储库函数生成的可执行程序的静态库相比。动态库的大小会小很多,也就更加节省磁盘空间
2.节省内存空间
动态链接生成的程序通过链接到动态库库函数的起始地址,向下执行指令实现库函数。而使用静态链接时,需要先将文件中所有静态库中的库函数实现的可执行程序加载到内存中。
3.生成可执行程序体积小
动态链接中只生成一个可执行程序,但是静态链接中会有很多可执行程序。假如动态链调用十个库函数,我们只需要链接其地址,加载库函数的指令即可。但是使用静态链接,就需要加载进十个可执行程序,其中库函数的可执行程序中有很多是重复的代码,所以会导致生成的指令增多,生成的可执行程序变大
4.加载速度快
因为动态链接添加的文件指令体积小,所以快
5.运行时可移植性比较差
因为我们链接是通过加载库函数的地址来进行指令的链接。但是如果我们的动态库被删除或者地址被改变,我们的编译器就无法从相应地址找到库和库函数。所以通过动态链接生成的可执行程序可能在Centos平台上可以跑,但是移植到Windows平台上就跑不了了。或者我们将库函数重命名,删除,改变路径也可能出现这样的情况

静态链接:
优点:不依赖第三方库,程序的运行可执行性强
缺点:比较占空间(磁盘,内存),生成的可执行程序较大,加载速度慢

因为我们调用的是静态库中的库函数的可执行程序,那么不管移植到哪个平台实现库函数的可执行程序指令都可以被执行,即是库被删除也可以运行生成的可执行程序。但是因为可执行程序体积比较大,运行文件生成的可执行程序前需要将文件调用的库函数生成的所有可执行程序先加载到内存中。不管是磁盘还是内存都占据跟多空间

3.7gcc/g++生成的可执行程序

静态链接:-static(选项)
gcc/g++ 编译生成的可执行程序默认是使用动态链接的
如果我们想要使用gcc/g++动态链接生成可执行文件,我们需要在编译时带上-static选项

4.Linux调试器-gdb使用

4.1生成可调试程序

当我们使用gdb test.c进入调试器时

[clx@VM-20-6-centos lesson_7_11]$ gdb test.c
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
"/home/clx/Lesson_Linux/lesson_7_11/test.c": not in executable format: File format not recognized
--最后一句话的意思是,文件没有调试信息

这是因为程序的发布方式有两种1.debug 2.release
debug方式会添加文件的调试信息(可以被调试)
release方式不会添加文件的调试信息(不可被调试)
Centos7 使用 gcc 编译生成的可执行程序默认是 release版本! 不可以调试
如果想要是要debug版本 需要添加-g选项

[clx@VM-20-6-centos lesson_7_11]$ clear
[clx@VM-20-6-centos lesson_7_11]$ ll
total 4
-rw-rw-r-- 1 clx clx 278 Jul 11 22:10 test.c         --这是我们已经编写好的.c文件
[clx@VM-20-6-centos lesson_7_11]$ gcc test.c -o test -std=c99    --生成默认release版本
[clx@VM-20-6-centos lesson_7_11]$ gcc test.c -o test_g -std=c99 -g  --生成debug版本
[clx@VM-20-6-centos lesson_7_11]$ ll
total 28
-rwxrwxr-x 1 clx clx 8392 Jul 11 22:24 test         --文件大小8392
-rw-rw-r-- 1 clx clx  278 Jul 11 22:10 test.c
-rwxrwxr-x 1 clx clx 9704 Jul 11 22:24 test_g       --文件大小9704

这里我们可以观察到debug版本比release版本大一点,原因就是debug版本加入了文件的调试信息

4.2readelf指令

语法:readelf -S + 可执行程序名称
功能:查看可执行程序的内容分段

查看debug信息
[clx@VM-20-6-centos lesson_7_12]$ ll
total 28
-rwxrwxr-x 1 clx clx 8392 Jul 12 07:41 test
-rw-rw-r-- 1 clx clx  278 Jul 12 07:41 test.c
-rwxrwxr-x 1 clx clx 9704 Jul 12 07:41 test_g
[clx@VM-20-6-centos lesson_7_12]$ readelf -S test | grep debug --查看release版本下的debug信息
[clx@VM-20-6-centos lesson_7_12]$ readelf -S test_g | grep debug--查看debug版本下的debug信息
  [27] .debug_aranges    PROGBITS         0000000000000000  00001061
  [28] .debug_info       PROGBITS         0000000000000000  00001091
  [29] .debug_abbrev     PROGBITS         0000000000000000  000011b7
  [30] .debug_line       PROGBITS         0000000000000000  0000125a
  [31] .debug_str        PROGBITS         0000000000000000  000012b0

debug版本携带可调试信息,release版本将其删除

4.3gdb的基本使用

基础指令

gdb + 文件名   --进入调试器
quit          --退出调试器
l + 行号       --显示代码
r             --运行代码
b + 行号       --打断点
info b        --查看断点信息
d + 编号       --删除断点
p + 变量名称    --查看变量相关数据
n              --逐过程
s              --逐语句(进入函数)
display + 变量名 --调用监视窗口(常显示)
undisplay + 编号 --取消常显示
until + 行号     --跳转至任意行(出循环)
finish          --直接将当前函数运行完毕
continue--跳转到下一个断点
set var=        --修改变量的值
delete breakpoints  --删除所有断点
disable + 断点编号  --禁用断点
enable  + 断点编号  --开启断点
bt            --查看栈(各级函数调用及其参数)

5.Linux项目自动化构建工具-make/Makefile

5.1多个源文件生成可执行程序

首先我们先使用vim编写好main.c mytest.c mytest.h

[clx@VM-20-6-centos lesson_7_12]$ ll
total 12
-rw-rw-r-- 1 clx clx 62 Jul 12 12:31 main.c
-rw-rw-r-- 1 clx clx 68 Jul 12 12:30 mytest.c
-rw-rw-r-- 1 clx clx 86 Jul 12 12:33 mytest.h
[clx@VM-20-6-centos lesson_7_12]$ cat main.c      --main.c
#include "mytest.h"


int main()
{
  show();
  return 0;



}
[clx@VM-20-6-centos lesson_7_12]$ cat mytest.c   --mytest.c
#include "mytest.h"


void show()
{
  printf("Hello Makefile\n");
}
[clx@VM-20-6-centos lesson_7_12]$ cat mytest.h  --mytest.h
#ifndef __MYTEST_H__
#define __MYTEST_H__ 

#include <stdio.h>
void show();


#endif 
如何使用这三个文件生成可执行程序呢
[clx@VM-20-6-centos lesson_7_12]$ gcc mytest.c main.c -o mytest 
[clx@VM-20-6-centos lesson_7_12]$ ll
total 24
-rw-rw-r-- 1 clx clx   62 Jul 12 12:31 main.c
-rwxrwxr-x 1 clx clx 8416 Jul 12 12:48 mytest
-rw-rw-r-- 1 clx clx   68 Jul 12 12:30 mytest.c
-rw-rw-r-- 1 clx clx   86 Jul 12 12:33 mytest.h
[clx@VM-20-6-centos lesson_7_12]$ clear
我们只需要将生成可执行程序所用到的源文件交给gcc编译器就可以了
使用gcc mytest.c main.c -o mytest 指令

但是在生成可执行程序的过程中我们并没有用到.h文件,这是因为.h文件在当前目录下。编译器会自动在当前目录或者文件调用的C库目录下寻找头文件。其找到头文件就可以自动加载进程序

在使用多个源文件的过程中,我们最好先将源文件编译生成可重定型的目标文件(.o文件)。因为在实际工程的链接过程中,同一个源文件需要被调用很多次,如果从源文件载入开始编译,相当于同一个源文件需要进行多次预处理,编译,汇编的过程,浪费时间。所以在工程中普遍先将源文件处理成(.o文件),加快生成可执行程序的速度,提高开发效率

这是比较标准的过程
[clx@VM-20-6-centos lesson_7_12]$ ll
total 12
-rw-rw-r-- 1 clx clx 62 Jul 12 12:31 main.c
-rw-rw-r-- 1 clx clx 69 Jul 12 12:59 mytest.c
-rw-rw-r-- 1 clx clx 86 Jul 12 12:33 mytest.h
[clx@VM-20-6-centos lesson_7_12]$ gcc -c mytest.c -o mytest.o
[clx@VM-20-6-centos lesson_7_12]$ gcc -c main.c -o main.o
[clx@VM-20-6-centos lesson_7_12]$ ll
total 20
-rw-rw-r-- 1 clx clx   62 Jul 12 12:31 main.c
-rw-rw-r-- 1 clx clx 1368 Jul 12 13:00 main.o
-rw-rw-r-- 1 clx clx   69 Jul 12 12:59 mytest.c
-rw-rw-r-- 1 clx clx   86 Jul 12 12:33 mytest.h
-rw-rw-r-- 1 clx clx 1496 Jul 12 13:00 mytest.o
[clx@VM-20-6-centos lesson_7_12]$ gcc mytest.o main.o -o mytest
[clx@VM-20-6-centos lesson_7_12]$ ll
total 32
-rw-rw-r-- 1 clx clx   62 Jul 12 12:31 main.c
-rw-rw-r-- 1 clx clx 1368 Jul 12 13:00 main.o
-rwxrwxr-x 1 clx clx 8416 Jul 12 13:01 mytest
-rw-rw-r-- 1 clx clx   69 Jul 12 12:59 mytest.c
-rw-rw-r-- 1 clx clx   86 Jul 12 12:33 mytest.h
-rw-rw-r-- 1 clx clx 1496 Jul 12 13:00 mytest.o
[clx@VM-20-6-centos lesson_7_12]$ ./mytest
Hello Makefile
[clx@VM-20-6-centos lesson_7_12]$ rm *.o mytest
[clx@VM-20-6-centos lesson_7_12]$ ll
total 12
-rw-rw-r-- 1 clx clx 62 Jul 12 12:31 main.c
-rw-rw-r-- 1 clx clx 69 Jul 12 12:59 mytest.c
-rw-rw-r-- 1 clx clx 86 Jul 12 12:33 mytest.h

我们可以发现想要多文件编辑会生成很多的(.o文件),假如以后文件数量变多,目录下的文件数目会十分惊人,不利于我们找到文件名进行删除或者编译文件。
Makefile文件可以帮助我们一键完成源文件的编译,链接,删除等过程

5.2使用Makefile处理多文件工程

注意:在Makefile中换行后输入依赖方法要使用Tab键打出空格,切勿直接空格!!!
首先我们介绍以下Makefile\make
Makefile 的本质是一个文件, 而make的本质是一条指令
接下来我将用Makefile来实现5.1最后的几个步骤

首先我们需要使用vim来编写Makefile
以下是Makefile内容展示,对于每条指令我会在后面一一讲解

[clx@VM-20-6-centos lesson_7_12]$ ll
total 16
-rw-rw-r-- 1 clx clx  62 Jul 12 12:31 main.c
-rw-rw-r-- 1 clx clx 197 Jul 12 13:07 Makefile
-rw-rw-r-- 1 clx clx  69 Jul 12 12:59 mytest.c
-rw-rw-r-- 1 clx clx  86 Jul 12 12:33 mytest.h
[clx@VM-20-6-centos lesson_7_12]$ cat Makefile
mytest:mytest.o main.o
		gcc mytest.o main.o -o mytest 
mytest.o:mytest.c
		gcc -c mytest.c -o mytest.o
main.o:main.c
		gcc -c main.c -o main.o

.PHONY:clean 
clean:
		rm -f mytest.o main.o mytest

mytest:mytest.o main.o
		gcc mytest.o main.o -o mytest 
mytest.o:mytest.c
		gcc -c mytest.c -o mytest.o
main.o:main.c
		gcc -c main.c -o main.o

.PHONY:clean 
clean:
		rm -f mytest.o main.o mytest
---------------------------------------------------------------------
在Makefile中存在者一种依赖关系,通过依赖关系我们可以使用依赖方法
目标文件:依赖文件列表
mytest:mytest.o main.o                         --依赖关系
		gcc mytest.o main.o -o mytest          --依赖方法
1.		
mytest:mytest.o main.o                         --依赖关系		
mytest是我们要生成的可执行程序,它是由mytest.o文件和 main.o 文件通过gcc 链接生成的
mytest: mytest.o main.o  可形象表现为 mytest <- (mytest.o + main.o) --说明依赖关系
2.
		gcc mytest.o main.o -o mytest          --依赖方法
注意在Makefile中换行后输入依赖方法要使用Tab键打出空格,切勿直接空格
我们通过执行依赖方法来生成mytest文件

3.相应的在
mytest.o:mytest.c  --依赖关系
		gcc -c mytest.c -o mytest.o  --依赖方法
我们可以将依赖关系中的:后面的文件看成原材料,经过依赖方法生成:前面的成品文件
4.
.PHONY:clean 
.PHONY 标记伪目标,前面带有.PHONY 的指令内容总是会被执行
4进行解释
[clx@VM-20-6-centos lesson_7_12]$ ll
total 16
-rw-rw-r-- 1 clx clx  62 Jul 12 12:31 main.c
-rw-rw-r-- 1 clx clx 197 Jul 12 13:07 Makefile
-rw-rw-r-- 1 clx clx  69 Jul 12 12:59 mytest.c
-rw-rw-r-- 1 clx clx  86 Jul 12 12:33 mytest.h
[clx@VM-20-6-centos lesson_7_12]$ make                --调用make
gcc -c mytest.c -o mytest.o
gcc -c main.c -o main.o
gcc mytest.o main.o -o mytest                          --调用成功
[clx@VM-20-6-centos lesson_7_12]$ ll
total 36
-rw-rw-r-- 1 clx clx   62 Jul 12 12:31 main.c
-rw-rw-r-- 1 clx clx 1368 Jul 12 13:22 main.o
-rw-rw-r-- 1 clx clx  197 Jul 12 13:07 Makefile
-rwxrwxr-x 1 clx clx 8416 Jul 12 13:22 mytest
-rw-rw-r-- 1 clx clx   69 Jul 12 12:59 mytest.c
-rw-rw-r-- 1 clx clx   86 Jul 12 12:33 mytest.h
-rw-rw-r-- 1 clx clx 1496 Jul 12 13:22 mytest.o
[clx@VM-20-6-centos lesson_7_12]$ make                  --调用make失败
make: `mytest' is up to date.
[clx@VM-20-6-centos lesson_7_12]$ make                  --调用make失败
make: `mytest' is up to date.
[clx@VM-20-6-centos lesson_7_12]$ make clean            --调用clean成功
rm -f mytest.o main.o mytest
[clx@VM-20-6-centos lesson_7_12]$ make clean            --调用clean成功
rm -f mytest.o main.o mytest

当我们调用make时,假如已经执行了Makefile的程序,并且源文件没有什么变化的话,系统不会执行我们的指令
但是我们调用make clean时,总是被执行,这就是.PHONY的作用。只要调用就会执行我们的指令

5.3Makefile中的快捷符号

还是相同的源文件和头文件,我们改动了Makefile文件,将gcc指令中的重定向删掉(-o指令)
我们发现程序依然可以正常运行。
Makefile会将通过依赖方法处理好的文件默认输出到前面的同名文件中
[clx@VM-20-6-centos lesson_7_12]$ ll
total 16
-rw-rw-r-- 1 clx clx  62 Jul 12 12:31 main.c
-rw-rw-r-- 1 clx clx 168 Jul 12 13:31 Makefile
-rw-rw-r-- 1 clx clx  69 Jul 12 12:59 mytest.c
-rw-rw-r-- 1 clx clx  86 Jul 12 12:33 mytest.h
[clx@VM-20-6-centos lesson_7_12]$ cat Makefile
mytest:mytest.o main.o
		gcc mytest.o main.o   
mytest.o:mytest.c
		gcc -c mytest.c 
main.o:main.c
		gcc -c main.c

.PHONY:clean 
clean:
		rm -f mytest.o main.o mytest
[clx@VM-20-6-centos lesson_7_12]$ make
gcc -c mytest.c 
gcc -c main.c
gcc mytest.o main.o   
[clx@VM-20-6-centos lesson_7_12]$ ll
total 36
-rwxrwxr-x 1 clx clx 8416 Jul 12 13:31 a.out
-rw-rw-r-- 1 clx clx   62 Jul 12 12:31 main.c
-rw-rw-r-- 1 clx clx 1368 Jul 12 13:31 main.o
-rw-rw-r-- 1 clx clx  168 Jul 12 13:31 Makefile
-rw-rw-r-- 1 clx clx   69 Jul 12 12:59 mytest.c
-rw-rw-r-- 1 clx clx   86 Jul 12 12:33 mytest.h
-rw-rw-r-- 1 clx clx 1496 Jul 12 13:31 mytest.o


结论Makefile会将通过依赖方法处理好的文件默认输出到前面的同名文件中

我们还可以使用$@ $^ $<来表示我们的文件
$@:依赖关系中的目标文件
$^:依赖关系中的依赖文件列表
$<:依赖关系中的一个一个依赖文件(比较难理解后面在作解释)

目标文件:依赖文件列表/依赖文件
mytest:mytest.o main.o                         --依赖关系
		gcc mytest.o main.o -o mytest          --依赖方法

Makefile在依赖关系行中,以冒号为分隔符,将前面的文件定义为目标文件($@),后面的文件(可能不止一个)定义为依赖文件列表($^)
在依赖方法中我们就可以使用这些特殊符号来代替文件名

上述指令等价于
mytest:mytest.o main.o                         --依赖关系
		gcc $^ -o $@                           --依赖方法

5.4使用Makefile完成进度条小程序

5.4.1 缓冲区概念

无缓冲:数据立马刷新
行缓冲:缓冲区中遇到\n时刷新数据
全缓冲:数据将缓冲区占满才刷新

显示器对应的刷新方式是:行刷新(\n),遇到\n后将缓冲区的数据打印在显示器上

5.4.2 换行的深刻理解

\n: 换行并且移至起始位置
\r: 移动至起始位置
回车(enter)等价于\n但是不仅仅是换行。回车=换行+移动至起始位置

[clx@VM-20-6-centos myproc.test]$ cat test.c
#include <stdio.h>


int main()
{

  printf("Hello Linux\r");
  printf("hello\n");
  return 0;
}
[clx@VM-20-6-centos myproc.test]$ ./a.out     --其中a.out 是test.c经过gcc编译后生成的可执行程序
hello Linux

hello Linux 首字母是小写,这说明hello 是来自于第二个printf
这说明
1.第一次printf在执行结束后并没有打印而是被存在缓冲区中。
2.\r回到行开头,程序输入hello 将第一行的 Hello进行了替换
3.当程序遇到\n字符,缓冲区的数据打印到显示器上

结论:我们可以运用显示器行显示的特性, 结合我们的\r选项对输出值进行覆盖,达到在同一块区域输出不同数据的目的

5.4.3 进度条的实现

成品展示

[####################################################################################################][100%][|]

1.编写Makefile

首先创建四个文件
-rw-rw-r-- 1 clx clx  60 Jul 14 18:47 main.c
-rw-rw-r-- 1 clx clx 131 Jul 14 18:31 Makefile
-rw-rw-r-- 1 clx clx 599 Jul 14 19:04 proc.c
-rw-rw-r-- 1 clx clx  98 Jul 14 18:52 proc.h

编写Makefile

myproc:main.o proc.o
		gcc -o $@ $^
main.o:main.c
		gcc -c $<
proc.o:proc.c
		gcc -c $<

.PHONY:clean
clean:
		rm -f ./*.o myproc 

2.实现进度条函数

//proc.c文件
#include "proc.h"

void ProcBar()
{
  int i = 0;
  char proc[102];                                --进度条的填充
  const char* lable = "|/-\\";                   --旋转小杠,代表程序正在运作
  memset(proc, '\0',sizeof(proc));               

  while (i < 101)
  {
    printf("[%-100s][%d%%][%c]\r", proc, i, lable[i%4]);    --打印进度条
    fflush(stdout);                               --将缓冲区的数据立刻打印到显示器上
    proc[i] = '#';
    usleep(100000);                               --休息0.1s
    i++;
  }
  printf("\n");

} 

//main.c文件
#include "proc.h"


int main()
{
  ProcBar();
  return 0;
}


//proc.h文件
#pragma once 

#include <stdio.h>
#include <string.h>
#include <unistd.h>

extern void ProcBar();

以上即是进度条的代码,比较简单就不多做解释了
我们还可以给我们进度条加上颜色,或者其他功能,美化我们的进度条。这里就先不展开讲了

6.Git实现代码仓库

首先我们必须先创建一个账号,以下展示使用的是gitee账号

6.1.首先登录我们的账号

点击新建仓库
在这里插入图片描述

6.2编写仓库信息

在这里插入图片描述

6.3克隆仓库

点击进入仓库,复制仓库地址(此处使用HTTPS协议,比较方便)
在这里插入图片描述
打开我们的云服务器

[clx@VM-20-6-centos lesson_7_14]$ cd ~            --跳转到工作目录
[clx@VM-20-6-centos ~]$ pwd
/home/clx
[clx@VM-20-6-centos ~]$ git clone https://gitee.com/xiaobais-attack/linux-c.git --仓库地址
Cloning into 'linux-c'...
Username for 'https://gitee.com': xiaobais-attack                        --输入你的用户名
Password for 'https://xiaobais-attack@gitee.com':                        --输入密码
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 5 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), done.   

> 若你在使用克隆命令时返回command not find 说明你还没由安装git
> 使用命令 sudo yum install -y git 进行安装
> 
[clx@VM-20-6-centos ~]$ ll
total 8
drwxrwxr-x 8 clx clx 4096 Jul 14 19:06 Lesson_Linux
drwxrwxr-x 3 clx clx 4096 Jul 14 19:57 linux-c                         --我们的git仓库

6.4上传代码

drwxrwxr-x 8 clx clx 4096 Jul 14 19:06 Lesson_Linux
drwxrwxr-x 3 clx clx 4096 Jul 14 20:09 linux-c
[clx@VM-20-6-centos ~]$ cp Lesson_Linux/* linux-c -rf       --拷贝代码到git本地仓库中
[clx@VM-20-6-centos ~]$ ll
total 8
drwxrwxr-x 8 clx clx 4096 Jul 14 19:06 Lesson_Linux
drwxrwxr-x 9 clx clx 4096 Jul 14 20:09 linux-c
[clx@VM-20-6-centos ~]$ ls -l linux-c
total 32
drwxrwxr-x 2 clx clx 4096 Jul 14 20:09 lesson_7_08
drwxrwxr-x 2 clx clx 4096 Jul 14 20:09 lesson_7_09
drwxrwxr-x 2 clx clx 4096 Jul 14 20:09 lesson_7_11
drwxrwxr-x 2 clx clx 4096 Jul 14 20:09 lesson_7_12
drwxrwxr-x 2 clx clx 4096 Jul 14 20:09 lesson_7_13
drwxrwxr-x 3 clx clx 4096 Jul 14 20:09 lesson_7_14
-rw-rw-r-- 1 clx clx  843 Jul 14 19:57 README.en.md
-rw-rw-r-- 1 clx clx  932 Jul 14 19:57 README.md

6.5git三部曲(上传三部曲)

[clx@VM-20-6-centos linux-c]$ ll
total 32
drwxrwxr-x 2 clx clx 4096 Jul 14 20:09 lesson_7_08
drwxrwxr-x 2 clx clx 4096 Jul 14 20:09 lesson_7_09
drwxrwxr-x 2 clx clx 4096 Jul 14 20:09 lesson_7_11
drwxrwxr-x 2 clx clx 4096 Jul 14 20:09 lesson_7_12
drwxrwxr-x 2 clx clx 4096 Jul 14 20:09 lesson_7_13
drwxrwxr-x 3 clx clx 4096 Jul 14 20:09 lesson_7_14
-rw-rw-r-- 1 clx clx  843 Jul 14 19:57 README.en.md
-rw-rw-r-- 1 clx clx  932 Jul 14 19:57 README.md
[clx@VM-20-6-centos linux-c]$ pwd                           --进入git仓库
/home/clx/linux-c
[clx@VM-20-6-centos linux-c]$ pwd
/home/clx/linux-c
[clx@VM-20-6-centos linux-c]$ git add .                     --第一步添加代码

第二步常见报错

假如你出现了以下报错,说明在仓库构建的过程中gitee并未将你的信息写入仓库

[clx@VM-20-6-centos linux-c]$ git commit -m '我的第一次提交'  --第二部提交,必须带上-m选项,后面‘’内是日志信息

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: empty ident name (for <clx@VM-20-6-centos.(none)>) not allowed


解决方案
[clx@VM-20-6-centos linux-c]$ ls -a                 --进入git仓库
.  ..  .git  .gitignore  lesson_7_08  lesson_7_09  lesson_7_11  lesson_7_12  lesson_7_13  lesson_7_14  README.en.md  README.md
[clx@VM-20-6-centos linux-c]$ cd .git               --找到.git目录,并且进入
[clx@VM-20-6-centos .git]$ ll
total 48
drwxrwxr-x  2 clx clx 4096 Jul 14 19:56 branches
-rw-rw-r--  1 clx clx   22 Jul 14 20:30 COMMIT_EDITMSG
-rw-rw-r--  1 clx clx  331 Jul 14 20:27 config          --注意这个文件
-rw-rw-r--  1 clx clx   73 Jul 14 19:56 description
-rw-rw-r--  1 clx clx   23 Jul 14 19:57 HEAD
drwxrwxr-x  2 clx clx 4096 Jul 14 19:56 hooks
-rw-rw-r--  1 clx clx 1784 Jul 14 20:13 index
drwxrwxr-x  2 clx clx 4096 Jul 14 19:56 info
drwxrwxr-x  3 clx clx 4096 Jul 14 19:57 logs
drwxrwxr-x 32 clx clx 4096 Jul 14 20:28 objects
-rw-rw-r--  1 clx clx  107 Jul 14 19:57 packed-refs
drwxrwxr-x  5 clx clx 4096 Jul 14 19:57 refs
[clx@VM-20-6-centos .git]$ vim config              --使用vim打开config文件

在结尾加上几行代码,如下
[user]
  name = (gitee的用户名)
  email = (gitee绑定的邮箱账号)

输入完毕后关闭即可返回git仓库主目录

解决完成报错后进行以下步骤

[clx@VM-20-6-centos linux-c]$ git commit -m '我的第一次提交'      --第二部曲,git提交 
[master ba14062] 我的第一次提交                                   --一定要带-m选项,并且后面添加日志信息
 17 files changed, 202 insertions(+)
 create mode 100644 lesson_7_09/test1.cpp
 create mode 100644 lesson_7_09/test2.cpp
 create mode 100755 lesson_7_11/test
 create mode 100644 lesson_7_11/test.c
 create mode 100755 lesson_7_11/test_g
 create mode 100644 lesson_7_12/Makefile
 create mode 100644 lesson_7_12/main.c
 create mode 100644 lesson_7_12/mytest.c
 create mode 100644 lesson_7_12/mytest.h
 create mode 100644 lesson_7_13/Makefile
 create mode 100644 lesson_7_13/main.c
 create mode 100644 lesson_7_13/proc.c
 create mode 100644 lesson_7_13/proc.h
 create mode 100644 lesson_7_14/myproc.test/Makefile
 create mode 100644 lesson_7_14/myproc.test/main.c
 create mode 100644 lesson_7_14/myproc.test/proc.c
 create mode 100644 lesson_7_14/myproc.test/proc.h              --提交成功
 [clx@VM-20-6-centos linux-c]$ git push                         --最后一步,推送
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Username for 'https://gitee.com': xiaobais-attack
Password for 'https://xiaobais-attack@gitee.com': 
Counting objects: 26, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (24/24), done.
Writing objects: 100% (25/25), 5.65 KiB | 0 bytes/s, done.
Total 25 (delta 2), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.3]
To https://gitee.com/xiaobais-attack/linux-c.git
   aa7be50..ba14062  master -> master                           --推送成功
   


在这里插入图片描述
这样我们就将我们云服务器上的代码上传到gitee仓库里了

[结语]

以上即是【Linux】2.0 Linux环境和基本开发工具的使用的全部内容,感谢各位观看,内容偏多,博主会下去好好练习争取以后给大家带来更详细的博客内容

上一篇:【Linux】1.0常见指令以及权限理解(下)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白在进击

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值