Linux gcc编译过程及动态/静态库制作

1: gcc编译的过程

1 预处理: 处理所有以#开头的代码,包括头文件、宏定义、条件编译

gcc -E hello.c -o hello.i

2 编译: 语法检查以及将C语言转成汇编语言

gcc -S hello.i -o hello.s

3 汇编: 将汇编语言转成二进制文件

gcc -c hello.s -o hello.o

4 链接: 链接代码需要用到其他文件(库文件等)

gcc hello.o -o hello

参数的介绍

参数介绍

-E:			只进行预编译,不做其他处理
-c:			只是编译不链接 生成目标文件 .o
-S:			只是编译不汇编 生成汇编代码
-g:			在可执行程序中包含标准调试信息
-o file		输出文件 到 file 这个文件中
-v:			打印出编译器内部编译各过程的命令行信息和编译器的版本
-I dir:		在头文件的搜索路径列表中添加dir目录
-L dir:		在库文件的搜索路径列表中添加dir目录
-static  	链接静态库
-l library	链接名为library的库文件

2: 分文件编程

如果玩过单片机啥的都会知道,当你的代码写的很多,一般分文件写就会更好的阅读,或者说各个模块都分别有一个.c 和.h的代码。或者就是大家合作做东西,都会分开 各做各的,然后给你接口你去使用。
比如你做一个项目 避障智能小车
网络: A同学
超声波: B同学
电机: C同学
好处:分模块的编程思想
a.分工明确(功能责任划分)、b.方便调试、c.主程序简洁
分文件编程步骤:

1.写一个调用的函数 add.c

#include "add.h"

int add(int num1,int num2)
{

	return (num1+num2);
}

2.声明函数 add.h

#ifndef __ADD_H
#define	__ADD_H

int add(int num1,int num2);

#endif

3.main函数(主程序入口)

#include <stdio.h>
#include "add.h"

int main()
{
	int ret = add(1,2);
	printf("ret = %d\n",ret);
	return 0;
}

4.编译main函数的和 函数的一起编译。

gcc main.c add.c -o main

5.运行程序

./main

3: 库(静态库和动态库)

3.1: 库的基本介绍

共享库,静态库,动态库相关资料参考来源网址
在这里插入图片描述

3.2: 静态和动态库的区别

1.静态库

静态函数库: 是在程序执行前(编译)就加入到目标程序中去了;

优点:
1. 运行快,
2. 静态库被打包到应用程序中加载速度快。
3. 发布程序无需提供静态库,因为已经在APP中,移植方便。

缺点:
1. 程序大
2. 更新,部署,发布麻烦(一更新就要往厂家发)
3. 链接时完整地拷贝至可执行文件中,别多次使用就有多份冗余拷贝。

2.动态库

动态函数库: 是在程序执行时动态(临时)由目标程序去调用;

优点:
1. 程序小
2. 链接时不复制,程序运行时由系统动态加载到内存,供内存调用,系统只加载一次,多个程序可以共用,节省内存。
3.程序升级简单,因为APP里面没有库的源代码,升级之后只要库名字不变,函数名以及参数不变,只是实现做了优化,就能加载成功。

缺点:
1. 运行慢
2. 加载速度比静态库慢
3. 发布程序需要提供依赖的动态库。

3.3: 库的制作及使用

3.3.1: 静态库制作

静态库文件名格式:		libxxx.a
库名前加lib
库的名称xxx
库名后缀.a

0-首先我们写几个代码
main.c

void func1();
void func2();

int main()
{
	func1();
	func2();
	return 0;
}

func1.c

#include <stdio.h>

void func1()
{
	printf("This is func1\n");
}

func2.c

#include <stdio.h>

void func2()
{
	printf("This is func2\n");
}

步骤1:将func1.c func2.c 编译成二进制 (.o文件)

我们在编译程序的时候在加一个 -c

gcc -c func1.c func2.c

这样会得到两个.o文件 分别是 func1.o func2.o

步骤2:然后将这两个.o文件生成静态库
名字随意,我这里就叫 my_static 吧

ar -crv libmy_static.a	func1.o func2.o

或者

ar  rcs libmy_static.a  func1.o func2.o

注意:
静态库是.a结尾

这样你会得到了一个名字叫 libmy_static.a 的文件

步骤3:编译main

gcc main.c -o main -L . -l my_static
-L:      	是指告诉gcc编译器先从-L指定的路径去找静态库,
. :       	是当前路径的意思
my_static:  是我最后想生成的文件名(这里可随意起名字)

完整步骤
在这里插入图片描述

3.3.2: 动态库制作

步骤1:直接对.c文件生成.so文件
比如我这里就叫 my_synamic 吧

gcc -fPIC -shared -o libmy_dynamic.so func1.c func2.c

或者

gcc -fpic -shared libmy_dynamic.so func1.c func2.c
-fPIC:		选项作用于编译阶段,在生成目标文件时就得使用该选项,
以生成位置无关的代码。
-shared:	指定生成动态库

步骤2:编译成可执行文件

gcc main.c -o main -L . -l my_synamic 

步骤3:运行main程序
这里就和静态库不一样了,不能直接运行。

参考来源网址

方法一(很少用):
把.so 结尾的文件拷贝到 /usr/lib/中去或者 ldd命令查看一下得到的位置(得切换会超级用户 在前面加sudo)

ldd main

在这里插入图片描述
我这里默认是去 /lib/x86_64-linux-gnu 找的,所以我们可以直接把我们的动态库放到那里去。

sudo cp libmy_dynamic.so /usr/lib/

sudo cp libmy_dynamic.so /lib/x86_64-linux-gnu/

这样就可以直接运行了
在这里插入图片描述

方法二:(推荐)
1.添加指令:export LD_LIBRARY_PATH=”路径”
例如 :

export LD_LIBRARY_PATH=/home/pikaqiu/linux_c/library/dynamicLibMake

路径可以通过输入命令pwd查看
但是这种也是有点缺陷,就是你换了一个窗口就没办法运行了

所以直接写一个脚本。
start.sh

export LD_LIBRARY_PATH=/home/pikaqiu/linux_c/library/dynamicLibMake/

./main

给 脚本 可执行权限

chmod +x start.sh

运行

./start.sh

这样不管换了新的窗口我们直接运行脚本就可以了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮卡丘吉尔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值