首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么一个简单的c程序链接到libc.a,而不是libc.so?

一个简单的C程序链接到libc.a而不是libc.so的原因有以下几点:

  1. 静态链接:libc.a是一个静态库,它包含了一组预编译的目标文件,这些目标文件包含了C标准库的函数和符号。当一个程序链接到libc.a时,编译器会将libc.a中的目标文件直接复制到最终的可执行文件中,使得程序在运行时不再依赖于外部的库文件。这种静态链接的方式可以提高程序的独立性和可移植性,因为程序不再依赖于特定的库文件版本。
  2. 性能优化:静态链接可以提高程序的执行效率。由于libc.a中的目标文件被直接复制到可执行文件中,程序在运行时可以直接调用这些函数,而不需要通过动态链接的方式进行函数调用。这样可以减少函数调用的开销,提高程序的执行速度。
  3. 简化部署:静态链接可以简化程序的部署过程。当一个程序链接到libc.a时,只需要将最终的可执行文件拷贝到目标机器上即可运行,不需要额外安装和配置动态链接库。这样可以减少部署过程中的复杂性和错误的可能性。
  4. 版本控制:静态链接可以避免版本冲突的问题。当一个程序链接到libc.so时,它依赖于系统中已安装的动态链接库。如果系统中存在多个版本的libc.so,可能会导致程序在运行时选择错误的库版本,从而引发运行时错误。而静态链接则可以避免这个问题,因为程序已经包含了自己所需的库文件。

腾讯云相关产品和产品介绍链接地址:

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

为什么 C# string.Empty 是一个静态只读字段,不是一个常量呢?

使用 C# 语言编写字符串常量时候,你可能会发现可以使用 "" 不能使用 string.Empty。...进一步可以发现 string.Empty 实际上是一个静态只读字段,不是一个常量。 为什么这个看起来最适合是常量 string.Empty,竟然使用静态只读字段呢?...string.Empty 需要是一个静态只读字段不是常量?...String 类构造函数(注意不是静态构造函数,String 类静态构造函数是特殊处理不会调用); 如果这是一个静态字段,那么编译器可以在不做特殊处理情况下,生成 ldsfld string...于是,当你需要一个代表 “空字符串” 含义时候,使用 string.Empty;当你必须要一个常量时,就使用 ""。

1K00

GCC -l选项:手动添加链接库

最近研究C语言CRC循环冗余校验,找到一个开源库: lammertb/libcrc 其中有实例代码,但是无论如何运行不起来,报错如下: [root@frytea-dev-test examples]#.../lib/libcrc.a 使用 gcc 究竟如何手动连接库呢,找到了一篇文章: GCC -l选项:手动添加链接库 下面简单记录: 标准库大部分函数通常放在文件 libc.a 中(文件名后缀 .a 代表...“achieve”,译为“获取”),或者放在用于共享动态链接文件 libc.so 中(文件名后缀 .so 代表“share object”,译为“共享对象”)。...当使用 GCC 编译和链接程序时, GCC 默认会链接 libc.a 或者 libc.so,但是对于其他库(例如非标准库、第三方库等),就需要手动添加。...gcc main.c -o main.out /usr/lib/libm.a 2) 使用 -L 选项,为 GCC 增加另一个搜索链接库目录: [root@bogon demo]# gcc main.c

2.3K20

一个奇怪链接问题

比如,下面就有一种奇怪现象。 一个奇怪链接问题 程序功能很简单,计算en次方。...分析 虽然最后终于成功编译运行,但是不免产生了几个疑问: 两段代码同样都调用了exp函数,为什么一个需要链接,一个不需要链接呢? 到底什么时候需要链接呢? 为什么链接时候放在前面就不行呢?...1.为什么一个需要链接,一个不需要? 我们可以观察到,代码一调用exp传入参数是常量2,代码二调用exp传入参数是变量b,那么对于代码一会不会在运行之前就计算好了呢?...事实上,C编译器总是主动传送libc.alibc.so给链接器,也就是说,对于使用包含在libc.alibc.so库中函数,是不需要在编译时手动链接。...调用函数是否需要链接,可以使用命令“man 3 函数名“查看,如果需要链接库,最后都有说明。 3.为什么链接时候放在前面就不行呢?

1.6K20

【Linux】Linux编译器-gccg++使用

