当前位置: 首页 > news >正文

Linux的编译器

程序编译的过程

程序的编译过程是将源代码转换为可执行文件的一系列步骤。这个过程涉及多个阶段,主要包括预处理、编译、汇编和链接。下面详细介绍每个阶段:

1. 预处理(Preprocessing)

在实际编译之前,源代码文件首先经过预处理器处理。预处理阶段主要处理那些以井号(#)开头的指令,如宏定义(#define)、文件包含(#include)等。预处理器执行的任务包括:

  • 宏展开:将所有的宏定义替换为相应的值。
  • 文件包含:将包含指令(#include)指定的文件内容插入到源代码文件中。
  • 条件编译:根据特定的条件编译指令,决定是否编译代码的特定部分。
  • 移除注释:从源代码中移除所有注释。

2. 编译(Compilation)

预处理后的代码(现在是纯文本)被送到编译器,编译器将其转换成汇编代码。编译阶段的主要任务是:

  • 语法分析:检查代码是否符合语言的语法规则。
  • 语义分析:检查代码中的表达式和语句是否有意义(比如类型检查)。
  • 生成中间代码:生成一种更接近机器语言的中间表示形式,通常是汇编语言。

3. 汇编(Assembly)

汇编器接收编译阶段生成的汇编代码,将其转换为机器码(二进制代码)。每一条汇编指令几乎直接对应一条机器指令。生成的输出通常是目标文件(.o 或 .obj 文件),这些文件包含了程序的机器语言表示。

4. 链接(Linking)

程序通常由多个源代码文件组成,这些文件需要被单独编译和汇编。链接器的任务是将一个或多个目标文件合并成一个单一的可执行文件。在链接过程中,链接器还会解决程序中各个部分之间的引用和依赖问题,例如:

  • 解析外部引用:处理程序不同部分或外部库之间的调用关系。
  • 地址绑定:确定程序和数据在内存中的位置。
  • 库链接:将程序需要的库(动态链接库或静态库)合并到最终的可执行文件中。

完整的流程图

源代码 -> [预处理] -> 预处理后的代码 -> [编译] -> 汇编代码 -> [汇编] -> 目标代码 -> [链接] -> 可执行文件

这个过程是高度自动化的,通常由构建系统(如 Makefiles、CMake 等)控制,它会根据需要执行上述所有步骤,生成最终的可执行程序。每个阶段都有专门的工具和软件来执行,比如 GCC 或 Clang(在 C/C++ 开发中)等。

语言自举的过程

语言自举(Bootstrapping a language)是一种使用编程语言的编译器或解释器来编写该语言本身的编译器或解释器的过程。简而言之,这意味着用一种语言编写该语言自身的编译器或解释器。这个过程中,该语言的初期版本通常是用另一种语言编写的,而后续版本则可能完全或部分使用该语言自身来进行重写或优化。

自举过程的步骤

  1. 初始实现:在最开始,编程语言的编译器或解释器通常用另一种已存在的语言编写。这样做是因为初始的编程语言还没有足够的工具和支持来自我编译。

  2. 自我编译:当这种新语言发展到足够成熟,可以支持更复杂的功能时,开发者会使用这种语言自身来重写其编译器或解释器。这意味着新语言现在可以编译自己的编译器,这通常被看作是一种成熟的标志。

  3. 优化和扩展:一旦编译器可以用其自身的语言成功编译,开发者就可以继续使用该语言来优化和扩展编译器的功能。这可能包括添加新的语言特性、优化性能或改进错误处理。

  4. 迭代改进:随着时间的推移,编译器可以不断通过自身来进行迭代改进和更新,这增强了其功能和效率,并可以支持新的编程范式或标准。

自举的优势

  • 独立性:自举减少了对其他编程语言的依赖,使得编程语言及其工具链更加独立。
  • 演示能力:使用一种语言编写其自身的编译器是对该语言功能强大和成熟度的展示。
  • 自我验证:自举过程可以作为一种验证手段,证明语言足够强大,能够处理复杂的编程任务,如编写和处理编译器代码。

自举的例子

  • C语言:C语言最初的编译器是用汇编语言编写的,但很快之后,C的编译器就开始用C语言本身来编写,这是最著名的自举案例之一。
  • Pascal:Niklaus Wirth 设计的 Pascal 语言也是先用其他语言编写了编译器,后来用 Pascal 自身重写。
  • Rust:Rust 语言最初的编译器是用 OCaml 编写的,现在的 Rust 编译器(rustc)主要用 Rust 本身编写。

gcc / g++

GCC(GNU Compiler Collection)是一个开源的编译器套件,支持多种编程语言,其中最为人熟知的是 C 和 C++(通过 G++ 编译器)。GCC 是在自由软件基金会(FSF)的 GNU 项目下开发的,旨在提供一个标准的、高性能、高可靠性的编译器,它在开源和自由软件开发中占有非常重要的地位。

  1. 多语言支持:GCC 最初是作为一个 C 语言编译器开始的,但后来扩展到支持多种语言,包括 C++(G++)、Objective-C、Fortran、Ada、Go,以及 Java 等。

  2. 跨平台:GCC 可以在多种类型的操作系统上运行,包括 Linux、Mac OS、Windows(通常通过 MinGW 或 Cygwin)等,支持广泛的架构,如 x86、x64、ARM、PowerPC 等。

  3. 代码优化:GCC 提供了多种级别的优化选项,可以帮助开发者提高程序的执行效率。从 -O0(无优化)到 -O3(最大优化),还有 -Os(优化空间)和 -Ofast(忽略严格标准的最快速优化)。

  4. 标准遵从:GCC 高度遵循各个编程语言的标准,如 ISO C、C++,并定期更新以支持最新的语言标准。

  5. 调试和错误报告:GCC 提供详细的错误和警告消息,帮助开发者诊断代码问题。配合 GDB(GNU Debugger)使用,可以有效地进行代码调试。

  6. 扩展性:GCC 也支持内联汇编,允许开发者插入架构特定的汇编代码来优化程序,同时支持自定义的编译器插件。

G++ 是 GCC 中的 C++ 编译器,支持 C++ 的所有标准特性,包括最新的 C++20 标准。G++ 不仅能够编译复杂的 C++ 应用程序和库,还支持异常处理、模板编程等现代 C++ 特性。

动态库&&静态库

静态库和动态库是在软件开发中用来实现代码重用和模块化的两种不同类型的库。它们主要的区别在于它们如何被集成和使用在应用程序中。

静态库

静态库是一种在程序编译时期就已经被包含进程序的库。它们通常包含一组编译好的代码,这些代码可以直接链接到最终的可执行文件中。

  • 集成方式:在编译阶段,静态库中的代码被复制到最终的可执行文件中。这个过程是由链接器完成的,链接器将程序中用到的静态库中的对象文件直接集成到程序的可执行文件中。
  • 部署和分发:由于静态库的内容已经被集成到可执行文件中,所以这些程序在分发时不需要附带这些库文件。可执行文件本身就包含了所有必要的代码。

动态库

动态库是一种在程序运行时才加载的库。它们的代码在程序运行时被载入内存,并通过操作系统进行管理。

  • 集成方式:动态库并不是在编译时被包含进可执行文件,而是在程序运行时由操作系统动态地加载。程序在运行时会请求操作系统加载所需的库,并将其链接到正在运行的程序中。
  • 部署和分发:因为动态库不是程序的一部分,所以在分发这些程序时,需要确保动态库可以在目标系统上被访问。通常,动态库需要与程序一起分发,或者确保目标系统已经安装了相应的库。

区别

  • 链接时期:静态库在编译时被集成,动态库在运行时被加载。
  • 体积影响:使用静态库的程序通常体积更大,因为所有需要的库代码都被包含在内;使用动态库的程序体积更小,但需要在运行环境中有对应的库。
  • 运行依赖:静态库的程序运行时不依赖外部库文件,而动态库的程序需要在运行时环境中访问这些库。
  • 更新和维护:动态库更易于更新和维护,因为只需替换单个库文件即可影响所有使用该库的程序;静态库的更新需要重新编译和分发整个程序。

相关文章:

Linux的编译器

程序编译的过程 程序的编译过程是将源代码转换为可执行文件的一系列步骤。这个过程涉及多个阶段,主要包括预处理、编译、汇编和链接。下面详细介绍每个阶段: 1. 预处理(Preprocessing) 在实际编译之前,源代码文件首…...

redis--安装

简介 官网:RedisInsight - The Best Redis GUI 各个版本官网下载地址:http://download.redis.io/releases/ Redis和Memcached是非关系型数据库也称为NoSQL数据库,MySQL、Mariadb、SQL Server、PostgreSQL Oracle 数据库属于关系型数据 应用…...

魔法程序员的奥妙指南:Java基本语法

作为一名魔法程序员,精通Java语言是至关重要的。Java作为一种强大的编程语言,在编写优质代码和开发强大应用程序时发挥着重要作用。让我们深入探讨Java基本语法的关键要点,从注释到变量,无所不包! Java基本语法的神秘魔…...

SpringMVC传递参数

1.RequestMapping RequestMapping本身可以处理,get或post,指定了get或post之后,就只能处理对应的请求。 RequestMapping(value{"haihiyo","goodMoring"},methodRequestMethod.POST)2.RestFul风格 RestFul是一种风格 比如:网站的访…...

【Scala---04】函数式编程 『 函数 vs 方法 | 函数至简原则 | 函数式编程』

文章目录 1. 函数 vs 方法1.1 方法(1) 定义方法(2) 运算符即方法 1.2 函数(1) 定义函数(2) 匿名函数 1.3 方法转为函数1.4 可变参数&默认参数 2. 函数至简原则3. 函数式编程3.1 函数式编程思想3.3 函数柯里化&闭包3.5 递归 & 尾递归 4. 补充4.1 访问元祖元素4.2 &g…...

[华为OD] B卷 树状结构查询 200

题目: 通常使用多行的节点、父节点表示一棵树,比如 西安 陕西 陕西 中国 江西 中国 中国 亚洲 泰国 亚洲 输入一个节点之后,请打印出来树中他的所有下层节点 输入描述 第一行输入行数,下面是多行数据,每行以空…...

基于机器学习的学生学习行为自主评价设计与实现

管理员功能: a)学生学习数据管理:可查看学生学习的详情,编辑学生学习的内容,删除和添加学生学习,设置学生学习库存。 b)角色管理:增加删除学生用户,分配学生用户权限,查看学生用户…...

