makefile 学习(2):C语言的编译及库文件的生成与链接

news2024/11/26 10:52:13

文章目录

    • 1. 介绍
    • 2. C语言编译
      • 2.1 预处理
      • 2.2 生成汇编语言
      • 2.3 编译目标文件
      • 2.4 编译为可执行文件
    • 3. .a静态库的编译与链接
      • 案例
    • 4 .so 动态库的编译与链接

1. 介绍

编译C语言的相关后缀

在这里插入图片描述

  • .a 文件是一个静态库文件
  • .c文件是c语言的源文件
  • .h c语言的头文件
  • .i 是预处理文件
  • .o 目标文件
  • .s汇编语言的文件
  • .so 动态库或者共享库或者称为运行时库

.c文件在github中可以看到另一种后缀,比如.cc 或者是其他的后缀,但是常用的还是.c后缀。在makefile 学习(1):C/C++ 编译过程, 我们讲到编译过程包括4个步骤: (1)预处理,(2)转换为汇编语言,(3) 生成目标文件(4) 链接为可执行文件。

2. C语言编译

2.1 预处理

main.c文件:

#include <stdio.h>

int main(int argc, char** argv)
{
	printf("Hello World\n");
	return 0;
}
  • 执行命令:
# 不会生成.i文件
gcc -E main.c

虽然进行了预处理编译,但是没有输出.i文件,需要-o指定下输出

gcc -E main.c -o main.i

可以看到了生成了预处理main.i,打开可以看到.i文件对应的是脚本
【图】

2.2 生成汇编语言

执行命令:

gcc -S main.c

可以看到生成汇编语言main.s,内容如下:

熟悉汇编语言的童学对生成的内容应该很熟悉

如果想指定输出的文件名,可以利用-o选项:

gcc -S main.c -o test.s

在这里插入图片描述

2.3 编译目标文件

  • 执行命令:
gcc -c main.c   # 没有指定输出名,默认为main.o
gcc -c main.c -o xxx.o #生成 xxx.o
  • 编译多个.c文件
gcc -c main.c add.c minus.c # 生成main.o add.o minus.o

2.4 编译为可执行文件

gcc main.c -o exec #exec 可执行文件名

【图】

生成了可执行文件exec, 然后运行可执行文件./exec就能输出对应结果

3. .a静态库的编译与链接

在实际的项目中,我们会写很多带有功能性源文件(比如特定的运算,放在不同的.c文件中),供其他脚本调用。如果不希望.c文件源码被外部看到或者不想拷贝一堆.c,而是直接输出库文件,供外部的可执行文件链接,此时就需要编译静态库或者动态库

案例

  • add.c中实现两个数相加,在minus.c文件中实现两个数相减。 在main.c中调用add.cminus.c中的函数,进行加减运算
  • 实现将add.cminus生成库文件
    [图]

add.c的代码

int add(int a, int b)
{
    return a+b;
}

minus.c的代码

int minus(int a, int b)
{
    return a-b;
}

main.c

#include <stdio.h>
int add(int a,int b);
int minus(int a,int b);

int main(int argc, char ** argv[])
{
    int a = 10;
    int b = 5;
    int c;
    c = add(a,b);
    printf("a+b = %d\n",c);
    c = minus(a,b);
    printf("a-b = %d\n",c);
    return 0;
}

(1)编译目标文件

  • 首先编译目标文件 add.ominus.o
gcc -c add.c minus.c

(2)编译静态库
生成静态库语法:

ar -r [lib自定义库名.a] [.o] [.o] ...
  • add.ominus.o编译为 静态库
ar -r liboperation.a add.o minus.o

在这里插入图片描述

可以看到生成了 liboperation.a静态库文件

(3)连接静态库

  • 方法1:
    生成静态库后,就可以将静态库连接到源文件main.c
gcc main.c liboperation.a -o  exec # 生成可执行文件exec
./exec # 执行可执行文件

【图】

  • 方法2
    main.c也编译为目标文件,然后利用gcc 把3个目标文件链接起来
  • 生成 main.o
gcc -c main.c
  • 3个目标文件链接,生成可执行文件
gcc main.o add.o minus.o -o exec
./exec

4 .so 动态库的编译与链接

动态库的编译与静态库的编译,其实是一样的。

  • (1)编译二进制.o文件 (需要加上 -fpic)
    语法
