【Linux03-基本工具之GCC】Linux下的C语言编译器

news/2024/11/7 18:36:39/

前言

接上篇,继续学习基本工具。

三、gcc

是什么

Linux下的C语言编译器(C++的编译器是g++,用法选项基本一样)。

既然是编译器,我们就再来加点餐……
在这里插入图片描述

链接其实分为两种类型:静态链接和动态链接,分别需要静态库和动态库。


加餐

动态链接

编译期间什么都不做,准备执行时,通过链接文件,将动态库载入内存。

  • 外部库变化影响程序
  • 可执行程序小

静态链接

编译期间把静态库的代码拷贝一份,编译完库就在可执行文件中。

  • 外部库变化不影响程序
  • 可执行程序大(重复包含更是十分冗余)

动态库

.so为后缀,程序准备运行时加载。

静态库

.a为后缀,程序编译时拷贝。

函数库名称

Linux下库的命名

动态库:libXXX.so

静态库:libYYY.a

去掉前缀"lib"和后缀".so"/".a"就是库名。

*windows下,动态库:.dll,静态库:.lib


怎么用

  • -E:编译,预处理完停下,可-o指定生成.i文件
  • -S:编译,汇编完停下,可-o指定生成.s文件
  • -c:编译,链接完停下,可-o指定生成.o文件
  • -o:编译,指定生成目标文件(直接-o生成可执行文件)
  • -std=c99:指定c99标准

首先看一下怎么在Linux上编译并运行一段代码:

[bacon@VM-12-5-centos 2-vim]$ cat test.c
#include <stdio.h>#define NUM(n) n int main()
{//1111//2222//3333printf("hello vim %d\n",NUM(1));printf("hello vim %d\n",NUM(2));printf("hello vim %d\n",NUM(3));return 0;
}
[bacon@VM-12-5-centos 2-vim]$ gcc test.c -o test
[bacon@VM-12-5-centos 2-vim]$ ls
test  test.c

有了可执行程序,如何执行呢?

“./ + 可执行程序名”,找到路径即可执行。

[bacon@VM-12-5-centos 2-vim]$ ./test 
hello vim 1
hello vim 2
hello vim 3

那我们如何知道可执行程序是动态链接还是静态链接呢?

file [文件]

[bacon@VM-12-5-centos 2-vim]$ file test
test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=896e927d85e4e51f3f11ab910c017db042736fbf, not stripped

能够知道:Linux默认选择动态动态链接。

我们还能查看它依赖的动态库——ldd [文件]

[bacon@VM-12-5-centos 2-vim]$ ldd testlinux-vdso.so.1 =>  (0x00007fffe77c2000)libc.so.6 => /lib64/libc.so.6 (0x00007fc7e976f000)/lib64/ld-linux-x86-64.so.2 (0x00007fc7e9b3d000)

我们去掉 “libc.so.6 => /lib64/libc.so.6 (0x00007fc7e976f000)” 的"lib"和后缀:c。

这就是c库。"0x00007fc7e976f000"就是我们依赖(需要)部分的起始位置。

[bacon@VM-12-5-centos 2-vim]$ ls -l /lib64/libc.so.6
lrwxrwxrwx 1 root root 12 Jul 25 16:58 /lib64/libc.so.6 -> libc-2.17.so
[bacon@VM-12-5-centos 2-vim]$ ls -l /lib64/libc-2.17.so
-rwxr-xr-x 1 root root 2156592 May 19  2022 /lib64/libc-2.17.so

原来,所谓"libc.so.6"是链接文件,链接到libc-2.17.so这个库,库的大小也能看到。

但,我们若有很多个程序都用这个动态库,不还是有很多份?

并没有,动态库只加载需要的部分,而且是共享的,所以也叫共享库。

如果我们想静态链接呢?

gcc -static

[bacon@VM-12-5-centos 2-vim]$ gcc test.c -static -o test_static 
[bacon@VM-12-5-centos 2-vim]$ ll
total 2
-rwxrwxr-x 1 bacon bacon   8360 Dec  1 08:17 test
-rwxrwxr-x 1 bacon bacon 861216 Dec  1 14:55 test_static
[bacon@VM-12-5-centos 2-vim]$ file test_static 
test_static: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=41f78cd6e97888d4295faa223090fd1d406097a3, not stripped

文件大小直接是百倍差距了。

*系统默认带动态库(系统运行需要它——Linux大部分指令是C写的),但不一定有静态库(可能需要自己安装)。

