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

linux gcc

一、常用编译选项

  1. 基本编译
    gcc [input].c -o [output]
    示例

    gcc hello.c -o hello  # 将 hello.c 编译为可执行文件 hello
    ./hello               # 运行程序
  2. 分步编译

    • 预处理:-E(生成 .i 文件)
      gcc -E hello.c -o hello.i
    • 编译为汇编:-S(生成 .s 文件)
      gcc -S hello.i -o hello.s
    • 汇编为目标文件:-c(生成 .o 文件)
      gcc -c hello.s -o hello.o
    • 链接为可执行文件:
      gcc hello.o -o hello
  3. 调试信息
    -g 选项生成带调试信息的文件(供 GDB 使用):

    gcc -g test.c -o test_debug
  4. 优化选项
    -O1-O2-O3 表示优化级别(-O2 最常用):

    gcc -O2 main.c -o optimized_program
  5. 警告选项

    • -Wall 启用所有常见警告
    • -Werror 将警告视为错误
    gcc -Wall -Werror strict_code.c -o strict_program
  6. 链接库文件

    • -l 指定库名(如数学库 -lm
    • -L 指定库文件路径
    gcc calc.c -lm -L/usr/local/lib -o calc

二、示例场景

1. 编译多文件项目
# 编译两个文件并链接
gcc main.c utils.c -o app
2. 生成静态库
# 1. 编译为 .o 文件
gcc -c mylib.c -o mylib.o
# 2. 打包为静态库
ar rcs libmylib.a mylib.o
# 3. 使用静态库
gcc main.c -L. -lmylib -o static_app
3. 生成动态库(共享库)
# 1. 编译为位置无关代码(-fPIC)
gcc -fPIC -c mylib.c -o mylib.o
# 2. 生成动态库(-shared)
gcc -shared mylib.o -o libmylib.so
# 3. 使用动态库(需设置库路径)
gcc main.c -L. -lmylib -o dynamic_app
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH  # 临时添加库路径

三、C语言是如何编译的

1. 预处理

类比:准备食材

想象你在做一道复杂的菜,首先你需要把所有的食材准备好,比如切菜、洗菜、调味等。预处理阶段就像是这个准备食材的过程。

具体过程

预处理器(cpp)会处理源代码文件中的预处理指令,比如 #include#define 和 #ifdef 等。它会将这些指令替换成实际的代码或数据。

  • #include​:将指定的头文件内容插入到当前文件中。
  • #define​:定义宏,替换代码中的宏定义。
  • #ifdef / #ifndef​:条件编译,根据条件决定是否包含某段代码。

示例

#include <stdio.h>
#define PI 3.14159int main() {printf("The value of PI is %f", PI);return 0;
}

预处理后,#include <stdio.h> 会被替换成 stdio.h 文件的内容,PI 会被替换成 3.14159

2. 编译

类比:编写食谱

现在你已经准备好了食材,接下来你需要编写一个详细的食谱,告诉厨师每一步该怎么做。编译阶段就像是这个编写食谱的过程。

具体过程

编译器(gcc)会将预处理后的源代码转换成汇编代码。这个过程会检查语法错误、类型检查等。

  • ​语法检查​​:确保代码符合C语言的语法规则。
  • ​类型检查​​:确保变量和函数的类型使用正确。

示例

预处理后的代码会被编译成类似以下的汇编代码(具体内容取决于编译器和平台):

main:push    rbpmov     rbp, rspsub     rsp, 16mov     edi, OFFSET FLAT:.LC0call    puts@PLTmov     eax, 0leaveret

3. 汇编

类比:将食谱翻译成操作步骤

现在你已经有了详细的食谱,接下来需要将这些食谱翻译成具体的操作步骤,让厨师可以一步步执行。汇编阶段就像是这个翻译过程。

具体过程

汇编器(as)会将汇编代码转换成机器码,生成目标文件(.o 文件)。这个过程不会进行任何优化,只是简单地将汇编指令转换成机器码。

示例

上面的汇编代码会被转换成机器码,生成一个目标文件 main.o

4. 链接

类比:将多个菜谱合并成一本完整的烹饪书

现在你已经有了每道菜的具体操作步骤,接下来需要将这些步骤合并成一本完整的烹饪书,确保所有的步骤和食材都能协调工作。链接阶段就像是这个合并过程。

