Linux 环境下 gcc 链接库 编译、链接(概览) 以及 自动化工具Makefile的编写

栏目: 服务器 · 编程工具 · 发布时间: 5年前

内容简介:2、库文件库是写好的 现有的、成熟的 一种可执行、可以复用代码的二进制形式(注,其本身不可执行),可以被操作系统载入内存执行;分为 静态链接库 和 动态链接库2.1 静态库

个人博客首页(点击查看详情) -- https://blog.51cto.com/11495268

1、简介

程序编译一般需要经预处理、编译、汇编和链接,在实际应用中,有些公共代码需要反复使用,就把这些代码编译成为 "库" 文件,本文 主要 描述 Linux 平台下 库文件的 创建 和 链接 相关操作(既然都看 这么底层的内容了,相信 也有一定的基础,所以本文 对相关命令 也不会进行详细解释)

Linux 环境下 gcc 链接库 编译、链接(概览) 以及 自动化工具Makefile的编写

备注:

linux平台下,静态链接库是以 .a 的后缀文件,动态链接库是以 .so 的后缀文件

widows平台下,静态链接库是以 .lib 的后缀文件,动态库文件是以 .dll 的后缀文件

2、库文件

库是写好的 现有的、成熟的 一种可执行、可以复用代码的二进制形式(注,其本身不可执行),可以被操作系统载入内存执行;分为 静态链接库 和 动态链接库

2.1 静态库

2.1.1 简介

静态链接库可以简单看成一组目标文件.o 的集合,即很多目标文件经过压缩打包后形成的一个文件

2.1.2 原理

链接器将从 静态(链接)库 取得所需的代码,复制到生成的可执行文件

Linux 环境下 gcc 链接库 编译、链接(概览) 以及 自动化工具Makefile的编写

2.1.3 特点

静态库对函数库的链接是放在程序编译时期完成

程序在运行时对函数库再无瓜葛(因为所有相关的目标文件和牵涉到的函数库被链接合成一个可执行文件)

浪费空间和资源(因为所有相关的目标文件和牵涉到的函数库被链接合成一个可执行文件)

2.1.4 创建流程

Linux 环境下 gcc 链接库 编译、链接(概览) 以及 自动化工具Makefile的编写

备注:

linux下使用ar工具(windows下用lib.exe)将目标文件压缩到一起,并且对其进行编号和索引,以便于查找和索引

2.1.5 命令规则

静态链接库的名称 和 库文件名称不同但有联系;例如,库名称为"static_library",那么起库文件名为"libstatic_library.a"

2.2 动态库

2.2.1 简介

程序在开始运行后调用 动态(链接)库(Dynamic Link Library)中的函数 才被载入

2.2.2 原理

程序编译是并不会被连接到目标代码中,而是在程序运行时才被载入

Linux 环境下 gcc 链接库 编译、链接(概览) 以及 自动化工具Makefile的编写

2.2.3 特点

动态库把对一些库函数的链接载入推迟到程序运行时期

进程之间的相同动态库实现共享

2.2.4 创建

创建动态库与创建静态库不同,不需要打包工具,直接使用编译器创建动态库

# gcc -fPIC -shared -o libxxx.so xx1.c xx2.c xx3.c

2.2.5 命名规则

动态链接库的名称 和 库文件名称不同但有联系;例如,库名称为"dynamic_library",那么起库文件名为"libdynamic_library.a"

3、库文件 编译、链接(实战操作)

3.1 静态库 编译、链接

3.1.1 静态库 源码

# cat gcc_lib_header.h
#ifndef __GCC_LIB_HEADER_H_ 
#define __GCC_LIB_HEADER_H_

#include <stdio.h>

void gcc_lib_one();
void gcc_lib_two();
void gcc_lib_three();

#endif
# cat gcc_lib_first.c 
/* 
    filename : gcc_lib_first.c 
*/
#include "gcc_lib_header.h"

void gcc_lib_one(){
    printf("call gcc_lib_one() function\n");
}
# cat gcc_lib_sec.c
/* 
    filename : gcc_lib_sec.c 
*/
    #include "gcc_lib_header.h"

void gcc_lib_two(){
    printf("call gcc_lib_two() function\n");
}
# cat gcc_lib_third.c
/* 
    filename : gcc_lib_third.c
*/
#include "gcc_lib_header.h"

void gcc_lib_three(){
    printf("call gcc_lib_three() function\n");
}
# cat gcc_lib_main.c
/* 
    filename : gcc_lib_main.c
*/
#include "gcc_lib_header.h"

int main(int argc, char *argv[])
{
    gcc_lib_one();
    gcc_lib_two();
    gcc_lib_three();

    return 0;
}

3.1.2 静态库 编译

# gcc -c gcc_lib_first.c
# gcc -c gcc_lib_sec.c
# gcc -c gcc_lib_third.c

# ar  cqs  libstatic_gcc.a  gcc_lib_first.o gcc_lib_sec.o gcc_lib_third.o

3.1.3 静态库 链接

