การปอกไลบรารี C ++ ของรหัสที่ไม่จำเป็นสำหรับแอปพลิเคชัน [ปิด]

ฉันมีแอปพลิเคชันที่ต้องอาศัยไลบรารีหลายแห่ง ฉันกำลังสร้างทุกอย่างจากแหล่งที่มาบนเครื่อง Ubuntu ฉันต้องการลบฟังก์ชัน/คลาสใดๆ ที่แอปพลิเคชันไม่จำเป็นออก มีเครื่องมือใดบ้างที่จะช่วยในเรื่องนั้น?

ป.ล. ฉันต้องการลบซอร์สโค้ดออกจากไลบรารี ไม่ใช่แค่สัญลักษณ์ออกจากไฟล์อ็อบเจ็กต์


person Ashok Vishnoi    schedule 24.05.2018    source แหล่งที่มา
comment
ดูเป็นไปได้ ดูที่นี่   -  person Paul Sanders    schedule 24.05.2018
comment
คุณไม่จำเป็นต้องเปลี่ยนซอร์สโค้ดเพื่อลบฟังก์ชัน วิธีการ หรือคลาสที่ไม่ได้ใช้ออกจากไบนารีของคุณ คำตอบของฉันมีจุดมุ่งหมายเพื่อแสดงให้คุณเห็นว่าต้องทำอย่างไรด้วยสวิตช์คอมไพเลอร์ง่ายๆ โปรดแจ้งให้เราทราบหากมีสิ่งใดต้องการคำชี้แจง   -  person Paul Sanders    schedule 25.05.2018
comment
ฉันเข้าใจประเด็นของคุณและขอขอบคุณสำหรับความช่วยเหลือของคุณ อย่างไรก็ตาม ฉันต้องการเพิ่มประสิทธิภาพไลบรารีโอเพ่นซอร์ส แต่ฉันไม่ต้องการฟังก์ชันไลบรารีที่สมบูรณ์ ดังนั้นหากฉันสามารถดึงซอร์สโค้ดได้ ก็จะปรับให้เหมาะสมได้ง่ายขึ้น   -  person Ashok Vishnoi    schedule 25.05.2018
comment
เหตุใดการเพิ่มประสิทธิภาพจึงง่ายกว่า สิ่งที่ฉันไม่เข้าใจคือทำไมคุณถึงคิดว่าการลบโค้ดออกจากไฟล์ต้นฉบับจะให้ผลลัพธ์ที่แตกต่างจากการที่คอมไพเลอร์และตัวเชื่อมโยงทำเพื่อคุณ   -  person Paul Sanders    schedule 25.05.2018
comment
ซอร์สโค้ดต้นฉบับมีขนาดใหญ่มาก (~200,000 ล็อค) ฉันต้องการ LOC ประมาณ 20,000 LOC   -  person Ashok Vishnoi    schedule 28.05.2018
comment
ล็อคคืออะไร? และหากคุณหมายถึงขนาดของไบนารี่ของคุณ ลองใช้แฟล็กนั้น ควรลบโค้ดที่ไม่สามารถเข้าถึงได้ออก และนั่นอาจเป็นทั้งหมดที่คุณต้องการ การแฮ็กข้อมูลแหล่งที่มาของห้องสมุดดูเหมือนเป็นความคิดที่ไม่ดี คุณเกือบจะทำลายบางสิ่งบางอย่างอย่างแน่นอน   -  person Paul Sanders    schedule 28.05.2018
comment
LOC->บรรทัดของโค้ด ฉันต้องการลบโค้ดที่ไม่ได้ใช้ เพิ่มประสิทธิภาพโค้ดและดูแลรักษาโค้ด การดูแลรักษาไลบรารีทั้งหมดนั้นมากเกินไปสำหรับฟังก์ชันการทำงานเล็กๆ   -  person Ashok Vishnoi    schedule 28.05.2018
comment
โอ้ โอเค ฉันไม่รู้ว่าคุณกำลังคิดจะผ่าตัดรุนแรงขนาดนี้ ขอโทษด้วย ฉันคิดว่าฉันแค่ใช้ IDE ที่เหมาะสม ของฉันมีเครื่องมือ 'Intellisense' มากมายที่จะช่วยในเรื่องนั้น   -  person Paul Sanders    schedule 28.05.2018


