zoukankan      html  css  js  c++  java
  • linux下的静态库和动态库的编译


    转自:http://www.diybl.com/course/6_system/linux/Linuxjs/20071027/80547.html

    每个程序实质上都会链接到一个或者多个的库。比如使用C函数的程序会链接到C运行时库,GUI程序会链接到窗口库等等。无论哪种情况,你都会要决定是链接到静态库(static libary)还是动态库(dynamic libary)。
    链接到静态库会使你的程序臃肿,并且难以升级,但是可能会比较容易部署。
    而链接到动态库会使你的程序轻便,并且易于升级,但是会难以部署。

    静态库
    静态库也就相当于是把一系列的object文件放在同一个文件中(类似windows中的.lib文件)。当你提供一个静态库给链接器时,连接器将会搜索静态库,从中找到他所需要的object文件,提取出他们,将他们链接到你的程序中,就像你直接提供那些文件一样。
    如何创建静态库呢?你可以使用ar命令来创建。
    下面我们举个例子:
    test/lib/test1.c
    #include <stdio.h>

    int hello_world1()
    {
        printf("hello world1\n");
        return 1;
    }

    test/lib/test2.c
    #include <stdio.h>

    void hello_world2()
    {
        printf(" hello world2\n");
    }

    test/app.c
    #include <stdio.h>

    int main()
    {
        hello_world1();
    }

    现在我们编译他们进入目录test/lib
    $gcc -c test1.c
    $gcc -c test2.c
    $ls
    test1.c  test1.o  test2.c  test2.o
    $ar cr libtest.a test1.o test2.o
    $ls
    libtest.a  test1.c  test1.o  test2.c  test2.o
    cr标志告诉ar将object文件封装(archive),我们可以使用nm -s 命令来查看.a文件的内容
    $nm -s libtest.a

    Archive index:
    hello_world1 in test1.o
    hello_world2 in test2.o

    test1.o:
    00000000 T hello_world1
             U puts

    test2.o:
    00000000 T hello_world2
             U puts

    现在让我们编译主程序
    首先退出lib目录
    $cd ..
    $gcc -o app app.c -Llib -ltest
    -L指定了lib的搜索路径,-l指定了链接的库的名字-ltest也就是链接libtest.a
    $./app
    hello world1
    hello_world1()被从libtest.a中找到并链接过来了,于是整个的过程中没有出现问题。

    动态库
    动 态库(static lib)也可一也可以成为共享库(shared lib),一般的后缀名是.so。动态库与静态库有点类似,他们都是一系列的object文件的集合,只是他们的组织方式不同。同样他们的链接方式也是不 同的,动态库只在执行是链接使用,并不把相应的部分编译入程序中,在使用是一个库可以被多个程序使用故可称为共享库,而静态库将会整合到程序中,链接时各 程序使用自己的库。
    下面我们来介绍如何创建动态库,还是之前的三个文件,同样的布局,进入lib目录
    $gcc -c -fPIC  test1.c
    $gcc -c -fPIC  test2.c
    -fPIC告诉gcc将源代码编译成共享的object文件,PIC(Position-Independent Code)非位置依赖性代码。
    $gcc -shared -fPIC -o libtest.so test1.o test2.o
    将两个文件整合为共享库libtest.so
    退出lib目录
    $cd ..
    $gcc -o app app.c -Llib -ltest
    $./app
    ./app: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
    啊哈,我们在这里遇到一个error没找到libtest.so,说明我们的编译成功了,libtest.so成为了一个shared libary。程序之所以不能运行是因为libtest.so不在默认的搜索路径上
    怎样才能让他跑呢?
    $LD_LIBRARY_PATH=$PWD/lib ./app
    hello world1
    我们在自己指定链接的路径,他找到了我们的libtest.so文件,并且链接成功了。

    参考资料:
        《Advenced linux Programming》Mark Mitchell, Jeffrey Oldham,and Alex Samuel
        man nm
        man ar

    作者:iTech
    微信公众号: cicdops
    出处:http://itech.cnblogs.com/
    github:https://github.com/cicdops/cicdops

  • 相关阅读:
    计算机组成原理:“性能”是什么?
    试题 基础练习 Huffuman树
    最小堆的插入删除函数
    特殊函数
    进程控制
    进程的描述
    进程管理
    生成和配置Linux操作系统
    系统调用
    Shell脚本编程
  • 原文地址:https://www.cnblogs.com/itech/p/1562292.html
Copyright © 2011-2022 走看看