ฉันมีห้องสมุดลินุกซ์ 2 คงที่สร้างขึ้นโดยar cr
, และlibabc.a
ฉันต้องการรวมเข้าเป็นห้องสมุดคงที่เดียว
ฉันจะทำสิ่งนี้ได้อย่างไรlibxyz.a
libaz.a
ฉันต้องการสร้างไลบรารีแบบคงที่ที่ผสานไม่ใช่เพื่อให้ทั้งสองไลบรารีไปยังลิงค์สุดท้ายของแอปพลิเคชัน
ฉันมีห้องสมุดลินุกซ์ 2 คงที่สร้างขึ้นโดย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
libabc.a
อาจมีวัตถุที่มีชื่อเดียวกัน (ที่มาจากไดเรกทอรีที่แตกต่างกัน) - การประกอบใหม่จะไม่ทำงาน!
ar -c
ไม่ได้ผลสำหรับฉัน (Ubuntu 14.04) ฉันar: no operation specified
เข้าใจแล้ว ฉันทำar -qc
แทนและได้ผลดี
มีอย่างน้อยสามวิธีที่จะทำเช่นนี้โดยกำเนิด วิธีแรกและพกพาสะดวกที่สุดคือใช้ libtool หลังจากสร้างไลบรารีอื่น ๆ ด้วย libtool แล้วคุณสามารถรวมเข้าด้วยกันได้เพียงแค่เพิ่ม. la libs เข้ากับตัวแปรอัตโนมัติ 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
ar cqT libaz.a libabc.a libxyz.a && echo -e 'create libaz.a\naddlib libaz.a\nsave\nend' | ar -M
. สิ่งนี้จะสร้างบางชั่วคราวlibaz.a
จากนั้นแปลงไฟล์เก็บถาวรแบบบางเป็นไฟล์ปกติ (คุณจึงสามารถย้าย / แจกจ่ายได้) นอกจากนี้ยังจัดการอย่างสง่างามเมื่อชื่อไลบรารีของคุณมีอักขระพิเศษ (เว้นวรรคเครื่องหมายบวกหรือลูกน้ำ) (เช่นar cqT libbundle.a libfoo++.a 'libbar baz.a'
) แต่ +1 จากฉัน!
libtool
รับข้อผิดพลาดเหล่านี้: มีlibtool: link: unable to infer tagged configuration libtool: error: specify a tag with '--tag'
ความคิดอย่างไรในการแก้ไขปัญหานั้น?
--Wl,-whole-archive
จำเป็นต้องใช้ตัวเลือกในคำสั่งการลิงก์ดั้งเดิมสำหรับ lib * .a หลายตัวและฉันต้องรวม lib * .a ทั้งหมดเข้าone.a
ด้วยกัน เมื่อเชื่อมโยงอีกครั้งจะไม่ทำงานกับ--Wl,-whole-archive
one.a
ข้อเสนอแนะของคุณคืออะไร? stackoverflow.com/questions/56323197/…
ถ้าคุณทำมันเป็น:
ar x a.a
ar x b.a
ar c c.a *.o
คุณจะสูญเสียไฟล์ออบเจ็กต์บางไฟล์หากมีสมาชิกที่มีชื่อเดียวกันทั้งใน aa และ ba ดังนั้นคุณต้องแยกสมาชิกของไฟล์เก็บถาวรที่แตกต่างกันไปยังโฟลเดอร์อื่น:
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
วิธีนี้ผู้เชื่อมโยงจะจัดการทุกสิ่งให้คุณ!
-fPIC
.
ยิ่งไปกว่านั้นคุณทำการลิงก์บางส่วนในแต่ละไลบรารีและสร้างไฟล์อ็อบเจ็กต์ที่เป็นผลลัพธ์สองไฟล์ ด้วยวิธีนี้จะทำงานเหมือนกับไลบรารีที่ใช้ร่วมกัน
คุณทำการเชื่อมโยงบางส่วนกับ
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" สองเวอร์ชัน
ar crsT libaz.a libabc.a libxyz.a
ที่นี่คุณสร้างที่เก็บถาวรของไฟล์เก็บถาวรจากนั้น 'แบน' (การทำให้ผอมบาง) ผลลัพธ์ด้วย T ไม่แน่ใจว่าจะทำงานอย่างไรกับไฟล์. o ชื่อเดียวกันที่อาจมีอยู่ภายใน
libtool
- วิธีแก้ปัญหา :libtool -static -o new.a old1.a old2.a