Linux文件编译

一、GCC编译

我们都知道想要实现一个程序首先需要写好代码让其能运行起来,那么写出来的.c文件是如何被编译出来的呢?

1.直接编译

首先将程序直接编译为可执行文件可以通过Linux中的GCC编译器。

GCC(是一套广泛使用的编译器工具集,由 GNU 项目开发和维护。它支持多种编程语言,包括 C、C++、Objective-C、Fortran、Go 和其他语言。GCC 提供了编译、链接和优化等功能,可以将源代码转换为可执行文件或库。

 gcc name.c:已经写好.c文件想生成执行文件,可直接用指令实现,会生成一个name.out文件,

输入指令"./name.out" 文件就会执行

2.分步编译

那么GCC是如何实现这个原理的呢?

预处理:

C 编译器对各种预处理命令进行处理,包括头文件包含、宏定义的扩展、条件编译的选择等;

gcc -E name.c -o name.i:对c程序文件进行预处理得到.i预处理文件

 编译:

将预处理得到的源代码文件进行语法词法分析,“翻译转换”得到机器语言的汇编文件;

gcc -S name.i:通过编译得到.s 汇编文件 (如果是c文件,会进行预处理+编译)

汇编:

将汇编代码翻译成了机器码,但是还不可以运行;

gcc -c name.s:通过汇编得到 hello.o 机器码文件 (如果是c文件,会进行预处理+编译+汇编)

链接:

处理可重定位文件,把各种符号引用转换成为可执行文件中的合适信息,通常是虚拟地址;

gcc name.o -o name:通过链接得到 a.out 可执行文件 (如果是c文件,进行完整编译步骤)

3.多文件编译

首先可以创建两个文件,一个是a.c文件

#include<stdio.h>
int main()
{printf("hello,world!\n");test();return 0;
}

 再创建一个文件用来存储外部函数

#include<stdio.h>void test()
{printf("test\n");
}

如果文件有更新,那么两个文件都需要重新编译

4.G++

g++:这是 GCC 中的 C++ 编译器。它将 C++ 源代码文件(通常以 .cpp 或 .cc 扩展名)作为输入,并生成可执行文件。与 gcc 相比,g++ 在编译 C++ 代码时会自动链接 C++ 的标准库。可以理解为一个是对C语言的编译,一个是对C++的编译

二、Make 

1.概述

make 是一个命令工具,它解释Makefile 中的指令。在Makefile 文件中述了整个工程所有文件的编译顺序、编译规则。

一个工程中的源文件不计其数,其按类型、功能、模块分别放在若千个目录中,Makefile
定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译
,甚至于进行更复杂的功能操作,因为 makefile 就像一个 Shell 脚本一样,也可以执行操作系统的命令

 如果是单独文件编译可以直接用make name就可以生成执行文件。

 2.使用步骤

  1. 创建Makefile:在项目根目录下创建一个名为Makefile的文本文件。Makefile中包含了构建项目所需的规则和命令。
  2. 定义规则:Makefile中的规则由目标文件、依赖文件和构建命令组成。目标文件是需要构建的文件,依赖文件是构建目标文件所需的文件,构建命令是用于生成目标文件的命令。
  3. 编写构建命令:在Makefile中为每个规则编写构建命令。构建命令可以是任意可执行的命令或脚本,用于生成目标文件。
  4. 运行Make:在终端或命令提示符中,进入到项目根目录,并执行make命令。Make工具会读取Makefile,并根据规则和依赖关系自动构建项目。

3.makefile创建规则 

3.1一个基本规则 

目标:依赖条件(可以设置多个依赖条件)

        命令

target: dependenciescommand1command2...

3.2两个常用函数

$(wildcard pattern):

这个函数用于匹配指定模式的文件,并返回符合模式的文件名列表。模式可以包含通配符,如*和?。该函数将返回一个字符串,其中包含匹配的文件名列表,每个文件名之间用空格分隔。例:

src = $(wildcard *.c)

在这个示例中,$(wildcard *.c)会返回当前目录中所有以.c为扩展名的文件,将其赋值给变量src。

$(patsubst 参数1,参数2,参数3):

这个函数用于在给定的文本中,将符合指定模式的部分替换为指定的内容。模式可以包含通配符,如%,用于匹配任意字符。例:

objects := $(patsubst %.c, %.o, $(src))


在这个示例中,假设src变量包含一些.c文件的文件名列表。使用$(patsubst %.c, %.o, $(src))将替换文件名的扩展名,将.c替换为.o,并将结果赋值给变量objects。

3.3三个自动变量

$@

在规则的命令中,表示规则中的目标。例:

target: dependencygcc -o $@ $<

 在这个示例中,$@将被替换为目标文件的名称。

$^

在规则的命令中,表示所有依赖条件。例:

target: dependency1 dependency2gcc -o $@ $^

在这个示例中,$^将被替换为所有依赖文件的列表,即dependency1 dependency2。 

$<: 在规则的命令中,表示第一个依赖条件。例:

target: dependencygcc -o $@ $<

在这个示例中,$<将被替换为第一个依赖文件的名称。 

 4.示例文件

# 编译器设置
CC := gcc
CFLAGS := -Wall -Wextra -g# 目标文件
TARGET := program# 源文件列表
SRCS := main.c utils.c# 生成目标
$(TARGET): $(SRCS)$(CC) $(CFLAGS) -o $@ $^# 清理生成的文件
clean:rm -f $(TARGET).PHONY: clean
  • CC:定义编译器的变量,这里使用gcc作为默认的编译器。
  • CFLAGS:定义编译选项的变量,这里设置了一些常用的编译选项,如-Wall和-Wextra用于开启更多的警告信息,-g用于生成调试信息。
  • TARGET:定义目标文件的变量,这里设置为program。
  • SRCS:定义源文件的变量,这里列出了main.c和utils.c。
  • $(TARGET): $(SRCS):这是一个生成目标的规则,指定了$(SRCS)作为依赖文件,当依赖文件发生变化时,执行后续的命令将源文件编译链接成目标文件。
  • $(CC) $(CFLAGS) -o $@ $^:这是生成目标的命令,$(CC)和$(CFLAGS)分别代表编译器和编译选项,$@代表目标文件名,$^代表所有的依赖文件。
  • clean::这是一个清理目标文件的规则,指定了clean作为伪目标。
  • rm -f $(TARGET):这是清理目标文件的命令,使用rm -f命令删除目标文件。
  • .PHONY: clean:这个声明用于指示clean是一个伪目标,而不是一个实际的文件。

 关于Makefile需要多加练习,对于多文件编译是很有用的。Linux环境下的程序员如果不会使用GNU make来构建和管理自己的工程,应该不能算是个合格的专业程序员,至少不能称得上是 Unix 程序员。

 三、GDB

示例:

使用gcc编译时加上g选项可以得到调试表

#include<stdio.h>
void my_print(int i)
{printf("打印第%d次\n",i);
}
int main(){int i = 0;while(i < 10) {i++;my_print(i);}return 0;
}

例如:

  • gcc -g main.c
  • gdb ./a.out

基本指令:

  • list/l或list[数字]: 列出源码。加数字,在指定行号位置附近显示
  • break/b 或 break [number]: b 20   在20行位置设置断点
  • d/delete:断点编号 删除断点
  • run/r: 运行程序
  • start: 运行程序(到主函数停止)
  • n/next:下一条指令 (会越过函数)
  • s/step:下一条指令 (会进入函数)
  • p/print[变量名]:查看变量的值
  • continue/c:继续执行断点后续指令
  • finish:结束当前函数调用
  • q/quit:退出 gdb 当前调试 

 上面只是GDB的基本用法,如果想更深入的学习需要自己查阅一下资料。

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

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

相关文章

读论文:DiffBIR: Towards Blind Image Restoration with Generative Diffusion Prior

DiffBIR 发表于2023年的ICCV&#xff0c;是一种基于生成扩散先验的盲图像恢复模型。它通过两个阶段的处理来去除图像的退化&#xff0c;并细化图像的细节。DiffBIR 的优势在于提供高质量的图像恢复结果&#xff0c;并且具有灵活的参数设置&#xff0c;可以在保真度和质量之间进…

【论文笔记】Lift-Attend-Splat: Bird’s-eye-view camera-lidar fusion using transformers

原文链接&#xff1a;https://arxiv.org/abs/2312.14919 1. 引言 多模态融合时&#xff0c;由于不同模态有不同的过拟合和泛化能力&#xff0c;联合训练不同模态可能会导致弱模态的不充分利用&#xff0c;甚至会导致比单一模态方法性能更低。 目前的相机-激光雷达融合方法多基…

【JMeter】使用技巧

在这此对新版本jmeter的学习温习的过程&#xff0c;发现了一些以前不知道的功能&#xff0c;所以&#xff0c;整理出来与大分享。本文内容如下。 如何使用英文界面的jmeter如何使用镜像服务器Jmeter分布式测试启动Debug 日志记录搜索功能线程之间传递变量 如何使用英文界面的…

YOLO部署实战(5):NVIDIA Jetson Tx2部署YOLO

1 一些概念 Jetson Tx2 NVIDIA Jetson 是NVIDIA为新一代自主机器设计的的嵌入式系统&#xff0c;是一个AI平台&#xff0c;它的优势就是可以覆盖不同领域、不同行业。目前Jetson产品线已经有四个产品系列&#xff0c;包括Jetson Nano、Jetson TX2、Xavier NX和AGX Xavier。四…

MySQL温故篇(一)SQL语句基础

一、SQL语句基础 1、SQL语言分类 DDL&#xff1a;数据定义语言 DCL&#xff1a;数据控制语言 DML&#xff1a;数据操作语言 DQL&#xff1a;数据的查询语言 2、数据类型 3、字符类型 char(11) &#xff1a; 定长 的字符串类型,在存储字符串时&#xff0c;最大字符长度11个&a…

【HarmonyOS应用开发】HTTP数据请求(十四)

文章末尾含相关内容源代码 一、概述 日常生活中我们使用应用程序看新闻、发送消息等&#xff0c;都需要连接到互联网&#xff0c;从服务端获取数据。例如&#xff0c;新闻应用可以从新闻服务器中获取最新的热点新闻&#xff0c;从而给用户打造更加丰富、更加实用的体验。 那么…

计算机网络——03网络核心

网络核心 网络核心 网络核心&#xff1a;路由器的网络状态基本问题&#xff1a;数据怎样通过网络进行传输 电路交换&#xff1a;为每个呼叫预留一条专有电路分组交换 将要传送的数据分成一个个单位&#xff1a;分组将分组从一个路由器传到相邻路由器&#xff08;hop&#xff…

101 C++内存高级话题 内存池概念,代码实现和详细分析

零 为什么要用内存池&#xff1f; 从前面的知识我们知道&#xff0c;当new 或者 malloc 的时候&#xff0c;假设您想要malloc 10个字节&#xff0c; char * pchar new char[10]; char *pchar1 malloc(10); 实际上编译器为了 记录和管理这些数据&#xff0c;做了不少事情&…

01-Datahub是什么?

Datahub是LinkedIn开源的基于现代数据栈的元数据管理平台&#xff0c;原来叫做WhereHows 。经过一段时间的发展datahub于2020年2月在Github开源。 官网地址为&#xff1a;A Metadata Platform for the Modern Data Stack | DataHub 源码地址为&#xff1a;GitHub - datahub-p…

幻兽帕鲁联机服务器 - 小白部署教程

简介&#xff1a; 本文将基于阿里云&#xff0c;介绍如何最低以24元的成本拥有一台幻兽帕鲁私人服务器 1. 基础部署幻兽帕鲁服务器 1.1 访问帕鲁专题活动页 首先登录阿里云官网&#xff1a;阿里云特惠专区-幻兽帕鲁专属云服务器 用钉钉或者支付宝app扫码注册新用户&#xff…

PyTorch 2.2 中文官方教程(六)

音频 音频 I/O pytorch.org/tutorials/beginner/audio_io_tutorial.html 此教程已移至pytorch.org/audio/stable/tutorials/audio_io_tutorial.html 3 秒后将重定向。 音频重采样 原文&#xff1a;pytorch.org/tutorials/beginner/audio_resampling_tutorial.html 译者&…

02.04

1.信号 include "myhead.h" //定义信号处理函数 void handler(int signo) {if(signo SIGINT){printf("用户按下了ctrl c键&#xff0c;hello world\n");} }int main(int argc, const char *argv[]) {if(signal(SIGINT, handler) SIG_ERR){perror("…

动态颗粒背景,适合VUE、HTML前端显示

动态颗粒背景&#xff0c;适合做背景使用&#xff0c;VUE、HTML前端显示直接看效果 废话不多说直接上代码&#xff1b; 一、html 代码部分 <template><div id"login"><div class"container"><div class"login-form"&g…

Vue中keep-alive的作用、原理及应用场景

在进行Vue开发的过程中&#xff0c;我们经常会遇到需要进行组件缓存的场景&#xff0c;这时候Vue提供的keep-alive组件就派上了用场。keep-alive组件是Vue内置的一个抽象组件&#xff0c;它可以将其包裹的组件进行缓存&#xff0c;提高组件的性能&#xff0c;同时也可以节省服务…

第二届 N1CTF Junior WEB方向 部分题解WP

zako 题目描述&#xff1a;很简单的rce哦 启动环境&#xff0c;源码直接给了。 execute.sh #!/bin/bashreject(){echo ${1}exit 1 }XXXCMD$1awk -v str"${XXXCMD}" \ BEGIN{deny";&$(){}[]!#$%^&*-";for(i 1; i < length(str); i){char su…

Open CASCADE学习|分割曲线

1、通过参数进行分割 分别获得曲线的 FirstParameter 和 LastParameter &#xff0c;然后对参数进行分割&#xff0c;获得n个ui&#xff0c;并对每个ui调用D0&#xff08;获得这个点的坐标值&#xff09;或D1&#xff08;获得这个点的坐标值和切向量&#xff09;。这个方法的优…

《图像处理》 图像细化

前言 图像细化算法又称之为Thinning Algorithms&#xff0c;或者骨架提取&#xff08;skeleton&#xff09;。该算法通常用于手写体数字的细化&#xff0c;输入的图像要求是黑白图像&#xff0c;即二值图像。从白色区域提取出该区域的中心线&#xff0c;中心线对于白色区域相当…

编译原理本科课程 专题5 基于 SLR(1)分析的语义分析及中间代码生成程序设计

一、程序功能描述 本程序由C/C编写&#xff0c;实现了赋值语句语法制导生成四元式&#xff0c;并完成了语法分析和语义分析过程。 以专题 1 词法分析程序的输出为语法分析的输入&#xff0c;完成以下描述赋值语句 SLR(1)文法的语义分析及中间代码四元式的过程&#xff0c;实现…

开源节点框架STNodeEditor使用

节点&#xff0c;一般都为树形Tree结构&#xff0c;如TreeNode&#xff0c;XmlNode。 树形结构有其关键属性Parent【父节点】&#xff0c;Children【子节点】 LinkedListNode为链表线性结构&#xff0c;有其关键属性Next【下一个】&#xff0c;Previous【上一个】&#xff0c…

1978-2022年人民币汇率(年平均价)数据

1978-2022年人民币汇率&#xff08;年平均价&#xff09;数据 1、时间&#xff1a;1978-2022年&#xff0c;其中人民币对欧元汇率时间为2002-2022年 2、指标&#xff1a;人民币对美元汇率(美元100)(元)、人民币对日元汇率(日元100)(元)、人民币对港元汇率(港元100)(元)、人民…