CMake : Linux 搭建开发 - g++、gdb

news2024/12/24 9:34:02

目录

1、环境搭建

1.1 编译器 GCC,调试器 GDB

1.2 CMake

2、G++ 编译

2.1 编译过程

编译预处理 *.i

编译 *.s

汇编 *.o

链接 bin

2.2 G++ 参数

-g

-O[n]

-l、-L

-I

-Wall、-w

-o

-D

-fpic

3、GDB 调试器

3.1 调试命令参数

4、CMake

4.1 含义

4.2 构建树

4.3 常用命令

4.4 构建流程


1、环境搭建

1.1 编译器 GCC,调试器 GDB

sudo apt update # 需要更新
sudo apt install build-essential gdb

# 确定版本号
gcc --version
g++ --version
gdb --version

1.2 CMake

sudo apt install cmake

cmake --version

2、G++ 编译

2.1 编译过程

编译预处理 *.i

  1. 主要对包含的**头文件(#include)和宏定义(#define, #ifdef ...)还有注释**等进行处理;

  2. 预处理之后停止编译过程,生成 *.ii.c 生成的是 .i)文件;

  3. #include 引入的内容被全部复制到预编译文件中,宏定义也会被相应替换处理。

    # -E 仅对源文件进行预处理
    g++  -E test.cpp  -o test.i
    • 最主要的工作:宏命令的替换;
    • #include 单纯导入,可以导入 cpp、txt 文件等等;

编译 *.s

  1. 语法错误检查,检查无误再翻译成汇编语言;

  2. 生成的是和 CPU 架构相关的汇编指令,不同 CPU 架构采用的汇编指令集不同,生成的汇编代码也不一样。

    # -S 产生汇编语言文件后停止编译
    g++  -S test.i  -o test.s

汇编 *.o

  1. g++ 生成:g++ -c test.s -o test.o

  2. 汇编器汇编生成:as test.s -o test.o

  3. 将汇编代码生成机器可执行的二进制目标代码

    # -c 仅把源代码编译为机器语言的目标代码
    g++  -c test.s  -o test.o

链接 bin

  1. 核心工作:解决模块间各种符号(变量、函数)相互引用的问题,除了使用 test.o 还会将静态(动态)库链接一同生成可执行文件

  2. 符号重定位:引用符号(对符号在内存中具体地址的引用),解决当前编译单元如何访问外部符号的问题。

    # -o 产生指定文件名的可执行文件
    g++ test.o -o test
    # g++ test.o test.so test.a

    添加 **g++ --save-temps **参数,保存编译过程中生成的所有中间文件。

2.2 G++ 参数

-g

  • 编译带调试信息的可执行文件;

  • 产生能被 GNU 调试器GDB使用的调试信息,以调试程序。

-O[n]

  • 优化,例如省略从未使用过的变量、直接将常量表达式用结果值代替等等;

  • -O 对源代码进行基本优化,如-O2,-O3,-On(n 常为0–3) :

    • -O 减小代码的长度和执行时间,等价 -O1;

    • -O0 不做优化;

    • -O1 默认优化;

    • -O2 完成-O1优化之外,还进行一些额外的调整工作,如指令调整等;

    • -O3 包括循环展开和其他一些与处理特性相关的优化工作。

-l、-L

  • -l : 指定库文件,如 -lglog ;

  • -L : 指定库文件路径,如 -L/home/lib 。

-I

  • 指定头文件搜索路径。

-Wall、-w

  • -Wall打印警告信息;

  • -w关闭警告信息。

-o

  • 指定输出文件名,如 -o test 。

-D

  • 定义预处理宏:-DDEBUG 开启或关闭 DEBUG。

-fpic

  • position-independent code,是否创建与位置无关的目标(可行性文件或共享库);

  • PIC广泛使用于共享库,使得同一个库中的代码能够被加载到不同进程的地址空间中。PIC 还用于缺少内存管理单元的计算机系统中,使得操作系统能够在单一的地址空间中将不同的运行程序隔离开来;

  • 地址无关代码能够在不做修改的情况下被复制到内存中的任意位置。这一点不同于重定位代码,因为重定位代码需要经过链接器或加载器的特殊处理才能确定合适的运行时内存地址;

  • cmake: set(CMAKE_POSITION_INDEPENDENT_CODEON)

3、GDB 调试器

3.1 调试命令参数

$(gdb)help(h) # 查看命令帮助,具体命令查询在gdb中输入help + 命令

