【Linux】工具GCC G++编译器轻度使用(C++)

news2025/1/21 15:33:58

目录

一、关联知识背景

二、GCC如何的编译过程

【2.1】预处理(进行宏替换)

【2.2】编译(生成汇编)

【2.3】连接(生成可执行文件或库文件)

三、GCC命令的常用选项

四、动静态链接


一、关联知识背景

gccg++ 分别是 gnuc & c++ 编译器 gcc/g++ 在执行编译工作的时候,总共需要4步:

  • 预处理,生成 .i 的文件[预处理器cpp]

  • 将预处理后的文件转换成汇编语言, 生成文件 .s [编译器egcs]

  • 有汇编变为目标代码(机器代码)生成 .o 的文件[汇编器as]

  • 连接目标代码, 生成可执行程序 [链接器ld]

>>预处理(进行宏替换) >>编译(生成汇编)  >>汇编(生成机器可识别代码) >>连接(生成可执行文件或库文件) 

测试代码如下:

#include <stdio.h>

// 宏定义
#define M 1234
int main(){
    // 注释:
    // 我是注释。                                                                             
    printf("Hello World\n");
    printf("Hello World\n");
    printf("Hello World\n");
    printf("Hello World\n");
    printf("Hello World\n");
    printf("Hello World\n");
    printf("Hello World\n");

#ifdef SHOW 
    printf("Hollo Show\n");
#else
    printf("Hollo Default\n");
#endif
    printf("宏:%d\n", M);
    return 0;
}

【不编译宏定义】

gcc main.c -o execute
// 执行结果:
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hollo Default
宏:1234

【编译宏定义】

gcc main.c -o execute -DSHOW
// 执行结果:
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hollo Show
宏:1234

二、GCC如何的编译过程

【2.1】预处理(进行宏替换)

>> 指令:gcc -E main.c -o main.i
  • 预处理功能主要包括宏定义,文件包含,条件编译,去注释等 。

  • 预处理指令是以#号开头的代码行 。

  • 选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。

  • 选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序

【2.2】编译(生成汇编)

>> 指令:gcc –S main.i –o main.s
  • 在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。

  • 用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。

【2.3】连接(生成可执行文件或库文件)

上面的三步只是在编译代码,需要把代码和c标准库的代码链接起来,代码才能执行,这个过程叫做链接。

>> 指令:gcc main.o –o myMain
// 查看结构
[shaxiang@VM-8-14-centos lesson]$ ls
main.c  main.i  main.o  main.s
// 生成可执行
[shaxiang@VM-8-14-centos lesson]$ gcc main.o -o myMain
[shaxiang@VM-8-14-centos lesson]$ ./myMain 
// main.c 源文件  main.i 预编译文件  main.s 编译文件  main.o 汇编文件  myMain 可执行文件
main.c  main.i  main.o  main.s  myMain
// 执行结果
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hollo Default
宏:1234

三、GCC命令的常用选项

选项解释
-ansi只支持 ANSI 标准的 C 语法。这一选项将禁止 GNU C 的某些特色, 例如 asm 或 typeof 关键词。
-c只编译并生成目标文件。
-DMACRO以字符串"1"定义 MACRO 宏。
-DMACRO=DEFN以字符串"DEFN"定义 MACRO 宏。
-E只运行 C 预编译器。
-g生成调试信息。GNU 调试器可利用该信息。
-IDIRECTORY指定额外的头文件搜索路径DIRECTORY。
-LDIRECTORY指定额外的函数库搜索路径DIRECTORY。
-lLIBRARY连接时搜索指定的函数库LIBRARY。
-m486针对 486 进行代码优化。
-o FILE生成指定的输出文件。用在生成可执行文件时。
-O0不进行优化处理。
-O 或 -O1优化生成代码。
-O2进一步优化。
-O3比 -O2 更进一步优化,包括 inline 函数。
-shared生成共享目标文件。通常用在建立共享库时。
-static禁止使用共享连接。
-UMACRO取消对 MACRO 宏的定义。
-w不生成任何警告信息。
-Wall生成所有警告信息。

四、动静态链接

        我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?

        最后的答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。

函数库一般分为静态库和动态库两种:

  • 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”。

  • 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件。

gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证。

file myMain     // 查看可执行文件的详细信息.
ldd myMain      // 查看可执行文件以来的动态库文件.

                在Linux环境下大多指令都是以来动态库的,所以说动态库很重要!

