【gcc/g++/gdb/cmake】命令

news2024/9/25 5:23:36

文章目录

  • 参考资料
  • 一、gcc/g++/make
    • 1 gcc和g++的区别
    • 2 gcc/g++与make区别
    • 3 make与cmake区别
  • 二、开发环境搭建
    • 1 编译器,调试器,CMake安装
    • 2 GCC编译器
      • 2.1 编译过程
        • 2.1.1 `-E` 预处理-Pre-Processing `.i文件`
        • 2.1.2 `-S` 编译-Compiling `.s文件`
        • 2.1.3 `-C` 汇编-Assembling `.o文件`
        • 2.1.4 链接(包括库文件)-Linking `bin文件`
      • 2.2 g++重要编译参数
        • 2.2.1 `-g` 编译带调试信息的可执行文件
        • 2.2.2 `-O[n]` 优化源代码
        • 2.2.3 `-l` 和 `-L` 指定库文件 | 指定库文件路径
        • 2.2.4 `-I` 指定头文件搜索目录
        • 2.2.5 `-Wall` 打印警告信息
        • 2.2.6 `-w` 关闭警告信息
        • 2.2.7 `-std=c++11` 设置编译标准
        • 2.2.8 `-o` 指定输出文件名
        • 2.2.9 `-D` 定义宏
      • 2.3 【实战】g++命令行编译
        • 2.3.1 直接编译
        • 2.3.2 生成库文件并编译
        • 2.3.3 运行可执行文件
    • 3 GDB调试器
      • 3.1 常用调试命令参数
    • 4 CMake

参考资料

  • gcc/g++常用编译选项和gdb常用调试命令

一、gcc/g++/make

编译的四个阶段

  • 预处理:编译处理宏定义等宏命令(eg:#define)——生成后缀为“.i”的文件
  • 编译:将预处理后的文件转换成汇编语言——生成后缀为“.s”的文件
  • 汇编:由汇编生成的文件翻译为二进制目标文件——生成后缀为“.o”的文件
  • 链接:多个目标文件(二进制)结合库函数等综合成的能直接独立执行的执行文件——生成后缀为“.out”的文件

gcc无法进行库文件的连接,即无法编译完成步骤4;
g++则能完整编译出可执行文件。(实质上,g++从步骤1-步骤3均是调用gcc完成,步骤4连接则由自己完成)

1 gcc和g++的区别

先说一下相关概念:GCC : GNU Compiler Collection(GUN 编译器集合),它可以编译C、C++、JAV、Fortran、Pascal、Object-C、Ada等语言。

  • gcc是GCC中的GUN C Compiler(C编译器)
  • g++是GCC中的GUN C++ Compiler(C++编译器)

主要区别:

  1. 对于 *.c和*.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法强度是不一样的);

  2. 对于 *.c和 *.cpp文件,g++则统一当做cpp文件编译;

  3. 使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL;

  4. gcc在编译C文件时,可使用的预定义宏是比较少的;

  5. gcc在编译cpp文件时,g++在编译c文件和cpp文件时(这时候gcc和g++调用的都是cpp文件的编译器),会加入一些额外的宏,这些宏如下:

#define __GXX_WEAK__ 1
#define __cplusplus 1
#define __DEPRECATED 1
#define __GNUG__ 4
#define __EXCEPTIONS 1
#define __private_extern__ extern
  1. 在用gcc编译c++文件时,为了能够使用STL,需要加参数 –lstdc++ ,但这并不代表 gcc –lstdc++ 和 g++等价,它们的区别不仅仅是这个;

  2. 在C语言中,我们使用gcc命令来编译和链接C程序。例如:

  • 编译单个源文件:
    gcc main.c
  • 编译多个源文件:
    gcc main.c module.c
  • 编译C++程序时,gcc命令也可以使用,不过要增加-lstdc++选项,否则会发生链接错误。

  • gcc命令在链接时默认使用C的库,只有添加了-lstdc++选项才会使用 C++ 的库。

  • 编译单个源文件:
    gcc main.cpp -lstdc++

  • 编译多个源文件:
    gcc main.cpp module.cpp -lstdc++

  • 不过 GCC 中还有一个g++命令,它专门用来编译 C++ 程序,广大 C++ 开发人员也都使用这个命令。g++命令和gcc命令的用法如出一辙,例如
  • 编译单个源文件:
    g++ main.cpp
  • 编译多个源文件:
    g++ main.cpp module.cpp
  • 使用-o选项可以指定可执行文件的名称:
    g++ main.cpp -o demo
    ./demo

