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的编写》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

九败一胜

九败一胜

李志刚 / 北京联合出版公司 / 2014-9-1 / 42.00元

所有的创业者都面临着很多问题,困惑不是个人的,是有共性的。 除了自身去摸索着石头走路,他们还可以通过学习,从那些在创业路上走得更远的创业者身上学到经验、教训。 这本书的主角——王兴,恰好就是一个很好的学习对象。出生于1979年的王兴,很早就创业了,2004他就开始和同学一块创业,2005年做出了校内网;2007年,他又做出了饭否网——这是中国最早的类似twitter的网站。 ......一起来看看 《九败一胜》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器

html转js在线工具
html转js在线工具

html转js在线工具