软件包管理器
Linux中安装软件:推荐包管理器yum(centos) apt/apt-get(ubuntu)网络下载,安装就是拷贝,必须使用root权限
安装到系统里面,只要安装一次,任何人都可以使用。
包管理器会给我们解决包依赖的问题。
什么是包管理器?
类似于我们手机上的应用商店。
开发者写源码开发一个软件,然后上传到社区中,这个社区有很多软件。
开源:本质是一种商业模式
机器怎么知道下载链接:操作系统的内部,内置链接(比如:www.centos.org)。
软件的生态在国外,外网有更新软件,在外网和国内的社区之间有镜像,会同步。
yum
下载yum :sudo yum -y install sl
root@VM-0-4-opencloudos /\]# ping -c3 www.baidu.com
如果有回音就说明,电脑是联网的,
\[root@VM-0-4-opencloudos /\]# sudo yum list\|grep sl
\[root@VM-0-4-opencloudos /\]# sudo yum remove -y sl卸载
安装:sudo yum install lrzsz
卸载:sudo yum remove lrzsz
查看:yum list \| grep lrzsz
**windows和Linux互传:**
```go
[root@VM-0-4-opencloudos /]# sudo yum list|grep lrzsz
```
windows传给Linux:rz会出来一个弹窗穿什么就穿
**Linux传给windows** :sz (假如要传target文件:`sz target`)
```go
sudo yum -y install man-pages(安装man 文档)
```
/etc/yum.repos.d/(yum源的配置文件)
扩展软件源:
```go
[root@VM-0-4-opencloudos ~]# yum install -y epel-realse
```
**yum工具的常用选项有:**
1. `install` 表示安装软件包
2. `list` 列出所有可供安装的软件包
3. `search` 搜索包含指定关键字的软件包
4. `remove` 卸载指定的软件包
5. `yum makecache`命令的功能是将服务器的软件包信息缓存到本地
6. `yum clean all` 命令可以清除缓存中老旧的头文件和软件包
7. `yum -y upgrade`:只升级所有包,不升级软件和系统内核,软件和内核保持原样。
### vim是一款编辑器
#### 命令模式:快速编辑
1. `gg`:快速回到第一行
2. `shift+g=G`:快速回到结尾n+shift+g快速到第几行
3. `shift +$`:光标定位到结尾
4. `shift+^`:光标定位到开头
5. `h:左 j:下 k:上 l:右`
6. `w`:单词为单位,向后移动;
7. `b`:单词为单位,向前移动。
8. `yy`:复制当前行;
9. `p`:光标所在位置进行粘贴;`yy和p`也可以在前面家加n
10. `u`:撤销历史操作;
11. `ctrl+r`:撤销u操作(一旦退出文件编辑,就无法在进行撤销了,但是只是保存没有进行q退出,可以撤销)。
12. `dd`:剪切当前行(前面可以加n)
13. `x`:删除光标所在位置的字符
14. `shift+x`:光标右侧不动,左侧删除
15. `r:`替换光标所在字符,`r`-\>目标字符
16. `shift+r`:批量化替换
17. `shift+~`大小写切换
18. `ctrl+v(V-BLOCK)`
如果要批量化注释掉代码:先ctrl+v到V-BLOCK界面,可以hjkl标识需要批量化注释的行数,接着shift+i进入插入模式,写//,最后Esc.
19. 撤销用`u`.
如果需要加行数:
> ctrl+v批量化注释掉,行数n+jj(向下n行)/行数n+hh(向上n行)
>
> 然后shift+i,输入//,最后Esc,就可以批量注释掉n行
>
> 如果保存之后想要撤销注释行为:
>
> 可以ctrl+v,然后选择需要撤销注释的行数,ll两次区域选择,然后d,就可以撤销。
20. `shift+3=#`:选中单词
`n`:逆向查找
#### 底行:
`shift+zz`;或者`shift+;=: wq`(保存)
`set nu/nonu`(设置行号,没有取消行号)
:!ls -l
:%s/ src / dst /(替换)
vs src.c(vs+一个已经存在的文件)可以分屏
ctrl+ww:分屏移动光标
### 使用vim的技巧
vim src +n (**打开 `src` 文件(或目录),并直接跳转到文件的第 `n` 行** 。)
打开vim 还可以用 !v
## vim的配置
在vim . vimrc(设置vim配置)里面配置
set nu:设置行号
syntax on
set tabstop=4
set autoindent
set cindent
## Linux编辑器-gcc/g++使用
1. 预处理(进行宏替换):`gcc -E code.c -o code.i`(开始进程程序翻译,在预处理做完的时候就停下来)
2. 编译(生成汇编):`gcc -S code.i -o code.s`(开始编译了,编译做完了就停下来)
3. 汇编(生成机器可识别代码):`gcc -c code.s -o code.o`(可重定位目标文件,win vs2022,xxxx.obj)
开始编译了,汇编做完了就停下来,已经是二进制文件了。
4. 连接(生成可执行文件或者库文件):`gcc code.o -o code`
条件编译的用途:
#include
2
3 #define M
4
5 int main()
6 {
7 #ifndef M
8 printf("社区版 /免费版 version 1\n");
9 #else
10 printf("专业版 /收费版 version 2\n");
11 #endif
12 }
13
1.软件进行专业度,收费情况进行区分(业务),使用条件编译,可进行代码动态裁减;
2.内核源代码也是采用条件编译进行代码裁减
3.开发工具,应用软件
**为什么C/C++编译要先编译成汇编?**
库是什么?
库是一套方法或者数据库,为我们开发提供最基本的保证(基本的接口,功能,加速我们的二次开发)
动态库:Linux(.so)windows(.dll)
静态库:Linux(.a)windows(.lib)
libc.so(动态库):内部实现方法,我们自己的程序,会使用库中的办法将内部的实现方法链接起来,会形成一个可执行程序,当其在执行目标方法的时候,需要跳转到库中执行,完了再返回。
连接:就是让我们的程序,能找到库中的方法的地址;
也就是再地址上传输关联。
*动态库缺点*:共享库,被多个程序共享,一旦缺失,会导致所有程序无法执行。
libc.a(静态库):静态链接就是拷贝,将库中的实现方法拷贝一份给我们自己的程序,当我们的程序在执行的时候,就会调用拷贝之后的,对应拷贝的方法自己实现执行程序。
*静态链接*:把程序中使用的库方法,拷贝给我自己,但是只有再链接的时候有用,一旦形成可执行程序,静态库可以不再需要。
对比静态动态库:
1. 动态库形成的可执行程序体积一定很小;
2. 可执行程序对静态库的依赖度很小,动态库不能缺失;
3. 程序运行需要加载到内存,静态链接的,会在内存中出现重复的代码;
4. 动态链接比较节省资源
[keda@VM-0-4-centos lesson8]$ gcc code.c -o code
[keda@VM-0-4-centos lesson8]$ .a./out
bash: .a./out: No such file or directory
[keda@VM-0-4-centos lesson8]$ ls
a.out code code.c
[keda@VM-0-4-centos lesson8]$ ./a
bash: ./a: No such file or directory
[keda@VM-0-4-centos lesson8]$ ./code
专业版 /收费版 version 2
[keda@VM-0-4-centos lesson8]$ ldd code
linux-vdso.so.1 => (0x00007fff7eba3000)
libc.so.6 => /lib64/libc.so.6 (0x00007f5b7f2d9000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5b7f6a7000)
[keda@VM-0-4-centos lesson8]$ file code
code: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=dfa9cc7ee34189ecff1d2c90e62e2d099924aa20, not stripped
[keda@VM-0-4-centos lesson8]$ ll
total 28
-rwxrwxr-x 1 keda keda 8360 Nov 14 22:22 a.out
-rwxrwxr-x 1 keda keda 8360 Nov 15 09:53 code
-rw-rw-r-- 1 keda keda 161 Nov 15 09:52 code.c
[keda@VM-0-4-centos lesson8]$ ls /usr/lib64/libc.so* -1
/usr/lib64/libc.so
/usr/lib64/libc.so.6
*** ** * ** ***
静态链接:C静态库就得存在
[keda@VM-0-4-centos lesson8]$ gcc code.c -o code -static
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
发现没有找到,也就是说在系统中,默认安装的是动态库,体积比较小,如果想要安装静态库,就可以:
`sudo yum install -y glibc-static `
切换到root超级用户下安装静态库。然后切换回来,
```go
`[keda@VM-0-4-centos lesson8]$ ls /usr/lib64/libc*`
`/usr/lib64/libc-2.17.so /usr/lib64/libcmdif.a /usr/lib64/libcroco-0.6.so.3 /usr/lib64/libc.so`
`/usr/lib64/libc.a /usr/lib64/libc_nonshared.a /usr/lib64/libcroco-0.6.so.3.0.1 /usr/lib64/libc.so.6`
`/usr/lib64/libcairo-script-interpreter.so.2 /usr/lib64/libcom_err.so /usr/lib64/libcrypt-2.17.so /usr/lib64/libc_stubs.a`
`/usr/lib64/libcairo-script-interpreter.so.2.11512.0 /usr/lib64/libcom_err.so.2 /usr/lib64/libcrypt.a /usr/lib64/libcupscgi.so.1`
`/usr/lib64/libcairo.so.2 /usr/lib64/libcom_err.so.2.1 /usr/lib64/libcrypto.so /usr/lib64/libcupsimage.so.2`
`/usr/lib64/libcairo.so.2.11512.0 /usr/lib64/libconfig.so.9 /usr/lib64/libcrypto.so.10 /usr/lib64/libcupsmime.so.1`
`/usr/lib64/libcap-ng.so.0 /usr/lib64/libconfig++.so.9 /usr/lib64/libcrypto.so.1.0.2k /usr/lib64/libcupsppdc.so.1`
`/usr/lib64/libcap-ng.so.0.0.0 /usr/lib64/libconfig.so.9.1.3 /usr/lib64/libcryptsetup.so.12 /usr/lib64/libcups.so.2`
`/usr/lib64/libcap.so.2 /usr/lib64/libconfig++.so.9.1.3 /usr/lib64/libcryptsetup.so.12.3.0 /usr/lib64/libcurl.so.4`
`/usr/lib64/libcap.so.2.22 /usr/lib64/libcpupower.so.0 /usr/lib64/libcryptsetup.so.4 /usr/lib64/libcurl.so.4.3.0`
`/usr/lib64/libcidn-2.17.so /usr/lib64/libcpupower.so.0.0.0 /usr/lib64/libcryptsetup.so.4.7.0`
`/usr/lib64/libcidn.so /usr/lib64/libcrack.so.2 /usr/lib64/libcrypt.so`
`/usr/lib64/libcidn.so.1 /usr/lib64/libcrack.so.2.9.0 /usr/lib64/libcrypt.so.1`
`[keda@VM-0-4-centos lesson8]$ ls /usr/lib64/libc.a*`
`/usr/lib64/libc.a`
`[keda@VM-0-4-centos lesson8]$ ls /usr/lib64/libc.a -1`
```
```go
`/usr/lib64/libc.a`
`[keda@VM-0-4-centos lesson8]$`
```
然后查看是不是安装好了,上面是安装成功的。
然后我们编译一下:
```go
[keda@VM-0-4-centos lesson8]$ gcc code.c -o code-static -static
[keda@VM-0-4-centos lesson8]$ ll
total 860
-rwxrwxr-x 1 keda keda 8360 Nov 14 22:22 a.out
-rw-rw-r-- 1 keda keda 161 Nov 15 09:52 code.c
-rwxrwxr-x 1 keda keda 861288 Nov 15 10:24 code-static
```
\[keda@VM-0-4-centos lesson8\]$
\`
看-rwxrwxr-x 1 keda keda 861288 Nov 15 10:24 code-static,体积特别大的
`[keda@VM-0-4-centos lesson8]$ file code-static `code-static: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID\[sha1\]=d45cde1e3edb78dade8fc718c43fb3104cebf2ac, not stripped` `
静态链接
g++cpp的动态库
`[keda@VM-0-4-centos lesson8]$ vim code.cpp
[keda@VM-0-4-centos lesson8]$ g++ code.cpp -o codecpp
[keda@VM-0-4-centos lesson8]$ ll
total 876
-rwxrwxr-x 1 keda keda 8360 Nov 14 22:22 a.out
-rw-rw-r-- 1 keda keda 161 Nov 15 09:52 code.c
-rwxrwxr-x 1 keda keda 8968 Nov 15 10:29 codecpp
-rw-rw-r-- 1 keda keda 89 Nov 15 10:28 code.cpp
-rwxrwxr-x 1 keda keda 861288 Nov 15 10:24 code-static
[keda@VM-0-4-centos lesson8]$ ./codecpp
hello world!
[keda@VM-0-4-centos lesson8]$ ldd codecpp
linux-vdso.so.1 => (0x00007ffd5d3c3000)
libstdc++.so.6 => /home/keda/.VimForCpp/vim/bundle/YCM.so/el7.x86_64/libstdc++.so.6 (0x00007ffbccf82000)
libm.so.6 => /lib64/libm.so.6 (0x00007ffbccc80000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007ffbcca6a000)
libc.so.6 => /lib64/libc.so.6 (0x00007ffbcc69c000)
/lib64/ld-linux-x86-64.so.2 (0x00007ffbcd303000)
[keda@VM-0-4-centos lesson8]$ file codecpp
codecpp: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=87e7e442733b09b39549cec378af54de4c89eeb9, not stripped
`
安装C++的静态库链接:
[root@VM-0-4-centos lesson8]# sudo yum install libstdc++-static
最后安装好了执行一下g++的静态库
[keda@VM-0-4-centos lesson8]$ g++ code.cpp -o codecpp-static -static
[keda@VM-0-4-centos lesson8]$ ll
total 2448
-rwxrwxr-x 1 keda keda 8360 Nov 14 22:22 a.out
-rw-rw-r-- 1 keda keda 161 Nov 15 09:52 code.c
-rwxrwxr-x 1 keda keda 8968 Nov 15 10:29 codecpp
-rw-rw-r-- 1 keda keda 89 Nov 15 10:28 code.cpp
-rwxrwxr-x 1 keda keda 1608368 Nov 15 10:58 codecpp-static
-rwxrwxr-x 1 keda keda 861288 Nov 15 10:24 code-static
[keda@VM-0-4-centos lesson8]$ ldd codecpp-static
not a dynamic executable
[keda@VM-0-4-centos lesson8]$ file codecpp-static
codecpp-static: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=41a1d208a07e3ae16009327f96ef3cb56abd6555, not stripped
关于动态库:
源文件,动态静态库文件,可执行程序都在磁盘里面
一旦我们静态链接的时候形成了静态的程序,这个静态库就不需要了,所以这种静态链接的程序就直接建立在内存了,占的内存链接会大很多。
动态库的本质是:将所有程序中语言层面公共的代码在内存中保证只出现一份
### 解决sudo权限问题(keda is not in the sudoers file.This incident will be reported.):
[keda@VM-0-4-centos lesson8]$ vim /etc/sudoers
[keda@VM-0-4-centos lesson8]$ whoami
keda
[keda@VM-0-4-centos lesson8]$ su -
Password:
Last login: Sat Nov 15 10:54:43 CST 2025 on pts/0
[root@VM-0-4-centos ~]# whoami
root
[root@VM-0-4-centos ~]# vim /etc/sudoers
[root@VM-0-4-centos ~]# logout
[keda@VM-0-4-centos lesson8]$ whoami
keda
[keda@VM-0-4-centos lesson8]$ sudo ls
[sudo] password for keda:
a.out code.c codecpp code.cpp codecpp-static code-static
[keda@VM-0-4-centos lesson8]$
切换到root超级用户,执行`vim /etc/sudoers`,会出来蓝色文字,找到100行,`yy/root` `ALL=(ALL) ALL/p`复制到101行,然后将101行的root改成自己的名字(比如:keda)最后Esc,:wq!强制退出。回退到keda普通账户下:ctrl+d ,然后sudo ls ,输入密码,就可以看到了。
#### 技术上理解一下库:
[keda@VM-0-4-centos lesson8]$ ll
total 2448
-rwxrwxr-x 1 keda keda 8360 Nov 14 22:22 a.out
-rw-rw-r-- 1 keda keda 161 Nov 15 09:52 code.c
-rwxrwxr-x 1 keda keda 8968 Nov 15 10:29 codecpp
-rw-rw-r-- 1 keda keda 89 Nov 15 10:28 code.cpp
-rwxrwxr-x 1 keda keda 1608368 Nov 15 10:59 codecpp-static
-rwxrwxr-x 1 keda keda 861288 Nov 15 10:24 code-static
[keda@VM-0-4-centos lesson8]$ mkdir lib
[keda@VM-0-4-centos lesson8]$ ll
total 2452
-rwxrwxr-x 1 keda keda 8360 Nov 14 22:22 a.out
-rw-rw-r-- 1 keda keda 161 Nov 15 09:52 code.c
-rwxrwxr-x 1 keda keda 8968 Nov 15 10:29 codecpp
-rw-rw-r-- 1 keda keda 89 Nov 15 10:28 code.cpp
-rwxrwxr-x 1 keda keda 1608368 Nov 15 10:59 codecpp-static
-rwxrwxr-x 1 keda keda 861288 Nov 15 10:24 code-static
drwxrwxr-x 2 keda keda 4096 Nov 15 11:45 lib
[keda@VM-0-4-centos lesson8]$ cd lib/
[keda@VM-0-4-centos lib]$ ll
total 0
[keda@VM-0-4-centos lib]$ touch main.c
[keda@VM-0-4-centos lib]$ vim main.c
[keda@VM-0-4-centos lib]$ ll
total 4
-rw-rw-r-- 1 keda keda 66 Nov 15 11:48 main.c
[keda@VM-0-4-centos lib]$ mkdir lib
[keda@VM-0-4-centos lib]$ ll
total 8
drwxrwxr-x 2 keda keda 4096 Nov 15 11:48 lib
-rw-rw-r-- 1 keda keda 66 Nov 15 11:48 main.c
[keda@VM-0-4-centos lib]$ cd lib/
[keda@VM-0-4-centos lib]$ ll
total 0
[keda@VM-0-4-centos lib]$ touch code1.c
[keda@VM-0-4-centos lib]$ touch code2.c
[keda@VM-0-4-centos lib]$ touch code1.h
[keda@VM-0-4-centos lib]$ touch code2.h
[keda@VM-0-4-centos lib]$ ll
total 0
-rw-rw-r-- 1 keda keda 0 Nov 15 11:48 code1.c
-rw-rw-r-- 1 keda keda 0 Nov 15 11:51 code1.h
-rw-rw-r-- 1 keda keda 0 Nov 15 11:51 code2.c
-rw-rw-r-- 1 keda keda 0 Nov 15 11:51 code2.h
[keda@VM-0-4-centos lib]$ vim code1.h
[keda@VM-0-4-centos lib]$ cat code1.h
#pragma once
void func1();
[keda@VM-0-4-centos lib]$ cat code1.c
#include
void fun1()
{
printf("hello fun1\n");
}
[keda@VM-0-4-centos lib]$ cat code1.h>code2.h
[keda@VM-0-4-centos lib]$ cat code1.c>code2.c
[keda@VM-0-4-centos lib]$ ll
total 16
-rw-rw-r-- 1 keda keda 61 Nov 15 11:57 code1.c
-rw-rw-r-- 1 keda keda 28 Nov 15 11:57 code1.h
-rw-rw-r-- 1 keda keda 61 Nov 15 11:58 code2.c
-rw-rw-r-- 1 keda keda 28 Nov 15 11:58 code2.h
[keda@VM-0-4-centos lib]$ vim code2.h
[keda@VM-0-4-centos lib]$ vim code2.c
[keda@VM-0-4-centos lib]$ cat *
#include
void fun1()
{
printf("hello fun1\n");
}
#pragma once
void func1();
#include
void fun2()
{
printf("hello fun2\n");
}
#pragma once
void func2();
[keda@VM-0-4-centos lib]$ cat ../main.c
#include
int main()
{
fun1();
fun2();
return 0;
}
[keda@VM-0-4-centos lib]$ vim ../main.c
[keda@VM-0-4-centos lib]$ cd ..
[keda@VM-0-4-centos lib]$ ll
total 8
drwxrwxr-x 2 keda keda 4096 Nov 15 11:51 lib
-rw-rw-r-- 1 keda keda 102 Nov 15 12:04 main.c
[keda@VM-0-4-centos lib]$ cp lib/* .
[keda@VM-0-4-centos lib]$ ll
total 24
-rw-rw-r-- 1 keda keda 61 Nov 15 12:05 code1.c
-rw-rw-r-- 1 keda keda 28 Nov 15 12:05 code1.h
-rw-rw-r-- 1 keda keda 61 Nov 15 12:05 code2.c
-rw-rw-r-- 1 keda keda 28 Nov 15 12:05 code2.h
drwxrwxr-x 2 keda keda 4096 Nov 15 11:51 lib
-rw-rw-r-- 1 keda keda 102 Nov 15 12:04 main.c
[keda@VM-0-4-centos lib]$ gcc main.c code1.c code2.c -o code
[keda@VM-0-4-centos lib]$ ll
total 36
-rwxrwxr-x 1 keda keda 8480 Nov 15 12:05 code
-rw-rw-r-- 1 keda keda 61 Nov 15 12:05 code1.c
-rw-rw-r-- 1 keda keda 28 Nov 15 12:05 code1.h
-rw-rw-r-- 1 keda keda 61 Nov 15 12:05 code2.c
-rw-rw-r-- 1 keda keda 28 Nov 15 12:05 code2.h
drwxrwxr-x 2 keda keda 4096 Nov 15 11:51 lib
-rw-rw-r-- 1 keda keda 102 Nov 15 12:04 main.c
[keda@VM-0-4-centos lib]$ ./code
hello fun1
hello fun2
[keda@VM-0-4-centos lib]$ rm code
[keda@VM-0-4-centos lib]$ rm code*
[keda@VM-0-4-centos lib]$ ll
total 8
drwxrwxr-x 2 keda keda 4096 Nov 15 11:51 lib
-rw-rw-r-- 1 keda keda 102 Nov 15 12:04 main.c
[keda@VM-0-4-centos lib]$
###### 场景设置:如果这个文件是共享的,你不想把自己写的后缀为.c的文件给其他人看,就可以形成.o后缀的。做法如下:
[keda@VM-0-4-centos lib]$ ll
total 8
drwxrwxr-x 2 keda keda 4096 Nov 15 11:51 lib
-rw-rw-r-- 1 keda keda 102 Nov 15 12:04 main.c
[keda@VM-0-4-centos lib]$ cat main.c
#include
#include"code1.h"
#include"code2.h"
int main()
{
fun1();
fun2();
return 0;
}
[keda@VM-0-4-centos lib]$ cd lib/
[keda@VM-0-4-centos lib]$ ll
total 16
-rw-rw-r-- 1 keda keda 61 Nov 15 11:57 code1.c
-rw-rw-r-- 1 keda keda 28 Nov 15 11:57 code1.h
-rw-rw-r-- 1 keda keda 61 Nov 15 12:00 code2.c
-rw-rw-r-- 1 keda keda 28 Nov 15 11:59 code2.h
[keda@VM-0-4-centos lib]$ gcc -c code1.c
[keda@VM-0-4-centos lib]$ gcc -c code2.c
[keda@VM-0-4-centos lib]$ ll
total 24
-rw-rw-r-- 1 keda keda 61 Nov 15 11:57 code1.c
-rw-rw-r-- 1 keda keda 28 Nov 15 11:57 code1.h
-rw-rw-r-- 1 keda keda 1496 Nov 15 12:12 code1.o
-rw-rw-r-- 1 keda keda 61 Nov 15 12:00 code2.c
-rw-rw-r-- 1 keda keda 28 Nov 15 11:59 code2.h
-rw-rw-r-- 1 keda keda 1496 Nov 15 12:12 code2.o
[keda@VM-0-4-centos lib]$ cd ..
[keda@VM-0-4-centos lib]$ ls
lib main.c
[keda@VM-0-4-centos lib]$ ll
total 8
drwxrwxr-x 2 keda keda 4096 Nov 15 12:12 lib
-rw-rw-r-- 1 keda keda 102 Nov 15 12:04 main.c
[keda@VM-0-4-centos lib]$ cp lib/*.h .
[keda@VM-0-4-centos lib]$ ll
total 16
-rw-rw-r-- 1 keda keda 28 Nov 15 12:13 code1.h
-rw-rw-r-- 1 keda keda 28 Nov 15 12:13 code2.h
drwxrwxr-x 2 keda keda 4096 Nov 15 12:12 lib
-rw-rw-r-- 1 keda keda 102 Nov 15 12:04 main.c
[keda@VM-0-4-centos lib]$ cp lib/.o .
cp: cannot stat 'lib/.o': No such file or directory
[keda@VM-0-4-centos lib]$ cp lib/*.o .
[keda@VM-0-4-centos lib]$ ll
total 24
-rw-rw-r-- 1 keda keda 28 Nov 15 12:13 code1.h
-rw-rw-r-- 1 keda keda 1496 Nov 15 12:15 code1.o
-rw-rw-r-- 1 keda keda 28 Nov 15 12:13 code2.h
-rw-rw-r-- 1 keda keda 1496 Nov 15 12:15 code2.o
drwxrwxr-x 2 keda keda 4096 Nov 15 12:12 lib
-rw-rw-r-- 1 keda keda 102 Nov 15 12:04 main.c
[keda@VM-0-4-centos lib]$ gcc -c main.c
[keda@VM-0-4-centos lib]$ ll
total 28
-rw-rw-r-- 1 keda keda 28 Nov 15 12:13 code1.h
-rw-rw-r-- 1 keda keda 1496 Nov 15 12:15 code1.o
-rw-rw-r-- 1 keda keda 28 Nov 15 12:13 code2.h
-rw-rw-r-- 1 keda keda 1496 Nov 15 12:15 code2.o
drwxrwxr-x 2 keda keda 4096 Nov 15 12:12 lib
-rw-rw-r-- 1 keda keda 102 Nov 15 12:04 main.c
-rw-rw-r-- 1 keda keda 1424 Nov 15 12:15 main.o
[keda@VM-0-4-centos lib]$ gcc main.o code1.o code2.o -o code
[keda@VM-0-4-centos lib]$ ll
total 40
-rwxrwxr-x 1 keda keda 8480 Nov 15 12:16 code
-rw-rw-r-- 1 keda keda 28 Nov 15 12:13 code1.h
-rw-rw-r-- 1 keda keda 1496 Nov 15 12:15 code1.o
-rw-rw-r-- 1 keda keda 28 Nov 15 12:13 code2.h
-rw-rw-r-- 1 keda keda 1496 Nov 15 12:15 code2.o
drwxrwxr-x 2 keda keda 4096 Nov 15 12:12 lib
-rw-rw-r-- 1 keda keda 102 Nov 15 12:04 main.c
-rw-rw-r-- 1 keda keda 1424 Nov 15 12:15 main.o
[keda@VM-0-4-centos lib]$ ./code
hello fun1
hello fun2
## Linux项目自动化构建工具-make/Makefile
make/makefile
1. 是什么?
make是一个命令,makefile是一个文件
###### 怎么用
[keda@VM-0-4-centos lesson8]$ mkdir mk
[keda@VM-0-4-centos lesson8]$ ll
total 2456
-rwxrwxr-x 1 keda keda 8360 Nov 14 22:22 a.out
-rw-rw-r-- 1 keda keda 161 Nov 15 09:52 code.c
-rwxrwxr-x 1 keda keda 8968 Nov 15 10:29 codecpp
-rw-rw-r-- 1 keda keda 89 Nov 15 10:28 code.cpp
-rwxrwxr-x 1 keda keda 1608368 Nov 15 10:59 codecpp-static
-rwxrwxr-x 1 keda keda 861288 Nov 15 10:24 code-static
drwxrwxr-x 3 keda keda 4096 Nov 15 12:16 lib
drwxrwxr-x 2 keda keda 4096 Nov 15 12:27 mk
[keda@VM-0-4-centos lesson8]$ cd mk/
[keda@VM-0-4-centos mk]$ cp ../code.c .
[keda@VM-0-4-centos mk]$ ll
total 4
-rw-rw-r-- 1 keda keda 161 Nov 15 12:27 code.c
[keda@VM-0-4-centos mk]$ cat code.c
#include
#define M
int main()
{
#ifndef M
printf("社区版 /免费版 version 1\n");
#else
printf("专业版 /收费版 version 2\n");
#endif
}
[keda@VM-0-4-centos mk]$ touch makefile
[keda@VM-0-4-centos mk]$ vim makefile
[keda@VM-0-4-centos mk]$ cat makefile
code:code.c
gcc -o code code.c
[keda@VM-0-4-centos mk]$ make
gcc -o code code.c
[keda@VM-0-4-centos mk]$ ll
total 20
-rwxrwxr-x 1 keda keda 8360 Nov 15 12:31 code
-rw-rw-r-- 1 keda keda 161 Nov 15 12:27 code.c
-rw-rw-r-- 1 keda keda 33 Nov 15 12:30 makefile
[keda@VM-0-4-centos mk]$ ./code
专业版 /收费版 version 2
makefile文件中要写gcc的编译过程,随后直接写make就会调出来`gcc -o code code.c`,再ll就会自动生成code文件。
2. makefile的基本概念--依赖关系,依赖方法
code:code.c(依赖关系)
gcc -o code code.c(tab键开头,写依赖方法)
[keda@VM-0-4-centos lesson9]$ touch myproc.c
[keda@VM-0-4-centos lesson9]$ ll
total 0
-rw-rw-r-- 1 keda keda 0 Nov 15 14:24 myproc.c
[keda@VM-0-4-centos lesson9]$ vim myproc.c
[keda@VM-0-4-centos lesson9]$ ll
total 4
-rw-rw-r-- 1 keda keda 85 Nov 15 14:25 myproc.c
[keda@VM-0-4-centos lesson9]$ touch Makefile
[keda@VM-0-4-centos lesson9]$ vim Makefile
[keda@VM-0-4-centos lesson9]$ cat Makefile
myproc:myproc.c
gcc -o myproc myproc.c
[keda@VM-0-4-centos lesson9]$ make
gcc -o myproc myproc.c
[keda@VM-0-4-centos lesson9]$ ll
total 20
-rw-rw-r-- 1 keda keda 41 Nov 15 14:27 Makefile
-rwxrwxr-x 1 keda keda 8360 Nov 15 14:27 myproc
-rw-rw-r-- 1 keda keda 85 Nov 15 14:25 myproc.c
[keda@VM-0-4-centos lesson9]$ vim Makefile
[keda@VM-0-4-centos lesson9]$ make clean
rm -f myproc
[keda@VM-0-4-centos lesson9]$ ll
total 8
-rw-rw-r-- 1 keda keda 76 Nov 15 14:31 Makefile
-rw-rw-r-- 1 keda keda 85 Nov 15 14:25 myproc.c
[keda@VM-0-4-centos lesson9]$ make
gcc -o myproc myproc.c
[keda@VM-0-4-centos lesson9]$ ./p
bash: ./p: No such file or directory
[keda@VM-0-4-centos lesson9]$ cat Makefile
myproc:myproc.c
gcc -o myproc myproc.c
.PHONY:clean
clean:
rm -f myproc
*
### 清理Makefile文件和创建Makefile文件
*
make命令扫描makefile文件的时候是从上往下扫描,默认形成第一个目标文件
```go
myproc:myproc.c
gcc -o myproc myproc.c
.PHONY:clean(//伪目标:总是被执行,对应的依赖关系和依赖方法)
clean:
rm -f myproc
```
**什么叫做不被执行?**
1. 默认老代码不做重新编译
2. make怎么知道bin和.c的新旧问题?(看Modify时间)
[keda@VM-0-4-centos lesson9]$ stat myproc.c
File: 'myproc.c'
Size: 124 Blocks: 8 IO Block: 4096 regular file
Device: fd01h/64769d Inode: 790828 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1001/ keda) Gid: ( 1001/ keda)
Access: 2025-11-15 14:49:45.245879542 +0800
Modify: 2025-11-15 14:49:45.243879480 +0800
Change: 2025-11-15 14:49:45.243879480 +0800
Birth: -
[keda@VM-0-4-centos lesson9]$ chmod u+x myproc.c
[keda@VM-0-4-centos lesson9]$ ll
total 24
drwxrwxr-x 2 keda keda 4096 Nov 15 14:47 code.cif
-rw-rw-r-- 1 keda keda 76 Nov 15 14:31 Makefile
-rwxrwxr-x 1 keda keda 8360 Nov 15 14:31 myproc
-rwxrw-r-- 1 keda keda 124 Nov 15 14:49 myproc.c
[keda@VM-0-4-centos lesson9]$ stat myproc.c
File: 'myproc.c'
Size: 124 Blocks: 8 IO Block: 4096 regular file
Device: fd01h/64769d Inode: 790828 Links: 1
Access: (0764/-rwxrw-r--) Uid: ( 1001/ keda) Gid: ( 1001/ keda)
Access: 2025-11-15 14:49:45.245879542 +0800
Modify: 2025-11-15 14:49:45.243879480 +0800
Change: 2025-11-15 14:51:46.138606905 +0800
Birth: -
[keda@VM-0-4-centos lesson9]$
所以每个文件都有对应的`Access,Modify,Change`属性,有时间
**那么如果在不重复多次加`.PHONY`的条件下,该怎么多次make命令?**
**touch可以更改文件的时间,变成最新的就又可以make了**
[keda@VM-0-4-centos lesson9]$ stat myproc.c
File: 'myproc.c'
Size: 124 Blocks: 8 IO Block: 4096 regular file
Device: fd01h/64769d Inode: 790828 Links: 1
Access: (0764/-rwxrw-r--) Uid: ( 1001/ keda) Gid: ( 1001/ keda)
Access: 2025-11-15 14:49:45.245879542 +0800
Modify: 2025-11-15 14:49:45.243879480 +0800
Change: 2025-11-15 14:51:46.138606905 +0800
Birth: -
[keda@VM-0-4-centos lesson9]$ touch myproc.c
[keda@VM-0-4-centos lesson9]$ make
gcc -o myproc myproc.c
[keda@VM-0-4-centos lesson9]$ make
make: `myproc' is up to date.
[keda@VM-0-4-centos lesson9]$ stat myproc.c
File: 'myproc.c'
Size: 124 Blocks: 8 IO Block: 4096 regular file
Device: fd01h/64769d Inode: 790828 Links: 1
Access: (0764/-rwxrw-r--) Uid: ( 1001/ keda) Gid: ( 1001/ keda)
Access: 2025-11-15 15:03:31.365351457 +0800
Modify: 2025-11-15 15:03:31.003340294 +0800
Change: 2025-11-15 15:03:31.003340294 +0800
Birth: -
写一个基于变量版本的Makefile
[keda@VM-0-4-centos lesson9]$ vim Makefile
[keda@VM-0-4-centos lesson9]$ cat Makefile
BIN=myproc
CC=gcc
SRC=myproc.c
FLAGS=-o
RM=rm -f
$(BIN):$(SRC)
$(CC) $(FLAGS) $(BIN) $(SRC)
.PHONY:
clean:
$(RM) $(BIN)
.PHONY:test
test:
@echo $(BIN)
@echo $(CC)
@echo $(SRC)
@echo $(FLAGS)
@echo $(RM)
*** ** * ** ***
[keda@VM-0-4-centos lesson9]$ make clean
rm -f myproc
[keda@VM-0-4-centos lesson9]$ ll
total 40
drwxrwxr-x 2 keda keda 4096 Nov 15 14:47 code.cif
-rw-rw-r-- 1 keda keda 548 Nov 15 16:11 Makefile
-rwxrw-r-- 1 keda keda 124 Nov 15 15:03 myproc.c
-rw-rw-r-- 1 keda keda 16929 Nov 15 15:22 myproc.i
-rw-rw-r-- 1 keda keda 1568 Nov 15 15:22 myproc.o
-rw-rw-r-- 1 keda keda 490 Nov 15 15:22 myproc.s
[keda@VM-0-4-centos lesson9]$ make
gcc -o myproc myproc.c
[keda@VM-0-4-centos lesson9]$ ll
total 52
drwxrwxr-x 2 keda keda 4096 Nov 15 14:47 code.cif
-rw-rw-r-- 1 keda keda 548 Nov 15 16:11 Makefile
-rwxrwxr-x 1 keda keda 8360 Nov 15 16:12 myproc
-rwxrw-r-- 1 keda keda 124 Nov 15 15:03 myproc.c
-rw-rw-r-- 1 keda keda 16929 Nov 15 15:22 myproc.i
-rw-rw-r-- 1 keda keda 1568 Nov 15 15:22 myproc.o
-rw-rw-r-- 1 keda keda 490 Nov 15 15:22 myproc.s
[keda@VM-0-4-centos lesson9]$ make clean
rm -f myproc
可见生成了一个myproc,也即是说变量版的Makefile可以生成一个myproc文件。
$(BIN):$(SRC)
8 $(CC) $(FLAGS) $@ $^
$@依赖的是最终的目标文件,$^依赖的是众多文件列表
3. 完善makefile
Makefile的第二个文件
BIN=myproc
2 CC=gcc
3 SRC=myproc.c
4 FLAGS=-o
5 RM=rm -f
6
7 $(BIN):$(SRC)
8 @$(CC) $(FLAGS) $@ $^
9 @echo "linking ... $^ to $@"
10 .PHONY:
11 clean:
12 @$(RM) $(BIN)
13 @echo "remove ... $(BIN)"
14
15 .PHONY:test
16 test:
17 @echo $(BIN)
18 @echo $(CC)
19 @echo $(SRC)
20 @echo $(FLAGS)
21 @echo $(RM)
如果有多个文件:
version1:
[keda@VM-0-4-centos lesson9]$ cat Makefile
BIN=myproc.exe
CC=gcc
SRC=myproc.c
OBJ=myproc.o
FLAGS=-o
FLAGS=-c
RM=rm -f
$(BIN):$(OBJ)
$(CC) $(LFLAGS) $@ $^
%.o:%.c//把当前路径下的所有.o /.c都展开
$(CC) $(FLAGS) $<
version2:
BIN=proc.exe
2 CC=gcc
3 SRC=$(shell ls *.c)//显示当前目录下的所有.c文件名
4 OBJ=$(SRC:.c=.o)//SRC内部的文件名.c替换成同名的.o名字
5 LFLAGS=-o
6 FLAGS=-c
7 RM=rm -f
8
9 $(BIN):$(OBJ)
10 @$(CC) $(LFLAGS) $@ $^
11 @echo "linking ... $^ to $@"
12 %.o:%.c
13 @$(CC) $(FLAGS) $<
14 @echo "compling ... $^ to $@"
15 .PHONY:clean
16 clean:
17 $(RM) $(OBJ) $(BIN)
18
19 .PHONY:test
20 test:
21 @echo $(SRC)
22 @echo $(OBJ)
23
SRC=$(wildcard *.c)
2 OBJ=$(SRC:.c=.o)
3 BIN=processbar
4
5 $(BIN):$(OBJ)
6 gcc -o $@ $^
7 %.o:%.c
8 gcc -c $< -g
9
10 .PHONY:
11 clean:
12 rm -f $(OBJ) $(BIN)