>> 命令:file /usr/bin/ls
>> 命令:file /usr/bin/pwd
>> 命令:file /usr/bin/which
>> 命令:ldd /usr/bin/ls

        在Linux下编译代码默认使用的就是动态链接库,那能不能用静态库进行编译呢?

>> 命令:gcc main.c -o myMain_s -static

一般来说静态库是需要自己安装的,这里列出静态库的安装方式:

  • 查看libc.a是否已经安装

>> 命令:sudo find / -name 'libc.a'  
  • 系统安装静态库

// centos系列安装
>> 命令:sudo yum install glibc-static   		// 安装C语言静态库
>> 命令:sudo yum install libstdc++-static   	// 安装C++语言静态库
// ubuntu系列安装
>> 命令:sudo apt-get install libc6-dev  
    
// 安装完成后,再次查看静态库
[shaxiang@VM-8-14-centos ~]$ sudo find / -name 'libc.a'
/usr/lib64/libc.a

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

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

相关文章

Leetcode 剑指 Offer II 043. 完全二叉树插入器

题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer&#xff08;专项突击版&#xff09;系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 完全二叉树是每一层&#xff08;除最后一层外&#xff09;都是完…

并发聊天服务器编写

并发聊天服务器 package mainimport ("fmt""net""strings""time" )// 结构体 type Client struct {C chan string //用户发送数据的管道Name string //用户名Addr string //网络地址 }// 保存在线用户 cliAddr -->cli…

Wireshark技巧[监听串口包]

监听串口包 本文摘录于&#xff1a;https://blog.csdn.net/qq_20405005/article/details/79652927只是做学习备份之用&#xff0c;绝无抄袭之意&#xff0c;有疑惑请联系本人&#xff01; 这里要保证安装了USBpcap: 打开USBpcap后一半都要输入过滤条件,否则USB太多数据了,比如…

输入验证在防止安全漏洞方面的重要性

在当今快速发展的数字环境中&#xff0c;技术推动创新和便利&#xff0c;确保我们数字资产的安全仍然是一个关键问题。创建强大的应用程序安全性的核心在于输入验证的基本且最重要的概念。 在这篇博文中&#xff0c;我们将介绍输​​入验证的重要性及其对加强我们的数字防御以…

python可视化模块—快速利用matplot绘制图表

文章目录 一、Matplotlib基本介绍二、两种绘图方式区别&#xff08;plt.*** 和ax.***&#xff09;三、如何使用Matplotlib绘图1、画布—绘画的画板2、配置—更个性化的绘图全局配置局部配置面向对象绘图过程&#xff1a;ax代表子图变量过程式绘图过程 四、常用绘图图形如何选择…

Java集合学习(2023年超详细)

java集合学习目录 一、基本概要0. 辅助工具类0.1 Collection 和 Collections 有什么区别&#xff1f;0.2 comparable 和 comparator的区别&#xff1f; 1.什么是集合2.集合的分类2.1 Collection接口2.2 Map接口 二、集合框架底层数据结构1. &#x1f60a;Collection1.1 ❤List1…

【数据结构】3000字剖析链表及双向链表

文章目录 &#x1f490; 链表的概念与结构&#x1f490;链表的介绍&#x1f490;链表的模拟实现 &#x1f490;双向链表&#x1f490;双向链表的模拟实现 &#x1f490;链表常用的方法&#x1f490;链表及顺序表的遍历&#x1f490;ArrayList和LinkedList的差异 &#x1f490; …

Python常用库(五):图像处理【Pillow】

1. Pillow 1.1 介绍 Pillow 是第三方开源的 Python 图像处理库&#xff0c;它支持多种图片格式&#xff0c;包括 BMP、GIF、JPEG、PNG、TIFF 等。Pillow 库包含了大量的图片处理函数和方法&#xff0c;可以进行图片的读取、显示、旋转、缩放、裁剪、转换等操作。在后续的深度学…

python开发基础篇2——登陆机制

文章目录 一、管理平台页面布局二、登录页面2.1 token登录2.2. kubeconfig登录2.3 添加装饰器 一、管理平台页面布局 应用名称&#xff1a; dashboard&#xff1a;存放公共 k8s&#xff1a; Node&#xff1a;K8s集群计算节点。Namespaces&#xff1a;命名空间&#xff0c;用于…

ABAP WS_DELIVERY_UPDATE 报错 BS013