具体过程

链接器(ld)会将多个目标文件和库文件合并成一个可执行文件。这个过程会解析所有的符号引用,确保每个函数和变量的调用都能找到正确的定义。

  • ​符号解析​​:确保每个函数和变量的调用都能找到正确的定义。
  • ​重定位​​:将符号的地址修正为最终的内存地址。

假设你有两个源文件 main.c 和 utils.c,编译后会生成 main.o 和 utils.o。链接器会将这两个目标文件合并成一个可执行文件 program

总结

  1. ​预处理​​:准备食材,处理 #include#define 等指令。
  2. ​编译​​:编写食谱,将预处理后的代码转换成汇编代码。
  3. ​汇编​​:将食谱翻译成操作步骤,生成目标文件。
  4. ​链接​​:合并多个菜谱,生成最终的可执行文件。

5.函数库

静态库

定义​​:静态库是将一系列的目标文件(.o 文件)打包成一个单独的文件,在编译链接时,链接器会把静态库中被程序使用的代码直接复制到最终的可执行文件中。静态库的文件扩展名通常是 .a

静态连接在静态连接中,编译器和链接器在编译阶段就把程序所需要使用的库代码(静态库)直接合并到最终生成的可执行文件中。

  • ​创建静态库​​:首先要有多个目标文件。假设我们有两个源文件 add.c 和 sub.c,分别实现加法和减法功能。
// add.c
int add(int a, int b) {return a + b;
}// sub.c
int sub(int a, int b) {return a - b;
}

使用 `gcc` 编译这两个源文件生成目标文件:

gcc -c add.c sub.c

然后使用 `ar` 工具创建静态库:

ar rcs libmath.a add.o sub.o

这里 ar 是归档工具,r 表示将目标文件插入到归档文件中,c 表示如果归档文件不存在则创建它,s 表示写入一个目标文件索引。

 这样来使用静态库

gcc main.c -L. -lmath -o main

-L. 表示在当前目录下查找库文件,-lmath 表示链接名为 libmath.a 的静态库(注意,-l 后面跟的是库名去掉 lib 前缀和 .a 后缀)。 

优点
  • ​独立性​​:可执行文件包含了静态库的所有代码,不依赖外部的库文件,移植方便。
  • ​性能​​:由于代码已经直接嵌入到可执行文件中,运行时不需要额外的加载时间,执行效率较高。
缺点
  • ​文件体积大​​:每个使用静态库的可执行文件都会包含一份库代码的副本,会导致可执行文件体积变大。
  • ​更新困难​​:如果静态库有更新,所有使用该库的可执行文件都需要重新编译链接。
动态库

定义​​:动态库是在程序运行时才被加载到内存中供程序使用的库。多个程序可以共享同一个动态库的内存副本。是C/C++或者其他第三方软件提供的所有方法的集合,被所有程序以链接的方式关联起来。动态库的文件扩展名通常是 .so

动态链接在动态连接中,编译阶段只是记录程序需要使用哪些动态库(.so 文件),然后再需要时加载,并不会把库代码复制到可执行文件中。

  • 创建动态库​​:同样使用之前的 add.c 和 sub.c 源文件,先编译成目标文件:
gcc -c -fPIC add.c sub.c

-fPIC 表示生成位置无关代码,这是创建动态库所必需的。
使用 gcc 创建动态库:

gcc -shared -o libmath.so add.o sub.o

-shared 表示生成共享库。

​使用动态库​​:

gcc main.c -L. -lmath -o main

编译命令和静态库类似,但在运行可执行文件时,需要确保系统能找到动态库。可以通过设置 LD_LIBRARY_PATH 环境变量来指定动态库的搜索路径:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./main
优点
  • ​节省内存​​:多个程序可以共享同一个动态库的内存副本,减少了内存的使用。
  • ​更新方便​​:如果动态库有更新,只需要替换动态库文件,不需要重新编译使用该库的所有程序。
缺点
  • ​依赖问题​​:可执行文件依赖于外部的动态库文件,如果动态库文件丢失或版本不兼容,程序可能无法正常运行。
  • ​加载时间​​:程序运行时需要加载动态库,会有一定的加载时间开销。

 

