zoukankan      html  css  js  c++  java
  • Linux生成动态链接库和静态链接库一

    $gcc -c hello.c -o hello.o

    1.连接成静态库
    连接成静态库使用ar命令,其实ar是archive的意思
    $ar cqs libhello.a hello.o
    2.连接成动态库
    生成动态库用gcc来完成,由于可能存在多个版本,因此通常指定版本号:
    $gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o

    另外再建立两个符号连接:
    $ln -s libhello.so.1.0 libhello.so.1
    $ln -s libhello.so.1 libhello.so
    这样一个libhello的动态连接库就生成了。最重要的是传gcc -shared 参数使其生成是动态库而不是普通执行程序.
    -Wl 表示后面的参数也就是-soname,libhello.so.1直接传给连接器ld进行处理。实际上,每一个库都有一个soname,当连接器发现它正 在查找的程序库中有这样一个名称,连接器便会将soname嵌入连结中的二进制文件内,而不是它正在运行的实际文件名,在程序执行期间,程序会查找拥有 soname名字的文件,而不是库的文件名,换句话说,soname是库的区分标志。
    这样做的目的主要是允许系统中多个版本的库文件共存,习惯上在命名库文件的时候通常与soname相同
    libxxxx.so.major.minor
    其中,xxxx是库的名字,major是主版本号,minor 是次版本号

    至于头文件的使用,只要.c文件和.h文件在同一目录下就可以直接用#include "your.h" 如果在.c文件的上层目录,那只要做如下修改#include "../your.h" 就能够让你的编译器找到了!

    参考:http://blog.csdn.net/lijing3933/archive/2008/01/28/2070381.aspx

    一、创建共享库
    1 单独编译SList.cpp,编译时需要传入-fPIC选项,告诉编译器生成位置无关代码.
    位置无关代码可以被加载到地址空间的任意位置而不需要修改.

    [root@LEE src]# ls
    main.cpp SList.cpp SList.h
    [root@LEE src]# g++ -fPIC -g -c SList.cpp

    2 当链接到库时,为链接器传入-shared选项,把目标文件SList.o链接为共享对象
    libSList.so.1.0.1
    每个共享库都有一个特定的搜索名(soname).搜索名约定如下:
    lib+库名+.so+.版本号
    在文件系统中,搜索名是一个指向实名的符号连接.每个共享库也有一个特定的实名,约定如下:
    搜索名+.子版本号+.发布号
    你可以使用一个特殊的编译器选项-Wl,option,将option传给ld,用逗号分隔多个option,
    为了在所有的系统上得到最好结果,链接libSList到标准C++库上

    [root@LEE src]# g++ -g -shared -Wl,-soname,libSList.so.1 -o libSList.so.1.0.1 SList.o -lstdc++
    [root@LEE src]# ls
    libSList.so.1.0.1 main.cpp SList.cpp SList.h SList.o

    libSList.so.1是搜索名,libSList.so.1.0.1是实名,SList.o是目标文件(也可以是多个目标文件的列表)
    ,-lstdc++是库需要访问的库(也可以是库的列表-llibrary,关于此选项参考附录.)

    3 创建一个从soname链接到库
    [root@LEE src]# ln -fs libSList.so.1.0.1 libSList.so.1
    [root@LEE src]# ln -fs libSList.so.1 libSList.so

    4 使用-L使链接器在当前目录中查找库,并且使用-lSList告诉它要链接哪个库
    [root@LEE src]# g++ -g -c main.cpp -o main.o
    [root@LEE src]# g++ -g -o main main.o -L. -lSList
    [root@LEE src]# ls
    libSList.so libSList.so.1.0.1 main.cpp SList.cpp SList.o
    libSList.so.1 main main.o SList.h

    5 运行命令
    [root@LEE src]# LD_LIBRARY_PATH=$(pwd) ./main
    4->17->19->10->23->21->11->20

    LD_LIBRARY_PATH
    提供用来搜索库的目录路径,以冒号作为间隔.正常情况下它不应该被设置,因为系统文件
    /ect/ld.so.conf提供了默认的路径.

    二、使用链接库
    当运行一个程序时,动态装载器通常在/ect/ld.so.conf.d目录查找程序所需要的库.但是,如果
    LD_LIBRARY_PATH 环境变量被设置,它首先扫描在LD_LIBRARY_PATH 中列出的目录.对于上一节5,如果直接运行
    命令 ./main,会出现找不到库的现象.如:
    [root@LEE src]# ./main
    ./main: error while loading shared libraries: libSList.so.1: cannot open shared object file: No such file or directory

    上述问题的解决方案有两种(我能想到的):
    1 如果LD_LIBRARY_PATH 没设定:
    拷贝libSList.so到目录 /usr/local/lib (同理也可以拷到/usr/lib下)
    [root@LEE src]# cp libSList.so /usr/local/lib
    [root@LEE src]# ldconfig /usr/local/lib
    [root@LEE src]# ./main
    4->17->19->10->23->21->11->20

    2 如果LD_LIBRARY_PATH 设定:
    编辑.bash_profile文件
    添加LD_LIBRARY_PATH:=$LD_LIBRARY_PATH:/path/to/libSList.so(不包括 libSList.so)
    执行.bash_profile 文件.
    [root@LEE src]# . /root/.bash_profile
    [root@LEE src]# ./main
    4->17->19->10->23->21->11->20

  • 相关阅读:
    【工具篇】抓包中的王牌工具—Fiddler (2-工具介绍)
    SQL注入攻击的常见方式及测试方法
    Xshell访问和连接Linux
    【户口篇】换房过程中,户口怎么迁移?
    【计算机篇】二维码解析、短地址生成器
    【工具篇】Sublime Text 2/3 安装汉化破解、插件包安装教程详解
    【通用】登录功能测试用例
    【工具篇】接口测试神器 -- Postman 入门教程
    【生活篇】微信运动刷步,高达98000!微信运动计步作弊教程!
    关于The C compiler "arm-none-eabi-gcc" is not able to compile a simple test program. 的错误自省...
  • 原文地址:https://www.cnblogs.com/snailrun/p/2644887.html
Copyright © 2011-2022 走看看