static link:关于gcc连接静态库的几种方式
开发一个应用程序不可避免要使用多个第三方库(library).
默认情况下,gcc采用动态连接的方式连接第三方库,比如指定-lpng,连接程序就会去找libpng.so。
gcc提供了一个-static参数,可以改变gcc默认的连接方式,GNU官网上关于gcc连接选项的手册《3.14 Options for Linking》中有说明:如下
这个-static选项是个大杀器,指定了这个选项,gcc在连接时对项目所有的依赖库都尝试去搜索名为lib<name>.a的静态库文件,完成静态连接,如果找不到就报错了。这里指的所有是不仅指我们常用的第三方库比如jpeg,png,opencv,zlib,...,还包括gcc编译器自带的库libgcc,libstdc++,libc,libm...,总之就是linux kernal之外的所有库。而且还要包括所有被间接引用的第三方库,比如png这个库在编译时还用到了zlib,那么静态连接png的时候,就要带上zlib的库:-lpng -lz,
这可麻烦大了,要把这些东西全静态连接,这得有多大?呵呵,这事儿我干过,十几兆字节总是有的,取决你的程序用到多少第三方库。
这种全静态连接有啥用处呢?也有用,就是你的程序自带干粮,只需要一个linux kernal就能跑了。
但是实际应用中,我们绝大多数应用场景不需要这么做,即使在嵌入式系统中也不一定必要,尤其是嵌入式系统的存储容量受限,这么一只大象装都装不下。所以我们大多数情况下需要有选择的进行静态编译,-static并不适合。
如何有选择的进行静态编译呢?
最简单的方式直接在连接参数中以全路径指定连接库就好了: your/path/lib<name>.a
但这种形式对管理结构简单而且自己写Makefile的小型项目还好,当一个项目结构复杂,有时需要静态连接有时需要动态连接,这种频繁的修改编译脚本的方式,可维护性就太差了。
-Bstatic
gnu的连接程序ld提供了一个-Bstatic选项用于对指定的库静态连接,ld的官方手册《2.1 Command Line Options》有说明,如下:
大意就是-Bstatic参数指定对跟在它后面的所有库执行静态连接,如下就指定LDFLAGS对png这个库静态连接,ld会自动去搜索libpng.a
-Bstatic -lpng -lz
1
-l:filename
如果你觉得上面一种静态连接方式不适合你,可以看看ld的官方手册《2.1 Command Line Options》中关于-l参数的说明,如下:
注意上面的说明中红框标注的内容,如果-l:filename格式指定一个文件名,连接程序直接去找这个文件名了,不会再像使用-lname时将name扩展成lib<name>.a格式的文件名.
所以使用 -l:libpng.a这样的形式来指定连接库,就指定了静态连接png库。
当然如果库的位置不在gcc默认搜索路径中,要用-L参数另外指定搜索库的路径,否则连接程序不知道该从哪里找到filename。
-L/your/library/path -l:libmylib.a
1
顺便贴出ld的官方手册《2.1 Command Line Options》中关于-L参数的说明
参考资料
以上内容只是我对最近做项目编译的一些总结和体会,可能会有所遗漏,权威资料还请参见gcc的官方文档
《3.14 Options for Linking》
《2.1 Command Line Options》
---------------------
作者:10km
来源:CSDN
原文:https://blog.csdn.net/10km/article/details/83239949
版权声明:本文为博主原创文章,转载请附上博文链接!
static link:关于gcc连接静态库的几种方式的更多相关文章
- GCC同时使用静态库和动态库链接
一 在应用程序需要连接外部库的情况下,linux默认对库的连接是使用动态库,在找不到动态库的情况下再选择静态库.使用方式为: gcc test.cpp -L. -ltestlib 如果当前目录有两个库 ...
- linux连接静态库
在项目中发现,使用 -l连接某个库时,如果存在同名的静态库(.a)和动态库(.so),默认会连接.so 那么如何指定连接静态库呢?如果有多个库,有些要连接静态库.有些要连接动态库,连接选项该如何指定呢 ...
- gcc创建静态库和共享库
静态库和动态(共享)库静态库:编译程序在编译使用库提供的功能代码的程序时将代码复制到该程序然后编译成可执行程序,这种库成为静态库共享库:共享库比静态库的处理方式更加灵活,因而其产生的可执行文件更小,其 ...
- GCC与静态库、动态库
GCC 常用指令 1 man gcc gcc工作流程例如: gcc hello.c 1234567891011121314 //***第一步***gcc -E hello.c >hello.i ...
- 不停止MySQL服务增加从库的两种方式
不停止MySQL服务增加从库的两种方式 转载自:http://lizhenliang.blog.51cto.com/7876557/1669829 现在生产环境MySQL数据库是一主一从,由于业务量访 ...
- 不停止MySQL服务增加从库的两种方式【转载】
现在生产环境MySQL数据库是一主一从,由于业务量访问不断增大,故再增加一台从库.前提是不能影响线上业务使用,也就是说不能重启MySQL服务,为了避免出现其他情况,选择在网站访问量低峰期时间段操作. ...
- Spring静态注入的三种方式
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/chen1403876161/article/details/53644024Spring静态注入的三 ...
- 不停mysql服务添加从库的两种方式
现在生产环境MySQL数据库是一主一从,由于业务量访问不断增大,故再增加一台从库.前提是不能影响线上业务使用,也就是说不能重启MySQL服务,为了避免出现其他情况,选择在网站访问量低峰期时间段操作. ...
- 基于 Webpack 引入公共库的几种方式
以 jquery 和其插件 jquery-modal 为例,记录下引入公共库的几种方式. 为了方便,首先安装 jquery 和 jquery-modal: cnpm i jquery jquery-m ...
随机推荐
- zzuli2226:神奇的薯条
题目描述 小明拿了n元钱去买薯条,薯条小份3元,大份7元.现在小明想知道如果只买薯条,自己的钱是否可以刚好花完,请你设计一个程序帮他计算一下. 输入 第一行输入一个整数T,表示实例数量.(1<= ...
- linux----磁盘介绍
1.磁盘简图: 2.常见分区 mbr:主引导区,共512byte 扩展分区 逻辑分区
- Eclipse实现数据库反向生成实体类(pojo)-------(插件安装和实现步骤的说明)
一.插件安装 1.下载插件: http://jaist.dl.sourceforge.net/sourceforge/jboss/HibernateTools-3.2.4.Beta1-R2008103 ...
- Go Example--闭包
package main import "fmt" func main() { //这里需要将闭包函数当作一个类理解,这里是实例化 nextInt := intSeq() fmt. ...
- 【BZOJ4521】【CQOI2016】手机号码
感觉数位dp好恶心…… 原题: 人们选择手机号码时都希望号码好记.吉利.比如号码中含有几位相邻的相同数字.不含谐音不 吉利的数字等.手机运营商在发行新号码时也会考虑这些因素,从号段中选取含有某些特征的 ...
- 【数据库】jdbc详解
try { if(resultSet!=null){ resultSet.close(); } }catch (SQLException e){ e.printStackTrace(); }final ...
- linux运维注意事项
防火墙和selinux一定要注意 服务器或应用出现错误是一定要查看服务器运行状态是否正确,及其相关运行日志 不管什么时候,能不要特殊字符就不要用特殊字符,避免不必要的错误 在看部署文档的时候一定要认真 ...
- MySQL Partition--分区基础
================================================================================= Mysql在5.1版本时增加对分区表 ...
- python结合redis模拟队列
实在无聊就写了个很小的python程序用来实现模拟redis队列的代码如下: redis_lpush.py #!/usr/bin/python3 import time import redis ...
- Promise实例的then方法