$(gdb)run(r) # 重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件)
$(gdb)start # 单步执行,运行程序,停在第一行执行语句
$(gdb)next(n)   # 单步调试(逐过程,函数直接执行)
$(gdb)step(s) # 单步调试(逐语句:跳入自定义函数内部执行)
$(gdb)continue(c) # 继续运行
$(gdb)finish # 结束当前函数,返回到函数调用点
$(gdb)quit(q) # 退出gdb

$(gdb)list(l) # 查看原代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数)
$(gdb)backtrace(bt) # 查看函数的调用的栈帧和层级关系
$(gdb)info(i) # 查看函数内部局部变量的数值
$(gdb)set # 设置变量的值
$(gdb)display # 追踪查看具体变量值
$(gdb)print(p) # 打印值及地址

$(gdb)undisplay # 取消追踪观察变量
$(gdb)watch # 被设置观察点的变量发生修改时,打印显示
$(gdb)i watch # 显示观察点

$(gdb)info breakpoints # 查看当前设置的所有断点
$(gdb)enable breakpoints # 启用断点
$(gdb)disable breakpoints # 禁用断点
$(gdb)break+num(b) # 在第num行设置断点
$(gdb)delete breakpoints num(d) # 删除第num个断点

$(gdb)x # 查看内存x/20xw 显示20个单元,16进制,4字节每单元
$(gdb)run argv[1] argv[2] # 调试时命令行传参
$(gdb)frame(f) # 切换函数的栈帧
$(gdb)set follow-fork-mode child # Makefile项目管理:选择跟踪父子进程(fork())

4、CMake

CMake 始于 1999 年,当时开发公司 Kitware 被委托设计一套工具来简化研究人员的日常工作软件。目标很明确:提供一组工具,可以在不同平台上配置、构建、测试和部署项目。

4.1 含义

CMake 本身是一个工具集,由五个可执行的程序组成:cmake、ctest、cpack、cmake-gui、ccmake

  • cmake:用于在构建项目的第一步,进行项目的配置、生成和构建项目的主要可执行文件的工作;

  • ctest:定义测试、测试套件,并设置应该如何执行,用于运行和报告测试结果的测试驱动程序

  • cpack:为打包需求提供了 DSL,用来生成安装程序和源包的打包程序

  • cmake-gui:cmake 的图形界面

  • ccmake:用于图形界面,与 cmake-gui 不同的地方在于ccmake是基于控制台(terminal)的图形界面

CDash 将项目的测试结果在面板中展示。

  • CMake tim,CMake 运行阶段,将处理项目中的 CMakeLists.txt 文件并进行配置;

  • Generation time,配置成功后,CMake 将生成本地构建工具所需的脚本,以执行项目中的后续步骤;

  • Build time,调用编译器,并在特定的构建目录中构建目标。递归的 CMake time 用来实现平台无关的构建;

  • CTest time,运行项目的测试套件,以检查目标是否按预期执行。

  • CDash timereport time,将测试结果上传到面板;

  • Install time,将项目的目标、源文件、可执行文件和库从构建目录安装到安装位置。

  • CPack timepackaging time,项目打包;

  • Package install time,在系统范围内安装新生成的包。

4.2 构建树

构建的每一个目标,都是树形的结构。

4.3 常用命令

  • cmake_minimum_required - 指定CMake的最小版本要求

语法: cmake_minimum_required(VERSION versionNumber [FATAL_ERROR]

  • project - 定义工程名称,并可指定工程支持的语言

语法: project(projectname [CXX] [C] [Java])

  • set - 显式的定义变量

语法:set(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])

set(SRC sayhello.cpp hello.cpp)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
set( CMAKE_BUILD_TYPE Debug )
  • include_directories - 向工程添加多个特定的头文件搜索路径

语法: include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)

include_directories(/usr/include/myincludefolder ./include)
  • link_directories - 向工程添加多个特定的库文件搜索路径

语法: link_directories(dir1 dir2 ...)

link_directories(/usr/lib/mylibfolder ./lib)
  • add_library - 生成库文件

语法: add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)

add_library(hello SHARED ${SRC})
  • add_compile_options - 添加编译参数

语法:add_compile_options

add_compile_options(-Wall -std=c++11 -O2)
  • add_executable - 生成可执行文件

语法:add_executable(exename source1 source2 ... sourceN)

  • target_link_libraries - 为 target 添加需要链接的共享库