注意:linux系统中认为后缀无意义,但不是代表gcc认为后缀无意义,也就是说我们后缀不对的话gcc编译会出错的。

相关文章:

linux gcc

一、常用编译选项 ​基本编译 gcc [input].c -o [output] ​示例&#xff1a; gcc hello.c -o hello # 将 hello.c 编译为可执行文件 hello ./hello # 运行程序 ​分步编译 预处理&#xff1a;-E&#xff08;生成 .i 文件&#xff09; gcc -E hello.c -o hello…...

无限滚动(Infinite Scroll)页面谷歌不收录!必须改回分页吗?

近三年&#xff0c;全球超过58%的网站采用无限滚动设计&#xff08;数据来源&#xff1a;PageTraffic 2023&#xff09; 谷歌官方数据显示&#xff0c;动态加载内容的索引失败率高达73%&#xff08;Google Webmaster Report 2022&#xff09;&#xff0c;而采用纯无限滚动的页…...

出现次数超过一半的数(信息学奥赛一本通-1186)

【题目描述】 给出一个含有n&#xff08;0 < n < 1000&#xff09;个整数的数组&#xff0c;请找出其中出现次数超过一半的数。数组中的数大于-50且小于50。 【输入】 第一行包含一个整数n&#xff0c;表示数组大小&#xff1b; 第二行包含n个整数&#xff0c;分别是数组…...

Git相关笔记1 - 本地文件上传远程仓库

Git相关笔记 目录 Git相关笔记Git上传相关文件第一步创建一个仓库&#xff1a;第二步本地创建空文件夹&#xff1a;第三步开始在gitbush上传文件&#xff1a;解决外网网络连接的问题&#xff1a;中文文件的编码问题&#xff1a;参考资料 Git上传相关文件 第一步创建一个仓库&a…...

Linux_4

开始学习ssh工具 在做开发的时候,肯定不止一台服务器,那么假设每台服务器都是Linux服务器,要在服务器上操作就需要登入终端,即Terminal。ssh的作用就是可以通过一个服务器登陆上其他的服务器。 登陆到哪个服务器看到的就是哪个服务器的终端terminal。 ssh登陆 ssh user@…...

如何计算财富自由所需要的价格?

写在前面&#xff1a;​【财富自由计算器】已上线&#xff0c;快算算财富自由要多少​ 多少钱&#xff0c;才能实现你的财富梦想&#xff1f; 需要多少&#xff0c;才能实现财务安全、财务独立&#xff0c;甚至财务自由&#xff1f; 看到结尾&#xff0c;你会很清楚地看到&…...

thinkphp每条一级栏目中可自定义添加多条二级栏目,每条二级栏目包含多个字段信息