用户可以使用“-S”选项来进行查看,该选项只进行编译不进行汇编,生成汇编代码 把C转换成汇编 gcc -S test.i -o test.s S:从现在开始,进行程序翻译,做完编译工作,变成汇编之后...,就停下来 用vim打开test.s我们就可以看到汇编代码了: 3.汇编 把汇编变成二进制(不是可执行,二进制目标文件) gcc -c test.s -o test.o c:从现在开始,进程程序翻译...:无非就是我们调用库函数时候和标准库是如何关联问题 我们C程序中,并没有定义“printf”函数实现,且在预编译中包含“stdio.h”中也只有该函数声明,没有定义函数实现,统把这些函数实现都被做到名为...其后缀名一般为“.a 不受库升级或者被删除影响,线程可执行程序体积太大,网络、磁盘、内存占用过大 去掉前缀lib去掉后缀.so剩下就是库名称 **对于上面的libc.so/6去掉后就剩下C,...所以,以后要下载一个C程序,我们并不需要下载C标准库,这让我们下载效率成本低很多 静态链接拷贝不是.so内部代码,拷贝是系统里必须存在.a结尾静态库。

2.1K30

hello程序是如何被编译出来

前言 hello程序几乎是我们每个人学习C语言写一个程序,但是它是如何从.c文本变成可以打印出”hello world“可执行文件呢?本文将简单介绍其过程。...编译 预处理之后就需要对生成预处理文件进行词法分析,语法分析,语义分析,最终产生汇编代码文件,说白点可以简单理解为将C代码“翻译”成汇编代码。该过程是核心同时也是较复杂一个过程。...我们hello程序中调用了printf函数,但是并不存在于helloWorld.o中,而是存在于libc.solibc.a中,因此我们需要通过链接将它们融合在一起。...,如果删除系统中libc.so库(记得事先备份),发现能够编译过,却在最后链接失败。...正是由于整个编译过程分阶段进行,我们可以看到不同类型问题在不同阶段出现并且有先后顺序。正因如此,链接问题在编译最后阶段才会出现。

72620

自定义规则实现将多个静态库合并为一个动态库或静态库

fdo_profile :表示工作区中或位于指定绝对路径 FDO 配置文件 cc_test :测试 C/C++ 样例 cc_toolchain :表示一个 C++ 工具 cc_toolchain_suite...:表示 C++ 工具集合 而我们知道规则(Rule)定义了 Bazel 对输入执行一系列操作,以生成一组输出。...$ sudo apt-get install libtool-bin # 生成libcombined.a ar -x 解压出来是 libA.a libB.a libC.a不是 *.o 文件。...) 3 总结 至此自定义规则实现完成,中间遇到了一些麻烦,不过最终都解决了,因为 Bazel 中文社区目前为止并不是很完善,可以说中文资料大都是概念性介绍和简单入门,很多内容都需要参考官方文档或者去...(ctx),不是直接使用 /usr/bin/gcc 等工具 这里实现自定义规则,我们只使用了 action.run_shell。

5.1K20

动态链接

动态链接 要解决空间浪费和更新困难这两个问题最简单办法就是把程序模块相互分割开来,形成独立文件,不再将它们静态地链接在一起。...动态库基本实现 动态链接基本思想是把程序按照模块拆分成各个相对独立部分,在程序运行时才将它们链接在一起形成一个完整程序,不是像静态链接一样把所有的程序模块都链接成一个个单独可执行文件。...整个系统只保留一份C语言库动态链接文件“libc.so”,所有的C语言编写、动态链接程序都可以在运行时使用它。...程序libc.so之间真正链接工作是由动态链接器完成,不是由我们前面看到过静态链接器ld完成。也就是说,动态链接是把链接这个过程从本来程序装载前被推迟到了装载时候。...当然,这仅仅是一个推断,至于为什么要这样做,为什么不将每个共享对象在进程中地址固定,或者在真正系统中是怎么运作,我们将在下一节进行解释。

1.3K20

【故障分析+解决】解决链接程序时,由于链接crt*.o顺序问题导致bug

