İki “ar” statik kitaplığı tek bir kitapta nasıl birleştirilir?


92

Ben yarattığı 2 statik Linux kitaplıkları, var ar cr, libabc.ave libxyz.a.
Bunları tek bir statik kitaplıkta birleştirmek istiyorum libaz.a.
Bunu nasıl yapabilirim.

Her iki kitaplığı da uygulamaların son bağlantılarına vermek için birleştirilmiş bir statik kitaplık oluşturmak istiyorum.


8
Ayrıca bkz: libtoollibtool -static -o new.a old1.a old2.a
-based

2
mükemmel çalışıyor, bu kitaplıkların ortak dosya.o'ya sahip olup olmadıkları konusunda biraz şüphe duyuyorum (ancak işlevsellik açısından farklılar) yine de çalışacak mı?
bindingofisaac

libtool -static -o new.a old1.a old2.a linux üzerinde çalışmıyor (centos 7)
20'de

Yanıtlar:


62

Nesneyi her iki .adosyadan çıkarabilir .ave ayıklanan .oe- postaları kullanarak dosyanızı oluşturabilirsiniz :

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

66
Tehlike, Will Robinson! Bu sadece libabc.a ve libxyz.a'daki üyelerin isimleri çakışmıyorsa işe yarar. Aksi takdirde birinin üzerine yazarsınız ve kaybolur.
David Verildi

7
Ayrıca, libabc.aaynı ada sahip nesneler içerebilir (farklı dizinlerden oluşturulmuş) - bu durumda yeniden birleştirme çalışmaz!
Igor R.

17
ar -cbenim için çalışmadı (Ubuntu 14.04). Var ar: no operation specified. Onun ar -qcyerine yaptım ve bu iyi çalıştı.
Maksimum

ar t lib.a, dosyaları ayıklamadan kitaplıktaki dosyaları görüntülemek için kullanılabilir.
raj_gt1

bunu automake'da nasıl yapabilirim?
shuva

126

Bunu yerel olarak yapmanın en az üç yolu vardır . İlk ve en taşınabilir yol libtool kullanmaktır. Diğer kitaplıkları da libtool ile oluşturduktan sonra, bunları bir automake libaz_la_LIBADD değişkenine .la lib'leri ekleyerek veya doğrudan Makefile'dan aşağıdaki gibi bir şeyle birleştirebilirsiniz:

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

Diğer ikisi en azından GNU ar kullanılırken kullanılabilir. Aşağıdakiler gibi bir MRI komut dosyası (örneğin libaz.mri olarak adlandırılır) kullanabilirsiniz:

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

ve sonra ar şu şekilde yürütün:

ar -M <libaz.mri

Ya da , diğer arşivleri iç içe yerleştirmeden eklemeye izin veren ince bir arşiv (seçenek -T) kullanabilirsiniz , ancak olumsuz yanı, statik kitaplığı dağıtmak istiyorsanız, ayrılmış nesnenin eksik olmasıdır:

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

Yukarıdaki yöntemlerin tümü, orijinal arşivlerden çakışan üye adlarını incelikle işler.

Aksi takdirde, örtüşen üye adlarını değiştirmekten kaçınmak için farklı dizinlere açmanız ve yeniden paketlemeniz gerekir:

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

19
Normal bir arşiv (ince değil) isteyenler için yapılabilecek basit bir şey, ince bir arşiv oluşturmak ve ardından onu normal bir arşive dönüştürmektir. Gibi bir şey: ar cqT libaz.a libabc.a libxyz.a && echo -e 'create libaz.a\naddlib libaz.a\nsave\nend' | ar -M. Bu, geçici bir inceltme oluşturur libaz.ave ardından ince arşivi normal bir arşiv haline dönüştürür (böylece onu taşıyabilir / dağıtabilirsiniz). Bu ayrıca, kütüphane adlarınızda özel karakterler (boşluklu, artılar veya virgül) (yani ar cqT libbundle.a libfoo++.a 'libbar baz.a') olduğunda da incelikle işler . Ama benden +1!
Cornstalks

Verilen ilk MRI komut dosyası örneğinin dezavantajı nedir?
jb

Güzel cevap! Ayıklamanızı ve yeniden elde etmenizi gerektirmeyen bazı seçenekleri görmek güzel. Ayrıca @Cornstalks fikrinin iyi olduğunu düşünüyorum. Belki cevaba eklenmelidir?
Lightbulb1

Hey komutu kullanmaya çalıştığımda libtoolşu hataları alıyorum: Bunu libtool: link: unable to infer tagged configuration libtool: error: specify a tag with '--tag' nasıl düzelteceğime dair bir fikrin var mı?
Lars Nielsen

@Guillem @Cornstalks Harika cevap. Ya --Wl,-whole-archiveçoklu lib * .a için orijinal bağlama komutunda seçenek gerekliyse ve tüm lib * .a'yı .a ile birleştirmem gerekiyorsa one.a. Tekrar bağlanırken, --Wl,-whole-archiveile çalışmaz one.a. Önerin nedir? stackoverflow.com/questions/56323197/…
thinkdeep

10

Basitçe şu şekilde yaparsanız:

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

hem aa hem de ba'da aynı ada sahip üyeler varsa bazı nesne dosyalarını kaybedersiniz, bu nedenle farklı arşivlerin üyelerini farklı klasöre çıkarmanız gerekir:

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

dahası, bir arşivde aynı isimde birden fazla üye olması olasıdır (örneğin aa'da), eğer ar x aa çalıştırırsanız , aynı isimdeki üyeler için sadece bir tane alırsınız.

Aynı isimdeki tüm üyeleri tek bir arşivden çıkarmanın tek yolu, üye numarasını 'N' seçeneği ile belirlemektir:

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
...

bu sıkıcı bir iş olurdu, bu yüzden bu işi yapmak için daha karmaşık bir senaryo yazmanız gerekecek.

Bir opsiyonel çözümler tek bir paylaşılan kitaplığa birden fazla arşiv birleştirebilirsiniz olmasıdır:

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

bu şekilde bağlayıcı sizin için her şeyi halleder!


1
Samuel, teşekkürler. Ancak paylaşılan kitaplıkta birleştirilirken, tüm nesneler ile derlenmelidir -fPIC.
osgx

0

Daha da iyisi, her kitaplıkta kısmi bağlantı gerçekleştirirseniz, ortaya çıkan iki nesne dosyasının bir arşivini oluşturur. Bu şekilde, paylaşılan kitaplıklar gibi çalışır.

İle kısmi bağlantı yaparsınız

gcc -r --nostdlib

yani ara arşiv oluşturmak yerine veya yeniden çıkarttıktan sonra,

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

sonra

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

Kütüphaneler için sorduğu gibi, sorulan soruyu gerçekten cevaplamıyor. Çoğu zaman, verilen kitaplıklar için kaynaklara sahip değilsiniz veya bunları başka nedenlerden dolayı önceden oluşturulmuş halde tutmak istemiyorsunuz.
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

artık "macroblock-10.o" nun iki sürümüne sahipsiniz


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

Burada, arşiv arşivini oluşturursunuz ve ardından sonucu T bayrağıyla 'yassılaştırır' (inceltme). İçinde bulunabilecek aynı ad .o dosyalarıyla nasıl çalışacağından emin değilim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.