语法: target_link_libraries(target library1<debug | optimized> library2...)

  • add_subdirectory - 向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置

语法: add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

  • aux_source_directory - 发现目录下所有源文件并将列表存储在一个变量中,被用来自动构建源文件列表

语法: aux_source_directory(dir VARIABLE)

  • target_include_directories( swap_lib PUBLIC ${PROJECT_SOURCE_DIR}/include ) - 链接静态库目录

    4.4 构建流程

  1. 建立 build 文件夹,并进入 build 目录:mkdir build & cd build

  2. 编译上级目录的 CMakeLists.txt 文件,生成 Makefile 和 其他文件:cmake ..

  3. 执行 make 命令,生成目标:make

  4. 流程图如下,包括三个基本阶段:配置、生成、构建阶段

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

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

相关文章

npm全局包及项目包的讲解与方法

看图可知 安装全局包和项目包 我们通过npm install 命令来安装包&#xff0c;简单说就是把包从npm的官网&#xff08;或者是指定的镜像源&#xff09;下载到我们自己的电脑中。那具体这个包下载到哪里了&#xff0c;还是有一点讲究的。 分成两类&#xff1a; 全局安装: 包被…

IntelliJ IDEA 新建安卓项目失败,网上的各种教程都不管用的看向这里!!!

目录 1、出现的问题&#xff1a; 2、解决办法&#xff1a; 1&#xff09;新建项目 2&#xff09;修改设置 3、注意 备注&#xff1a; 目的&#xff1a;最近开发机器人远程控制需要一个安卓app&#xff0c;之前是自己做了个H5app来用的&#xff0c;H5不是很稳定&#xff0c;所…

Kotlin基础

Kotlin基础 一.Kotlin介绍1.诞生2.Kotlin与JVM3.为什么学习kotlin&#xff1f;4.Kotlin跨平台特性 二.变量常量类型条件语句函数1.声明变量2.内置数据类型3.只读变量4.类型推断5.编译时常量6.条件语句&#xff1a;表达式7.String模板8.函数 三.匿名函数函数类型高阶函数&#x…

关于OKD(OpenShift)中组件资源介绍和命令行操作的一些笔记

写在前面 参加考试&#xff0c;会陆续分享一些 OpenShift 的笔记博文内容为 openshift 常见 API 资源对象介绍&#xff0c;包括所特有的 Route&#xff0c;IS&#xff0c;DC&#xff0c;BC 等。学习环境为 openshift v3 的版本&#xff0c;有些旧这里如果专门学习 openshift &a…

第一节 ogre源码编译与安装

一. 电脑环境要求 本机使用的编译环境为&#xff1a;系统为Windows 10&#xff0c; Microsoft Visual Studio Enterprise 2019&#xff0c;版本 16.11.26&#xff0c;cmake-3.18.6-win64-x64 这些为基本的操作环境自己可以从网上下载安装。 二. 依赖环境下载 DirectX SDK &a…

Blade项目的IDE支持

Blade是一个C/C构建工具&#xff0c;详细介绍见Blade构建工具。虽然功能强大&#xff0c;但是缺少IDE支持。本文介绍如何在Blade项目中使用IDE的智能提示、自动补全、自动跳转等特性。 1.VSCode VSCode的C/C插件(ms-vscode.cpptools)提供了C/C代码的智能提示、自动补全和调试…

Java编程设计语言-集合类

API(application programming interface)是JDK的重要组成部分&#xff0c;API提供了Java程序与运行它的系统软件&#xff08;Java虚拟机&#xff09;之间的接口&#xff0c;可以帮助开发者方便、快捷地开发Java程序 集合在程序设计中是一种重要的是数据结构&#xff0c;Java中提…

数据湖Iceberg-FlinkSQL-kafka类型表数据无法成功写入(6)

数据湖Iceberg-简介(1) 数据湖Iceberg-存储结构(2) 数据湖Iceberg-Hive集成Iceberg(3) 数据湖Iceberg-SparkSQL集成(4) 数据湖Iceberg-FlinkSQL集成(5) 数据湖Iceberg-FlinkSQL-kafka类型表数据无法成功写入(6) 数据湖Iceberg-Flink DataFrame集成(7) 数据湖Iceberg-FlinkSQL-…

Linux离线状态下在anaconda中安装pytorch