现象 今天在为DragonOS编译http服务器程序时,遇到了一个神奇bug: 程序在一台机器A上能够正常编译、正常运行,但是,换了机器B编译之后,就无法运行,会报错: 两台编译用机器,操作系统都是...我一开始以为是机器B上面的编译器/链接器有问题,于是重新安装了编译工具。但是无法解决问题。...因此把最终调用链接器命令打出来,发现B机器上,输入链接器文件参数顺序如下: main.o crt1.o crtn.o crti.o crt0.o libc.a 正常A机器上,输入链接器文件参数顺序如下...: main.o crt0.o crt1.o crti.o crtn.o libc.a 观察发现,机器A上,输入crt*.o文件顺序是按照升序排列,而有问题B机器则不是按照升序。...错误顺序会导致程序无法运行,链接器不会报任何错误。 并且,我们不能假设find命令输出结果是按照升序排列,必须使用sort命令进行排序,才能够确保结果升序。

22820

浅析Makefile、make、cmake

如果你是在Linux下做开发,你就必须知道Makefile是什么东西,如果不知道那就可以说你不是一个合格Linux开发工程师,因为Makefile是必备一项技能。...使用gcc命令编译你会遇到一些麻烦: 对于c语言,使用gcc编译时候,其实它只会默认帮你链接一些基本c语言标准库(例如libc.a或者libc.so),有很多依赖库(例如非标准库、第三方库等)是需要我们手动链接...当你程序只有一个源文件时候,直接使用gcc命令编译就行,但是当你有很多个源文件怎么办?在gcc命令那逐个文件敲上去?100个源文件你也敲上去?...对于一些不是很大工程,Makefile完全是可以我们手工写,但是工程非常大时候,手写Makefile也是一件麻烦事,而且Makefile又不是万能,换了一个别的平台,Makefile又得重写。...于是又有人想,我们是不是可以自动生成一个Makefile呢?

90820

业内同行盆友来稿:对libc.so下毒手引发惨痛血案,围观大型翻车现场...

写在开篇为了在线上安装环境依赖,给glibc库升级,由于线上环境libc.so版本低,不支持安装,所以手贱把动态库中libc.so.6给移走了,直接导致Linux系统崩溃,系统瘫痪,所有用户均被强制退出...意识到缺少对libc.so认识,以为跟普通lib包类似,直接把新版so软连过去就可以满足安装和升级,现在哦豁....... 软不软已经不重要了,反正腿是软趴趴。...1、什么是libc.solibc.so.6 是很基础库(glibc),是软连接到在Linux系统中基本命令,有很多可执行文件都会依赖这个共享库。...libc.so.6是一个类似于WINDOWS下一个快捷指向型文件, linux有两种库,分别为:glibc、libc 说明libc 是Linux下ANSI C 函数库;glibc 是Linux下...[root@IDC-Redhat 6.8 ~]# 说明:LD_PRELOAD允许你定义在程序运行前优先加载动态链接库,因此在使用ln前就加载了lib库,不是等到使用ln时加载,这样就能临时使用命令了也可以使用

70400

平头哥 TH1520 RISC-V BeagleV-Ahead使用Thead-Yocto自定义构建系统 最详细版本

YOCTO项目:他不是一个嵌入式Linux发行版,是一个专门创建属于你自定义系统! ​...开发属于自己 应用程序/产品,那么就需要构建出来一个 专门且配套 SDK(交叉工具 + 组件应用库和头文件) ,这样才可以使用配套工具来进行编译系统。...生成配套SDK命令很简单,只需要在原来 编译镜像命令 后 加上 -c populate_sdk 参数即可。...如下图蓝框所示,这是一个 针对于 xuantie 900系列专用工具。...在 libc.so文件内修改GROUP整行为如下图所示,如果你安装路径不是前面提示默认 /usr/local/oecore-x86_64 ,则需要根据你实际路径进行修改。

40440

linux 动态库 静态库_静态库里面包含动态库

其实,动态链接是当执行到要调用接口时,编译器会自动去搜寻所链接库,静态链接则是暴力将所要用库中可执行程序使用二进制代码全部拷贝到我们生成可执行文件中,这也就是为什么静态链接生成文件这么大原因了...静态库与动态库 一般命名方式为lib+库名字+.a比如C语言提供标准静态库名字就是libc.a。 静态库是指程序在编译链接时候把库代码链接到可执行文件中。...程序运行时候将不再需要静态库。 动态库则是指程序在运行时候才去链接动态库代码,多个程序共享使用库代码。...一个与动态库链接可执行文件仅仅包含它用到函数入口地址一个表(头文件),不是外部函数所在目标文件(.o)整个机器码 在可执行文件开始运行以前,外部函数机器码由操作系统从磁盘上该动态库中复制到内存中...这里需要提一下是,我们之前所提过进程地址空间中有一个共享区,一般动态库代码就映射在共享区,所有进程都共享着动态库代码。