在使用 WS_DELIVERY_UPDATE 创建内向交货单时 报错&#xff1a;System status ESTO is active (EQU ***) 可以用事务代码IE03--->历史去看下 你可以手动将它的状态去改回EDEL 或者 SLOR IE02--> Special serial no. functions --> Manual transaction.

C#,《小白学程序》第十七课:随机数(Random)第四,移动平均值(Moving Average)的计算方法与代码

1 文本格式 /// <summary> /// 《小白学程序》第十七课&#xff1a;随机数&#xff08;Random&#xff09;第四&#xff0c;移动平均值的计算方法与代码 /// 继续学习数据统计&#xff0c;移动平均值的计算方法 /// 移动平均值就是一定步长内数值的平均值&#xff0c;用…

Llama 2 论文《Llama 2: Open Foundation and Fine-Tuned Chat Models》阅读笔记

文章目录 Llama 2: Open Foundation and Fine-Tuned Chat Models1.简介2.预训练2.1 预训练数据2.2 训练详情2.3 LLAMA 2 预训练模型评估 3. 微调3.1 supervised Fine-Tuning(SFT)3.2 Reinforcement Learning with Human Feedback (RLHF)3.2.1 人类偏好数据收集3.2.2 奖励模型训…

Matlab 如何选择窗函数和 FFT 的长度

Matlab 如何选择窗函数和 FFT 的长度 1、常用的四种窗函数 对于实际信号序列&#xff0c;如何选取窗函数呢&#xff1f;一般来说&#xff0c;选择第一旁瓣衰减大&#xff0c;旁瓣峰值衰减快的窗函数有利于緩解截断过程中产生的頻泄漏问题。但具有这两个特性的窗函数&#xff0…

[BFS] 广度优先搜索

1. 数字操作 常见的模板 // 使用一个数组判断元素是否入过队 int inqueue[N] {0}; // 层数或者可以称为深度 int step 0; // 判断是否可以入队的条件 int isvalid(){ } BFS(int x){ // 将初始的元素压入队列 // 注意每次压队的时候都要将inque[x] 1,表明入队过…

python实现adb辅助点击屏幕工具

#!/usr/bin/env python # -*- coding: utf-8 -*-import re import os import time import subprocess import tkinter as tk from tkinter import messagebox from PIL import Image, ImageTk# 设置ADB路径&#xff08;根据你的系统和安装路径进行调整&#xff09; ADB_PATH C…

Ubuntu快速搭建内网NTP Server

文章目录 安装NTP服务配置NTP配置NTP 同步源配置NTP 允许客户端访问重启NTP服务使得配置生效 推荐阅读 NTP(Network Time Protocol)------网络时间协议-----应用层协议&#xff0c;用来在分布式时间服务器和客户端之间进行时间同步。 是对网络内所有具有时钟的设备进行时钟同步…

图解 LeetCode 算法汇总——链表

本文首发公众号&#xff1a;小码A梦 一般数据主要存储的形式主要有两种&#xff0c;一种是数组&#xff0c;一种是链表。数组是用来存储固定大小的同类型元素&#xff0c;存储在内存中是一片连续的空间。而链表就不同于数组。链表中的元素不是存储在内存中可以是不连续的空间。…

酒店类型的软文怎么写?

马上就放长假了&#xff0c;有不少酒店行业来找盒子做推广&#xff0c;其实酒店行业想要写好软文只要掌握三种类型就好了&#xff0c;今天就让盒子告诉大家酒店类型的软文怎么写才能吸引用户。 一、以故事打动用户 故事型软文大多用于民宿酒店&#xff0c;民宿酒店文案除了展现…

Docker认识即安装

Docker及相关概念 Docker和虚拟机方式的区别&#xff1a;虚拟机技术是虚拟出一套硬件后&#xff0c;在其上运行一个完整的操作系统&#xff0c;在该系统上在运行所需应用进程&#xff1b;而容器内的应用进程是直接运行于宿主的内核&#xff0c;容器内没有自己的内核&#xff0…

2023区块链应用操作员认证(4级)报名来弘博创新

区块链应用操作员&#xff0c;是指运用区块链技术及工具&#xff0c;从事政务、金融、医疗、教育、养老等场景系统应用操作的人员。 腾讯作为广东省第一批公布的社会培训评价组织&#xff0c;可开展职业技能等级认定职业(工种)区块链应用操作员(4-3-2-1级)。 证书含金量 证书是…