1. 下载与安装说明 下载地址&#xff08;按安装方法选取&#xff09; bz2压缩包下载地址&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/win-64/?CM&ODwhl包下载 torch、torchversion、torchaudio下载地址&#xff1a;https://download.pytorc…

【OS】Linux Process Memory的探究

【OS】Linux Process Memory的探究 前言 刷B站刷到了南大OS的课程&#xff0c;不得不说酒吧舞的教育水平真滴高&#xff0c;狠狠的看了一些关于进程地址相关的课程。 进程地址空间 1.导言 先导入两个问题&#xff1a; 如下的程序会输出什么&#xff1f; #include<stdio…

axios的使用,axios的get请求、post请求方式、put请求方式

axios (发音&#xff1a;艾克C奥斯)是前端圈最火的、专注于数据请求的库。react/vue官方都推荐使用axios发送ajax请求&#xff0c;是一个基于 promise 的 HTTP 库&#xff0c;可以用在浏览器和 node.js 中。 中文官网地址&#xff1a;http://www.axios-js.com/ 英文官网地址&a…

快速下载VScode并配置Python运行环境【详细教程】

快速下载VScode并配置Python运行环境【详细教程】 博主&#xff1a;命运之光 目录 快速下载VScode并配置Python运行环境【详细教程】前言下载vscode第一步vscode官网下载第二步点击下载![请添加图片描述](https://img-blog.csdnimg.cn/1d76c427314b4ddcbd350e0a7e5449d5.png)第…

数据湖Iceberg-FlinkSQL集成(5)

文章目录 数据湖Iceberg-FlinkSQL集成环境准备**Flink与Iceberg的版本对应关系如下**jar包下载地址jar包上传到Flink lib目录下修改flink-conf.yaml配置 创建和使用Catalog创建语法说明Hive CatalogHadoop Catalog配置sql-client初始化文件 DDL语句创建数据库创建表创建分区表使…

ubuntu22.04安装ROS2

ubuntu22.04安装ROS2 0.前言一、安装ROS21.首先将本地的编码格式修改为utf-82.添加ROS2 GPG key3.安装ROS24.设置环境变量 二、简单测试1.Hello ROS&#xff01;2.ROS Turtle 三、总结 0.前言 最近也没找到什么特别感兴趣的小项目&#xff0c;不过偶然间看见ROS2这个东西&#…

中期国际:安卓MT4怎么下载以及下载后需要注意哪些问题

投资现货黄金&#xff0c;需要使用到现货黄金软件。一个简单易用的现货黄金软件&#xff0c;就像是给厨师一把趁手的菜刀&#xff0c;以后的使用会得心应手&#xff0c;投资更加顺利。对于投资者来说&#xff0c;什么现货黄金软件才算是好的呢?小编这里推荐MT4软件。如今不少投…

c++11 标准模板(STL)(std::priority_queue)(四)

适配一个容器以提供优先级队列 std::priority_queue 定义于头文件 <queue> template< class T, class Container std::vector<T>, class Compare std::less<typename Container::value_type> > class priority_queue; priority_queu…

Mysql 查询同类数据中某一数字最大的所有数据

方法一、将时间进行排序后再分组 该表表名为customer, park_id表示园区id&#xff0c;joined_at表示用户的加入时间&#xff0c;created_at表示用户的创建时间。 需求&#xff1a;查出每个园区中&#xff0c;最早加入园区的第一位用户 select * from (select * from custome…

outlook手动配置保姆级别教学

outlook保姆级教学 hello&#xff0c;各位小伙伴&#xff0c;今天呢讲一下outlook的配置&#xff0c;相信啊再次之前也必然看到过其他博主写的&#xff0c;我呢也是前段时间有需求但是网上总是零零散散的。 我呢配置过qq 和126的邮箱这里呢开始教程. 第一步呢首先点击账户的设…

每日一个小技巧:1招教你wav格式如何转换mp3

wav是一种质量较高的音频格式&#xff0c;但它的文件大小通常比较大。为了更方便地分享和存储音频文件&#xff0c;许多人都会选择将其转换为mp3格式。因为mp3格式能够在保持较高音质的同时&#xff0c;尽量降低文件大小&#xff0c;帮助你节省许多磁盘空间。那你们知道wav格式…

Python每日一练(20230425)

目录 1. 多数元素 &#x1f31f; 2. 二叉树的层序遍历 II &#x1f31f;&#x1f31f; 3. 最接近的三数之和 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专…