g ++: В каком порядке должны быть связаны статические и динамические библиотеки?

Вы вызываете сабвуфер OpenMe для сабвуферов Open и Close.

Если вы хотите, чтобы это запускалось автоматически, где вызывается close sub, кроме командной кнопки?

24
задан hivert 9 March 2014 в 18:18
поделиться

5 ответов

В статическом случае это действительно не имеет значения, потому что Вы на самом деле не связываете статические библиотеки - все, что Вы делаете упаковать некоторые объектные файлы вместе в одном архиве. Все, к чему Вы имеете, является компиляцией Ваши объектные файлы, и можно создать статические библиотеки сразу же.

ситуация с динамическими библиотеками является более замысловатой, существует два аспекта:

  1. А совместно использовал работы библиотеки точно тот же путь как статическая библиотека (за исключением общих сегментов, если они присутствуют), что означает, можно просто сделать, то же - просто связывает общую библиотеку, как только у Вас есть объектные файлы. Это означает, например, что символы от libDA появятся как неопределенные в libDB

  2. , с которым можно указать библиотеки для соединения на командной строке при соединении общих объектов. Это имеет тот же эффект как 1., но, libDB меток как нуждающийся libDA.

различие - то, что при использовании бывшего пути необходимо указать все три библиотеки (-lDA,-lDB,-lDC) на командной строке при соединении исполняемого файла. При использовании последнего Вы просто указываете-lDC, и он вытянет другие автоматически во время ссылки. Обратите внимание, что время ссылки непосредственно перед Вашими прогонами программы (то, что означает Вас, может получить различные версии символов, даже из различных библиотек).

это все относится к UNIX; Windows DLL работает вполне по-другому.

Редактирование после разъяснения вопроса:

Кавычка от ld информационное руководство.

компоновщик будет искать архив только однажды в местоположении, где он указан на командной строке. Если архив определит символ, который был не определен в некотором объекте, который появился то перед архивом на командной строке компоновщик будет включать соответствующий файл (файлы) из архива. Однако неопределенный символ в объекте, появляющемся позже командная строка, не заставит компоновщика искать архив снова.

Посмотрите '-(' опция для способа вынудить компоновщика искать архивы многократно.

можно перечислить тот же архив многократно на командной строке.

Этот тип поиска архива является стандартным для компоновщиков Unix. Однако при использовании 'ld' на AIX обратите внимание, что это отличается от поведения компоновщика AIX.

, Который означает:

Любая статическая библиотека или объект, который зависит от другой библиотеки, должны быть размещены перед нею в командной строке. Если статические библиотеки зависят друг от друга циркулярного, Вы можете, например, использовать -( параметр командной строки или размещать библиотеки по командной строке дважды (-lDA -lDB -lDA). Порядок динамических библиотек не имеет значения.

26
ответ дан jpalecek 28 November 2019 в 23:08
поделиться

Это - вид вопроса, это лучше всего решено тривиальным примером.В самом деле! Займите 2 минуты, кодируйте простой пример и испытайте его! Вы изучите что-то, и это быстрее, чем выяснение.

, Например, учитывая файлы:

Выполнение a1.cc

#include <stdio.h>
void a1() { printf("a1\n"); }

a2.cc

#include <stdio.h>
extern void a1();
void a2() { printf("a2\n");  a1(); }

a3.cc

#include <stdio.h>
extern void a2();
void a3() { printf("a3\n"); a2(); }

aa.cc

extern void a3();
int main()
{
  a3();
}

:

g++ -Wall -g -c a1.cc
g++ -Wall -g -c a2.cc
g++ -Wall -g -c a3.cc
ar -r liba1.a a1.o
ar -r liba2.a a2.o
ar -r liba3.a a3.o
g++ -Wall -g aa.cc -o aa -la1 -la2 -la3 -L.

Шоу:

./liba3.a(a3.o)(.text+0x14): In function `a3()':
/tmp/z/a3.C:4: undefined reference to `a2()'

принимая во внимание, что:

g++ -Wall -g -c a1.C
g++ -Wall -g -c a2.C
g++ -Wall -g -c a3.C
ar -r liba1.a a1.o
ar -r liba2.a a2.o
ar -r liba3.a a3.o
g++ -Wall -g aa.C -o aa -la3 -la2 -la1 -L.

Успешно выполняется. (Просто порядок параметра-la3-la2-la1 изменяется.)

пз:

nm --demangle liba*.a

liba1.a:
a1.o:
                 U __gxx_personality_v0
                 U printf
0000000000000000 T a1()

liba2.a:
a2.o:
                 U __gxx_personality_v0
                 U printf
                 U a1()
0000000000000000 T a2()

liba3.a:
a3.o:
                 U __gxx_personality_v0
                 U printf
                 U a2()
0000000000000000 T a3()

От [1 127] человек nm :

  • , Если нижний регистр, символ локален; если верхний регистр, символ глобален (внешний).

  • "T" символ находится в тексте (код) раздел.

  • "U" символ не определен.

24
ответ дан Mr.Ree 28 November 2019 в 23:08
поделиться

Я работал в проекте с набором внутренних библиотек, которые, к сожалению, зависели друг от друга (и он ухудшался со временем). Мы закончили тем, что "решили" это путем установки SCons, чтобы указать, что все освобождает дважды при соединении:

g++ ... -la1 -la2 -la3 -la1 -la2 -la3 ...
2
ответ дан Fredrik Jansson 28 November 2019 в 23:08
поделиться

Зависимости для соединения библиотеки или исполняемого файла должны присутствовать в разовом ссылкой, таким образом, Вы не можете связать libXC, прежде чем libXB будет присутствовать. Это не имеет значения если статически или динамично.

Запускаются с самого основного, который имеет не (или только за пределами Вашего проекта) зависимости.

0
ответ дан Kosi2801 28 November 2019 в 23:08
поделиться

Это - хорошая практика для хранения библиотек независимыми друг от друга для предотвращения проблем порядка ссылки.

0
ответ дан Scottie T 28 November 2019 в 23:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: