目录
一、gcc生成静态库.a和动态库.so
函数库分为静态库和动态库。
- 静态库
在程序编译时会被连接到目标代码中,程序运行是则不需要静态库的存在。- 动态库
在程序编译时不会被连接到目标代码中,而是程序运行时载入的。
两者区别:前者是编译连接的,后者是程序运行载入的。
(一)以hello word 为例子
1.编写程序和编译文件
hello.h
hello.c
main3.c
gcc编译得到.o文件
gcc -c hello.c
2. 静态库使用
创建静态库
创建静态库的工具:ar
静态库文件命名规范:以lib作为前缀,是.a文件
ar -crv libmyhello.a hello.o
程序中使用静态库
gcc main.c libmyhello.a -o hello
验证静态库的特点
在删掉静态库的情况下,运行可执行文件,发现程序仍旧正常运行,表明静态库跟程序执行没有联系。同时,也表明静态库是在程序编译的时候被连接到代码中的。
3.动态库的使用
创建动态库gcc -shared -fPIC -o libmyhello.so hello.o
shared:表示指定生成动态链接库,不可省略
-fPIC:表示编译为位置独立的代码,不可省略
在程序中执行动态库
gcc main.c libmyhello.so -o hello
再运行可执行文件hello,会出现错误
解决方法:将libmyhello.so复制到目录/usr/lib中
mv libmyhello.so /usr/lib
(二)实例
1.编写程序
rsub1.c
rsub2.c
rsub.h
rmain.c
gcc -c sub1.c sub2.c
2.静态库
ar crv libsub.a sub1.o sub2.o
gcc -o main main.c libsub.a
3.动态库
gcc -shared -fPIC libsub.so sub1.o sub2.o
gcc -o main main.c libsub.so
4.静态库与动态库的比较
静态库比动态库要小很多,生成的可执行文件有较小的差别
二、gcc常用命令
GCC 的意思也只是 GNU C Compiler 而已。经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言;它现在还支持 Ada 语言、C++ 语言、Java 语言、Objective C 语言、Pascal 语言、COBOL 语言,以及支持函数式编程和逻辑编程的 Mercury 语言,等等。而 GCC 也不再单只是 GNU C 语 言编译器的意思了,而是变成了 GNU Compiler Collection 也即是 GNU 编译器家族的意思了。另 一方面,说到 GCC 对于操作系统平台及硬件平台支持,概括起来就是一句话:无所不在
(一)、单程序编译
以下面这个程序为例
1.预处理
终端输入
gcc -E hello.c -o hello.i
gcc 的-E 选项,可以让编译器在预处理后停止,并输出预处理结果
2.编译为汇编代码(Compilation)
终端输入
gcc -S hello.i -o hello.s
3.汇编(Assembly)
终端输入
gcc -c hello.s -o hello.o
4. 连接(Linkin)
终端输入
gcc hello.o -o hello
gcc 连接器是 gas 提供的,负责将程序的目标文件与所需的所有附加的目标文件连接起来,最终生 成可执行文件。附加的目标文件包括静态连接库和动态连接库
5.运行
终端输入
./hello
(二)多程序编译
通常整个程序是由多个源文件组成的,相应地也就形成了多个编译单元,使用 GCC 能够很好地管理 这些编译单元。假设有一个由 test1.c 和 test2.c 两个源文件组成的程序,为了对它们进行编译,并 最终生成可执行程序 test,可以使用下面这条命令
gcc test1.c test2.c -o test
如果同时处理的文件不止一个,GCC 仍然会按照预处理、编译和链接的过程依次进行。如果深究起 来,上面这条命令大致相当于依次执行如下三条命令
gcc -c test1.c -o test1.o
gcc -c test2.c -o test2.o
gcc test1.o test2.o -o test
(三)检错
gcc -pedantic illcode.c -o illcod
-pedantic 编译选项并不能保证被编译程序与 ANSI/ISO C 标准的完全兼容,它仅仅只能用来帮助 Linux 程序员离这个目标越来越近。或者换句话说,-pedantic 选项能够帮助程序员发现一些不符合 ANSI/ISO C 标准的代码,但不是全部,事实上只有 ANSI/ISO C 语言标准中要求进行编译器诊断的 那些情况,才有可能被 GCC 发现并提出警告
除了-pedantic 之外,GCC 还有一些其它编译选项也能够产生有用的警告信息。这些选项大多以-W 开头,其中最有价值的当数-Wall 了,使用它能够使 GCC产生尽可能多的警告信息
gcc -Wall illcode.c -o illcode
GCC 给出的警告信息虽然从严格意义上说不能算作错误,但却很可能成为错误的栖身之所。一个优 秀的 Linux 程序员应该尽量避免产生警告信息,使自己的代码始终保持标准、健壮的特性。所以将 警告信息当成编码错误来对待,是一种值得赞扬的行为!所以,在编译程序时带上-Werror 选项,那 么 GCC 会在所有产生警告的地方停止编译,迫使程序员对自己的代码进行修改,如下: gcc -Werror test.c
(四)库文件连接
开发软件时,完全不使用第三方函数库的情况是比较少见的,通常来讲都需要借助许多函数库的支 持才能够完成相应的功能。从程序员的角度看,函数库实际上就是一些头文件(.h)和库文件(so、 或 lib、dll)的集合。。虽然 Linux 下的大多数函数都默认将头文件放到/usr/include/目录下,而库文 件则放到/usr/lib/目录下;Windows 所使用的库文件主要放在 Visual Stido 的目录下的 include 和 lib, 以及系统文件夹下。但也有的时候,我们要用的库不再这些目录下,所以 GCC 在编译时必须用自己 的办法来查找所需要的头文件和库文件。
将test.c编译为目标文件
gcc –c –I /usr/dev/mysql/include test.c –o test.o
将所有目标文件链接成可执行文件
gcc –L /usr/dev/mysql/lib –lmysqlclient test.o –o test
Linux 下的库文件分为两大类分别是动态链接库(通常以.so 结尾)和静态链接库(通常以.a 结尾), 二者的区别仅在于程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。
(五)强制链接时使用静态链接库
默认情况下, GCC在链接时优先使用动态链接库,只有当动态链接库不存在时才考虑使用静态链接库,如果需要的话可以在编译时加上-static选项,强制使用静态链接库。 在/usr/dev/mysql/lib目录下有链接时所需要的库文件libmysqlclient.so和libmysqlclient.a,为了让GCC在链接时只用到静态链接库,可以使用下面的命令:
gcc –L /usr/dev/mysql/lib –static –lmysqlclient test.o –o test
静态库链接时搜索路径顺序:
1. ld会去找GCC命令中的参数-L
2. 再找gcc的环境变量LIBRARY_PATH
3. 再找内定目录 /lib /usr/lib /usr/local/lib
这是当初compile gcc时写在程序内的 动态链接时、执行时搜索路径顺序:
1. 编译目标代码时指定的动态库搜索路径
2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径
3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径
4. 默认的动态库搜索路径/lib 5. 默认的动态库搜索路径/usr/lib
有关环境变量:
LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径
LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径
三、OpenCV的简单应用
开源计算机视觉(OpenCV)是一个主要针对实时计算机视觉的编程函数库。
(一)认识OpenCV
OpenCV的应用领域包括:
2D和3D功能工具包
运动估计
面部识别系统
手势识别
人机交互
移动机器人
动作理解
物体识别
分割和识别
实体影像立体视觉:来自两个摄像机的深度感知
运动中的结构(SFM)
运动跟踪
增强现实
为了支持上述一些领域,OpenCV包括一个统计机器学习库,其中包含:
提升(Boosting)
决策树学习
梯度提升树
期望最大化算法
k最近邻算法
朴素贝叶斯分类器
人工神经网络
随机森林
支持向量机(SVM)
深层神经网络(DNN)
(二)opencv关于图片的简单应用
1.编写文件并写代码
创建一个 test1.cpp 文件
gedit test1.cpp
将代码放进去
2.编译文件
在终端输入
g++ test1.cpp -o test1 `pkg-config --cflags --libs opencv`
gcc编译器:gcc + 文件名 + -o + 输出文件流名称 +` 支持包
在相同文件下放一张图片
3.输出
在终端输入
./test1
输出结果如下
第一张图为原图,第二张为输出的图,可以看到两张图的效果不同
(三)opencv关于视频的应用
1.创建文件并编写代码
代码如下图
2.编译文件
g++ test2.cpp -o test2 `pkg-config --cflags --libs opencv`
输出
生成了一个 .avi 文件,并不断生成帧
3.问题分析
1)如果要求打开你硬盘上一个视频文件来播放,请问代码如何修改?
将代码中的VideoCapture capture(0);修改为VideoCapture capture("/home/ubuntu/video/test.mp4")
即将0改为需要播放的视频名称以及它所存放的路径
2)在示例代码1第9行的while循环中,Mat是一个什么数据结构? 为什么一定要加一句waitKey延时代码,删除它行不行?
Mat是一个矩阵,每个图像都是由无数的点构成的,即Mat是一个图像矩阵。
waitKey()函数的功能是不断刷新图像,如果没有这个就无法实现画面的实时显示,即看不到画面的变化。
3)示例代码1代码会在while循环中一直运行,你如果试图用鼠标关闭图像显示窗口,会发现始终关不掉。需要用键盘Ctrl+C 强制中断程序,非常不友好。如何改进?
增加一个判断语句,来进行关闭
四、总结
在gcc上用简单例子生成了静态库和动态库,了解了静态库.a与.so库文件的生成与使用,了解了gcc的一些常用命令,在linux安装了opencv并进行了简单应用
参考文献:
linux gcc常用命令_pink_lemon的博客-CSDN博客目录一、单程序编译(1)预处理(2)编译为汇编语代码(3)汇编(4)链接(5)运行二、多程序编译三、检错四、库文件链接五、gcc编译工具集中各软件GCCBinutilsC运行库六、ELF文件七、总结八、参考文献一、单程序编译以下面这个程序为例//hello.c#include<stdio.h>int main(){ printf("hello world\n"); return 0;}(https://blog.csdn.net/pink_lemon/article/details/120621590gcc生成静态库.a和动态库.so_Harriet的博客-CSDN博客https://blog.csdn.net/qq_43279579/article/details/109026927Ubuntu18.04下OpenCV3.4.11的安装及使用示例_ssj925319的博客-CSDN博客https://blog.csdn.net/ssj925319/article/details/109231145