zoukankan      html  css  js  c++  java
  • Linux C/C++ 链接选项之静态库--whole-archive,--no-whole-archive和--start-group, --end-group

    参照这两篇博客:

    http://stackoverflow.com/questions/805555/ld-linker-question-the-whole-archive-option

    http://codemacro.com/2014/09/15/inside-static-library/

    这四个都是链接器的选项,所以在编译的时候要用-Wl,[options]来传递给链接器,不然编译器会不认得这个选项。

    --whole-archive选项解决的是编译中常遇到的问题。在代码中定义的符号(如函数名)还未使用到之前,链接器并不会把它加入到连接表中。如下面这个例子:

    a.cpp:

    void func(){printf("I am in a.cpp. ");}

    main.cpp:

    extern void func();

    int main(){func(); printf("I am in main.cpp"); return 0;}

    首先编译g++ -c a.cpp,再打包ar -r liba.a a.o。

    如果这么链接g++ -L. -la main.cpp -o main,则链接器会报错,称func()未定义。其实改一下顺序既可以解决g++  main.cpp -L. -la -o main。

    或者使用g++ -Wl,--whole-archive -L. -la -Wl,--no-whole-archive main.cpp -o main,将liba.a中的所有.o中的符号都链接进来。

    对于C++中使用的Register机制,即动态对象创建会遇到这样的问题。在使用Caffe库的时候也遇到了这样的问题。

    对于--start-group和--end-group, gcc liner man中如下描述:

    The archives should be a list of archive files. They may be either explicit file names, or -l options.

    The specified archives are searched repeatedly until no new undefined references are created. Normally, an archive is searched only once in the order that it is specified on the command line. If a symbol in that archive is needed to resolve an undefined symbol referred to by an object in an archive that appears later on the command line, the linker would not be able to resolve that reference. By grouping the archives, they all be searched repeatedly until all possible references are resolved.

    Using this option has a significant performance cost. It is best to use it only when there are unavoidable circular references between two or more archives

    这里有一个链接顺序的问题,在command line上前面的库会依赖之后的库,如果碰到循环链接,-lliba -llibb -lliba,这样就需要使用--start-group和--end-group反复在.a中进行搜索直到所有的未定义字符都被找到为止,而不是默认的只搜索一次。MKL库有这样的问题。

  • 相关阅读:
    MySql存储过程学习总结
    JAVA设计模式之策略模式
    JAVA设计模式之装饰模式
    JAVA设计模式之代理模式
    动手学servlet(四) cookie和session
    动手学servlet(三) 请求头和响应头信息
    动手学servlet(二) servlet基础
    动手学servlet(一) 第一个servlet程序
    HTTP与HttpServlet
    HttpServlet详解
  • 原文地址:https://www.cnblogs.com/JimmyTY/p/5856217.html
Copyright © 2011-2022 走看看