У меня есть 2 статические библиотеки Linux, созданные ar cr, libabc.a и libxyz.a. Я хочу объединить их в одну статическую библиотеку libaz.a. Как я могу это сделать? Я хочу создать объединенную статическую библиотеку, а не использовать обе библиотеки для окончательной компоновки приложений.
Ответ 1
Существует по крайней мере три способа сделать это нативно. Первый и наиболее удобный способ – использовать 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
Или вы можете использовать «тонкий» архив (опция -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
Ответ 2
Если вы просто сделаете это так:
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
Более того, возможно, что в одном архиве есть несколько одноименных членов (скажем, в a.a), если вы запустите ar x a.a, вы получите только один одноименный член. Единственный способ извлечь все одноименные члены в одном архиве - указать номер члена с помощью опции '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
таким образом, компановщик все сделает за вас!
Ответ 3
Еще лучше выполнить частичное связывание каждой библиотеки и создать архив из двух получившихся объектных файлов. Таким образом, это работает как разделяемые библиотеки. Вы выполняете частичное связывание с помощью:
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
Linux