toml与json联系对比

前言 本文简单介绍toml;并且和json转化做对比,以及我对toml设计的理解。 参考: TOML: 简体中文 v1.0.0 json和toml转化工具 在线JSON转toml-toml转JSON - bejson在线工具 正文 数组 说白了,就是一个变量名,有多个…...

(已解决)org.springframework.amqp.rabbit.support.ListenerExecutionFailedException

报错截图 解决方案 1、登录rabbitMQ网址,删除所有队列 2、重启rabbitMQ 亲测有效!!!亲测有效!!!亲测有效!!!...

基于FPGA的数字信号处理(9)--定点数据的两种溢出处理模式:饱和(Saturate)和绕回(Wrap)

1、前言 在逻辑设计中,为了保证运算结果的正确性,常常需要对结果的位宽进行扩展。比如2个3bits的无符号数相加,只有将结果设定为4bits,才能保证结果一定是正确的。不然,某些情况如77 14(1110),如果结果只…...

基于STM32的宠物箱温度湿度监控系统毕业设计

基于STM32的宠物箱温度湿度监控系统毕业设计 一、项目背景与意义 随着人们生活水平的提高,养宠物已经成为一种流行趋势。然而,对于宠物的居住环境,尤其是温度与湿度的控制,是确保宠物健康的关键。本项目旨在设计一款基于STM32微…...

