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

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

概述个人博客首页(点击查看详情) -- https://blog.51cto.com/11495268   1、简介     程序编译一般需要经预处理、编译、汇编和链接,在实际应用中,有些公共代码需要反复使用,就把这些代码编译成为 "库" 文件,本文 主要 描述 Linux 平台下 库文件的 创建 和 链接 相关 *** 作(既然都看 这么底层的内容了,相信 也有一定的基础,所以本文 对相关命令 也不会进行详 个人博客首页(点击查看详情) -- https://blog.51cto.com/11495268
 
1、简介
    程序编译一般需要经预处理、编译、汇编和链接,在实际应用中,有些公共代码需要反复使用,就把这些代码编译成为 "库" 文件,本文 主要 描述 linux 平台下 库文件的 创建 和 链接 相关 *** 作(既然都看 这么底层的内容了,相信 也有一定的基础,所以本文 对相关命令 也不会进行详细解释)


    
备注:
    linux平台下,静态链接库是以 .a 的后缀文件,动态链接库是以 .so 的后缀文件
    wIDows平台下,静态链接库是以 .lib 的后缀文件,动态库文件是以 .dll 的后缀文件
    

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

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

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


    

2.1.3 特点
    静态库对函数库的链接是放在程序编译时期完成
    程序在运行时对函数库再无瓜葛(因为所有相关的目标文件和牵涉到的函数库被链接合成一个可执行文件)
    浪费空间和资源(因为所有相关的目标文件和牵涉到的函数库被链接合成一个可执行文件)
    

2.1.4 创建流程


    

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

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

2.2 动态库
2.2.1 简介
    程序在开始运行后调用 动态(链接)库(Dynamic link library)中的函数 才被载入
    

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


    

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() functioncall gcc_lib_two() functioncall 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 共享路径设置(不详细解释)

## 共享路径设置 :##     [email protected]:LD_liBRARY_PATH 修改 这个全局变量##     [email protected]:修改 /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() functioncall gcc_lib_two() functioncall gcc_lib_three() function

    

4、自定义工具(Makefile)
4.1 安装 make

# apt-get install make

    

4.2 编写 Makefile

# cat Makefdefault_target : helphelp :    @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.cgcc_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_gccdynamic_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_gccar  cqs  /tmp/libstatic_gcc.a  gcc_lib_first.o gcc_lib_sec.o gcc_lib_third.ogcc -o gcc_lib_main_static gcc_lib_main.c  -L /tmp -static -l static_gcc## 创建 动态库 链接的 可执行文件# make dynamic_gccgcc -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_gcccp /tmp/libdynamic_gcc.so /usr/local/lib/ldconfig
总结

以上是内存溢出为你收集整理的Linux 环境下 gcc 链接库 编译、链接(概览) 以及 自动化工具Makefile的编写全部内容,希望文章能够帮你解决Linux 环境下 gcc 链接库 编译、链接(概览) 以及 自动化工具Makefile的编写所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/1027020.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存