Bagaimana cara menggabungkan dua library statis “ar” menjadi satu?


91

Saya memiliki 2 pustaka Linux statis, dibuat oleh ar cr, libabc.adan libxyz.a.
Saya ingin menggabungkannya menjadi satu perpustakaan statis libaz.a.
Bagaimana saya bisa melakukan ini.

Saya ingin membuat pustaka statis gabungan, bukan untuk memberikan kedua pustaka ke tautan terakhir aplikasi.


7
Lihat juga: libtoolsolusi berbasis :libtool -static -o new.a old1.a old2.a
osgx

2
ini berfungsi dengan sempurna, hanya sedikit keraguan jika perpustakaan tersebut memiliki file yang sama.o (tetapi secara fungsionalitasnya berbeda) apakah itu masih akan berfungsi?
bindingofisaac

libtool -static -o new.a old1.a old2.a tidak bekerja di linux (centos 7)
vacing

Jawaban:


60

Anda dapat mengekstrak objek dari kedua .afile dan membuat .afile Anda menggunakan .os:

ar -x libabc.a
ar -x libxyz.a
ar -c libaz.a  *.o

64
Bahaya, Akankah Robinson! Ini hanya berfungsi jika nama anggota di libabc.a dan libxyz.a tidak tumpang tindih. Jika tidak, Anda akan menimpa satu dan itu akan hilang.
David Diberikan

6
Selain itu, libabc.amungkin berisi objek yang memiliki nama yang sama (berasal dari direktori yang berbeda) - perakitan ulang tidak akan berfungsi!
Igor R.

17
ar -ctidak berhasil untuk saya (Ubuntu 14.04). Saya mengerti ar: no operation specified. Saya melakukannya ar -qcdan itu berhasil dengan baik.
Maks.

ar t lib.a dapat digunakan untuk melihat file di perpustakaan tanpa benar-benar mengekstrak file.
raj_gt1

bagaimana saya bisa melakukannya di automake?
shuva

121

Setidaknya ada tiga cara untuk melakukan ini secara native . Cara pertama dan paling portabel adalah menggunakan libtool. Setelah membangun pustaka lain juga dengan libtool, Anda dapat menggabungkannya hanya dengan menambahkan .la libs ke variabel libaz_la_LIBADD automake, atau langsung dari Makefile dengan sesuatu seperti:

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

Dua lainnya setidaknya tersedia saat menggunakan GNU ar. Anda dapat menggunakan skrip MRI (dinamai misalnya libaz.mri), seperti:

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

dan kemudian jalankan ar sebagai:

ar -M <libaz.mri

Atau Anda dapat menggunakan arsip tipis (opsi -T), yang akan memungkinkan penambahan arsip lain tanpa membuatnya bersarang di dalam, meskipun sisi negatifnya adalah jika Anda ingin mendistribusikan pustaka statis, objek yang terlepas akan hilang:

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

Semua metode di atas dengan anggun menangani nama anggota yang tumpang tindih dari arsip asli.

Jika tidak, Anda harus membongkar ke dalam direktori yang berbeda dan mengemas ulang lagi, untuk menghindari penggantian nama anggota yang tumpang tindih:

mkdir abc; cd abc; ar -x ../libabc.a
mkdir xyz; cd xyz; ar -x ../libxyz.a
ar -qc libaz.a abc xyz

19
Bagi yang menginginkan arsip biasa (tidak tipis), salah satu hal sederhana yang bisa dilakukan adalah membuat arsip tipis, kemudian mengubahnya menjadi arsip biasa. Sesuatu seperti: ar cqT libaz.a libabc.a libxyz.a && echo -e 'create libaz.a\naddlib libaz.a\nsave\nend' | ar -M. Ini membuat thin sementara libaz.a, dan kemudian mengubah arsip tipis menjadi arsip normal (sehingga Anda dapat memindahkan / mendistribusikannya). Ini juga menangani dengan baik ketika nama perpustakaan Anda memiliki karakter khusus (spasi, plus, atau koma) (yaitu ar cqT libbundle.a libfoo++.a 'libbar baz.a'). Tapi +1 dari saya!
Cornstalks

Apa kerugian dari contoh skrip MRI pertama yang diberikan?
jb

Jawaban bagus! Senang melihat beberapa opsi yang tidak mengharuskan Anda mengekstraksi dan mencapai kembali. Juga menurut saya ide @Cornstalks bagus. Mungkin harus ditambahkan jawabannya?
Lightbulb1

Hei ketika saya mencoba menggunakan perintah untuk libtoolsaya mendapatkan kesalahan ini: libtool: link: unable to infer tagged configuration libtool: error: specify a tag with '--tag' Ada ide bagaimana memperbaikinya?
Lars Nielsen

@Guillem @Cornstalks Jawaban yang bagus. Bagaimana jika --Wl,-whole-archiveopsi diperlukan dalam perintah penautan asli untuk beberapa lib * .a, dan saya perlu menggabungkan semua lib * .a menjadi one.a. Saat menautkan lagi, --Wl,-whole-archivetidak akan berfungsi dengan one.a. Apa saran anda stackoverflow.com/questions/56323197/…
pikirkan

10

Jika Anda melakukannya sebagai:

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

Anda akan kehilangan beberapa file objek jika ada anggota dengan nama yang sama di aa dan ba jadi, Anda perlu mengekstrak anggota dari arsip yang berbeda ke folder yang berbeda:

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

Lebih jauh lagi, ada kemungkinan bahwa ada beberapa anggota dengan nama yang sama dalam satu arsip (katakanlah dalam aa), jika Anda menjalankan ar x aa , Anda hanya akan mendapatkan satu untuk anggota dengan nama yang sama.

Satu-satunya cara untuk mengekstrak semua anggota dengan nama yang sama dalam satu arsip adalah dengan menentukan nomor anggota dengan opsi '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
...

ini akan menjadi pekerjaan yang membosankan, jadi Anda harus menulis skrip yang lebih canggih untuk melakukan pekerjaan itu.

Salah satu solusi opsional adalah Anda dapat menggabungkan beberapa arsip menjadi satu perpustakaan bersama:

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

dengan cara ini linker akan menangani semua hal untuk Anda!


1
Samuel, terima kasih. Namun dalam menggabungkan ke dalam pustaka bersama, semua objek harus dikompilasi dengan -fPIC.
osgx

0

Lebih baik lagi Anda melakukan penautan parsial pada setiap pustaka dan mereka membuat arsip dari dua file objek yang dihasilkan. Dengan cara itu ia beroperasi seperti perpustakaan bersama

Anda melakukan penautan parsial dengan

gcc -r --nostdlib

jadi alih-alih membuat arsip perantara atau setelah mengekstraksi ulang, jalankan

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

kemudian

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

Ini tidak benar-benar menjawab pertanyaan yang diajukan - saat dia meminta perpustakaan. Sering kali Anda bahkan tidak memiliki sumber untuk perpustakaan yang diberikan, atau ingin membuatnya tetap dibuat sebelumnya karena alasan lain.
pholat

0
ar -x libx264.a
mkdir sub && cd sub
ar -m ../libx264.a `ar -t ../libx264.a |sort|uniq|grep "\.o"`
ar -x ../libx264.a

sekarang Anda memiliki dua versi "macroblock-10.o"


0
ar crsT libaz.a libabc.a libxyz.a

Di sini, Anda membuat arsip arsip dan kemudian 'meratakan' (menipis) hasil dengan bendera T. Tidak yakin bagaimana itu akan bekerja dengan nama yang sama .o file yang mungkin ada di dalamnya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.