zoukankan      html  css  js  c++  java
  • gcc杂谈

    1. -l选项自动给库文件名增加lib前缀和.a/.so后缀。所以如果你有一个lib叫做libusb.a,那么编译选项是-lusb。另一方面,如果你有一个文件叫做libusb.o(是目标文件而不是库文件),并希望将其作为库的形式使用,那么使用-llibusb.o。

    2. pkg-config

        这玩意自动给你的gcc命令行加上相关的lib和include位置选项。例如:

        gcc -o test test.c ·pkg-config --libs --cflags glib-2.0·

        附上pkg-config项目自己给出的介绍:

    pkg-config is a helper tool used when compiling applications and libraries. It helps you insert the correct compiler options on the command line so an application can use gcc -o test test.c pkg-config --libs --cflags glib-2.0 for instance, rather than hard-coding values on where to find glib (or other libraries). It is language-agnostic, so it can be used for defining the location of documentation tools, for instance.

    3. ldconfig

    Linux在加载应用程序的时候,并不直接加载共享库,而是由/lib/ld.so来干这个事情。ld.so在标准路径(/lib,/usr/lib)中寻找共享库。But,如果.so在非标路径,ld.so就抓虾了。所以,我们需要将非标路径加入/etc/ld.so.conf,然后运行ldconfig生成/etc/ld.so.cache。ld.so加载共享库的时候,会从ld.so.cache查找(但不会理睬ld.so.conf!)。

    4. 静态库和动态库

    4.1 静态库的生成

    使用gcc -c生成.o文件,然后使用ar归档为.a文件。

    4.2 静态库的使用

    4.2.1 直接将.a作为源代码交给gcc:

    gcc x.c libmy.a -o myelf

    4.2.2 通过指定库文件位置:

    gcc -o myelf x.c -LYOUR_LIB_PATH -lmy

    4.3 动态库的生成

    gcc -o libmy.so -shared my.o [-fPIC]

    所生成的.so同时用于编译和执行。

    4.4 -fPIC

    -fPIC选项生成位置无关代码,即.so内的代码和数据在使用时不需要重定位,但也因为此,只能通过got(global offset table)间接寻址。如果不使用-fPIC,.so在使用时必须进行重定位,为每个使用该库的进程都在物理内存中复制一份副本,因为需要修改其中的地址。

    4.5 动态库的使用

    4.5.1 直接将.so交给gcc

    gcc x.c libmy.so -o myelf

    这种方法生成的ELF文件中包含编译时so文件所在的位置,在执行时要求so文件处于相同位置。

    4.5.2 使用-L和-l指定.so位置

    gcc -o myelf x.c -LYOUR_LIB_PATH -lmy

    4.5.3 使用dlopen在应用程序执行时加载

    参考http://www.ibm.com/developerworks/cn/linux/l-dynamic-libraries/index.html

    4.5.4 其他

          上面我们说过,.so同时用于编译和执行,但编译和执行时的查找方式和顺序是不一样的(嗯,在历史上曾经一样过)。

    编译时gcc的查找顺序:

    • LIBRARY_PATH(仅对native编译器有效,对cross compiler无效)
    • -L -l指定位置
    • 标准位置

    执行时ld.so的查找顺序:

    • LD_LIBRARY_PATH
    • 标准位置
    • ld.so.cache指定位置 

    4.6 可以通过ldd查看某个应用程序需要哪些动态库

    4.7 LD_LIBRARY_PATH和LD_RUN_PATH

          前者对运行时有效,后者对编译时有效。(这好像和它们的名字不一样啊!黑人问号脸。)

          [LD_RUN_PATH似乎是在链接时指定编译出的程序在运行时搜索的动态库路径?]

    4.8 有时候我们的两个静态库可能会有相互依赖,而gcc默认情况下只扫描一遍参数中的库文件,所以这时候我们要求gcc反复扫描:

          -Wl,--start-group -la -lb -Wl,--end-group

          # -Wl表示将后面的参数交给linker。

    5. 移除不需要的sections

          -ffunction-sections -fdata-sections -Wl,--gc-sections

  • 相关阅读:
    Design and Analysis of Algorithms_Decrease-and-Conquer
    TCPL 札记
    谬论:64 = 65?
    二叉树内部顶点与外部顶点在数量上的关系
    Design and Analysis of Algorithms_Divide-and-Conquer
    LeetCode 36. Valid Sudoku
    LeetCode 58. Length of Last Word
    LeetCode 66. Plus One
    LeetCode 67. Add Binary
    LeetCode 70. Climbing Stairs
  • 原文地址:https://www.cnblogs.com/byeyear/p/5264949.html
Copyright © 2011-2022 走看看