7.3K20

CSAPP---第七章-链接

将所有标准c函数都放在一个可重定位目标模块中,应用程序直接把该模块链接到他们可执行文件中。 缺点: 每个可执行文件都包含一份标准函数集合完全副本,对磁盘和内存空间浪费特别大!...ISO C99定义了一组广泛标准I/O,字符串操作和整数数学函数,它们在libc.a库中,对于每个c程序来说都是可用。...因为程序不引用任何由multvec.o定义符号,所以链接器不会复制整个模块到可执行文件。链接器还会复制libc.aprintf.o模块,以及许多C运行时系统中模块。...当一个来自 Web 浏览器请求到达时,服务器动态地加载和链接适当函数,然后直接调用它,不是使用 fork 和 execve 在子进程上下文中运行函数。...多个目标文件可以定义相同符号,链接器用来悄悄地解析这些多重定义规则可能在用户程序中引入微妙错误。 多个目标文件可以被连接到一个单独静态库中。链接器用库来解析其他目标模块中符号引用。

83910

静态库 VS 动态库

如何得到库 ①先写好一堆.c文件(.c:我们所需要各种工具函数) ②将这些.c编译为对应.o ③将所有的这些.o打包为一个仓库文件(静态库或者动态库) 静态库:按照静态库方式打包 动态库:按照动态库方式打包...eg:如果没有库提供printf的话,写个简单helloworld,printf函数还需要自己实现,这就扯淡了。 二者区别 这两种库链接方式不同。...静态库是.o集合,printf在其中某个.o中,链接静态库时,使用printf这个符号去搜索静态库中所有的.o,如果找到了printf所在.o,将其链接到自己程序中。...实际上只包含printf部分 动态库 主要是为了解决静态库缺点存在。...程序运行起来后,“动态链接器”一看你想链接libc.so动态库,首先检查内存中有没有这个动态库。

26410

GDB读取动态库中定义全局变量错误

问题发现和描述 首先optind是使用getopt时候全局变量,表示使用getopt时候一个argv指针索引。...+++ 问题探讨 根据多方面的探索,后来查看到,这个涉及到一个“Copy Relocation”技术。...回到原先问题,那么GDB打印出来并不是程序中.BSS通过Copy Relocation产生全局变量optind, 而是打印libc.so中原有的变量值。...首先我们通过"Info var optind"查看下optind相关信息,可以看到两处指名了optind出处,第一处其实说明了这个是在libc.so中定义gdb默认打印也是libc.so中定义...其实一个简单问题背后,会隐藏着很多技术和机制。而要真正明白问题产生根本原因,目前所掌握知识还远远不够,楼主一定还需再接再厉。

2.1K30

【CSAPP】深入理解计算机系统 第九章 虚拟内存 动态链接 printf 1726

静态链接 在我们实际开发中,不可能将所有代码放在一个源文件中,所以会出现多个源文件,而且多个源文件之间不是独立,而会存在多种依赖关系,如一个源文件可能要调用另一个源文件中定义函数,但是每个源文件都是独立编译...,即每个.c 文件会形成一个.o 文件,为了满足前面说依赖关系,则需要将这些源文件产生目标文件进行链接,从而形成一个可以执行程序。...更高明 这里有一个小问题,就是从上面的图中可以看到静态运行库里面的一个目标文件只包含一个函数,如libc.a里面的printf.o只有printf()函数,strlen.o里面只有strlen...由于运行库有成百上千个函数,数量非常庞大,每个函数独立地放在一个目标文件中可以尽量减少空间浪费,那些没有被用到目标文件就不要链接到最终输出文件中。...C printf() 详解之终极无惑 不定长参数 …用法 virtualize VA----CPU----(MMU)-----PA 物理地址 空间对应于系统中实际拥有的DRAM容量 虚拟地址 —大得多

22620
领券