zoukankan      html  css  js  c++  java
  • gcc链接外部函数库,比如数学函数库

    摘自http://hi.baidu.com/newyork_zero/blog/item/601ab9d7af1913ce50da4b16.html

    链接外部库(摘子ubuntu中文论坛)

    库是预编译的目标文件(object files)的集合,它们可被链接进程序。静态库以后缀为‘.a’的特殊的存档文件(archive file)存储。

    标准系统库可在目录 /usr/lib/lib 中找到。比如,在类 Unix 系统中 C 语言的数学库一般存储为文件/usr/lib/libm.a。该库中函数的原型声明在头文件 /usr/include/math.h 中。C 标准库本身存储为/usr/lib/libc.a,它包含 ANSI/ISO C 标准指定的函数,比如‘printf’。对每一个 C 程序来说,libc.a 都默认被链接。

    下面的是一个调用数学库 libm.asin 函数的的例子,创建文件calc.c

    #include <math.h> #include <stdio.h>  int main (void) {     double x = 2.0;
        double y = sin (x);
        printf ("The value of sin(2.0) is %f\n", y);
        return ;}

    尝试单独从该文件生成一个可执行文件将导致一个链接阶段的错误:

    $ gcc -Wall calc.c -o calc
    /tmp/ccbR6Ojm.o: In function 'main':
    /tmp/ccbR6Ojm.o(.text+0x19): undefined reference to ‘sin’

    函数 sin,未在本程序中定义也不在默认库‘libc.a’中;除非被指定,编译器也不会链接‘libm.a’。

    为使编译器能将 sin 链接进主程序‘calc.c’,我们需要提供数学库‘libm.a’。一个容易想到但比较麻烦的做法是在命令行中显式地指定它:

    $ gcc -Wall calc.c /usr/lib/libm.a -o calc

    函数库‘libm.a’包含所有数学函数的目标文件,比如sin,cos,exp,logsqrt。链接器将搜索所有文件来找到包含sin 的目标文件。

    一旦包含 sin 的目标文件被找到,主程序就能被链接,一个完整的可执行文件就可生成了:

    $ ./calc
    The value of sin(2.0) is 0.909297

    可执行文件包含主程序的机器码以及函数库‘libm.a’中 sin 对应的机器码。

    为避免在命令行中指定长长的路径,编译器为链接函数库提供了快捷的选项‘-l’。例如,下面的命令

    $ gcc -Wall calc.c -lm -o calc

    与我们上面指定库全路径‘/usr/lib/libm.a’的命令等价。

    一般来说,选项 -lNAME使链接器尝试链接系统库目录中的函数库文件 libNAME.a。一个大型的程序通常要使用很多-l 选项来指定要链接的数学库,图形库,网络库等。

    例如,如果已经在/home/fred/include 下保存了自定义的头文件,那么为了让gcc能够找到它们,可按下面的例子使用-I选项:
    $gcc myapp.c -I /home/fred/include -o myapp
    -L选项对库文件起的作用和-I选项告诉gcc把DIRNAME添加到库文件搜索路径里,要保证DIRNAME比标准位置先被搜索.
      假设读者需要测试一个新的编程库libnew.so,当前它保存在/home/fred/lib下(.so是共享库文件的标准扩展名).为了链接库文件,gcc命令行应与下面类似:
    $gcc myapp.c -L/home/fred/lib -lnew -o myapp
    -L/home/fred/lib结构让gcc先在/home/fred/lib下查找库文件,然后再到默认的库文件搜索路径下进行查找.-l选项使得链接程序使用指定的函数库中的目标代码,也就是本例中的libnew.so.把函数库命名为lib{名字}是UNIX的约定,与许多其他编译器一样,gcc 也遵循此约定.如果忘了使用-l选项,则与库的链接将失败,并且gcc产生错误,说明程序中引用了未定义的函数名.
    默认情况下,gcc使用共享库进行链接,所以在需要链接静态库时必须使用-static选项来保证只使用静态库.
    $gcc cursesapp.c -lncurses -static -o cursesapp
    在链接静态库时,可执行程序的大小比链接共享库要达很多.使用共享库时,程序所使用的代码是在运行时动态链接,而不是在编译时静态链接,因此,如果所需要的共享库没有在用户系统中安装,运行就会失败.

  • 相关阅读:
    LeetCode 24. Swap Nodes in Pairs (两两交换链表中的节点)
    LeetCode 1041. Robot Bounded In Circle (困于环中的机器人)
    LeetCode 1037. Valid Boomerang (有效的回旋镖)
    LeetCode 1108. Defanging an IP Address (IP 地址无效化)
    LeetCode 704. Binary Search (二分查找)
    LeetCode 744. Find Smallest Letter Greater Than Target (寻找比目标字母大的最小字母)
    LeetCode 852. Peak Index in a Mountain Array (山脉数组的峰顶索引)
    LeetCode 817. Linked List Components (链表组件)
    LeetCode 1019. Next Greater Node In Linked List (链表中的下一个更大节点)
    29. Divide Two Integers
  • 原文地址:https://www.cnblogs.com/CodeWorkerLiMing/p/12007837.html
Copyright © 2011-2022 走看看