GNU编译器学习 --> 如何链接外部库【Linking with external libraries】
库也就是我们常说的library,一个库是若干个已经编译过的目标文件(.obj)的集合,它可以被链接到程序里。那么我们最常见的使用就是,我们在编程时会调用一些函数,这些函数别人已经写好了,它就放在库里面。比如C的数学库里的sqrt开根号函数,这个函数在libm.a里。
库通常存放在专门的档文件里,以".a"为文件后缀,也即linux下的静态库。使用GNU的归档命令ar就可以从目标文件(.obj)构建档文件。链接工具linker会在编译时解决函数引用问题。本文将只介绍静态库。需要使用共享库的动态链接可期待我接下来的文章。
在linux下,一般的系统库都放在"/usr/lib"和"/lib"下。例如,在类Unix系统下,C的数学库一般存放在"/usr/lib/libm.a"。而相应的函数原型声明则在"/usr/include/math.h"给出。C的标准库则存在"/usr/lib/libc.a',这里面有ANSI/ISO C标准中指定的函数,比如"printf",这个库默认被所有C程序自动链接。
接下来给一个例程,在这个例程(calc.c)里,需要调用数学库(libm.a)中的一个函数sqrt。
#include <math.h>
#include <stdio.h> int
main (void)
{
double x = sqrt (2.0);
printf ("The square root of 2.0 is %f\n", x);
return ;
}
当我们尝试创建一个可执行文件时,compiler在链接阶段发出error。
$ gcc -Wall calc.c -o calc
/tmp/ccbR6Ojm.o: In function `main':
/tmp/ccbR6Ojm.o(.text+0x19): undefined reference
to `sqrt'
这个问题产生的原因是链接时无法解析sqrt函数(这个calc.c里并没有对sqrt函数的定义,默认链接的库libc.a里也找不到相关解析。而真正定义声明了这个函数的外部库libm.a没有被链接到,所以不能从这个库里找)。顺便说一下,报错里提到的这个“/tmp/ccbR60jm.o”是一个用于链接进程的临时目标文件。那么应该如何解决这个问题呢?
我们需要想办法提供"libm.a"这个库给编译器。一个很容易想到但是十分笨拙的方法就是在编译命令里显式地提到这个库:
$ gcc -Wall calc.c /usr/lib/libm.a -o calc
"ilbm.a"这个库包含了所有数学公式的目标文件,例如sin,cos,exp,log以及sqrt。链接器linker会去搜索这个库去找包含sqrt这个函数的目标文件。
一旦找到了那个目标文件,刚才的代码就可以顺利地生成完整的可执行文件:
$ ./calc
The square root of 2.0 is 1.414214
生成的这个可执行文件将会含括main函数的机器码和sqrt函数的机器码(从libm.a中拷贝相应的目标文件)。也就是运行的时候已经不需要libm.a了。
但是我们不会希望每次都要在编译的命令里放辣么长的path吧。因此gcc编译器提供了短的选项命令符"-l" 一遍链接时触及你想要的库。下面的命令可以替换之前的编译命令。
$ gcc - Wall calc.c -lm -o calc

