`
makeyouown
  • 浏览: 50482 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

保存的linux 知识

 
阅读更多
  Linux下文件的类型是不依赖于其后缀名的,但一般来讲:
    .o,是目标文件,相当于windows中的.obj文件
    .so 为共享库,是shared object,用于动态连接的,和dll差不多
    .a为静态库,是好多个.o合在一起,用于静态连接
    .la为libtool自动生成的一些共享库,vi编辑查看,主要记录了一些配置信息。可以用如下命令查看*.la文件的格式   $file *.la

       *.la: ASCII English text
    所以可以用vi来查看其内容。
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    创建.a库文件和.o库文件:
    [yufei@localhost perl_c2]$ pwd
    /home/yufei/perl_c2

    [yufei@localhost perl_c2]$ cat mylib.c
    #include <stdio.h>
    #include <string.h>
    void hello(){
            printf("success call from perl to c library\n");
    }
    [yufei@localhost perl_c2]$ cat mylib.h
    extern void hello();


    [yufei@localhost perl_c2]$ gcc -c mylib.c
    [yufei@localhost perl_c2]$ dir
    mylib.c  mylib.h  mylib.o
    [yufei@localhost perl_c2]$ ar -r mylib.a mylib.o
    ar: 正在创建 mylib.a
    [yufei@localhost perl_c2]$ dir
    mylib.a  mylib.c  mylib.h  mylib.o


    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    动态链接库*.so的编译与使用- -


    动态库*.so在Linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一点帮助。


    1、动态库的编译

    下面通过一个例子来介绍如何生成一个动态库。这里有一个头文件:so_test.h,三个.c文件:test_a.c、test_b.c、test_c.c,我们将这几个文件编译成一个动态库:libtest.so。

    so_test.h:

    #include <stdio.h>
    #include <stdlib.h>
    void test_a();
    void test_b();
    void test_c();

    test_a.c:

    #include "so_test.h"
    void test_a()
    {
        printf("this is in test_a...\n");
    }

    test_b.c:

    #include "so_test.h"
    void test_b()
    {
        printf("this is in test_b...\n");
    }

    test_c.c:

    #include "so_test.h"
    void test_c()
    {
        printf("this is in test_c...\n");
    }

    将这几个文件编译成一个动态库:libtest.so
    $ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so

    2、动态库的链接

    在1、中,我们已经成功生成了一个自己的动态链接库libtest.so,下面我们通过一个程序来调用这个库里的函数。程序的源文件为:test.c。
    test.c:

    #include "so_test.h"
    int main()
    {
        test_a();
        test_b();
        test_c();
        return 0;

    }
    l         将test.c与动态库libtest.so链接生成执行文件test:
    $ gcc test.c -L. -ltest -o test

    l         测试是否动态连接,如果列出libtest.so,那么应该是连接正常了

    $ ldd test
    l         执行test,可以看到它是如何调用动态库中的函数的。
    3、编译参数解析
    最主要的是GCC命令行的一个选项:
              -shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件

    l         -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

    l         -L.:表示要连接的库在当前目录中

    l         -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称

    l         LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

    l         当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。
    4、注意
          调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过“-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作的就是通过修改LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。

    makefile里面怎么正确的编译和连接生成.so库文件,然后又是在其他程序的makefile里面如何编译和连接才能调用这个库文件的函数????
    答:
           你需要告诉动态链接器、加载器ld.so在哪里才能找到这个共享库,可以设置环境变量把库的路径添加到库目录/lib和/usr/lib,LD_LIBRARY_PATH=$(pwd),这种方法采用命令行方法不太方便,一种替代方法
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^注释^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    LD_LIBRARY_PATH可以在/etc/profile还是 ~/.profile还是 ./bash_profile里设置,或者.bashrc里,

    改完后运行source /etc/profile或 . /etc/profile
    更好的办法是添入/etc/ld.so.conf, 然后执行 /sbin/ldconfig

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^注释^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    是把库路径添加到/etc/ld.so.conf,然后以root身份运行ldconfig
          也可以在连接的时候指定文件路径和名称 -I  -L.

          GCC=gcc
    CFLAGS=-Wall -ggdb -fPIC
    #CFLAGS=
    all: libfunc test
    libfunc:func.o func1.o
            $(GCC) -shared -Wl,-soname,libfunc.so.1 -o libfunc.so.1.1 $<
            ln -sf libfunc.so.1.1 libfunc.so.1
            ln -sf libfunc.so.1 libfunc.so
    ***********************************************注释************************************************
    ln -s是用来创建软链接,也就相当于windows中的快捷方式,在当前目录中创建上一级目录中的文件ttt的命名为ttt2软链接的命令是ln -s ../ttt ttt2,如果原文件也就是ttt文件删除的话,ttt2也变成了空文件。
    ln -d是用来创建硬链接,也就相当于windows中文件的副本,当原文件删除的时候,并不影响“副本”的内容。

    编译目标文件时使用gcc的-fPIC选项,产生与位置无关的代码并能被加载到任何地址:
    gcc –fPIC –g –c liberr.c –o liberr.o
    使用gcc的-shared和-soname选项;
    使用gcc的-Wl选项把参数传递给连接器ld;
    使用gcc的-l选项显示的连接C库,以保证可以得到所需的启动(startup)代码,从而避免程序在使用不同的,可能不兼容版本的C库的系统上不能启动执行。
    gcc –g –shared –Wl,-soname,liberr.so –o liberr.so.1.0.0 liberr.o –lc

    建立相应的符号连接:
    ln –s liberr.so.1.0.0 liberr.so.1;
    ln –s liberr.so.1.0.0 liberr.so;

    在MAKEFILE中:
    $@
        表示规则中的目标文件集。在模式规则中,如果有多个目标,那么,"$@"就是匹配于目标中模式定义的集合。
    $%
       仅当目标是函数库文件中,表示规则中的目标成员名。例如,如果一个目标是"foo.a(bar.o)",那么,"$%"就是"bar.o","$@"就是"foo.a"。如果目标不是函数库文件(Unix下是[.a],Windows下是[.lib]),那么,其值为空。
    $<
        依赖目标中的第一个目标名字。如果依赖目标是以模式(即"%")定义的,那么"$<"将是符合模式的一系列的文件集。注意,其是一个一个取出来的。
    $?
        所有比目标新的依赖目标的集合。以空格分隔。
    $^
        所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。
    *********************************************注释***********************************************************************
    test: test.o libfunc
            $(GCC) -o test test.o -L. -lfunc
    %.o:%.c
            $(GCC) -c $(CFLAGS) -o $@ $<
    clean:
            rm -fr *.o
            rm -fr *.so*
            rm -fr test

    要生成.so文件,cc要带-shared 参数;要调用.so的文件,比如libfunc.so,可以在cc命令最后加上-lfunc,还要视情况加上-L/usr/xxx 指出libfunc.so的路径;这样,在你要编译的源文件中就可以调用libfunc.so这个库文件的函数.
           前面的都说的差不多了,最后提醒一下最好提供一个接口头文件
           动态加载,用dlopen,dlclose,dlsym

分享到:
评论

相关推荐

    测试一下你的linux知识

    一....3. 将/home/ixdba目录做归档压缩,压缩后生成ixdba.tar.bz2文件,并将此文件保存到/home目录下,实现此任务的tar命令格式_____ 4. 在Linux系统下,第二个IDE通道的硬盘(从盘)被标识为_____

    Linux 编程学习代码保存.rar

    编辑结束,按ESC 键 跳到命令模式,然后输入退出命令: :w (write)保存文件但不退出vi 编辑 :w! 强制保存,不退出vi 编辑 :w file 将修改另存到file中,...文章知识点与官方知识档案匹配,可进一步学习相关知识

    Linux防火墙思维导图.xmind

    linux防火墙知识:利用思维导图的形式(包括举例),一张图进行全部详解 1.何为防火墙?2.防火墙的分类 3.iptables原理 4.防火墙顺序 5.iptables语法规则

    LINUX操作系统(电子教案,参考答案)

    芬兰青年Linus Torvalds和其杰作的传奇故事吸引了无数的电脑爱好者尝试去使用Linux,但他们中的大多数人却被Unix类操作系统传统的枯燥的字符界面、艰涩难懂的操作命令和数量庞大的基本概念以及基础知识所吓退。Linux...

    linux基础知识1

    1.&gt;hostname
查看主机名 2.&gt;
vi
/etc/sysconfig/network

修改hostname的值保存 3.&gt;
vi
/etc/host

    Linux基础知识之基本命令

    一:配置环境变量,实现执行history...基本命令语法格式可以通过man 命令来进行查询,这里只是通过date这个命令进行简单示范,在学习linux知识,融合帮助文档进行学习很多时候都可以达到事半功倍的效果! 举例: man

    Linux服务器配置与管理:Linux磁盘接口及设备命名.pptx

    【知识目标】 了解:Linux的磁盘接口 熟悉:Linux磁盘分区表示方法 【能力目标】 认识磁盘各类接口,能为磁盘分区命名。 【思政目标】 磁盘命名及操作程序来不得半点马虎,培养学生精益求精的工匠精神。 1.1 磁盘的...

    操作系统安全:linux系统日志介绍.ppt

    系统日志介绍 Linux系统拥有非常灵活和强大的日志功能,可以保存几乎所有的操作记录,并可以从中检索出我们需要的信息。 大部分Linux发行版默认的日志守护进程为 syslog,位于 /etc/syslog 或 /etc/syslogd 或/etc/...

    linux零基础学习.pdf

    linux 学习入门级宝典  Linux零基础初级教程作者:红联 Linux零基础初级教程 ...也给自己留下有保存价值的信息,以便今后再学习。怎么样,学习笔记有那么大的魅力,还等什么, diy写一份属于自己学习Linux的资料吧!

    linux tar命令详解

     有了上面的知识,你应该能解开多种压缩文件了,下面对于tar系列的压缩文件作一个小结:  1)对于.tar结尾的文件  tar -xf all.tar  2)对于.gz结尾的文件  gzip -d all.gz  gunzip all.gz  3)对于.tgz或.tar....

    嵌入式设计及linux驱动开发指南——基于ARM9处理器.pdf

    6.5.20 保存内核配置 第7章 Linux设备驱动程序开发 7.1 设备驱动概述 7.1.1 设备驱动和文件系统的关系 7.1.2 设备类型分类 7.1.3 内核空间和用户空间.. 7.2 设备驱动基础 7.2.1 设备驱动中关键数据结构 ...

    Linux管理员指南

    知识 226 15.3.2 Sendmail软件使用的宏命令 228 15.3.3 一个完整的配置示例 235 15.3.4 把宏命令编译到配置文件里 235 15.4 安装Sendmail软件 235 15.5 主配置文件以外的其他配置文件 236 15.5.1 ...

    Linux环境下贪吃蛇游戏

    Linux环境下贪吃蛇源代码,基于C语言实现的。用到知识点包括双链表,文件操作,frame buffer接口,键盘接口等等。实现了随机生成实物,游戏暂停,运行,退出状态显示,退出时提示是否保存,下次运行时可以加载。也...

    Linux服务器配置与管理:linux打包压缩.pptx

    【知识目标】 熟悉: Linux打包压缩命令 【能力目标】 会使用打包和解包命令对文件或目录打包和解包 【思政目标】 培养学生职业素养和工匠精神。 tar——是一种标准的文件打包格式 利用tar命令可将要备份的一组文件和...

    深入分析Linux内核源码

    3.3.1 在内核栈中保存寄存器的值 3.3.2 中断请求队列的初始化 3.3.3中断请求队列的数据结构 3.4 中断处理 3.4.1中断和异常处理的硬件处理 3.4.2 Linux对异常和中断的处理 3.4.3 与堆栈有关的常量、数据结构及...

    Linux应用技术:Linux常用命令与VI文件编辑器.docx

    任务5 Linux常用命令与VI编辑器 实验目的 学会Linux基本操作命令 学会Linux目录及文件操作命令 学会启动vi编辑器 掌握vi编辑器的工作模式和常用命令 实验内容 注意!实验前,请将主机名修改为zhangsan(zhangsan为...

    linux启动过程说明

    这篇文章对linux启动过程调用的一些配置文件做了说明,知识本身很简单,一看就明白了,可以作为资料保存,在你需要修改的linux启动配置的时候可以很快帮你找到要改的文件。

    Linux日志分析小工具-GooLogAnalysis_v0.12

    使用Java技术完成,分析Linux登录日志,并将提取到的数据保存入数据库; 后续再通过SQL语句,导出报表;或使用视图,得到需要的分析结果; 看点:基本涉及CoreJava大部分的知识点; 难点:对象匹配方法equals()和...

Global site tag (gtag.js) - Google Analytics