精华内容
下载资源
问答
  • gcc编译链接动态库
    2021-07-18 11:07:57

    1 库的分类

    根据链接时期的不同,库又有静态库和动态库之分。静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行。有别于静态库,动态库的链接是在程序执行的时候被链接的。所以,即使程序编译完,库仍须保留在系统上,以供程序运行时调用。

    2 静态库和动态库的比较

    链接静态库其实从某种意义上来说也是一种粘贴复制,只不过它操作的对象是目标代码而不是源码而已。因为静态库被链接后库就直接嵌入可执行文件中了,这样就带来了两个问题。

    首先就是系统空间被浪费了。这是显而易见的,想象一下,如果多个程序链接了同一个库,则每一个生成的可执行文件就都会有一个库的副本,必然会浪费系统空间。

    再者,人非圣贤,即使是精心调试的库,也难免会有错。一旦发现了库中有bug,挽救起来就比较麻烦了。必须一一把链接该库的程序找出来,然后重新编译。

    而动态库的出现正弥补了静态库的以上弊端。因为动态库是在程序运行时被链接的,所以磁盘上只须保留一份副本,因此节约了磁盘空间。如果发现了bug或要升级也很简单,只要用新的库把原来的替换掉就行了。

    那么,是不是静态库就一无是处了呢?

    如果你用libpcap库编了一个程序,要给被人运行,而他的系统上没有装pcap库,该怎么解决呢?最简单的办法就是编译该程序时把所有要链接的库都链接它们的静态库,这样,就可以在别人的系统上直接运行该程序了。

    所谓有得必有失,正因为动态库在程序运行时被链接,故程序的运行速度和链接静态库的版本相比必然会打折扣。然而瑕不掩瑜,动态库的不足相对于它带来的好处在现今硬件下简直是微不足道的,所以链接程序在链接时一般是优先链接动态库的,除非用-static参数指定链接静态库。

    动态链接库

    1. 创建动态链接库

    用命令gcc -shared hello.c -o libhello.so编译为动态库。可以看到,当前目录下多了一个文件libhello.so。

    2. 再编辑一个测试文件test.c,内容如下

    编译 gcc test.c -lhello

    -l 选项告诉编译器要使用hello这个库。奇怪的地方是动态库的名字是libhello.so,这里却使用hello.

    但这样还不行,编译会出错。

    In function `main':

    test.c:(.text+0x1d): undefined reference to `hello'

    collect2: ld returned 1 exit status

    这是因为hello这个库在我们自己的路径中,编译器找不到。

    需要使用-L选项,告诉hello库的位置

    gcc test.c -lhello -L. -o test

    -L .告诉编译器在当前目录中查找库文件

    3. 编译成功后执行./test, 仍然出错

    说找不到库

    有两种方法:

    一、可以把当前路径加入 /etc/ld.so.conf中然后运行ldconfig,或者以当前路径为参数运行ldconfig(要有root权限才行)。

    二、把当前路径加入环境变量LD_LIBRARY_PATH中

    当然,如果你觉得不会引起混乱的话,可以直接把该库拷入/lib,/usr/lib/等位置(无可避免,这样做也要有权限),这样链接器和加载器就都可以准确的找到该库了。

    我们采用第二种方法:

    export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

    这样,再执行就成功了。

    下面再讲讲静态链接库

    仍使用刚才的hello.c和test.c。

    1. gcc -c hello.c 注意这里没有使用-shared选项

    2. 把目标文件归档    ar -r libhello.a hello.o

    程序 ar 配合参数 -r 创建一个新库 libhello.a 并将命令行中列出的对象文件插入。采用这种方法,如果库不存在的话,参数 -r 将创建一个新的库,而如果库存在的话,将用新的模块替换原来的模块。

    3. 在程序中链接静态库

    gcc test.c -lhello -L. -static -o hello.static 

    或者   gcc test.c libhello.a -L. -o hello.static

    生成的hello.static就不再依赖libhello.a了
     

    更多相关内容
  • gcc编译链接动态库

    千次阅读 2022-01-27 10:04:10
    -fPIC: 表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的,所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。 -shared: 该选项指定生成动态连接(让...


    前言

    以下内容主要作为学习记录,有不准确的地方希望帮忙指出来,谢谢


    以下是本篇文章正文内容,下面示例可供参考

    操作步骤

    1.直接生成目标so文件

    如下图:
    在这里插入图片描述

    部分参数说明

    -fPIC: 表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的,所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
    -shared: 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件。

    这里没有单独生成 .o 中间文件,直接通过 .cc 文件生成了目标 so 文件。

    2.先生成.o中间文件再链接成目标so文件

    如下图:
    在这里插入图片描述

    可以看到,生成 .o文件时也加了-fPIC,如果不加,后面链接时会报错。一般在写Makefile文件时建议用第二种方式,先生成多个.o文件,最后再链接成目标文件。

    关于-fPIC编译选项可以参考这篇文章
    gcc编译参数-fPIC的一些问题

    总结

    以上就是在Linux下编译链接动态库的简单示例,记录学习过程,供以后参考。
    展开全文
  • gcc编译链接动态库详解

    千次阅读 2015-01-14 16:00:35
    比较详细的介绍了gcc编译链接动态库的原理。 转载: http://kmoving.blog.163.com/blog/static/205049197201267113438532/ 一、GNU gcc的编译工具用法 我们先来写一个简单的C程序:hello.c 1. #include ...

    比较详细的介绍了gcc编译链接动态库的原理。
    转载: http://kmoving.blog.163.com/blog/static/205049197201267113438532/


    一、GNU gcc的编译工具用法


    我们先来写一个简单的C程序:hello.c
    1. #include <stdio.h>
    2.
    3. void print_hello() {
    4. printf("Hello World/n");
    5. }
    6.
    7. int main(int argc, char argv[]) {
    8. print_hello();

    9. return 0;

    10. }


    定义了一个print_hello函数,调用main函数打印Hello World。
    如何编译它呢?
    1. gcc -o hello -O2 hello.c
    -o参数指定生成的可执行程序的文件名, -O2是优化级别。该命令会编译生成hello可执行程序,看看这个文件:ls -l hello
    C代码 复制代码
    1. -rwxr-xr-x 1 robbin users 11939 2008-11-02 13:48 hello
    有11KB大小。


    看看他链接了哪些系统动态链接库,用ldd命令:

    1. ldd hello

    输出信息为:

    1. libc.so.6 => /lib64/tls/libc.so.6 (0x0000002a9566d000)
    2. /lib64/ld-linux-x86-64.so.2 (0x0000002a95556000)


    libc是C语言标准函数库,ld是动态链接器。
    接着我们看看hello这个程序里面有哪些符号,用nm命令:

    1. nm hello

    输出:
    1. 00000000005008f8 A __bss_start
    2. 000000000040043c t call_gmon_start
    3. ......
    4. 00000000004004f0 T main
    5. 0000000000500658 d p.0
    6. 00000000004004e0 T print_hello
    7. U puts@@GLIBC_2.2.5
    8. 0000000000400410 T _start


    中间省略了一些,不过我们还是可以在符号表里面找到函数定义。
    hello有11KB,体积偏大,去处符号表可以给它瘦身,我们用strip命令:

    1. strip hello

    然后再ls -l hello,输出为:

    1. -rwxr-xr-x 1 webuser users 4464 2008-11-02 13:56 hello

    只有4.4KB了,瘦身效果明显! 不过这次符号表再也看不到了,nm hello,输出为:nm: hello: no symbols。


    最后如果我们想从可执行程序里面提取出来一点什么文本信息的话,还可以用strings命令:

    1. strings hello

    输出信息为:


    1. /lib64/ld-linux-x86-64.so.2
    2. SuSE
    3. libc.so.6
    4. puts
    5. __libc_start_main
    6. __gmon_start__
    7. GLIBC_2.2.5
    8. t fff
    9. Hello World


    友情提醒一下,如果你用Java写一个HelloWorld.java,编译以后你也可以用strings窥探一番。


    二、动态共享库怎么使用


    这次我们把hello.c拆开成为两个文件:hello.c和main.c。hello.c的代码是:


    1. #include <stdio.h>
    2.
    3. void print_hello() {
    4. printf("Hello World/n");
    5. }


    而main.c的代码是:


    1. int main(int argc, char argv[]) {
    2. print_hello();
    3. return 0;
    4. }


    hello.c是我们的动态共享库,在hello.c里面我们声明和实现了各种公用的函数,最后main.c可以去调用这些公用函数。首先我们要把hello.c编译成为动态共享库:

    C代码 复制代码


    1. gcc -o libhello.so -O2 -fPIC -shared hello.c

    -fPIC参数声明链接库的代码段是可以共享的,-shared参数声明编译为共享库。请注意这次我们编译的共享库的名字叫做libhello.so,这也是Linux共享库的一个命名的惯例了:后缀使用so,而名称使用libxxxx格式。
    然后编译main.c的时候,我们需要更多的参数让gcc知道如何寻找共享库:

    1. gcc -o main -O2 -L. -lhello main.c

    -L参数指定到哪个附加路径下面去寻找共享库,现在我们指定在当前目录下面寻找;
    -l (L的小写字母)参数指定链接到哪个共享库上面,我们传的参数hello,那么gcc就会自动链接到libhello.so这个共享库上面(注意我们上面说的libXXXX.so命名规则);


    -I ( i 的大写字母)参数指定到哪个附加路径下面去寻找h文件,这个我们没有使用。


    最后我们成功编译好了main,执行一下,报错:

    引用
    ./main: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory

    找不到libhello.so这个共享库,怎么回事?这是因为libhello.so并不在操作系统默认的共享库的路径下面,我们可以临时指定一下

    链接路径:

    1. export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

    这样就成功了。我们用ldd main看一下:


    1. libhello.so => ./libhello.so (0x0000002a9566d000)
    2. libc.so.6 => /lib64/tls/libc.so.6 (0x0000002a9576e000)
    3. /lib64/ld-linux-x86-64.so.2 (0x0000002a95556000)


    这次main程序链接到了libhello.so这个共享库上面。


    三、关于Linux的动态共享库的设置

    可执行程序找不到要链接的动态共享库,这是Linux上面编译和运行程序很容易碰到的问题,通过上面的小例子,我们已经大致了解共享库的一点基本原理,接下来我们要探讨一下怎么设置程序寻找动态共享库的行为。


    Linux操作系统上面的动态共享库大致分为三类:


    1、操作系统级别的共享库和基础的系统工具库

    比方说libc.so, libz.so, libpthread.so等等,这些系统库会被放在/lib和/usr/lib目录下面,如果是64位操作系统,还会有/lib64和/usr /lib64目录。如果操作系统带有图形界面,那么还会有/usr/X11R6/lib目录,如果是64位操作系统,还有/usr/X11R6 /lib64目录。此外还可能有其他特定Linux版本的系统库目录。这些系统库文件的完整和版本的正确,确保了Linux上面各种程序能够正常的运行。


    2、应用程序级别的系统共享库
    并非操作系统自带,但是可能被很多应用程序所共享的库,一般会被放在/usr/local/lib和/usr/local/lib64这两个目录下面。很多你自行编译安装的程序都会在编译的时候自动把/usr/local/lib加入gcc的-L参数,而在运行的时候自动到/usr/local/lib下面去寻找共享库。


    以上两类的动态共享库,应用程序会自动寻找到他们,并不需要你额外的设置和担心。这是为什么呢?因为以上这些目录默认就被加入到动态链接程序的搜索路径里面了。Linux的系统共享库搜索路径定义在/etc/ld.so.conf这个配置文件里面。这个文件的内容格式


    大致如下:

    1. /usr/X11R6/lib64
    2. /usr/X11R6/lib
    3. /usr/local/lib
    4. /lib64
    5. /lib
    6. /usr/lib64
    7. /usr/lib
    8. /usr/local/lib64
    9. /usr/local/ImageMagick/lib


    假设我们自己编译安装的ImageMagick图形库在/usr/local/ImageMagick目录下面,并且希望其他应用程序都可以使用ImageMagick的动态共享库,那么我们只需要把/usr/local/ImageMagick/lib目录加入/etc /ld.so.conf文件里面,然后执行:ldconfig 命令即可。


    ldcofig将搜索以上所有的目录,为共享库建立一个缓存文件/etc/ld.so.cache。为了确认ldconfig已经搜索到ImageMagick的库,我们可以用上面介绍的strings命令从ld.so.cache里面抽取文本信息来检查一下:


    1. strings /etc/ld.so.cache | grep ImageMagick

    输出结果为:

    1. /usr/local/ImageMagick/lib/libWand.so.10
    2. /usr/local/ImageMagick/lib/libWand.so
    3. /usr/local/ImageMagick/lib/libMagick.so.10
    4. /usr/local/ImageMagick/lib/libMagick.so
    5. /usr/local/ImageMagick/lib/libMagick++.so.10
    6. /usr/local/ImageMagick/lib/libMagick++.so


    已经成功了!


    3、应用程序独享的动态共享库

    有很多共享库只被特定的应用程序使用,那么就没有必要加入系统库路径,以免应用程序的共享库之间发生版本冲突。因此Linux还可以通过设置环境变量 LD_LIBRARY_PATH来临时指定应用程序的共享库搜索路径,就像我们上面举的那个例子一样,我们可以在应用程序的启动脚本里面预先设置 LD_LIBRARY_PATH,指定本应用程序附加的共享库搜索路径,从而让应用程序找到它。


    具体如下:

    (1)新建自己的头文件路径/home/user/workspace/include和库文件路径/home/user/workspace/lib,这两个目录用来存放我自己编写的头文件和库文件;
    (2)接下来写个头文件和库文件作测试,在/home/user/workspace/include下新建文件test.h,在/home/user/workspace/lib下新建test.c,test.h中是一些函数原型,test.c是函数的实现;
    (3)通过命令gcc -fPIC -shared -o libtest.so test.c在/home/user/workspace/lib生成了一个动态链接库文件libtest.so;
    (4)现在把库文件路径添加进.bash_profile文件,添加内容如下:


    # my code

    C_INCLUDE_PATH=/home/cheney/workspace/include
    export C_INCLUDE_PATH
    LD_LIBRARY_PATH=/home/cheney/workspace/lib
    export LD_LIBRARY_PATH


    然后通过source .bash_profile把.bash_profile文件即时更新了。


    展开全文
  • (TODO:链接动态库时链接阶段到底做了什么) 2 静态库和动态库的比较 链接静态库其实从某种意义上来说也是一种粘贴复制,只不过它操作的对象是目标代码而不是源码而已。因为静态库被链接后库就直接嵌入可执行文件中...
  • gcc编译工具生成动态库和静态库之一--介绍 gcc作为编译工具,用在Linux操作系统中,可以编译C、C++、Object-C、JAVA等语言。编译过程中可以带编译选项,选择编译过程。 一、GCC编译流程 1)预处理 Pre-...

    目录

    即看即用

    一、GCC 简介

    GCC编译流程

    GCC编译选项

    二、GCC生成动态库和静态库

    三、生成动态库和静态库实例

    四、静态库和动态库的使用和配置

    静态库的使用

    共享库的使用

    不到你指定链接的so错误

    编译链接静态库、动态库

    链接动态库


    即看即用

    多个源文件/目标生成动态库
    a.
    gcc -fPIC -shared xxx1.c xxx2.c xxx3.c -o libxxx.so 
    b.
    gcc -fPIC -shared xxx1.o xxx2.o xxx3.o -o libxxx.so 

    2.多个源文件/目标生成静态库
    a.
    ar -rc libxxx.a xxx1.o xxx2.o xxx3.o (正确方法)
    b.
    ar -rc libxxx.a xxx1.c xxx2.c xxx3.c (静态库可以生成;当运行连接了该静态库的可执行程序会报错could not read symbols:Archive has no index;run ranlib to add one

    链接静态库

    gcc -o main2 main.o -L./ -ladd_minus

    链接动态库

    1. 在外部告诉程序,动态库在哪里
      有两种方法:
    • 将 libmulti_div.so copy到/lib/ 或 /usr/lib/ 下
      这个方法对很多软件都要使用的库比较友好
    • 在 LD_LIBRARY_PATH 变量中指定库文件路径
      这个一般就是临时弄一下。用法:
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/yourpath
    
    1. 编译链接
    gcc -o main4 main.o -L./ -ladd_minus -lmulti_div
    

    一、GCC 简介

    《gcc命令》http://man.linuxde.net/gcc

    gcc作为编译工具,用在Linux操作系统中,可以编译C、C++、Object-C、JAVA等语言。编译过程中可以带编译选项,选择编译过程。

    GCC编译流程

    1)预处理 Pre-Processing
    2)编译 Compiling
    3)汇编 Assembling
    4)链接 Linking

    GCC编译选项


    1、一般选项


    1) -c :只编译,不链接,生成目标文件“.o”。
    2) -S :只编译,不汇编,生成汇编代码“.S”。
    3) -E :只进行预编译/预处理,不做其他处理。

    4) -o file:输出文件名为file
    5) -g :在可执行程序中包含标准调试信息。
    6) -v :打印出编译器内部编译各过程的命令行信息和编译器的版本。
    7) -I dir :在头文件的搜索路径列表中添加dir目录
    8) -L dir :在库文件的搜索路径列表中添加dir目录
    9) -static :连接静态库(静态库也可以用动态库链接方式链接)
    10) -llibrary :连接名为library的库文件(显示指定需要链接的动态库文件)


    -shared 该选项指定生成动态连接库
    l -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真 正代码段共享的目的。
    l -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称
    l LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。
    l 当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。
       


    2、gcc告警和出错选项


    1) -ansi :支持符合ANSI标准的C程序
    2) -pedantic :允许发出ANSI C标准所列出的全部警告信息
    3) -pedantic-error :允许发出ANSI C标准所列出的全部错误信息
    4) -w :关闭所有警告
    5) -Wall :允许发出gcc提供的所有有用的报警信息
    6) -werror :把所有的告警信息转化为错误信息,并在告警发生时终止编译过程


    3、gcc优化选项

    1)-On:n的取值范围不一致,比较典型的范围为0变化到2或者3。

    虽然优化选项可以加速代码的运行速度,但对于调试而言将是一个很大的挑战。因为代码在经过优化之后,原先在源程序中声明和使用的变量很可能不再使用,控制流也可能会突然跳转到意外的地方,循环语句也可能因为循环展开而变得到处都有。
     

    二、GCC生成动态库和静态库


    (1)静态库
         静态是指每个用到该库的应用程序都拥有一份自己的库拷贝;
    (2) 共享库
         一个共享库有可能被多个所有应用程序共享。


    1)动态库生成
    1.单个源文件/目标直接生成动态库
    a. 
    gcc -fPIC -shared xxx.c -o libxxx.so
    b.
    gcc -fPIC -shared xxx.o -o libxxx.so


    2.多个源文件/目标生成动态库
    a.
    gcc -fPIC -shared xxx1.c xxx2.c xxx3.c -o libxxx.so 
    b.
    gcc -fPIC -shared xxx1.o xxx2.o xxx3.o -o libxxx.so 


    2)静态库生成

    简单地说,静态库是一个目标文件的简单集合。因此,首先有目标文件。

    第一步:
    gcc -c myfunc.c myproc.c将得到myfunc.o和myproc.o。

    第二步:由ar(archive,归档的意思)把多个目标文件集合起来。
    $ar -r libmyjob.a myfunc.o myproc.o
        

    通常,静态库的命名方式应遵守libXXXXX.a格式。应用程序在使用静态库的时候,通常只需要把命名中的XXXXX部分传递给gcc即可。


    1.单个源文件/目标直接生成静态库
    a.
    ar -rc libxxx.a xxx.o(正确方法)
    b. ar -rc libxxx.a xxx.c (静态库可以生成;当运行连接了该静态库的可执行程序会报错could not read symbols:Archive has no index;run ranlib to add one


    2.多个源文件/目标生成静态库
    a.
    ar -rc libxxx.a xxx1.o xxx2.o xxx3.o (正确方法)
    b.
    ar -rc libxxx.a xxx1.c xxx2.c xxx3.c (静态库可以生成;当运行连接了该静态库的可执行程序会报错could not read symbols:Archive has no index;run ranlib to add one


    四、多个源文件生成一个可执行文件
    gcc xxx1.c xxx2.c xxx3.c xxx4.c main.c -o main

    三、生成动态库和静态库实例

    gcc编译工具生成动态库和静态库之二----实例_yanlaifan的博客-CSDN博客

    四、静态库和动态库的使用和配置



    (1)静态库
         静态是指每个用到该库的应用程序都拥有一份自己的库拷贝;应用程序运行的时候,即使将库删除也没有问题,因为应用程序自己已经有了自己的拷贝。
    (2) 共享库
         一个共享库有可能被多个所有应用程序共享。因此,对每个应用程序来说,即使不再使用某个共享库,也不应将其删除。此外,应用程序需要正确的环境变量设置 (LD_LIBRARY_PATH),从而找到共享库所在的位置,否则,应用程序运行时会报告找不到这个库。


    二、关于使用库的问题


         对于静态库来说,gcc 的命令行参数(-I, -L)shell的环境变量(C_INCLUDE_PATH, LIBRARY_PATH)
         对于共享库来说,程序在运行时,如果用到了动态库,也需要找到对应的动态库文件;实现的方法:
    shell的环境变量 (LD_LIBRARY_PATH)

     

    静态库的使用

    1) gcc命令行参数(-I, -L)


     默认情况下,gcc会自动搜索下面的路径:
    对 头文件:
     

    /usr/local/include/
    /usr/include/
    对库文件:
    /usr/local/lib/
    /usr/lib/

    开发者自定义路径:
      
     例如:如果工程涉及到GDBM(GNU DataBase Management)包,需要libgdbm库,而系统中安装GDBM的路径是:
     

    头文件:/opt/gdbm-1.8.3 /include
    库文件:/opt/gdbm-1.8.3/lib/
      那么,gcc的命令参数是:
    $gcc … -I/opt/gdbm-1.8.3/include  -L/opt/gdbm-1.8.3/lib –lgdbm

     注意:为保证兼容性,必须坚决杜绝在C/C++源文件的#include语句中或者其他相关语句中使用上述路径。


    2) shell环境变量(Environmental Variable)


         除了用命令行参数,还可以用环境变量来指示gcc搜索适当的路径。
    (1)Bash
         对于Bash来说,除了由系统管理员配置的内容以外,每个用户的用户目录($HOME)下,有个.bash_profile文件。可在该文件内,增加下面 的两个语句来设置GDBM头文件路径的环境变量:

    C_INCLUDE_PATH=/opt/gdbm-1.8.3/include
    export C_INCLUDE_PATH


         类似地,在该文件内用下面的两个语句来设置库文件路径的环境变量:

    LIBRARY_PATH=/opt/gdbm-1.8.3/lib
    export LIBRARY_PATH


         在.bash_profile中有了上述语句以后,就不用再使用-I和-L来搜索特定包的路径了。但是链接库的时候,还是要用-l选项。
    $gcc … –lgdbm
      

       在Bash下,要检查有什么样的环境变量,可用env命令。
    $env


    共享库的使用


         使用共享库的应用程序,要通过环境变量LD_LIBRARY_PATH找到对应的共享库文件,不要忘了之前已经设置的共享库目录,所以是=xxxx:$LD_LIBRARY_PATH,即赋值新增的路径和原来的路径

    LD_LIBRARY_PATH=/opt/gdbm-1.8.3/lib:$LD_LIBRARY_PATH
    export LD_LIBRARY_PATH

    转自:http://blog.csdn.net/gnuhpc/article/details/5448149

    gcc -E hello.c -o hello.i   对hello.c文件进行预处理,生成了hello.i 文件
    gcc -S hello.i -o hello.s    对预处理文件进行编译,生成了汇编文件
    gcc -c hello.s -o hello.o  对汇编文件进行编译,生成了目标文件
    gcc hello.o -o hello 对目标文件进行链接,生成可执行文件
    gcc hello.c -o hello 直接编译链接成可执行目标文件
    gcc -c hello.c 或 gcc -c hello.c -o hello.o 编译生成可重定位目标文件

    不到你指定链接的so错误

    调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作的就是通过修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。

    编译链接静态库、动态库

     链接静态库

    上节的1~3已经得到了libadd_minus.a和main.o文件,这一步需要把这两个文件链接起来

    gcc -o main2 main.o -L./ -ladd_minus
    

    说明1:-L./表明库文件位置在当前文件夹

    说明2: -ladd_minus 表示链接 libadd_minus.a 文件,使用“-l”参数时,前缀“lib”和后缀“.a”是需要省略的。

    编译链接动态库

    链接动态库

    1. 在外部告诉程序,动态库在哪里
      有两种方法:
    • 将 libmulti_div.so copy到/lib/ 或 /usr/lib/ 下
      这个方法对很多软件都要使用的库比较友好
    • 在 LD_LIBRARY_PATH 变量中指定库文件路径
      这个一般就是临时弄一下。用法:

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/yourpath
    
    1. 编译链接
    gcc -o main4 main.o -L./ -ladd_minus -lmulti_div
    

    展开全文
  • gcc常见选项和动态库静态库
  • gcc 编译动态库

    2021-03-04 19:46:42
    1.编译指令 gcc -shared-fPCI-olibmyhello.sohello.c 2.链接编译指令 gccmain.c-I/usr/local/include ...-L后面接动态库目录 3.设置环境变量 参考https://mp.csdn.net/editor/html/114375663 4.调用 ./a.out ...
  • GCC 编译使用动态链接库

    千次阅读 2016-08-12 16:13:42
    动态链接库 1. 创建动态链接库 复制代码代码如下: ...用命令gcc -shared hello.c -o libhello.so编译动态库。可以看到,当前目录下多了一个文件libhello.so。 2. 再编辑一个测试文件test
  • GCC编译链接静态(.a)

    千次阅读 2021-08-10 14:17:51
    1.GCC编译链接静态(.a) (1)生成.o gcc -c a.c b.c c.c (2)链接生成.a(将a.o与b.o链接生成.a) ar rc libaaa.a a.o b.o (3)生成可执行文件c.c中main调用libaaa.a库函数 ...GCC编译链接动态
  • g++ 链接 gcc 编译动态库

    千次阅读 2020-08-13 21:30:43
    编译c/c++代码的时候,有人用gcc,有人用g++,于是各种说法都来了,譬如c代码用gcc,而 c++代码用g++,或者说编译gcc链接用g++,一时也不知哪个说法正确,如果再遇上个extern "C",分歧就更多了,这里我想作个...
  • gcc 动态库编译使用
  • gcc编译指定动态库路径

    千次阅读 2019-02-26 09:57:34
    看一下gcc编译时常用到的两个参数-l(小写L)和-L 当需要编译的程序中用到了外链(非标准)时,我们在编译时就需要用到-l参数,后面紧跟库名 如果程序用到了多线程,编译时就得加上-lphread gcc test.c -...
  • gcc指定要链接动态库

    千次阅读 2021-12-28 15:40:35
    gcc指定链接库
  • gcc编译动态库

    2018-11-27 19:46:15
    在使用GCC编译程序时,只需加上-shared选项即可,这样生成的执行程序即为动态链接库。 其中-fPIC选项的作用是:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的, 所以动态载入时是通过代码拷贝...
  • gcc编译动态链接库[参考].pdf
  • 亲测成功,不过.so动态链接库用起来为什么这么麻烦呢,不晓得有没有更好的办法 GCC编译动态和静态链接库例子 - woainilsr - 博客园
  • gcc编译过程 我们知道gcc是一个强大的编译器,很多Linux下的GNU工具都是用C语言写的,并且用gcc编译的,那么gcc的编译过程是怎样的呢,先来看一个总的流程图,我自己简单画的,凑合着看 1首先是源文件经过预加载...
  • 编译动态链接库,windows,linux,mac平台各不相同,从文件上来说,windows下是dll,linux下是so,mac下是dylib;... 这里介绍在mac下手动编译动态库示例: 准备hello.h #ifndef SO_H #define SO_H int add(int a,...
  • gcc编译链接头文件和文件

    千次阅读 2019-11-24 23:51:31
    GCC与头文件 gcc -参数: -I ( i 的大写) :指定头文件路径(相对...gcc头文件的搜索路径: 头文件 gcc编译时如何去寻找所需要的头文件: 头文件的搜索会从-I指定的目录开始; 然后搜索gcc的环境变量 C_INCLU...
  • GCC编译动态和静态链接库.pdf 学习资料 复习资料 教学资源
  • gcc生成静态库和动态库gcc生成静态态库gcc生成动态库三级目录 gcc生成静态态库 gcc生成动态库 三级目录
  • gcc背景介绍 谈到 GCC,就不得不提 GNU 计划。GNU 全称 GNU’s Not UNIX,又被称为“革奴计划”,由理查德·斯托曼于 1983 年发起。GNU 计划的最终目标是打造出一套完全自由(即自由使用、自由更改、自由发布)、...
  • 总结使用gcc生成动态库及使用动态库的方法: step 1: 生成test.o目标文件,使用如下命令。此处需要添加-fPIC参数,该参数用于生成位置无关代码已共生成动态库使用: [xgqin@xgqin-desktop so]$ gcc -c -o ...
  • Linux下gcc编译生成动态链接库*.so文件并调用它 gcc -c test.c将生成test.o的目标文件 gcc -o app test.c将生成可执行程序app 动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的...
  • Linux基础——gcc编译、静态库与动态库(共享库)

    万次阅读 多人点赞 2018-07-03 17:44:34
    gcc编译器 1、gcc工作流程 2、gcc常用参数 参数 用途 -v 查看版本 -o 产生目标文件 -I+目录 指定头文件目录 -D 编译时定义宏 -00/-01/-03 没有优化/缺省值/优化级别最高 -Wall ...
  • gcc编译动态链接库

    2012-10-20 21:01:08
    演示动态链接库编译和使用 1. 编写代码 *************hello.h************** void print_hello(); ***********hello.c************** #include "hello.h" #include void print_hello() { printf("hello...
  • gcc编译工具生成动态库和静态库之一----介绍 ...(TODO:链接动态库时链接阶段到底做了什么) 2 静态库和动态库的比较 链接静态库其实从某种意义上来说也是一种粘贴复制,只不过它操作的对象是目标代
  • 本文记录了Windows下使用gcc制作静态的过程。 一、测试代码编写 测试函数为一个加法函数,它将被制作成静态,并被函数main()调用。各个文件如下所示,它们被放在同一个目录下。 add.h int add(int a, int b);...
  • 库有两种:静态库(.a、.lib)和动态库(.so、.dll)。 windows上对应的是.lib .dll linux上对应的是.a .so 在这里先介绍下Linux下的gcc编译的几个选项 g++ -c hellospeak.cpp 会将hellospeak.cpp

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 59,949
精华内容 23,979
关键字:

gcc编译链接动态库