使用编译器选项 -lNAME 可以让编译器尝试链接 "libNAME.a"(一般来说这个库必须处于标准库目录)里的目标文件。至于其他目录里的库文件如何链接(使用编译器选项指明环境变量)请期待后续文章。所以一般大型的项目将会用到很多-l 选项去链接各种能够各样的库:数学库、图形库还有网络库等等。
参考资源:
1 gcc入门
2 An Introduction to GCC - for the GNU compilers gcc and g++
4 linux下的find文件查找命令与grep文件内容查找命令
GNU编译器学习 --> 如何链接外部库【Linking with external libraries】的更多相关文章
- Keil5.15使用GCC编译器链接.a库文件
我们知道,当使用第三方的代码时,人家有可能会扔个Lib文件给你.这时候,别人仅仅要提供header文件给你,则你就能够通过Lib文件及header的函数声明,对Lib中的函数进行调用.在Keil中假设 ...
- vc如何编译链接opengl库
强烈推荐的一篇强大的OpenGl学习博文OpenGL入门学习 vc2012如何链接opengl库? 首先,我们需要下载opengl的库文件,http://pan.baidu.com/s/1kTsjkZ ...
- linux下 GCC编译链接静态库&动态库
静态库 有时候需要把一组代码编译成一个库,这个库在很多项目中都要用到,例如libc就是这样一个库, 我们在不同的程序中都会用到libc中的库函数(例如printf),也会用到libc中的变量(例如以后 ...
- Linux gcc链接动态库出错:LIBRARY_PATH和LD_LIBRARY_PATH的区别
昨天在自己的CentOs7.1上写makefile的时候,发现在一个C程序在编译并链接一个已生成好的lib动态库的时候出错.链接命令大概是这样的: [root@typecodes tcpmsg]# g ...
- Linux下Qt创建共享库与链接共享库详解
随着程序写的逐渐变多,或多或少的我们都会使用别人写好的库:或者我们不想让别人看到我们的一些核心程序,可以将核心程序封装成库.本次和大家分享的是在Ubuntu下使用Qt生成共享库以及在Qt中链接共享库的 ...
- vs2010静态链接MFC库报链接错误
由于需要将MFC程序在其它电脑上运行,所以需要将动态链接的MFC改成静态链接,本以为很简单,没想到链接的时候出现下面的链接错误: uafxcw.lib(afxmem.obj) : error LNK2 ...
- C++学习笔记23:库
静态库(Archives) 后缀一般为"*.a" 使用两个目标文件创建单一静态库的编译与链接命令:ar cr libtest.a test1.o test2.o 链接器搜索静态库 ...
- 从Theano到Lasagne:基于Python的深度学习的框架和库
从Theano到Lasagne:基于Python的深度学习的框架和库 摘要:最近,深度神经网络以“Deep Dreams”形式在网站中如雨后春笋般出现,或是像谷歌研究原创论文中描述的那样:Incept ...
- Unix环境链接静态库
静态库 请点评 有时候需要把一组代码编译成一个库,这个库在很多项目中都要用到,例如libc就是这样一个库,我们在不同的程序中都会用到libc中的库函数(例如printf),也会用到libc中的变量(例 ...
随机推荐
- UI:sqlite数据库
使用sqllite的时候一些笔记 数据库(管理类),在工程 general 导入 动态链接库 libsqllite3.0.dylib 在.h文件里引入导入 sqllite3.h 头文件 在.h里面声 ...
- sql server 日期模糊查询
转换成varchar类型 ) like '%2010-10-09%' 两个字段拼接成一个字段 SELECT C0252_ID, C0252_name,C0252_Addr, ((select top ...
- E20170519-ts
numeric adj. 数字的; 数值的; nibble vt. 啃,一点一点地咬(吃); rational adj. 理性的; 合理的; n. 合理的事物; [数] 有理数; numerato ...
- svn报错:privious operation has not finshed;run 'cleanup' if it was interrupted
在更新svn的过程中,可能中途会取消,取消之后再次更新时可能提示,如下图: 下载sqlite3工具,进入此下载地址:https://www.sqlite.org/download.html 将sqli ...
- 百度地图API详细介绍
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...
- pytest特色与实用插件
pytest特色 1.fixture的特点 fixture是pytest特有的功能,其特点如下: 必须用pytest.fixture装饰器装饰:fixture有明确的名字,在其他函数(function ...
- ACM_不知所措的统计员
Problem Description: GDUFE-GAME完美结束,按照惯例,会有一篇报道,描述活动期间的盛况,因此相关人员找到负责统计的ASDF,但是ASDF只知道第i个人在S_i时进场,在E_ ...
- dotnetty源码解读一些要点
DefaultAttributeMap 它绑定在Channel或者ChannelHandlerContext上的一个附件. ChannelHandlerContext都是ChannelHandler和 ...
- 如何用PS快速做出3D按钮效果的图片
1 先建立一个透明图层 2:再创建一个矩形 3:选用过喷样式 4: 双击图层并应用蓝色,记得这里应该复制下颜色的16进制值. 效果如图所示 取消光泽选项,大功告成! 最终效果如图所示,将其保存为PNG ...
- HBase简介(很好的梳理资料) 转
一. 简介 history started by chad walters and jim 2006.11 G release paper on BigTable 2007.2 inital HBas ...