嵌入式Linux开发工具-编译器gcc以及库的制作

一、交叉编译器:

  1. 是什么?

    • 在一个平台上生成仅可在另个平台上运行的可执行代码→区别于本地编译
  2. 为什么?(嵌入式硬件受限于成本)

    • 运行速度:目标平台的嵌入式硬件通常被设计为低成本和低功耗,没有太高的性能,运行速度较主机过慢。
    • 编译能力:嵌入式系统往往没有足够的内存或磁盘空间来支持极为消耗系统资源的编译过程
    • 可使用性:有的嵌入式系统连目标平台还没有建立,操作系统都没有,就算资源足以支持编译,可连编译器都没有,怎么运行编译器呢?所以至少目标平台的编译器得由交叉编译植入
    • 可移植性:一个完整的Linux编译环境需要很多支持包,交叉编译使我们不需要花时间将各种支持包移植到目标板上
  3. 怎么做?(画个饼

二、编译选项:

(编译命令的各种后缀)

-c:			//对源文件进行编译或汇编
-E:			//对源文件进行预处理
-S:			//对源文件进行编译
-o file:		//输出目标文件file
-W:			//屏蔽所有的警告信息
-Wall:		    //显示所有类型的警告信息
-o0123 :       //零、一、二、三级优化
-Idir:			//指定头文件的搜索目录dir
-Ldir:			//指定搜索目录dir

三、库文件:

  1. 存放函数和变量的仓库;

  2. 特点:只能使用库里函数和变量,不能看到其实现(例如:printf strcpy)

四、Linux库文件

  • 静态库-a: 当使用静态库时,库里的函数和变量是在编译时加载到可执行文件;

  • 动态库-so:当使用动态库时,库里的函数和变量是在运行时加载到可执行文件;

静态库和动态库的区别(可执行文件的区别)

  1. 可执行文件的大小:静态库 > 动态库(内存的使用效率)
  2. 可执行文件的速度:静态库 > 动态库(运行效率)
  3. 可执行文件的功能升级:静态库 < 动态库(功能升级的难易度)
  4. 可执行文件代码部署:静态库 > 动态库(代码位置的部署)
  5. 库文件的存放路径: /lib/ /usr/lib
  6. 如何制作静态库和动态库

五、静态库制作:

  1. gcc -o *.o -c *.c (源文件)
  2. ar rcs lib*(库文件名).a *(目标文件1).o *(目标文件2).o
  3. gcc 源文件 -l库名 -L库的路径

实例:

  1. 用vim创建一个静态库,库中包含4个函数,分别为加、减、乘、除,源程序文件取名为static_lib.c
  2. 编译"static_lib.c"成静态库"static_lib.a vim static_lib.c"
    - 创建源文件 gcc -c static_lib.c
    - 编译源文件使它生成一个可重定位的目标文件 *.o ar rcs static_lib.a static_lib.o
    - 用ar工具生成静态库,参数r表示把列表中目标文件加入到静态库中;参数c表示若指定静态库不存在则创建该库;参数s表示更新静态库文件索引使其包含新加入的目标文件内容;再ls查看目录,有发现生成了static_lib.a static_lib.a static_lib.c static_lib.o即为创建成功
  3. 用vim创建一个头文件,使应用程序可以正确引用该库中的全局符号,头文件源文件命名为static_lib.h
  4. 用vim创建一个应用程序并命名为main.c,该程序实现功能很简单:接受用户输入两个数,调用static_lib.a库中的函数进行加减乘除。
#include <stdio.h>
#include "static_lib.h"

int main()
{
    
    
int a, b;
printf("please input a and b:\n");
scanf("%d%d",&a,&b);
printf("the add : %d\n",add(a, b));
printf("the sub : %d\n",sub(a, b));
printf("the mul : %d\n",mul(a, b));
printf("the div : %d\n",div(a, b));
return 0;
}

5、编译应用程序

./main                       //运行程序
please input a and b:        //提示输入
11 11                        //输入两个数
the add : 22                 //运行结果                           
the sub : 0
the mul : 121
the div : 1

六、总结:

“undefined reference error”错误的原因可能来自以下几方面:

  1. 没有指定对应的库(.o/.a/.so)

    • 使用了库中定义的实体,但没有指定库(-lXXX)或者没有指定库路径(-LYYY),会导致该错误。
  2. 连接库参数的顺序不对

    • 在默认情况下,对于-l 使用库的要求是越是基础的库越要写在后面,无论是静态还动态。
  3. gcc/ld 版本不匹配

    1. gcc/ld的版本的兼容性问题,由于gcc2 到 gcc3大版本的兼容性存在问题(其实gcc3.2到3.4也一定程度上存在这样的问题)
    2. 当在高版本机器上使用低版本的机器就会导致这样的错误,
    3. 这个问题比较常见在32位的环境上,另外就在32位环境不小心使用了64位的库或者反过来64位环境使用了32位的库。
  4. C/C++相互依赖和链接

    • gcc和g++编译结果的混用需要保证能够extern “C” 两边都可以使用的接口,在我们的64位环境中gcc链接g++的库还需要加上"-lstdc++"。
  5. 运行期报错

    • 这个问题基本上是由于程序使用了dlopen方式载入.so文件,但.so文件没有把所有需要的库都链接上,具体参加上文中对于静态库和动态库混合使用的说明。
  6. 动态库制作:(未完成学习)

    • gcc -shared -fPIC 源文件 -o 库名
    • gcc 源文件 ./库名 -o 可执行文件
      后期会分享我的动态库学习经验(画个饼

猜你喜欢

转载自blog.csdn.net/qq_45792897/article/details/113705497