Linux sudo 指令

sudo命令 概念: sudo是linux下常用的允许普通用户使用超级用户权限的工具,允许系统管理员让普通用户执行一些或者全部的root命令,如halt,reboot,su等。这样不仅减少了root用户的登录和管理时间,同样也提高…...

【NumPy数组】:深入了解numpy.linspace()函数

一、numpy.linspace()函数的原理 numpy.linspace()函数的核心原理是在指定的起始值和终止值之间,按照给定的元素个数,生成等间隔的数值序列。与numpy.arange()函数不同,numpy.linspace()生成的是等间隔的数值,而不是等差的数值&a…...

计算机网络实验二:交换机的基本配置与操作

实验二:交换机的基本配置与操作 一、实验要求 (1)掌握windows网络参数的设置(TCP/IP协议的设置); (2)掌握交换机命令行各种操作模式的区别,以及模式之间的切换; (3)掌握交换机的全局的基本配置; (4)掌握交换机端口的常用配置参数; (5)查看交换机系统和…...

宏的优缺点?C++有哪些技术替代宏?(const)权限的平移、缩小

宏的优缺点? 优点: 1.增强代码的复用性。【减少冗余代码】 2.提高性能,提升代码运行效率。 缺点: 1.不方便调试宏。(因为预编译阶段进行了替换) 2.导致代码可读性差,可维护性差&#xff0…...

2024数维杯数学建模选题建议及各题思路来啦!

大家好呀,2024数维杯数学建模挑战赛开始了,来说一下初步的选题建议吧: 首先定下主基调, 本次数维杯建议选B。难度上C>A>B。B题目是比较经典的数据分析类题目,主要做统计分析差异显著性以及相关…...

centos的常用命令

CentOS是一个基于Red Hat Enterprise Linux(RHEL)的开源操作系统,常用于服务器环境。以下是一些CentOS中常用的命令: 文件和目录管理: ls:列出目录中的文件。 ls -l:以长格式列出文件和目录的…...

【Android】使用Handler实现一个定时器

需求 实现一个定时任务,每隔一秒执行一次 实现 使用Handler实现 private Handler topUIHandler;private void initTopUiHandler() {topUIHandler new Handler(getMainLooper()) {Overridepublic void handleMessage(Message msg) {//执行这个定时任务updateTop…...

Java | Leetcode Java题解之第80题删除有序数组中的重复项II

题目&#xff1a; 题解&#xff1a; class Solution {public int removeDuplicates(int[] nums) {int n nums.length;if (n < 2) {return n;}int slow 2, fast 2;while (fast < n) {if (nums[slow - 2] ! nums[fast]) {nums[slow] nums[fast];slow;}fast;}return sl…...

java后端15问!

前言 最近一位粉丝去面试一个中厂&#xff0c;Java后端。他说&#xff0c;好几道题答不上来&#xff0c;于是我帮忙整理了一波答案 G1收集器JVM内存划分对象进入老年代标志你在项目中用到的是哪种收集器&#xff0c;怎么调优的new对象的内存分布局部变量的内存分布Synchroniz…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...