精华内容
下载资源
问答
  • Linux下链接动态库静态库的理解 [日期:2009-04-18] 来源:Linux社区 作者:dingjoey   Linux程序GCC编译基本过程 一个程式从原始码到可执行文件(或共享库文件),一般都要经过预处理、编译...

    Linux下链接动态库静态库的理解

    [日期:2009-04-18]            来源:Linux社区  作者:dingjoey

     

    Linux程序GCC编译基本过程

    一个程式从原始码到可执行文件(或共享库文件),一般都要经过预处理、编译、汇编和链接这四个步骤。

    编译过程扫描头文件的搜索路径顺序

    gcc 在编译时如何去寻找所需要的头文件 :

    ※所以header file的搜寻会从-I开始

    ※然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH

    1.编译目标代码时指定的动态库搜索路径;

    2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;

    3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;

    4.默认的动态库搜索路径/lib;

    5.默认的动态库搜索路径/usr/lib。

    有关环境变量:

    LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径

    LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径

    链接过程

     建立静态库方法(包括静态内部库和动态外部库)

    gcc -c fun.c

    ar cqs libfun.a fun.o

     编译中使用静态库方法

    gcc call.c -static -L. -lfun -o fun_static_call

     建立动态库(包括动态内部库和动态外部库)

    gcc fun.c -fPIC -shared -o libfun.so

     编译中使用动态库方法

    gcc call.c -L. -lfun -o fun_dyn_call

    编译器会先在path文件夹下搜索libxxx.so文件,如果没有找到,继续搜索libxxx.a(静态库)。

    执行过程

     无论是使用动态库还是外部库链接时都是使用的ld连接器;

     使用动态库的程序执行时使用动态加载器。在Linux 下,加载器是/lib/ld-Linux.so.X(X是版本号)。然后加载器搜索、加载程序所要使用的动态链接库。搜索顺序见上。

     

    展开全文
  • 一个程式从原始码到可执行文件(或共享文件),一般都要经过预处理、编译、汇编和链接这四个步骤。 编译过程扫描头文件的搜索路径顺序 gcc 在编译时如何去寻找所需要的头文件 : ※所以header file的搜寻...

    Linux程序GCC编译基本过程

    一个程式从原始码到可执行文件(或共享库文件),一般都要经过预处理、编译、汇编和链接这四个步骤。

    编译过程扫描头文件的搜索路径顺序

    gcc 在编译时如何去寻找所需要的头文件 :

    ※所以header file的搜寻会从-I开始

    ※然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH

    ※再找内定目录

    /usr/include

    /usr/local/include

    /usr/lib/gcc-lib/i386-linux/2.95.2/include

    /usr/lib/gcc-lib/i386-linux/2.95.2/../../../../include/g++-3

    /usr/lib/gcc-lib/i386-linux/2.95.2/../../../../i386-linux/include

    库文件但是如果装gcc的时候,是有给定的prefix的话,那么就是

    /usr/include

    prefix/include

    prefix/xxx-xxx-xxx-gnulibc/include

    prefix/lib/gcc-lib/xxxx-xxx-xxx-gnulibc/2.8.1/include

    尤其注意链接过程是本文要重点讨论的:

    链接步骤要经历链接内部库(即当前程序源码编译而成的.a,.o,.so)和外部库(依赖的外部静态lib.a、动态库lib.so)

    外部库

    外部库有两种: (1)静态连接库lib.a

           (2)共享连接库lib.so

    共同点:

    .a, .so都是.o目标文件的集合,这些目标文件中含有一些函数的定义(机器码),而这些函数将在连接时会被最终的可执行文件用到。

    区别:

    静态库.a  : 当程序与静态库连接时,库中目标文件所含的所有将被程序使用的函数的机器码被copy到最终的可执行文件中。

    共享库.so : 与共享库连接的可执行文件只包含它需要的函数的表,而不是所有的函数代码,在程序执行之前,那些需要的函数代码被拷贝到内存中,这样就使可执行文件比较 小,节省磁盘空间(更进一步,操作系统使用虚拟内存,使得一份共享库驻留在内存中被多个程序使用)。共享库还有个优点:若库本身被更新,不需要重新编译与 它连接的源程序。

    Linux下库是如何产生的

    静态库的后缀是.a,它的产生分两步

    Step 1.由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表

    Step 2.ar命令将很多.o转换成.a,成文静态库

    动态库的后缀是.so,它由gcc加特定参数编译产生。

    例如:

    $ gcc -fPIC -c *.c $ gcc -shared -Wl,-soname, libfoo.so.1 -o libfoo.so.1.0 *.

    Linux下库文件是如何命名的,如何存放

    静态库的名字一般为libxxxx.a,其中xxxx是该lib的名称

    动态库的名字一般为libxxxx.so.major.minor,xxxx是该lib的名称,major是主版本号, minor是副版本号

    Linux下,库文件一般放在/usr/lib /lib下,

    如果安装在/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作。

    如果安装在其他目录,需要将其添加到/etc/ld.so.cache文件中,步骤如下

    1.编辑/etc/ld.so.conf文件,加入库文件所在目录的路径

    2.运行ldconfig,该命令会重建/etc/ld.so.cache文件

    Linux中有关编译链接要是用的库扫描路径,与有关环境变量

    静态库链接时搜索路径顺序:

    1.ld会去找GCC命令中的参数-L

    2.再找gcc的环境变量LIBRARY_PATH

    3.再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的

    动态链接时、执行时搜索路径顺序:

    1.编译目标代码时指定的动态库搜索路径;

    2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;

    3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;

    4.默认的动态库搜索路径/lib;

    5.默认的动态库搜索路径/usr/lib。

    有关环境变量:

    LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径

    LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径

    链接过程

     建立静态库方法(包括静态内部库和动态外部库)

    gcc -c fun.c

    ar cqs libfun.a fun.o

     编译中使用静态库方法

    gcc call.c -static -L. -lfun -o fun_static_call

     建立动态库(包括动态内部库和动态外部库)

    gcc fun.c -fPIC -shared -o libfun.so

     编译中使用动态库方法

    gcc call.c -L. -lfun -o fun_dyn_call

    编译器会先在path文件夹下搜索libxxx.so文件,如果没有找到,继续搜索libxxx.a(静态库)。

    执行过程

     无论是使用动态库还是外部库链接时都是使用的ld连接器;

     使用动态库的程序执行时使用动态加载器。在Linux 下,加载器是/lib/ld-Linux.so.X(X是版本号)。然后加载器搜索、加载程序所要使用的动态链接库。搜索顺序见上。

    展开全文
  • gcc -shared -fpic add.o sub.o -o ...(一)此时动态库文件只在当前目录 ① gcc main.c -o main -L./ -lcount1 //编译通过:-L指定动态库文件所在路径,l指定库文件名 ./main //运行报错:error while ...

    一、gcc链接动态库编译时-L的问题

    gcc -shared -fpic add.o sub.o -o libcount1.so  
    //(-l(小写l)指定动态库文件名)
    //生成动态库文件libcount1.so
    

    (一)此时动态库文件只在当前目录下

    gcc main.c -o main -L./ -lcount1
    //编译通过:-L指定动态库文件所在路径,l指定库文件名
    
    ./main
    //运行报错:error while loading shared libraries: libcount1.so: cannot open shared object file:
    //          加载共享库时出错:libcount1。因此:无法打开共享对象文件:没有这样的文件或目录
    //原因?(看结论)
    

    gcc main.c -o main -lcount1
    //编译时没有用-L指定动态库文件所在路径
    //编译报错 /usr/bin/ld: cannot find -lcount1
    //          /usr/bin/ld下找不到count1
    //原因?(看结论)
    

    (二)将动态库文件libcount1.so复制到/lib/下,但原目录下动态库文件并未删除 :

    sudo cp libcount1.so /lib/
    

    gcc main.c -o main -L./ -lcount1
    //编译通过
    //运行通过
    

    gcc main.c -o main -lcount1
    //编译通过
    //运行通过
    

    (三)将动态库文件libcount1.so复制到/lib/后,并且删除原目录下动态库文件 :

    rm libcount1.so
    

    gcc main.c -o main -L./ -lcount1
    //编译通过
    //运行通过
    

    gcc main.c -o main -lcount1
    //编译通过
    //运行通过
    

    结论:在linux下gcc编译时如果需要链接动态库文件,则有两个链接过程:
    编译时链接,运行时链接

    编译时链接:系统会优先从-L指定的路径查找库文件,若没有则从/lib/下查找,所以如果/lib/下面有所需静态库文件则-L可省略,链接之后的文件会记住动态库里面相应的函数地址

    运行时链接:系统会直接在/lib/下查找所需动态库文件,若没有则运行报错,找到后将相应函数定义链接进来然后执行

    所以实际上用-L指定动态库文件路径只能保证编译通过,是否能执行还是得看/lib/下面有没有该库文件

    二、gcc编译链接静态库时-L的问题

    ar -rc libhaha.a add.o sub.o
    //生成静态库文件libhaha.a
    

    此时动态库文件只在当前目录下

    gcc main.c -o main -L./ -lhaha
    //编译通过
    //运行通过
    
    gcc main.c -o main -lhaha
    //编译报错
    //usr/bin/ld: cannot find -lhaha
    // /bin/下无法找到静态库文件
    

    结论:在进行编译链接静态库时,必须用-L指定静态库文件路径即可编译并运行通过,因为链接静态库时只有编译时来链接而没有运行时链接所以不需要将静态库放到/lib/下面

    展开全文
  • 首先说/etc/ld.so.conf: ...这个文件记录了编译时使用的动态链接库的路径。 默认情况,编译器只会使用/lib和/usr/lib这两个目录文件 如果你安装了某些,比如在安装gtk+-2.4.13时它会需要glib-2.0

    http://dev.firnow.com/course/6_system/linux/Linuxjs/200874/130190.html

    首先说下/etc/ld.so.conf:

    这个文件记录了编译时使用的动态链接库的路径。
    默认情况下,编译器只会使用/lib和/usr/lib这两个目录下的库文件
    如果你安装了某些库,比如在安装gtk+-2.4.13时它会需要glib-2.0 >= 2.4.0,辛苦的安装好glib后
    没有指定 --prefix=/usr 这样glib库就装到了/usr/local下,而又没有在/etc/ld.so.conf中添加/usr/local/lib
    这个搜索路径,所以编译gtk+-2.4.13就会出错了 
    对于这种情况有两种方法解决:
    一:在编译glib-2.4.x时,指定安装到/usr下,这样库文件就会放在/usr/lib中,gtk就不会找不到需要的库文件了 
    对于安装库文件来说,这是个好办法,这样也不用设置PKG_CONFIG_PATH了 (稍后说明)

    二:将/usr/local/lib加入到/etc/ld.so.conf中,这样安装gtk时就会去搜索/usr/local/lib,同样可以找到需要的库 
    将/usr/local/lib加入到/etc/ld.so.conf也是必须的,这样以后安装东东到local下,就不会出现这样的问题了。
    将自己可能存放库文件的路径都加入到/etc/ld.so.conf中是明智的选择 ^_^
    添加方法也极其简单,将库文件的绝对路径直接写进去就OK了,一行一个。例如:
    /usr/X11R6/lib
    /usr/local/lib
    /opt/lib

    再来看看ldconfig是个什么东东吧 :

    它是一个程序,通常它位于/sbin下,是root用户使用的东东。具体作用及用法可以man ldconfig查到
    简单的说,它的作用就是将/etc/ld.so.conf列出的路径下的库文件 缓存到/etc/ld.so.cache 以供使用
    因此当安装完一些库文件,(例如刚安装好glib),或者修改ld.so.conf增加新的库路径后,需要运行一下/sbin/ldconfig
    使所有的库文件都被缓存到ld.so.cache中,如果没做,即使库文件明明就在/usr/lib下的,也是不会被使用的,结果
    编译过程中抱错,缺少xxx库,去查看发现明明就在那放着,搞的想大骂computer蠢猪一个。 ^_^
    我曾经编译KDE时就犯过这个错误,(它需要每编译好一个东东,都要运行一遍),所以

    切记改动库文件后一定要运行一下ldconfig,在任何目录下运行都可以。


    再来说说 PKG_CONFIG_PATH这个变量吧:

    经常在论坛上看到有人问"为什么我已经安装了glib-2.4.x,但是编译gtk+-2.4.x 还是提示glib版本太低阿?
    为什么我安装了glib-2.4.x,还是提示找不到阿?。。。。。。"都是这个变量搞的鬼。
    先来看一个编译过程中出现的错误 (编译gtk+-2.4.13):

    checking for pkg-config... /usr/bin/pkg-config
    checking for glib-2.0 >= 2.4.0 atk >= 1.0.1 pango >= 1.4.0... Package glib-2.0 was not found in the pkg-config search path.
    Perhaps you should add the directory containing `glib-2.0.pc'
    to the PKG_CONFIG_PATH environment variable
    No package 'glib-2.0' found

    configure: error: Library requirements (glib-2.0 >= 2.4.0 atk >= 1.0.1 pango >= 1.4.0) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.
    [root@NEWLFS gtk+-2.4.13]#
    很明显,上面这段说明,没有找到glib-2.4.x,并且提示应该将glib-2.0.pc加入到PKG_CONFIG_PATH下。
    究竟这个pkg-config PKG_CONFIG_PATH glib-2.0.pc 是做什么的呢? let me tell you ^_^
    先说说它是哪冒出来的,当安装了pkgconfig-x.x.x这个包后,就多出了pkg-config,它就是需要PKG_CONFIG_PATH的东东
    pkgconfig-x.x.x又是做什么的? 来看一段说明:

    The pkgconfig package contains tools for passing the include path and/or library paths to build tools during the make file execution.

    pkg-config is a function that returns meta information for the specified library.

    The default setting for PKG_CONFIG_PATH is /usr/lib/pkgconfig because of the prefix we use to install pkgconfig. You may add to PKG_CONFIG_PATH by exporting additional paths on your system where pkgconfig files are installed. Note that PKG_CONFIG_PATH is only needed when compiling packages, not during run-time.

    我想看过这段说明后,你已经大概了解了它是做什么的吧。
    其实pkg-config就是向configure程序提供系统信息的程序,比如软件的版本啦,库的版本啦,库的路径啦,等等
    这些信息只是在编译其间使用。你可以 ls /usr/lib/pkgconfig 下,会看到许多的*.pc,用文本编辑器打开
    会发现类似下面的信息:

    prefix=/usr
    exec_prefix=$
    libdir=$/lib
    includedir=$/include

    glib_genmarshal=glib-genmarshal
    gobject_query=gobject-query
    glib_mkenums=glib-mkenums

    Name: GLib
    Description: C Utility Library
    Version: 2.4.7
    Libs: -L$ -lglib-2.0
    Cflags: -I$/glib-2.0 -I$/glib-2.0/include

    明白了吧,configure就是靠这些信息判断你的软件版本是否符合要求。并且得到这些东东所在的位置,要不去哪里找呀。
    不用我说你也知道为什么会出现上面那些问题了吧。

    解决的办法很简单,设定正确的PKG_CONFIG_PATH,假如将glib-2.x.x装到了/usr/local/下,那么glib-2.0.pc就会在
    /usr/local/lib/pkgconfig下,将这个路径添加到PKG_CONFIG_PATH下就可以啦。并且确保configure找到的是正确的
    glib-2.0.pc,就是将其他的lib/pkgconfig目录glib-2.0.pc干掉就是啦。(如果有的话 ^-^)
    设定好后可以加入到~/.bashrc中,例如:
    PKG_CONFIG_PATH=/opt/kde-3.3.0/lib/pkgconfig:/usr/lib/pkgconfig:/usr/local/pkgconfig:
    /usr/X11R6/lib/pkgconfig
    [root@NEWLFS ~]#echo $PKG_CONFIG_PATH
    /opt/kde-3.3.0/lib/pkgconfig:/usr/lib/pkgconfig:/usr/local/pkgconfig:/usr/X11R6/lib/pkgconfig

    从上面可以看出,安装库文件时,指定安装到/usr,是很有好处的,无论是/etc/ld.so.conf还是PKG_CONFIG_PATH
    默认都会去搜索/usr/lib的,可以省下许多麻烦,不过从源码包管理上来说,都装在/usr下
    管理是个问题,不如装在/usr/local下方便管理
    其实只要设置好ld.so.conf,PKG_CONFIG_PATH路径后,就OK啦 ^_^ 
      
    附:ldconfig man(8) 
       
    Name
    /sbin/ldconfig - configure dynamic linker run time bindings

    Synopsis
    /sbin/ldconfig [ -nNvXV ] [ -f conf ] [ -C cache ] [ -r root ] directory ...
    /sbin/ldconfig -l [ -v ] library ...
    /sbin/ldconfig -p

    Description


    ldconfig creates the necessary links and cache to the most recent shared libraries found in the directories specified on the command line, in the file /etc/ld.so.conf, and in the trusted directories (/lib and /usr/lib). The cache is used by the run-time linker, ld.so or ld-linux.so. ldconfig checks the header and filenames of the libraries it encounters when determining which versions should have their links updated.

    ldconfig will attempt to deduce the type of ELF libs (ie. libc5 or libc6/glibc) based on what C libs, if any, the library was linked against. Therefore, when making dynamic libraries, it is wise to explicitly link against libc (use -lc).

    Some existing libs do not contain enough information to allow the deduction of their type. Therefore, the /etc/ld.so.conf file format allows the specification of an expected type. This is only used for those ELF libs which we can not work out. The format is "dirname=TYPE", where TYPE can be libc4, libc5, or libc6. (This syntax also works on the command line.) Spaces are not allowed. Also see the -p option. ldconfig should normally be run by the superuser as it may require write permission on some root owned directories and files.

    Options
    -v 
    Verbose mode. Print current version number, the name of each directory as it is scanned, and any links that are created. Overrides quiet mode.

    -n

    Only process directories specified on the command line. Don't process the trusted directories (/lib and /usr/lib) nor those specified in /etc/ld.so.conf. Implies -N.

    -N

    Don't rebuild the cache. Unless -X is also specified, links are still updated.

    -X

    Don't update links. Unless -N is also specified, the cache is still rebuilt.

    -f conf 
    Use conf instead of /etc/ld.so.conf. 
    -C cache 
    Use cache instead of /etc/ld.so.cache. 
    -r root 
    Change to and use root as the root directory. 
    -l 
    Library mode. Manually link individual libraries. Intended for use by experts only.

    -p

    Print the lists of directories and candidate libraries stored in the current cache.

    Files
    /lib/ld.so 
    run-time linker/loader

    /etc/ld.so.conf

    File containing a list of colon, space, tab, newline, or comma-separated directories in which to search for libraries.

    /etc/ld.so.cache

    File containing an ordered list of libraries found in the directories specified in /etc/ld.so.conf.

    展开全文
  • 在centos编译动态库,测试的时候始终通不过,一直报错,在网上查资料,想起来编译链接动态库时需要设置查询动态库的路径,我设置的是LD_LIBRARY_PATH,命令为 export LD_LIBRARY_PATH=$(BIN_DIR):$LD_LIBRARY_...
  • 最近又重新复习了一下Linux下动态链接库和静态链接库,稍作笔记以备后查。 1. 静态链接库动态链接库  静态链接库就是一个多个汇编文件(obj文件)的集合,在Linux中通常命名为libxxx.a。对于静态链接库函数的连接...
  • PS1、linux库文件分为静态库和动态库两种。静态库习惯以.a 结尾,而动态库习惯以.so(shared object)结尾。而且必须以lib开头。2、静态库的原则是“以空间换时间”,增加程序体积,减少运行时间;生成:在编译时候,...
  • 对于Linux下的c++部署来说,最头疼的就是动态库依赖了。在本地运行很好的程序换一台机器可能就不好用了。(此处暂时部考虑docker) 因为安装在本地的动态库在部署的机器上没有,就算有路径也未必一致,版本也不一定...
  • Linux 下动态链接库so

    2019-09-12 17:00:22
    Linux 下动态链接库(shared object file,共享对象文件)的文件后缀为.so,它是一种特殊的目标文件(object file),可以在程序运行时被加载(链接)进来。使用动态链接库的优点是:程序的可执行文件更小,便于程序...
  • linux下QT链接动态库

    千次阅读 2019-04-18 11:27:35
    QT链接动态库.so 在.pro中空白地方右键添加库 选中你要链接的库,会自动在.pro中生成相对链接代码,完全不需要手动添加 如果你要使用链接的库函数,需要在你的项目头文件的中#include进来你所链接的库的头文件 这是...
  • 类似Windows系统中的动态链接库,Linux中也有相应的共享库...Windows中为*.dll,而Linux中为*.so,我来详细的告诉你如何在linux下编写动态库,以及如何使用它. 在linux下编写动态链接库的步骤: 1. 编写库的头文...
  • Linux下动态链接库调用 2014-11-01 10:39 3人阅读 评论(0) 收藏 编辑 删除 Linux下动态链接库调用  2013-06-08 20:52:48| 分类:集成开发环境相关 |举报|字号 订阅 Linux下的静态...
  • ... Linux下找不到共享文件的典型现象为明明已经安装某个软包(如libnet,MySQL),编译连接可以正常进行,但是在运行时出现如“error while loading shared libraries: libnet.so.1:cannot...
  • Linux下静态链接库动态链接库的区别 标签: linuxlibrarypathgcc编译器file 2011-01-14 11:52 14552人阅读 评论(3) 收藏 举报  分类: linux高级编程(9)  目录(?)[+] ...
  • linux 下动态链接库的制作与使用动态链接库*.so的编译与使用- -动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记...
  • 主要介绍了Linux下动态链接库加载路径及搜索路径问题,需要的朋友可以参考下
  • Linux下动态链接库的使用 Linux下的静态链接库,做起来比较容易,只要将目标文件用ar打包就可以,下面写一下动态链接库的制作和使用方法,完全是根据个人理解和经验总结,有不对的地方还请大家指正。 动态链接库...
  • Linux下动态链接库的2种链接方式 方式一 通过 dlopen, dlsym, dlerror, dlclose 在代码中直接打开与使用动态链接库 dlopen 用于打开动态链接库,返回句柄 dlsym 使用dlopen返回的句柄与函数名来获得函数位置,返回...
  • Linux 下动态链接库的生成与使用 动态链接库介绍 动态链接库是一种不可以直接执行的二进制程序文件,它允许程序共享执行一段公用的代码和资源。 在 Linux 平台上动态链接库是以 .so 作为后缀名的。 相对于静态链接库...
  • Linux下动态库链接问题 今天在编译一个软件做链接时,提示找不到-lgtk-3,安装此库 1.安装libgtk-3库 apt-get install libgtk-3-0 apt-get install libgtk-3-dev 安装完成后查找动态库的安装路径 dpkg -L libgtk-3-...
  • 关于链接库的知识,网上太多资料了,但是并不代表我...链接库,顾名思义,就是一些函数代码的集合,主要有静态链接库动态链接库两种 二者的不同点在于代码被载入的时刻不同。 静态的代码在编译过程中已经被载...
  • Linuxc链接动态库

    2016-12-21 12:21:24
    linux下,C程序中引用动态库的方法: 程序中引用: 例子: #include //必须添加的头文件 char *p = dlopen("./lib/test.so",RTLD_LAZY); //打开 p = dlerror(void); p = dlsym(void *handl
  • LINUX下动态链接库的使用 2.1 重要的dlfcn.h头文件 LINUX下使用动态链接库,源程序需要包含dlfcn.h头文件,此文件定义了调 用动态链接库的函数的原型。下面详细说明一下这些函数...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,044
精华内容 1,617
关键字:

linux下链接动态库

linux 订阅