Как объединить две статические библиотеки ar в одну? - PullRequest
78 голосов
/ 29 сентября 2010

У меня есть 2 статические библиотеки Linux, созданные ar cr, libabc.a и libxyz.a.
Я хочу объединить их в одну статическую библиотеку libaz.a.
Как я могу это сделать.

Я хочу создать объединенную статическую библиотеку, чтобы не дать обеим библиотекам окончательную ссылку приложений.

Ответы [ 5 ]

91 голосов
/ 13 мая 2014

Существует как минимум три способа сделать это изначально . Первый и самый переносимый способ - использовать libtool. Собрав другие библиотеки также с помощью libtool, вы можете объединить их, просто добавив библиотеки .la в переменную automake libaz_la_LIBADD или непосредственно из файла Makefile, например:

libtool --mode=link cc -static -o libaz.la libabc.la libxyz.la

Два других по крайней мере доступны при использовании GNU ar. Вы можете использовать скрипт MRI (названный, например, libaz.mri), например:

create libaz.a
addlib libabc.a
addlib libxyz.a
save
end

и затем выполните ar как:

ar -M <libaz.mri

Или вы можете использовать архив thin (опция -T), который позволит добавлять другие архивы, не вкладывая их внутрь, хотя недостатком является то, что если вы хотите распространять статическую библиотеку, отсоединенный объект будет отсутствовать:

ar -rcT libaz.a libabc.a libxyz.a

Все вышеперечисленные методы изящно обрабатывают перекрывающиеся имена членов из исходных архивов.

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

mkdir abc; cd abc; ar -x ../libabc.a
mkdir xyz; cd xyz; ar -x ../libxyz.a
ar -qc libaz.a abc xyz
48 голосов
/ 29 сентября 2010

Вы можете извлечь объект из обоих файлов .a и создать файл .a, используя извлеченные .o s:

ar -x libabc.a
ar -x libxyz.a
ar -c libaz.a  *.o
8 голосов
/ 09 мая 2014

Если вы просто сделаете это как:

ar x a.a
ar x b.a
ar c c.a  *.o 

вы потеряете некоторые объектные файлы, если в a.a и b.a есть члены с одинаковыми именами Итак, вам нужно извлечь элементы разных архивов в разные папки:

ar x a.a && mv *.o a_objs
ar x b.a && mv *.o b_objs
ar c c.a a_objs/*.o b_objs/*.o

Более того, возможно, что в одном архиве есть несколько членов с одинаковыми именами (скажем, в aa), если вы запустите ar x aa , вы получите только один для этих членов с одинаковыми именами .

Единственный способ извлечь всех членов с одним и тем же именем в одном архиве - указать номер участника с помощью опции 'N':

ar xN 1 a.a  xxx.c.o && mv xxx.c.o xxx.c.1.o
ar xN 2 b.a  xxx.c.o && mv xxx.c.o xxx.c.2.o
...

это будет утомительная работа, поэтому вам придется написать более сложный сценарий для этой работы.

Одно необязательное решение заключается в том, что вы можете объединить несколько архивов в одну общую библиотеку:

g++ -shared -o c.so -Wl,--whole-archive a.a b.a 

таким образом, компоновщик будет обрабатывать все для вас!

0 голосов
/ 28 мая 2019
ar -x libx264.a
mkdir sub && cd sub
ar -m ../libx264.a `ar -t ../libx264.a |sort|uniq|grep "\.o"`
ar -x ../libx264.a

теперь у вас есть две версии "macroblock-10.o"

0 голосов
/ 24 октября 2018

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

. Вы делаете частичное связывание с

gcc -r --nostdlib

, поэтому вместо создания промежуточного архива или после его повторного извлечения выполните

gcc -r --nostdlib $CFLAGS $OBJECTS_A -o $LIBNAME_A.o
gcc -r --nostdlib $CFLAGS $OBJECTS_B -o $LIBNAME_B.o

тогда

ar -cr $LIBNAME_JOINED.a $LIBNAME_A.o $LIBNAME_B.o
...