news 2026/7/7 23:14:12

Linux常见工具使用方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux常见工具使用方法



🎬 个人主页:Vect个人主页

🎬 GitHub:Vect的代码仓库

🔥 个人专栏: 《数据结构与算法》《C++学习之旅》《Linux》
⛺️Per aspera ad astra.


文章目录

  • Makefile
    • 0. 简单代码演示
    • 1. Makefile结构及规则
      • 变量定义部分
      • 默认目标部分
      • 编译目标部分
      • 清理目标部分
    • 2. 过程推导
      • 目标文件`.o`和依赖关系
      • 规则推导过程
      • 时间戳
      • 伪目标
  • gdb和cgdb

Makefile

0. 简单代码演示

// add.h#pragmaonceintadd(inta,intb);
// add.cpp#include"add.h"intadd(inta,intb){returna+b;}
// main.cpp#include<iostream>#include"add.h"intmain(){std::cout<<add(1,2)<<std::endl;return0;}

1. Makefile结构及规则

这里先提前有个认知:

  • Makefile是文件
  • make是指令

先来看代码,然后解读:

# 变量定义部分SRC=main.cpp add.cpp OBJ=$(SRC:.cpp=.o)BIN=myapp# 默认目标$(BIN):$(OBJ)g++ -o$@$^# 编译目标%.o: %.cpp g++ -c $<-o$@# 清理目标.PHONY: clean clean:rm-f$(OBJ)$(BIN)

变量定义部分

SRC = main.cpp add.cpp

  • 作用:定义源文件变量,包含所有.cpp的源文件
  • 解释:SRC是一个包含需要编译的源文件的列表

OBJ = $(SRC:.cpp=.o)

  • 作用:通过模式替换,将SRC中的.cpp全部转换成.o文件
  • 解释:$(VAR)用来引用一个变量的值,$(SRC:.cpp=.o)利用替换模式得到OBJ = main.o add.o

BIN = myapp

  • 作用:定义最终生成的目标文件名(最后的可执行文件)

默认目标部分

$(BIN):$(OBJ)

  • 作用:表示目标$(BIN)依赖于$(OBJ)中的main.o add.o

g++ -o $@ $^

  • 作用:使用g++.o文件链接成最终可执行文件myapp
  • 解释:
    • $@:代表当前规则中的目标文件,这里是$(BIN)
    • $^:代表所有的依赖文件(去除重复的),这里是$(OBJ)

编译目标部分

%.o: %.cpp

  • 作用:表示一条通用规则,告诉make如何将.cpp文件编译成.o文件
  • 解释:%是通配符,代表一个任意的字符序列,这里表示会匹配所有的.cpp文件,将它们全部编译为对应的.o文件

g++ -c &< -o $@

  • 作用:使用g++.cpp文件编译成.o文件
  • 解释:
    • $<:代表当前规则中的第一个依赖文件,在这里就是.cpp文件
    • $@:表示当前规则中的目标文件,在这里是.o文件

清理目标部分

.PHONY: clean

  • 作用:声明clean是一个伪目标,而不是文件名
  • 解释:make会认为clean是一个任务,而不是文件,因此即使当前目录下存在名为clean的文件,make也会执行clean规则的命令

clean: rm -f $(OBJ) $(BIN)

  • 作用:clean目标的命令部分,删除所有生成的目标文件和最终的可执行文件。

2. 过程推导

目标文件.o和依赖关系

  • main.o依赖于main.cpp
  • add.o依赖于add.cpp

在Makefile中,$OBJ是要生成的目标文件,它的生成依赖于.cpp文件

规则推导过程

make会从默认目标myapp开始,通过依赖关系逐步推导出需要做的工作

  1. make看到myapp

    myapp的形成依赖于main.oadd.omake会从main.oadd.o开始推导

  2. 生成main.o

    main.o的生成又依赖于main.cpp,所以make会执行:g++ -c main.cpp -o main.o

  3. 生成add.o

    同理add.o的生成依赖于add.cpp,所以make会执行:g++ -c add.cpp -o add.o

  4. 链接成myapp

    当生成了main.oadd.omake会执行:g++ -o mayapp main.o add.o

推导是一个出栈入栈的过程

  • 出栈:make开始时看到myapp,出栈myapp,处理它的依赖main.oadd.o
  • **入栈:**当main.oadd.o处理完后,它们的目标文件会入栈,然后make执行生成myapp的命令

我们梳理清楚依赖链:

目标直接依赖构建规则
myappmain.oadd.og++ -o myapp main.o add.o
main.omain.cppg++ -c main.cpp -o main.o
add.oadd.cppg++ -c add.cpp -o add.o
clean伪目标rm -f main.o add.o myapp

时间戳

make在做依赖关系推导的时候,会用时间戳来决定哪些目标需要重新构建

时间戳的作用

make会比较每个目标文件和它的依赖文件的时间戳

  • 如果依赖文件比目标文件新,make会重新构建目标文件
  • 如果目标文件存在且没有被更新,make会跳过编译过程