小程序客户端需要展示团购详情这种结构的内容,后台会新增多条套餐,每条套餐可以新增多条菜品信息,每条菜品信息包含菜品名称,价格,份数等字段信息,类似于购物网的商品多规格属性,数据表中以json类型存储,手写了一个后台添加和编辑的demo 添加页面 编辑页面(json数据…...

Perl语言的文件系统

Perl语言中的文件系统操作 引言 在软件开发中&#xff0c;文件系统操作是一个不可或缺的部分。无论是简单的文件读取、写入&#xff0c;还是复杂的文件管理&#xff0c;合理的文件系统操作都能极大提升程序的效率和可维护性。Perl语言是一种强大的文本处理语言&#xff0c;凭…...

深入解析ARM与RISC-V架构的Bring-up核心流程

深入解析ARM与RISC-V架构的Bring-up核心流程 作者&#xff1a;嵌入式架构探索者 | 2023年10月 引言 在嵌入式开发中&#xff0c;处理器的Bring-up&#xff08;启动初始化&#xff09;是系统运行的第一道门槛。ARM和RISC-V作为两大主流架构&#xff0c;其Bring-up流程既有共性…...

关于UDP端口扫描概述

尽管互联网上大多数流行服务都基于 TCP 协议运行&#xff0c;但 UDP 服务也广泛部署。DNS、SNMP 和 DHCP&#xff08;注册端口 53、161/162 和 67/68&#xff09;是最常见的服务之一。 由于 UDP 扫描通常比 TCP 扫描更慢、更困难&#xff0c;一些安全审计人员可能会忽略这些端…...

C语言的操作系统

C语言的操作系统 引言 操作系统是一种系统软件&#xff0c;它管理计算机硬件和软件资源&#xff0c;并为计算机程序提供公共服务。在现代计算机科学中&#xff0c;操作系统是不可或缺的组成部分&#xff0c;而C语言则是实现高效操作系统的主要编程语言之一。本文将探讨C语言在…...

洛谷题单3-P5725 【深基4.习8】求三角形-python-流程图重构

题目描述 模仿例题&#xff0c;打印出不同方向的正方形&#xff0c;然后打印三角形矩阵。中间有个空行。 输入格式 输入矩阵的规模&#xff0c;不超过 9 9 9。 输出格式 输出矩形和正方形 输入输出样例 输入 4输出 01020304 05060708 09101112 13141516010203040506 …...

Lettuce与Springboot集成使用

一、Lettuce核心优势与Spring Boot集成背景 Lettuce特性 基于Netty的非阻塞I/O模型&#xff0c;支持同步/异步/响应式编程线程安全&#xff1a;共享单连接实现多线程并发操作&#xff0c;性能衰减低原生支持Redis集群、哨兵、主从架构&#xff0c;自动重连机制保障高可用Spring…...

C# 类库生成后自动复制到指定目录

C# 类库生成后自动复制到指定目录 在C#中,当你开发了一个类库项目(通常是.NET Core或.NET Framework项目),你可能会希望在构建(Build)完成后自动将生成的DLL文件复制到指定的目录。有几种方法可以实现这个需求,下面是一些常用的方法: 方法1:使用MSBuild的AfterBuild…...

《系统分析师-基础篇-1-6章总结》

第1章 绪论 系统分析师角色 职责&#xff1a;需求分析、系统设计、项目管理、技术协调。 能力要求&#xff1a;技术深度&#xff08;架构设计、开发方法&#xff09; 业务理解&#xff08;企业流程、行业知识&#xff09; 沟通能力。 系统开发生命周期 传统模型&#xf…...

一个完整的 HTTP/HTTPS 请求流程

HTTP 一个完整的 HTTP 请求流程可以分为以下几个步骤&#xff1a; 1. DNS 解析 当客户端&#xff08;通常是浏览器&#xff09;输入 URL&#xff08;例如 https://www.example.com&#xff09;时&#xff0c;它首先需要解析出对应的 IP 地址。这个过程涉及 DNS&#xff08;域…...

go游戏后端开发25:红中麻将规则介绍

一、游戏基础规则介绍 在开发红中麻将游戏之前&#xff0c;我们需要先了解其基础规则。红中麻将的牌面由 a、b、c、d 四种花色组成&#xff0c;其中 a、b、c 分别代表万、条、筒&#xff0c;每种花色都有 1 - 9 的九种牌&#xff0c;每种牌各有四张&#xff0c;总计 36 张 4 …...

【YOLO系列(V5-V12)通用数据集-电梯内电动车检测数据集】

YOLO格式的电梯内电动车检测数据集&#xff0c;适用于YOLOv5-v11所有版本&#xff0c;可以用于本科毕设、发paper、做课设等等&#xff0c;有需要的在这里获取&#xff1a; 电梯内电动车检测数据集 数据集专栏地址&#xff1a;https://blog.csdn.net/qq_41304809/category_1290…...

Python每日一题(15)

Python每日一题2025.4.4 一、题目题目描述输入格式输出格式输入输出样例 #1输入 #1输出 #1 二、分析三、源代码四、deepseek 一、题目 题目描述 您需要写一种数据结构&#xff0c;来维护一些数&#xff08;都是绝对值 1 0 9 10^9 109 以内的数&#xff09;的集合&#xff0c…...

算法题(114):矩阵距离

审题&#xff1a; 本题需要我们找出所有0距离最近的1的曼哈顿距离 思路&#xff1a; 方法一&#xff1a;多源bfs 分析曼哈顿距离&#xff1a; 求法1&#xff1a;公式法&#xff0c;带入题目公式&#xff0c;利用|x1-x2||y1-y2|求出 求法2&#xff1a;曼哈顿距离就是最短距离 本…...

0102-web架构网站搭建-基础入门-网络安全

文章目录 1. 常规2 站库分离3 前后端分离4 集成环境5 docker6 分配站结语 1. 常规 结构&#xff1a;源码数据都在同服务器 影响&#xff1a;无&#xff0c;常规安全测试手法 2 站库分离 结构&#xff1a;源码和数据库不在同服务器 存储&#xff1a;其他服务器上数据库或者…...

Linux系统编程:进程管理、内存对比与树莓派应用

一、认识进程和线程&#xff0c;在Linux系统下查看系统中各进程的编号pid并终止一个进程pid 1.进程和线程 ​​进程​​&#xff1a;操作系统分配资源&#xff08;如内存、CPU时间片&#xff09;的基本单位。每个进程有独立的内存空间&#xff0c;进程间通信需要较复杂的机制…...

ue5 仿鬼泣5魂类游戏角色和敌人没有碰撞

UE5系列文章目录 文章目录 UE5系列文章目录前言一、问题原因二、设置碰撞2.读入数据 总结 前言 ue5 仿鬼泣5魂类游戏角色和敌人没有碰撞 一、问题原因 在UE5中&#xff0c;角色和敌人没有碰撞可能是由多种原因导致的&#xff0c;以下是一些可能的原因及解决方法&#xff1a…...

基于Flask的MBA考生成绩查询系统设计与实现

基于Flask的MBA考生成绩查询系统设计与实现 序言 2024年吉林大学MBA在职研究生考试成绩公布后&#xff0c;考生收到的成绩单为PDF格式文档。为方便考生快速查询个人成绩及排名信息&#xff0c;笔者基于Python Flask框架开发了本查询系统。该系统支持关键词模糊查询、序号范围…...

GATT(Generic Attribute Profile)是蓝牙低功耗(Bluetooth Low Energy,简称BLE)协议栈中的一个核心协议

蓝牙的 GATT&#xff08;Generic Attribute Profile&#xff09; 是蓝牙低功耗&#xff08;Bluetooth Low Energy&#xff0c;简称BLE&#xff09;协议栈中的一个核心协议&#xff0c;用于定义设备如何通过蓝牙进行数据传输和交互。GATT 是基于 ATT&#xff08;Attribute Proto…...

DHCP之报文格式

字段说明&#xff1a; op (op code): 表示报文的类型&#xff0c;取值为 1 或 2&#xff0c;含义如下 1:客户端请求报 2:服务器响应报文 Secs (seconds):由客户端填充&#xff0c;表示从客户端开始获得 IP 地址或 IP 地址续借后所使用了的秒数&#xff0c;缺省值为 3600s。 F…...

React 文件上传新玩法:Aliyun OSS 加持的智能上传组件

文件上传是前端开发中的“老朋友”&#xff0c;但如何让它既简单又强大&#xff0c;还能无缝对接云端存储&#xff1f;今天&#xff0c;我要带你认识一个超酷的 React 组件 AliUploader&#xff0c;它不仅支持拖拽上传、批量编辑和文件排序&#xff0c;还直接把文件传到 Aliyun…...

群体智能优化算法-变色龙优化算法(Chameleon Swarm Algorithm, CSA,含Matlab源代码)

摘要 变色龙优化算法&#xff08;Chameleon Swarm Algorithm, CSA&#xff09;是一种受变色龙行为启发的群体智能优化算法。该算法模拟了变色龙在自然界中通过变换颜色来适应环境的能力&#xff0c;以此为基础&#xff0c;设计了一个适应性强、搜索能力广泛的优化算法。CSA 通…...

使用 React 和 Konva 实现一个在线画板组件

文章目录 一、前言二、Konva.js 介绍三、创建 React 画板项目3.1 安装依赖3.2 创建 CanvasBoard 组件 四、增加画布控制功能4.1 清空画布4.2 撤销 & 重做功能 五、增加颜色和画笔大小选择5.1 选择颜色5.2 选择画笔大小 六、最终效果七、总结 一、前言 在线画板是许多应用&…...

GitHub高级筛选小白使用手册

GitHub高级筛选小白使用手册 GitHub 提供了强大的搜索功能&#xff0c;允许用户通过高级筛选器来精确查找仓库、Issues、Pull Requests、代码等。下面是一些常用的高级筛选用法&#xff0c;帮助你更高效地使用 GitHub 搜索功能。 目录 搜索仓库搜索Issues搜索Pull Requests搜…...