คำตอบ (3)


ยูทิลิตี strip มาตรฐานถูกสร้างขึ้นมาเพื่อสิ่งนี้โดยเฉพาะ

person Chugaister    schedule 24.05.2018
comment
นั่นเป็นเพียงการละทิ้ง สัญลักษณ์ OP (และแน่นอนว่าฉัน) ต้องการละเว้นโค้ดจากไฟล์ปฏิบัติการสุดท้ายที่ไม่เคยถูกเรียก - person Paul Sanders; 24.05.2018

ตอนนี้ฉันได้ค้นคว้าเรื่องนี้เล็กน้อยในบริบทของโครงการของตัวเองและตัดสินใจว่านี่คุ้มค่ากับคำตอบที่สมบูรณ์มากกว่าแค่ความคิดเห็น คำตอบนี้อิงตาม toolchain ของ Apple บน macOS (ซึ่งใช้เสียงดังกราวแทนที่จะเป็น gcc) แต่ฉันคิดว่าสิ่งต่าง ๆ ทำงานในลักษณะเดียวกันสำหรับทั้งคู่

กุญแจสำคัญในการดำเนินการนี้คือการเปิดใช้งาน 'การเพิ่มประสิทธิภาพเวลาลิงก์' เมื่อสร้างไลบรารีและไฟล์ปฏิบัติการของคุณ จริงๆ แล้วกลไกของสิ่งนี้ง่ายมาก - เพียงส่ง -flto ไปยัง gcc และ ld บนบรรทัดคำสั่ง สิ่งนี้มีสองเอฟเฟกต์:

  • รหัส (ฟังก์ชัน / วิธีการ) ในไฟล์อ็อบเจ็กต์หรือไฟล์เก็บถาวรที่ไม่เคยถูกเรียกจะถูกละเว้นจากไฟล์ปฏิบัติการขั้นสุดท้าย
  • ตัวเชื่อมโยงดำเนินการเพิ่มประสิทธิภาพที่คอมไพลเลอร์สามารถทำได้ (เช่น ฟังก์ชันอินไลน์) แต่มีความรู้ที่ขยายข้ามขอบเขตของหน่วยการคอมไพล์

มันจะไม่ช่วยคุณหากคุณกำลังเชื่อมโยงกับไลบรารีที่ใช้ร่วมกัน แต่อาจช่วยได้หากไลบรารีที่ใช้ร่วมกันนั้นเชื่อมโยงกับไลบรารี (คงที่) อื่น ๆ ซึ่งมีโค้ดที่ไลบรารีที่ใช้ร่วมกันไม่เคยเรียกใช้

ในทางกลับกัน สิ่งนี้ทำให้ขนาดไฟล์ปฏิบัติการสุดท้ายของฉันลดลงประมาณ 5% ซึ่งฉันพอใจ YMMV.

ข้อเสียคือไฟล์อ็อบเจ็กต์ของฉันมีขนาดเพิ่มขึ้นประมาณสองเท่า และเวลาในการลิงก์ บางครั้ง เพิ่มขึ้นอย่างมาก (ประมาณ 100 เท่า) แล้วถ้าฉันเชื่อมโยงใหม่ มันก็เร็วขึ้นมาก อย่างไรก็ตาม พฤติกรรมนี้อาจเป็นลักษณะเฉพาะของ Toolchain ของ Apple บางทีมันอาจจะเป็นการซ่อนตัวกลางบิวด์บางส่วนไว้ที่ลิงค์แรก ไม่ว่าในกรณีใด หากคุณเปิดใช้งานตัวเลือกนี้สำหรับรุ่นที่วางจำหน่ายเท่านั้น ก็ไม่ควรเป็นปัญหาสำคัญ

มีรายละเอียดเพิ่มเติมเกี่ยวกับชุดตัวเลือกบรรทัดคำสั่ง gcc ทั้งหมดที่ควบคุมการเพิ่มประสิทธิภาพได้ที่นี่: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html ค้นหาหน้านั้นด้วย flto เพื่อจำกัดการค้นหาของคุณให้แคบลง