2 gcc/g++与make区别

  • 当你的程序只有一个源文件时,直接就可以用gcc命令编译它。但是当你的程序包含很多个源文件时,用gcc命令逐个去编译时,你就很容易混乱而且工作量大。
  • 所以出现了make工具!make工具可以看成是一个智能的批处理工具,它本身并没有编译和链接的功能,而是用类似于批处理的方式—通过调用makefile文件中用户指定的命令来进行编译和链接的。
  • makefile命令中就包含了调用gcc(也可以是别的编译器)去编译某个源文件的命令。

3 make与cmake区别

  • makefile在一些简单的工程完全可以人工手下,但是当工程非常大的时候,手写makefile也是非常麻烦的,如果换了个平台makefile又要重新修改。
  • 这时候就出现了cmake这个工具,cmake就可以更加简单的生成makefile文件给上面那个make用。当然cmake还有其他功能,就是可以跨平台生成对应平台能用的makefile,你不用再自己去修改了。

二、开发环境搭建

1 编译器,调试器,CMake安装

  • 安装GCC,GDB
sudo apt update
# 通过以下命令安装编译器和调试器
sudo apt install build-essential gdb
  • 安装成功确认
# 以下命令确认每个软件是否安装成功
# 如果成功,则显示版本号
gcc --version
g++ --version
gdb --version
  • CMake安装
# 通过以下命令安装编译器和调试器
sudo apt install cmake

# 确认是否安装成功
# 如果成功,则显示版本号
cmake --version

2 GCC编译器

实际使用中:

  • 使用 gcc 指令编译 C 代码
  • 使用 g++指令编译 C++ 代码

2.1 编译过程

2.1.1 -E 预处理-Pre-Processing .i文件

# -E 选项指示编译器仅对输入文件进行预处理
g++ -E test.cpp -o test.i  #.i文件

2.1.2 -S 编译-Compiling .s文件

# -S 编译选项告诉 g++ 在为 C++ 代码产生了汇编语言文件后停止编译
# g++ 产生的汇编语言文件的缺省扩展名是 .s
g++ -S test.i -o test.s

2.1.3 -C 汇编-Assembling .o文件

# -C 选项告诉 g++ 仅把源代码编译为机器语言的目标代码
# 缺省时 g++ 建立的目标代码文件有一个.o 的扩展名
g++ -c test.s -o test.o

2.1.4 链接(包括库文件)-Linking bin文件

# -o 编译选项来为将产生的可执行文件用指定的文件名
g++ test.o -o test

2.2 g++重要编译参数

  • 注:使用 man gccman g++ 命令可以查看gcc英文使用手册,见下图

在这里插入图片描述

2.2.1 -g 编译带调试信息的可执行文件

# -g 选项告诉 GCC 产生能被 GNU 调试器GDB使用的调试信息,以调试程序。
# 产生带调试信息的可执行文件test
g++ -g test.cpp