gcc -c -fpic [.c/.cpp] [.c/.cpp] ...

编译 add.o, minus.o目标文件

gcc -c -fpic add.c minus.c
  • (2)编译动态库 (需要加上 -share)
    语法
gcc -shared [.o][.o] ... -o [lib自定义库名.so]

生成动态库liboperation.so

gcc -shared add.o  minus.o -o liboperation.so

[图]

  • (3)链接动态库到可执行文件
    语法
gcc [.c/.cpp] -o [自定义可执行文件名] -l(库名) -L(库路径) -Wl,-rpath =[库路径]

链接可执行文件

gcc main.c -loperation -o exec -L/home/yuanwushui/project/tensorrt-integrate/1.C/src

在这里插入图片描述

编译成功了可执行文件,这里还有一些小细节并没有说,比如-Wl,-rpath等,这些都将在后续makefile章节进行讲解

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

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

相关文章

两个用字符串表示的大数字的和

文章目录 题目详情Java实现分析Java 怎么获取到字符串中的对应位置的数字值Java完整代码测试验证 python实现python 怎么获取到字符串中的对应位置的数字值python完整代码 总结 这是遇到的一道快手数仓岗位的面试题目&#xff0c;题目大意如下&#xff1a; 题目详情 现在有两个…

【树莓派4B安装18.04桌面+远程SSH】

【树莓派4B安装18.04桌面远程SSH】 1. 前言2 .树莓派安装ubuntu18.04 系统2.1 下载ubuntu Server 18.04 的镜像包2.2 镜像烧录2.3 高级设置2.4 配置WiFi2.5 ssh文件配置2.6 Pi 4B启动文件 3. 安装finalshell3.1 windows版下载3.2 windows版安装3.3 SSH连接 4. 安装ubuntu桌面4.…

【野火启明_瑞萨RA6M5】梦的开始 ---- 点灯(寄存器)

文章目录 一、IOPORT简介二、IOPORT的框图分析三、IOPORT的寄存器描述1. 端口引脚功能选择寄存器2. 端口输出数据寄存器3. 端口输入数据寄存器4. 端口输出置位/复位寄存器5. 写保护寄存器 四、点亮LED灯&#xff08;寄存器&#xff09; 从本文开始&#xff0c;我将以瑞萨RA系列…

【夜莺(Flashcat)V6监控】3.链路追踪

链路追踪 介绍 链路追踪是分布式系统下的一个概念&#xff0c;它的目的就是要解决上面所提出的问题&#xff0c;也就是将一次分布式请求还原成调用链路&#xff0c;将一次分布式请求的调用情况集中展示&#xff0c;比如&#xff0c;各个服务节点上的耗时、请求具体到达哪台机…

Java 把一个 List 转换为字符串

在本快速指南中&#xff0c;我们将会解释如何在 Java 把一个 List 转换为 String 字符串。 这个在某些特定的场合可能比较有用&#xff0c;比如说在控制台中输出 List 中的内容&#xff0c;转换为可以人为阅读的内容来进行调试。 使用 List 中标准的 toString() 方法 一个最简…

(2)数码管

LED数码管:数码管是一种简单、廉价的显示器&#xff0c;是由多个发光二极管封装在一起组成"8"字器件 51单片机是共阴极连接 74HC245这个芯片有什么作用呢&#xff1f;解&#xff1a;这个芯片被称之为双向数据缓冲器这个芯片的作用&#xff0c;用来进行数据缓冲(提高驱…

【网络编程】详解UDP/TCP套接字的创建流程

目录 一、网络编程套接字 1、一些概念 1.1源IP地址和目的IP地址 1.2端口号port 1.3TCP和UDP的性质 1.4网络字节序、IP地址类型转换、数据接收与发送函数、popen函数 2、UDP套接字 2.1UDP服务器创建流程 2.2UDP客户端创建流程 2.3创建socket套接字 2.4绑定套接字对应…

快速找出PATH 路径下重复的命令程序文件

RT&#xff0c;就是想找出命名冲突的可执行文件。日积月累的&#xff0c;PATH 环境变量里乱七八糟堆了一堆东西&#xff0c;很可能想叫一个命令出来&#xff0c;结果实际执行的是另一个地方的程序。 Python 脚本 import ospath os.environ[PATH] folders path.split(;) fil…

理解HttpSession