## -L ./ 等同于 -L.
# gcc -o gcc_lib_main_static gcc_lib_main.c -L. -static -l static_gcc

# ./gcc_lib_main_static 
call gcc_lib_one() function
call gcc_lib_two() function
call gcc_lib_three() function

3.2 动态库 编译、链接

3.1.1 动态库 源码

为了便于测试比较,使用 与 静态库编译相同的源码

3.1.2 动态库 编译

# gcc -fPIC -shared -o libdynamic_gcc.so  gcc_lib_first.c gcc_lib_sec.c gcc_lib_third.c

3.1.3 动态库 链接

# gcc -o gcc_lib_main_dynamic gcc_lib_main.c -L ./ -l dynamic_gcc

3.1.4 共享路径设置(不详细解释)

## 共享路径设置 :
##     1@:LD_LIBRARY_PATH 修改 这个全局变量
##     2@:修改 /etc/ld.so.conf 配置
## 本文 就 详细描述了,直接把 生成的共享库 cp 至 系统默认路径下
# cp libdynamic_gxx.so /usr/local/lib/

## 重新读取 库文件信息(需root用户执行)
# ldconfig

备注:

如果 不设置 共享路径 或者 共享路径下 找不到 指定的 库文件,系统 就会 提示相关的错误信息:"./g++_lib_main_static: error while loading shared libraries: libstatic_gcc.so: cannot open shared object file: Error 40"

3.1.5 执行

## 查看 依赖库,没有问题 就执行
# ldd gcc_lib_main_dynamic
    linux-vdso.so.1 =>  (0x00007fff241e9000)
    libdynamic_gcc.so => /usr/local/lib/libdynamic_gcc.so (0x00007fe587990000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe5875c6000)
    /lib64/ld-linux-x86-64.so.2 (0x000055b1d62ea000)

# ./gcc_lib_main_dynamic 
call gcc_lib_one() function
call gcc_lib_two() function
call gcc_lib_three() function

4、自定义工具(Makefile)

4.1 安装 make

# apt-get install make

4.2 编写 Makefile

# cat Makef
default_target : help

help :
    @echo "usage : make [opt]"
    @echo "\topt arguement is one of \"static_gcc、dynamic_gcc\""

gcc_lib_first.o : gcc_lib_first.c gcc_lib_header.h
    gcc -c gcc_lib_first.c 

gcc_lib_sec.o : gcc_lib_sec.c gcc_lib_header.h
    gcc -c gcc_lib_sec.c

gcc_lib_third.o : gcc_lib_third.c gcc_lib_header.h
    gcc -c gcc_lib_third.c  

static_gcc : gcc_lib_first.o gcc_lib_sec.o gcc_lib_third.o
    ar  cqs  /tmp/libstatic_gcc.a  gcc_lib_first.o gcc_lib_sec.o gcc_lib_third.o
    gcc -o gcc_lib_main_static gcc_lib_main.c  -L /tmp -static -l static_gcc

dynamic_gcc :
    gcc -fPIC -shared -o /tmp/libdynamic_gcc.so  gcc_lib_first.c gcc_lib_sec.c gcc_lib_third.c 
    gcc -o gcc_lib_main_dynamic gcc_lib_main.c -L /tmp -l dynamic_gcc
    cp /tmp/libdynamic_gcc.so /usr/local/lib/
    ldconfig

4.3 执行

## 创建 静态库 链接的 可执行文件
# make static_gcc
ar  cqs  /tmp/libstatic_gcc.a  gcc_lib_first.o gcc_lib_sec.o gcc_lib_third.o
gcc -o gcc_lib_main_static gcc_lib_main.c  -L /tmp -static -l static_gcc

## 创建 动态库 链接的 可执行文件
# make dynamic_gcc
gcc -fPIC -shared -o /tmp/libdynamic_gcc.so  gcc_lib_first.c gcc_lib_sec.c gcc_lib_third.c 
gcc -o gcc_lib_main_dynamic gcc_lib_main.c -L /tmp -l dynamic_gcc
cp /tmp/libdynamic_gcc.so /usr/local/lib/
ldconfig

以上所述就是小编给大家介绍的《Linux 环境下 gcc 链接库 编译、链接(概览) 以及 自动化工具Makefile的编写》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

你不知道的JavaScript(上卷)

你不知道的JavaScript(上卷)

[美] Kyle Simpson / 赵望野、梁杰 / 人民邮电出版社 / 2015-4 / 49.00元

JavaScript语言有很多复杂的概念,但却用简单的方式体现出来(比如回调函数),因此,JavaScript开发者无需理解语言内部的原理,就能编写出功能全面的程序;就像收音机一样,你无需理解里面的管子和线圈都是做什么用的,只要会操作收音机上的按键,就可以收听你喜欢的节目。然而,JavaScript的这些复杂精妙的概念才是语言的精髓,即使是经验丰富的JavaScript开发者,如果没有认真学习也无......一起来看看 《你不知道的JavaScript(上卷)》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码