2.2.2 -O[n] 优化源代码

  • 所谓优化,例如省略掉代码中从未使用过的变量、直接将常量表达式用结果值代替等等,这些操作
    会缩减目标文件所包含的代码量,提高最终生成的可执行文件的运行效率。
  • -O 选项告诉 g++ 对源代码进行基本优化。这些优化在大多数情况下都会使程序执行的更快。 -O2
    选项告诉 g++ 产生尽可能小和尽可能快的代码。 如-O2-O3-On(n 常为0–3
    • -O 同时减小代码的长度和执行时间,其效果等价于-O1
    • -O0 表示不做优化
    • -O1 为默认优化
    • -O2 除了完成-O1的优化之外,还进行一些额外的调整工作,如指令调整等。
    • -O3 则包括循环展开和其他一些与处理特性相关的优化工作。
    • 选项将使编译的速度比使用 -O 时慢, 但通常产生的代码执行速度会更快。
# 使用 -O2优化源代码,并输出可执行文件
g++ -O2 test.cpp

2.2.3 -l-L 指定库文件 | 指定库文件路径

# -l参数(小写)就是用来指定程序要链接的库,-l参数紧接着就是库名
# 在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接

# 链接glog库
g++ -lglog test.cpp
# 如果库文件没放在上面三个目录里,需要使用-L参数(大写)指定库文件所在目录
# -L参数跟着的是库文件所在的目录名

# 链接mytest库,libmytest.so在/home/bing/mytestlibfolder目录下
g++ -L/home/bing/mytestlibfolder -lmytest test.cpp

2.2.4 -I 指定头文件搜索目录

# -I
# /usr/include目录一般是不用指定的,gcc知道去那里找,但是如果头文件不在/usr/icnclude
# 里我们就要用-I参数指定了,比如头文件放在/myinclude目录里,那编译命令行就要加上
# -I/myinclude 参数了,如果不加你会得到一个”xxxx.h: No such file or directory”的错
# 误。-I参数可以用相对路径,比如头文件在当前目录,可以用-I.来指定。上面我们提到的–cflags参
# 数就是用来生成-I参数的。

g++ -I/myinclude test.cpp

2.2.5 -Wall 打印警告信息

# 打印出gcc提供的警告信息
g++ -Wall test.cpp

2.2.6 -w 关闭警告信息

# 关闭所有警告信息
g++ -w test.cpp

2.2.7 -std=c++11 设置编译标准

# 使用 c++11 标准编译 test.cpp
g++ -std=c++11 test.cpp

2.2.8 -o 指定输出文件名

# 指定即将产生的文件名

# 指定输出可执行文件名为test
g++ test.cpp -o test

2.2.9 -D 定义宏

  • 在使用gcc/g++编译的时候定义宏

常用场景:

  • -DDEBUG 定义DEBUG宏,可能文件中有DEBUG宏部分的相关信息,用个DDEBUG来选择开启或关闭DEBUG
// -Dname 定义宏name,默认定义内容为字符串“1”

#include <stdio.h>
int main()
{
#ifdef DEBUG

    printf("DEBUG LOG\n");

#endif

    printf("in\n");
}

// 1. 在编译的时候,使用gcc -DDEBUG main.cpp
// 2. 第七行代码可以被执行

2.3 【实战】g++命令行编译

# 最初目录结构
.
├── include
│   └── Swap.h
├── main.cpp
└── src
	└── Swap.cpp
	
2 directories, 3 files

2.3.1 直接编译

  • 最简单的编译,并运行
# 将 main.cpp src/Swap.cpp 编译为可执行文件
g++ main.cpp src/Swap.cpp -Iinclude
# 运行a.out
./a.out
  • 增加参数编译,并运行
# 将 main.cpp src/Swap.cpp 编译为可执行文件 附带一堆参数
g++ main.cpp src/Swap.cpp -Iinclude -std=c++11 -O2 -Wall -o b.out
# 运行 b.out
./b.out

2.3.2 生成库文件并编译

  • 链接静态库生成可执行文件①:
  • 使用 ar rs 命令将多个可重定位目标文件打包成静态库
  • 库文件名都是以lib开头的,静态库以.a作为后缀 ,表示Archive。ar命令将目标文件打包成静态库,选项r表示将后面的文件列表添加到文件包,如果文件包不存在就创建它,如果文件包中已有同名文件就替换成新的。选项s是专用于生成静态库的,表示为静态库创建索引,这个索引被链接器使用。例如:
  • ar rs libstack.a stack.o push.o pop.o is_empty.o
## 进入src目录下
cd src

# 汇编,生成Swap.o文件
g++ Swap.cpp -c -I../include
# 生成静态库libSwap.a
ar rs libSwap.a Swap.o

## 回到上级目录
cd ..
# 链接,生成可执行文件:staticmain
g++ main.cpp -Iinclude -Lsrc -lSwap -o staticmain
  • 链接动态库生成可执行文件②:
## 进入src目录下
cd src

# 生成动态库libSwap.so
g++ Swap.cpp -I../include -fPIC -shared -o libSwap.so
## 上面命令等价于以下两条命令
# gcc Swap.cpp -I../include -c -fPIC
# gcc -shared -o libSwap.so Swap.o

## 回到上级目录
cd ..

# 链接,生成可执行文件:sharemain
g++ main.cpp -Iinclude -Lsrc -lSwap -o sharemain
  • 编译完成后的目录结构
    在这里插入图片描述

2.3.3 运行可执行文件

  • 运行可执行文件①
# 运行可执行文件
./staticmain
  • 运行可执行文件②
# 运行可执行文件
LD_LIBRARY_PATH=src ./sharemain

3 GDB调试器

  • GDB(GNU Debugger)是一个用来调试C/C++程序的功能强大的调试器,是Linux系统开发C/C++最常用的调试器
  • 程序员可以使用GDB来跟踪程序中的错误,从而减少程序员的工作量。
  • Linux 开发C/C++ 一定要熟悉 GDB
  • VSCode是通过调用GDB调试器来实现C/C++的调试工作的;

Windows 系统中,常见的集成开发环境(IDE),如 VS、VC等,它们内部已经嵌套了相应的调试器

GDB主要功能:

  • 设置断点(断点可以是条件表达式)
  • 使程序在指定的代码行上暂停执行,便于观察
  • 单步执行程序,便于调试
  • 查看程序中变量值的变化
  • 动态改变程序的执行环境
  • 分析崩溃程序产生的core文件

3.1 常用调试命令参数

  • 调试开始:执行gdb [exefilename] ,进入gdb调试程序,其中exefilename为要调试的可执行文件名。
  • 编译程序时需要加上-g,之后才能用gdb进行调试:gcc -g main.c -o main
  1. 回车键:重复上一命令
## 以下命令后括号内为命令的简化使用,比如run(r),直接输入命令 r 就代表命令run
$(gdb)file [exefilename] # 调试该文件
$(gdb)exec-file [exefilename] # 调试该文件
$(gdb)help(h) # 查看命令帮助,具体命令查询在gdb中输入help + 命令
$(gdb)run(r) # 重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件)
$(gdb)start # 单步执行,运行程序,停在第一行执行语句
$(gdb)list(l) # 查看原代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数)
$(gdb)set # 设置变量的值
$(gdb)next(n) # 单步调试(逐过程,函数直接执行)
$(gdb)step(s) # 单步调试(逐语句:跳入自定义函数内部执行)
$(gdb)backtrace(bt) # 查看函数的调用的栈帧和层级关系
$(gdb)frame(f) # 切换函数的栈帧
$(gdb)info(i) # 查看函数内部局部变量的数值
$(gdb)finish # 结束当前函数,返回到函数调用点
$(gdb)continue(c) # 继续运行
$(gdb)print(p) # 打印值及地址
$(gdb)quit(q) # 退出gdb
$(gdb)break+num(b) # 在第num行设置断点
$(gdb)info breakpoints # 查看当前设置的所有断点
$(gdb)delete breakpoints num(d) # 删除第num个断点
$(gdb)display # 追踪查看具体变量值
$(gdb)undisplay # 取消追踪观察变量
$(gdb)watch # 被设置观察点的变量发生修改时,打印显示
$(gdb)i watch # 显示观察点
$(gdb)enable breakpoints # 启用断点
$(gdb)disable breakpoints # 禁用断点
$(gdb)x # 查看内存x/20xw 显示20个单元,16进制,4字节每单元
$(gdb)run argv[1] argv[2] # 调试时命令行传参
$(gdb)set follow-fork-mode child #Makefile项目管理;选择跟踪父子进程(fork())

4 CMake

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/187538.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件工程(二)——需求工程、统一建模语言UML

目录 一、需求获取 二、需求分析 1.结构化需求分析 2.面向对象分析方法OOA 三、UML 41视图 四、UML 图 (1)用例图 (2)类图、对象图 (3)顺序图 &#xff08;4&#xff09;活动图 &#xff08;5&#xff09;状态图 &#xff08;6&#xff09;通信图 软件需求指用户对系…

【科研】ET-BERT代码分析

0. 数据集 论文使用的TLS1.3数据集是从 2021 年 3 月到 2021 年 7 月在中国科技网 (CSTNET) 上收集的。 如果要使用自己的数据集的话&#xff0c;需要检查数据格式是否与datasets/cstnet-tls1.3/目录下一致&#xff0c;并且在data_process/目录下指定数据集路径。 用于微调的…

Pomotroid 使用指南:一款高颜值 PC 端番茄时钟

文章首发于个人公众号&#xff1a;「阿拉平平」 番茄工作法作为一套高效易行的时间管理方案&#xff0c;是由意大利人弗朗西斯科西里洛于 1992 年创立的。作者发明的初衷源自于自身严重的拖延症&#xff0c;于是他找来一个厨房用的番茄计时器&#xff0c;调到 10 分钟&#xff…

游戏SDK(二)框架设计

前言 根据上一篇游戏SDK&#xff08;一&#xff09; 客户端整体架构&#xff0c;介绍了游戏SDK 及 游戏SDK的需求分析。根据需求分析&#xff0c;对游戏SDK的设计分为3大块&#xff1a; 客户端&#xff1a;接口统一&#xff0c;做好逻辑转发和处理。具体渠道具体实现&#xf…

【高并发】- 生产级系统搭建 - 4

前言 关于高并发系统中&#xff0c;当前比较热门的还是属于“秒杀”系统&#xff0c;前面章节在整理了“秒杀”系统的相关设计概念后&#xff0c;本章节&#xff0c;来讲解扣减库存相关的业务逻辑。 1 库存的那些事 一般电商网站中&#xff0c;购买流程一般都是这样的&#xff…

多线程之Callable接口、ReentrantLock、信号量 Semaphore以及CountDownLatch

目录&#xff1a;一、Callable接口Callable的用法小结二、ReentrantLockReentrantLock 的用法ReentrantLock 和 synchronized 的区别&#xff1f;为什么有了 synchronized 还需要 juc(java.util.concurrent) 下的 lock&#xff1f;三、信号量 Semaphore如何理解信号量&#xff…

Python接口测试实战4(下) - 框架完善:用例基类,用例标签,重新运行上次失败用例

本节内容使用用例基类自定义TestSuitecollect-only的实现testlist的实现用例tags的实现rerun-fails的实现命令行参数的使用更简单的用例编写使用用例基类因为每条用例都需要从excel中读取数据&#xff0c;解析数据&#xff0c;发送请求&#xff0c;断言响应结果&#xff0c;我们…

阿里云ECS学习笔记1

ECS&#xff1a;弹性计算服务。CPU可以热插、内存可变大变小、硬盘可以增加~ 注册&#xff1a; 在企业中&#xff0c;应该以企业的身份进行注册&#xff0c;而不是以个人身份进行注册。 手机号&#xff1a;行政部门专门管理注册的账号资源的&#xff0c;而不使用个人或者老板…

【可解释性机器学习】解释基于XGBoost对泰坦尼克号数据集的预测过程和结果

解释基于XGBoost对泰坦尼克号数据集的预测过程和结果1. 训练数据2. 简单的 XGBoost 分类器3. 解释重量4. 解释预测5. 添加文本特性参考资料本文介绍如何分析XGBoost分类器的预测&#xff08; eli5也支持 XGBoost和大多数 scikit-learn树集成的回归&#xff09;。 我们将使用 Ti…

【数据结构】8.5 归并排序

文章目录相邻两个有序子序列的归并归并排序算法归并排序算法分析基本思想 将两个或两个以上的有序子序列归并为一个有序序列。在内部排序中&#xff0c;通常采用的是2-路归并排序。 即&#xff1a;将两个位置相邻的有序子序列 R[l…m] 和 R[m1…n] 归并为一个有序序列 R[l…n]…

1个寒假能学会多少网络安全技能?

现在可以看到很多标题都声称三个月内就可以转行网络安全领域&#xff0c;并且成为月入15K的网络工程师。那么&#xff0c;这个寒假的时间能学多少网络安全知识&#xff1f;是否能入门网络安全工程师呢&#xff1f; 答案是肯定的。 虽然网络完全知识是一门广泛的学科&#xff…

在线支付系列【9】微信支付之申请微信公众号

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录前言申请微信公众号前言 由于微信支付的产品体系全部搭载于微信的社交体系之上&#xff0c;所以直连商户或服务商接入微信支付之前&#xff0c;都需要有一个微信社交载体&#xff0c;该载体对应…

天啦撸~ChatGPT通过国际软件测试工程师(ISTQB)认证了~

天啦撸&#xff01;目前最火的AI应用ChatGPT通过ISTQB认证了~ 近期&#xff0c;国外的一位工程师&#xff0c;放出了他用ChatGPT通过认证的相关信息。 ChatGPT相信大家都知道是什么了&#xff0c;ISTQB相信很多测试小伙伴也不陌生&#xff0c;而且很多考证的小伙伴也对此梦寐以…

Linux之网络性能测试工具netperf实践

一、netperf简介 Netperf是一种网络性能的测量工具&#xff0c;主要针对基于TCP或UDP的传输。Netperf根据应用的不同&#xff0c;可以进行不同模式的网络性能测试&#xff0c;即批量数据传输&#xff08;bulk data transfer&#xff09;模式和请求/应答&#xff08;request/rep…

公司通知要大裁员,hr太强势,和所有人吵起来,老板见势不妙,不得不答应大家要求,把HR一起裁掉了!...

在裁员中&#xff0c;hr一般都会代表老板的利益和员工对抗&#xff0c;但如果hr和员工闹翻了&#xff0c;老板会维护hr吗&#xff1f;一位网友说&#xff1a;一上班就收到消息要裁员&#xff0c;立马让报上名单面谈&#xff0c;锁电脑关权限。后面那些人面谈的时候吵起来了&…

OpenAI Chatgpt注册及使用教程

零、什么是chatgpt?​ 1、简介 ChatGPT&#xff08;Chat Generative Pre-trained Transformer&#xff09;是OpenAI于 2022 年 11 月推出的聊天机器人。它建立在 OpenAI 的GPT-3大型语言模型家族之上&#xff0c;并经过微调&#xff08;一种迁移学习的方法&#xff09;…

双点双向的ISIS与OSPF、OSPF与OSPF、ISIS与ISIS环境以路由策略解决(1tag、2tag、4tag介绍与配置)

3.1.1 双点双向的ISIS与OSPF、OSPF与OSPF、ISIS与ISIS环境以路由策略解决&#xff08;1tag、2tag、4tag介绍与配置&#xff09; OSPF与ISIS双点双向 次优的产生与解决&#xff1a; 由于OSPF引入外部路由之后其优先级为150&#xff0c;再由ASBR进行双向引入之后。 原先OSPF外部…

闲鱼自动化软件——筛选/发送系统 V20已经测试完毕

做程序&#xff0c;就是不断地改&#xff0c;不断地优化。当改动达到一定程序&#xff0c;已经和前面形成断代&#xff0c;程序的升级时刻便到了。V20做了哪些更改或优化。1。优化抓取&#xff1a;在抓取环境优化参数&#xff0c;使抓取更顺滑&#xff0c;抓取数据效果上更准确…

智能家居创意DIY-Homekit智能灯

一、什么是智能灯 传统的灯泡是通过手动打开和关闭开关来工作。有时&#xff0c;它们可以通过声控、触控、红外等方式进行控制&#xff0c;或者带有调光开关&#xff0c;让用户调暗或调亮灯光。 智能灯泡内置有芯片和通信模块&#xff0c;可与手机、家庭智能助手、或其他智能…

若依-excel预览功能实现

实现效果及源码 实现效果如下图所示&#xff1a; 实现思路&#xff1a; 1.动态表格&#xff1a;定义表头数组&#xff0c;表格遍历表头生成表格列 2.读取excel文件内容&#xff0c;封装表头&#xff0c;绑定表格数据 代码修改 首先参考若依官网&#xff0c;先实现excel导入功…