[vect@VM-0-11-centos make_file]$statmain.cpp File: ‘main.cpp’ Size:102Blocks:8IO Block:4096regularfileDevice: fd01h/64769d Inode:1051720Links:1Access:(0664/-rw-rw-r--)Uid:(1002/ vect)Gid:(1002/ vect)Access:2025-12-1420:12:03.883557588 +0800 Modify:2025-12-1420:12:01.955499062 +0800 Change:2025-12-1420:12:01.955499062 +0800 Birth: -

看一下三种时间:

  • Acesstime:访问时间,文件内容被读取/访问的时间
  • Modifytime:修改时间,文件时间内容被修改的时间(文件大小、内容变化)
  • Changetime:状态改变时间,文件**元数据(属性)**改变的时间(文件属性)

过程演示:

  1. 第一次运行make

    make的行为:

    [vect@VM-0-11-centos make_file]$makeg++ -c main.cpp -o main.o g++ -c add.cpp -o add.o g++ -o myapp main.o add.o

    此时目标文件和可执行文件都生成了,时间戳被记录

  2. 修改源文件并运行make

    假设修改了add.cpp文件中的代码,例如:

    intadd(inta,intb){returna*b;// 修改了加法为乘法}

    现在,make会根据文件时间戳决定是否重新编译:

    • main.o时间戳未变化,main.cpp不重新编译
    • add.o文件的时间戳比add.cpp新,make会发现add.o的依赖文件add.cpp发生变化

    运行指令得到:

    [vect@VM-0-11-centos make_file]$makeg++ -c add.cpp -o add.o g++ -o myapp main.o add.o
  3. 不做任何修改,直接运行make

    [vect@VM-0-11-centos make_file]$makemake: `myapp' is up to date.

总结:

  1. 目标文件不存在:如果目标文件(.o)或依赖文件(.cpp)不存在,make会强制编译并生成目标文件。

  2. 依赖文件更新:如果依赖文件的时间戳比目标文件更新,make会重新编译依赖文件并更新目标文件。

  3. 无更新时跳过编译:如果目标文件和依赖文件的时间戳都没有变化,make会跳过编译过程,避免重复工作。

伪目标

伪目标:没有对应文件的目标文件,用来执行命令而不关心文件的存在

伪目标不会检查时间戳,每次执行都会运行相关指令

.PHONY: clean clean:rm-f$(OBJ)$(BIN)

.PHONY告诉makeclean是伪目标,即使当前目录下有一个clean文件,make也不会认为它是一个文件,而是会执行rm命令

gdb和cgdb

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/2 1:54:56

服务器文件管理太麻烦?宝塔 FTP+cpolar 让远程操作像本地一样简单

文章目录前言1. Linux安装Cpolar2. 创建FTP公网地址3. 宝塔FTP服务设置4. FTP服务远程连接小结5. 固定FTP公网地址6. 固定FTP地址连接**宝塔 FTP 让服务器文件管理变得简单&#xff0c;而 cpolar 则打破了局域网的限制&#xff0c;两者结合为远程文件操作提供了安全、高效的解决…

作者头像 李华
网站建设 2026/7/6 3:18:29

Web3.js钱包与账户管理

简介 Web3.js Wallet是我们在想要直接使用私钥进行任何区块链操作&#xff08;交易&#xff09;时的主要入口点&#xff0c;在其它库中也被称为Signer。 与其它只能保存一个账户的库不同&#xff0c;Web3.js Wallet可以保存多个账户&#xff0c;每个账户都有它自己的私钥和地…

作者头像 李华
网站建设 2026/7/7 9:17:13

Java 虚拟机(JVM)内存模型与垃圾回收机制研究

Java 虚拟机&#xff08;JVM&#xff09;是Java跨平台特性的核心&#xff0c;其内存模型与垃圾回收&#xff08;GC&#xff09;机制是Java领域的重要学术研究课题&#xff0c;直接决定了Java程序的运行效率与稳定性。JVM 内存模型将运行时数据区分为方法区、堆、虚拟机栈、本地…

作者头像 李华
网站建设 2026/7/3 9:12:27

Java 面向对象设计模式的应用与设计原则

设计模式是Java面向对象编程的高级应用形式&#xff0c;是对软件开发中常见问题的标准化解决方案&#xff0c;也是Java学术研究与工程实践的重要结合点。GoF&#xff08;四人组&#xff09;提出的23种设计模式&#xff0c;基于封装、继承、多态的核心特性&#xff0c;将代码设计…

作者头像 李华
网站建设 2026/7/4 16:09:35

AC15启动项分析,漏洞分析

1、固件模拟sudo chroot . sh /bin/httpd第一个问题&#xff0c;监听ip有问题我们需要配置网卡sudo brctl addbr br0sudo ifconfig br0 192.168.100.3这里我们设置br0网卡&#xff0c;启动web成功启动&#xff0c;这里监听的就是我们设置的ip这里我们可以运行这个脚本&#xff…

作者头像 李华
网站建设 2026/7/7 19:27:52

二、python语法基础

一、前言与概述前面了解了python安装以及环境的准备&#xff0c;下面是关于python语法基础的一个概要&#xff1a;二、语法内容&#xff08;一&#xff09;、基础语法开始之前&#xff1a;注释代码# 单行注释 """ 多行注释 """多行注释 1、变量与…

作者头像 李华