什么是session 在我刚刚从事后端开发的时候&#xff0c;有一个问题困扰了我很久。 就有个玩意叫session。 PostMapping("login")public Result login(RequestParam("id") String id,RequestParam("password") String password, HttpSession se…

哈希及模拟实现

文章目录 哈希1. 哈希相关概念1.1 哈希概念1.2 哈希冲突1.3 哈希函数1.4 哈希冲突解决1.4.1 闭散列/开放定址法(1)线性探测(2) 二次探测 1.4.2 开散列/哈希桶 2. 开放定址法的实现2.1 结构2.2 插入Insert2.2.1 传统写法2.2.2 现代写法 2.3 查找Find2.4 删除Erase2.5 整体代码 3…

springcloud基于web的智慧养老平台

系统分析 可行性分析 在开发系统之前要进行系统可行性分析&#xff0c;目的是在用最简单的方法去解决最大的问题&#xff0c;程序一旦开发出来满足了用户的需要&#xff0c;所带来的利益也很多。下面我们将从技术、操作、经济等方面来选择这个系统最终是否开发。 1、技术可行…

一图看懂 dateutil 模块:Python datetime 模块的扩展,资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 dateutil 模块&#xff1a;Python datetime 模块的扩展&#xff0c;资料整理笔记&#xff08;大全&#xff09; &#x1f9ca;摘要&#x1f9ca;模块图&#x1f9ca;类关系…

005、数据库结构

数据库结构 1、数据库集簇逻辑结构2、对象标识符3、数据库集簇物理结构4、其它目录结构表空间物理文件位置1、数据库集簇逻辑结构 • 数据库集簇逻辑结构 数据库 : 把数据逻辑分开存放。 对象是放在数据库当中。表空间: 把数据从逻辑或者物理上分割存放2、对象标识符 Postg…

Weblogic SSRF 漏洞(CVE-2014-4210)

SSRF漏洞 ​ SSRF&#xff08;服务端请求伪造&#xff09;&#xff0c;指的是攻击者在未能取得服务器所有权限时&#xff0c;利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网。SSRF攻击通常针对外部网络无法直接访问的内部系统。 ​ 简单的说就是利用一个可…

《统计学习方法》——隐马尔可夫模型(下)

学习算法 HMM的学习&#xff0c;在有观测序列的情况下&#xff0c;根据训练数据是否包含状态序列&#xff0c;可以分别由监督学习算法和无监督学习算法实现。 监督学习算法 监督学习算法就比较简单&#xff0c;基于已有的数据利用极大似然估计法来估计隐马尔可夫模型的参数。…

详解二叉树

&#x1f308;目录 一、树形结构​ &#x1f333;1.1 概念1.2 其他概念1.3 树的表示形式 二、二叉树✨2.1 概念2.2 两种特殊二叉树2.3 性质2.4 二叉树存储 三、二叉树的基本操作&#x1f64c;3.1 前置说明3.2 二叉树的遍历3.3 二叉树的基本操作 四、二叉树的OJ✍️ 一、树形结构…

springboot+vue医院信管系统(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的医院信管系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风歌&a…

Service Control Manager 服务管理器简介

在windows驱动开发流程中&#xff0c;写完sys驱动binary之后&#xff0c;为了让OS能够正确的从注册表中读取到对应的信息&#xff0c;并且将其load运行起来&#xff0c;还需要编写inf文件来描述配置驱动文件。不过这也不是必须的&#xff0c;可以通过ServiceControlManager直接…

Fiddler 抓包工具 - 全网最全最细教程,没有之一

Fiddler 简介 Fiddler 是位于客户端和服务器端的 HTTP 代理 目前最常用的 http 抓包工具之一 功能非常强大&#xff0c;是 Web 调试的利器 监控浏览器所有的 HTTP/HTTPS 流量 查看、分析请求内容细节 伪造客户端请求和服务器响应 测试网站的性能解密 HTTPS 的 Web 会话 全局…

Go语音基于zap的日志封装

zap日志封装 Zap是一个高性能、结构化日志库&#xff0c;专为Go语言设计。它由Uber开源&#xff0c;并且在Go社区中非常受欢迎。它的设计目标是提供一个简单易用、高效稳定、灵活可扩展的日志系统。 以下是Zap的一些主要特点&#xff1a; 1.高性能&#xff1a;Zap的性能非常出…