包管理器,yum工具,vim编辑器常见指令,解决sudo权限问题,Linux项目自动化构建工具-make/Makefile

软件包管理器

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.

  1. 撤销用u.

如果需要加行数:

ctrl+v批量化注释掉,行数n+jj(向下n行)/行数n+hh(向上n行)

然后shift+i,输入//,最后Esc,就可以批量注释掉n行

如果保存之后想要撤销注释行为:

可以ctrl+v,然后选择需要撤销注释的行数,ll两次区域选择,然后d,就可以撤销。

  1. 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<stdio.h>
  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, BuildIDsha1=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<stdio.h>

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<stdio.h>

void fun1()
{
  printf("hello fun1\n");
}
#pragma once

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

void fun2()
{
  printf("hello fun2\n");
}
#pragma once

void func2();
[keda@VM-0-4-centos lib]$ cat ../main.c
#include<stdio.h>

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<stdio.h>
#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<stdio.h>

#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文件。

  1. 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) $@ $^

$@依赖的是最终的目标文件,$^依赖的是众多文件列表
  1. 完善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)
相关推荐
剑神一笑2 小时前
Linux pgrep 命令详解:按名称查找进程 PID 的高效方法
linux·运维·chrome
剑神一笑3 小时前
Linux killall 命令详解:按进程名批量终止进程的原理与实践
linux·运维·chrome
日取其半万世不竭7 小时前
iftop、nethogs 和 nload:Linux 服务器网络流量实时监控工具介绍
linux·运维·服务器
mounter6257 小时前
Linux 内核资源管理:控制组(cgroup)的演进与“策略组”新提案
linux·运维·服务器·cgroup·kernel
bksczm7 小时前
文件在磁盘中的存储方式
linux·运维·服务器
L1624767 小时前
OpenSSH 半自动升级方案(独立编译 + 手动迁移 + 重建 systemd 服务)
linux·服务器·ssh
半旧夜夏7 小时前
【保姆级】微服务组件环境搭建(Docker Compose版)
java·linux·spring cloud·微服务·云原生·容器
爱莉希雅&&&8 小时前
zabbix快速搭建和使用
android·linux·数据库·zabbix·监控
z200509308 小时前
【linux学习】深入理解linux文件I/O,从C标准库到内核态
linux·学习·操作系统
weixin_307779139 小时前
面向高性能保密计算的定制 Linux 系统构建与自动部署方案
linux·安全·网络安全·性能优化·系统安全