และดูเบื้องหลังได้ที่ https://gcc.gnu.org/onlinedocs/gccint/LTO-Overview.html

แก้ไข:

ข้อมูลเพิ่มเติมเล็กน้อยเกี่ยวกับเวลาลิงก์ ตัวเชื่อมโยงของ Apple จะสร้างไฟล์ขนาดใหญ่บางไฟล์ในไดเรกทอรีชื่อ LTOCache เมื่อคุณเชื่อมโยง วันนี้ฉันไม่เห็นสิ่งเหล่านี้มาก่อน ดังนั้นสิ่งเหล่านี้จึงดูเหมือนเป็นตัวกลางในการสร้างที่เร่งการเชื่อมโยงเป็นครั้งที่สอง สำหรับลิงก์เริ่มต้นของฉันที่ช้ามาก ส่วนหนึ่งอาจเป็นเพราะในกรณีของฉัน ลิงก์เหล่านี้ถูกสร้างขึ้นบนเซิร์ฟเวอร์ SMB แต่อีกครั้ง CPU เต็มจนเต็มแล้วอาจจะไม่ได้

person Paul Sanders    schedule 24.05.2018

ตกลง ตอนนี้ฉันเข้าใจข้อกำหนดของ OP ดีขึ้นแล้ว ฉันก็มีคำตอบอื่นสำหรับเรื่องนี้ซึ่งฉันคิดว่าอาจเหมาะกับความต้องการของเขามากกว่า ฉันคิดว่าวิธีแก้ไขปัญหานี้คือการใช้เครื่องมือ การครอบคลุมโค้ด ท้ายที่สุดแล้ว ปัญหาอยู่ที่ การระบุ สิ่งที่คุณสามารถแก้ไขได้อย่างปลอดภัย จริงๆแล้วการถอดมันออกเป็นเรื่องง่าย

IDE ของฉัน (Visual Studio) มีหนึ่งในนั้นในตัว แต่ฉันคิดว่า OP กำลังใช้ gcc ดังนั้นพอร์ตการโทรแรกดูเหมือนจะเป็น gcov. มีตัวเลือกเชิงพาณิชย์อยู่หลายรายการ แต่มีราคาแพง นอกจากนี้ยังมีโพสต์ที่อาจเป็นประโยชน์ที่นี่

แน่นอนว่าสิ่งอื่นที่คุณต้องการคือโปรแกรมที่ออกกำลังกายทุกส่วนของห้องสมุดที่คุณต้องการเก็บไว้เพื่อจัดทำรายงานความครอบคลุมให้คุณใช้งานได้ แต่ดูเหมือนว่า OP จะมีสิ่งนั้นอยู่แล้ว IDE ที่ดีก็ช่วยได้เช่นกัน เนื่องจากทำให้การนำทางโค้ดง่ายขึ้นมาก ใน Visual Studio ฉันพบว่า ข้ามไปที่คำจำกัดความ และ 'บุ๊กมาร์ก' ที่ง่ายและรวดเร็วเป็นคุณสมบัติหลัก

person Paul Sanders    schedule 28.05.2018
comment
ขอบคุณ. มันช่วยให้ฉันลดขนาดลงได้ อย่างไรก็ตาม ฉันต้องลบโค้ดบางส่วนที่ไม่ได้ดำเนินการออก และสร้างโค้ดเพื่อตรวจสอบว่ามีข้อผิดพลาดในการคอมไพล์หรือไม่ เนื่องจากเครื่องมือที่ครอบคลุมให้ข้อมูลรันไทม์เท่านั้น ดังนั้นหากฟังก์ชันถูกเรียกใช้จากส่วน else ของคำสั่ง if..else และในขณะที่ดำเนินการ ส่วน if จะถูกดำเนินการ แม้ว่าฟังก์ชันจะแสดงว่าไม่ได้ดำเนินการในรายงานความครอบคลุม แต่ก็ไม่สามารถลบออกได้ - person Ashok Vishnoi; 03.06.2018
comment
ใช่ มันสมเหตุสมผลแล้ว บางทีคุณอาจไปต่อและลบส่วน else ได้ด้วย (คุณบอกว่าต้องการกำจัดบรรทัดต้นฉบับให้ได้มากที่สุด) - person Paul Sanders; 03.06.2018