Ответ 1
Вы можете извлечь объект из файлов .a
и создать файл .a
с помощью извлеченного .o
s:
ar -x libabc.a
ar -x libxyz.a
ar -c libaz.a *.o
У меня есть 2 статические библиотеки Linux, созданные ar cr
, libabc.a
и libxyz.a
.
Я хочу объединить их в одну статическую библиотеку libaz.a
.
Как я могу это сделать.
Я хочу создать объединенную статическую библиотеку, чтобы не дать обеим библиотекам окончательную ссылку приложений.
Вы можете извлечь объект из файлов .a
и создать файл .a
с помощью извлеченного .o
s:
ar -x libabc.a
ar -x libxyz.a
ar -c libaz.a *.o
Существует как минимум три способа сделать это изначально. Первым и самым переносимым способом является использование libtool. После создания других библиотек также с помощью libtool вы можете объединить их, просто добавив .LLs к переменной automake libaz_la_LIBADD или непосредственно из Makefile с чем-то вроде:
libtool --mode=link cc -static -o libaz.la libabc.la libxyz.la
Остальные два, по крайней мере, доступны при использовании GNU ar. Вы можете использовать MRI script (названный, например, 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
Если вы просто сделаете это как:
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
...
это было бы утомительной работой, поэтому вам придется написать более изощренную script, чтобы выполнить эту работу.
Один дополнительный решение состоит в том, что вы можете объединить несколько архивов в одну общую библиотеку:
g++ -shared -o c.so -Wl,--whole-archive a.a b.a
таким образом компоновщик будет обрабатывать все для вас!
Еще лучше, если вы выполните частичное связывание для каждой библиотеки, и они сделают архив двух результирующих объектных файлов. Таким образом, он работает как общие библиотеки
Вы делаете частичную связь с
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
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"