[bacon@VM-12-5-centos 2-vim]$ ls /usr/bin/which
/usr/bin/which
[bacon@VM-12-5-centos 2-vim]$ ldd /usr/bin/whichlinux-vdso.so.1 =>  (0x00007ffd21fae000)libc.so.6 => /lib64/libc.so.6 (0x00007f8c708f8000)/lib64/ld-linux-x86-64.so.2 (0x00007f8c70cc6000

到这我们也能知道,系统为了支持我们编程,提供了动静态库(定义)和其.h文件(声明)。所以,

我的代码 + 库的代码(链接.lib和.o文件) = 可执行程序。


接下来,我们用gcc的选项一步步看程序编译的过程

-E 生成.i文件

[bacon@VM-12-5-centos 2-vim]$ ls
test.c
[bacon@VM-12-5-centos 2-vim]$ gcc test.c -E -o test.i
[bacon@VM-12-5-centos 2-vim]$ ls
test.c  test.i
[bacon@VM-12-5-centos 2-vim]$ vim test.i

在这里插入图片描述

-S 生成.s文件

[bacon@VM-12-5-centos 2-vim]$ gcc test.c -S -o test.s
[bacon@VM-12-5-centos 2-vim]$ vim test.s

在这里插入图片描述

-c 生成.o文件

[bacon@VM-12-5-centos 2-vim]$ gcc test.c -c -o test.o
[bacon@VM-12-5-centos 2-vim]$ vim test.o

在这里插入图片描述

以上是对于编译型语言,而对于解释型语言的一种运行方法:编辑完成后,给文件加上可执行属性就可以"./ filename"运行


今天的分享就到这里啦

这里是培根的blog,期待与你共同进步,下期见!


http://www.ppmy.cn/news/2131.html

相关文章

国际学校妈妈哭诉IB太难:中国孩子都不知道怎么答题?

听别人说考国际学校的IB体系相对简单直到我看到IB试题才知道其实IB一点都不容易特别对于中国学生有大量写论文的部分来看看IB的真题有些学生真的很难下笔不知道怎么答题啊&#xff01;商科生物 题目都是非常考验综合能力的&#xff0c;学生需要掌握很多知识点并融会贯通&#x…

2022CTF培训(五)字符串混淆进阶代码自解密

附件下载链接 复杂的字符串混淆 原理 之前的字符串混淆是一次性解密的&#xff0c;找到解密函数即可获得所有字符串&#xff0c;同时执行解密函数后内存中也可直接获得所有字符串。 因此对抗人员升级了混淆技术&#xff0c;使得解密仅在使用时发生&#xff0c;从而避免了全部…

c++还原简单的vector

文章目录vectorvecotor的介绍vector的模拟实现类的框架成员变量迭代器构造函数析构函数size()capacity()operator[]重载扩容resize()尾插验证是否为空尾删clear 清除swap交换insert插入erase删除迭代器区间初始化构造函数拷贝构造赋值运算符重载n个val构造函数再谈构造函数vect…

【强化学习论文合集】五.2017国际表征学习大会论文(ICLR2017)

强化学习(Reinforcement Learning, RL),又称再励学习、评价学习或增强学习,是机器学习的范式和方法论之一,用于描述和解决智能体(agent)在与环境的交互过程中通过学习策略以达成回报最大化或实现特定目标的问题。 本专栏整理了近几年国际顶级会议中,涉及强化学习(Rein…

嵌入式开发--RS-485通讯的问题

嵌入式开发 RS-485通讯的问题RS-485说明接口芯片硬件连接CubeMX设置代码编写引脚定义使能串口中断函数发送数据接收数据有一个问题&#xff0c;多收了一个数数据线上的波形问题分析问题解决RS-485说明 RS-485一般简称485总线&#xff0c;是最常用的工业总线之一&#xff0c;一…

Verilog入门学习笔记:Verilog基础语法梳理

无论是学IC设计还是FPGA开发&#xff0c;Verilog都是最基本、最重要的必备技能。但任何一门编程语言的掌握都需要长期学习。并不是简简单单的随便读几本书&#xff0c;随便动动脑筋那么简单。Verilog是一门基于硬件的独特语言&#xff0c;由于它最终所实现的数字电路&#xff0…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java焦作旅游网站q5msq

首先选择计算机题目的时候先看定什么主题&#xff0c;一般的话都选择当年最热门的话题进行组题&#xff0c;就比如说&#xff0c;今年的热门话题有奥运会&#xff0c;全运会&#xff0c;残运会&#xff0c;或者疫情相关的&#xff0c;这些都是热门话题&#xff0c;所以你就可以…

MySQL 数据库的增删查改 (2)

文章目录一. 数据库约束1. 约束类型2.NULL 约束3.UNIQUE 约束4.DEFAULT 约束5. PRIMARY KEY 约束6.FOREIGN KEY 约束二.表的设计三.插入四.查询1.聚合查询2.联合查询3.合并查询本篇文章继承与 MySQL 表的增删改查(1) 一. 数据库约束 1. 约束类型 NOT NULL -- 表示某一行不能…