【问题标题】:Static Libraries which depend on other static libraries依赖于其他静态库的静态库
【发布时间】:2012-06-21 23:44:16
【问题描述】:

我有一个关于制作使用其他静态库的静态库的问题。

我设置了一个包含 3 个文件的示例 - main.cpp、slib1.cpp 和 slib2.cpp。 slib1.cpp 和 slib2.cpp 都被编译为单独的静态库(例如,我最终得到 slib1.a 和 slib2.a) main.cpp 被编译成与这两个库链接的标准 ELF 可执行文件。
还有一个名为 main.h 的头文件,它是 slib1 和 slib2 中函数的原型。

main.cpp 从 slib2 调用一个名为 lib2func() 的函数。该函数依次从 slib1 调用 lib1func()。

如果我按原样编译代码,g++ 将返回一个链接器错误,指出它在 slib1 中找不到 lib1func()。但是,如果我在调用 slib2 中的任何函数之前调用 lib1func(),则代码会编译并正常工作。

我的问题很简单:是否可以创建一个依赖于另一个静态库的静态库?如果这是不可能的,这似乎是一个非常严重的限制。

这个问题的源代码附在下面:

main.h:

#ifndef MAIN_H
#define MAIN_H

int lib1func();
int lib2func();

#endif

slib1.cpp:

#include "main.h"

int lib1func() {
  return 1;
}

slib2.cpp:

#include "main.h"

int lib2func() {
  return lib1func();
}

main.cpp:

#include <iostream>
#include "main.h"

int main(int argc, char **argv) {
  //lib1func();  // Uncomment and compile will succeed.  WHY??

  cout << "Ans: " << lib2func() << endl;
  return 0;
}

gcc 输出(注释掉的行):

g++ -o src/slib1.o -c src/slib1.cpp
ar rc libslib1.a src/slib1.o
ranlib libslib1.a
g++ -o src/slib2.o -c src/slib2.cpp
ar rc libslib2.a src/slib2.o
ranlib libslib2.a
g++ -o src/main.o -c src/main.cpp
g++ -o main src/main.o -L. -lslib1 -lslib2
./libslib2.a(slib2.o): In function `lib2func()':
slib2.cpp:(.text+0x5): undefined reference to `lib1func()'
collect2: ld returned 1 exit status

gcc 输出(行未注释)

g++ -o src/slib1.o -c src/slib1.cpp
ar rc libslib1.a src/slib1.o
ranlib libslib1.a
g++ -o src/slib2.o -c src/slib2.cpp
ar rc libslib2.a src/slib2.o
ranlib libslib2.a
g++ -o src/main.o -c src/main.cpp
g++ -o main src/main.o -L. -lslib1 -lslib2

$ ./main 
Ans: 1

【问题讨论】:

    标签: c++ static-libraries static-linking


    【解决方案1】:

    请尝试g++ -o main src/main.o -L. -Wl,--start-group -lslib1 -lslib2 -Wl,--end-group

    使用--start-group--end-group 定义的组有助于解决库之间的循环依赖关系。

    另请参阅:GCC: what are the --start-group and --end-group command line options?

    【讨论】:

      【解决方案2】:

      顺序决定一切。这是来自gcc(1) 手册页:

      It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, <b>foo.o -lz bar.o</b> searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.

      【讨论】:

      • 库之间甚至可能存在循环依赖。在这种情况下,您需要在命令行中两次提供其中一个库。
      • 或者按照@Ruben 的建议使用链接器选项。
      猜你喜欢
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-10
      • 1970-01-01
      相关资源
      最近更新 更多