Статические библиотеки, которые зависят от других статических библиотек.

У меня есть вопрос о создании статических библиотек, которые используют другие статические библиотеки.

Я создал пример с 3 файлами - main.cpp, slib1.cpp и slib2.cpp. slib1.cpp и slib2.cpp скомпилированы как отдельные статические библиотеки (например, я получил slib1.a и slib2.a) main.cpp скомпилирован в стандартный исполняемый файл ELF, связанный с обеими библиотеками.
Также существует заголовочный файл с именем main.h, который прототипирует функции в slib1 и slib2.

main.cpp вызывает функцию lib2func() из slib2. Эта функция, в свою очередь, вызывает lib1func() из slib1.

Если я скомпилирую код как есть, g++ вернет ошибку компоновщика о том, что не удалось найти lib1func() в slib1. Однако, если я вызову lib1func() ДО любых вызовов любых функций в slib2, код компилируется и работает правильно.

Мой вопрос заключается в следующем: возможно ли создать статическую библиотеку, которая зависит от другой статической библиотеки? Если бы это было невозможно, это казалось бы очень серьезным ограничением.

Исходный код для этой проблемы прилагается ниже:

основной.ч:

#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();
}

основной.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

person knelson    schedule 19.06.2012    source источник


Ответы (2)


Пожалуйста, попробуйте g++ -o main src/main.o -L. -Wl,--start-group -lslib1 -lslib2 -Wl,--end-group.

Группа, определенная с помощью --start-group, --end-group, помогает разрешить циклические зависимости между библиотеками.

См. также: GCC: что такое --start-group и --end-group параметры командной строки?

person Ruben    schedule 19.06.2012

Порядок имеет значение. Вот страница руководства 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, foo.o -lz bar.o 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.
person Nikolai Fetissov    schedule 19.06.2012
comment
Возможна даже циклическая зависимость между библиотеками. В таких случаях вам нужно дважды указать одну из библиотек в командной строке. - person Tamás Szelei; 20.06.2012
comment
Или используйте параметры компоновщика, как предлагает @Ruben. - person Nikolai Fetissov; 20.06.2012