ทำไมฉันถึงติดตั้งไลบรารี่ที่แชร์หลายเวอร์ชันไม่ได้?


10

มีหลายครั้งที่โปรแกรมบางโปรแกรมจะขึ้นอยู่กับไลบรารี่รุ่น xy และอีกอันบน xz แต่เท่าที่ฉันทราบไม่มีตัวจัดการแพ็กเกจจะอนุญาตให้ฉันติดตั้งทั้ง xy และ xz บางครั้งพวกเขาจะอนุญาตทั้งสองเวอร์ชันหลัก (เช่น qt4 และ qt5 ซึ่งสามารถติดตั้งได้ในเวลาเดียวกัน) แต่ (ดูเหมือน) จะไม่มีรุ่นรอง

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

คำตอบ:


13

ที่จริงแล้วคุณสามารถติดตั้งไลบรารี่ที่แชร์ได้หลายเวอร์ชั่นถ้าทำได้ถูกต้อง

ไลบรารีที่แบ่งใช้มักจะตั้งชื่อดังนี้:

lib<name>.so.<api-version>.<minor>

ถัดไปมี symlinks ไปยังไลบรารีภายใต้ชื่อต่อไปนี้:

lib<name>.so
lib<name>.so.<api-version>

เมื่อนักพัฒนาลิงก์กับไลบรารีเพื่อสร้างไบนารี่มันเป็นชื่อไฟล์ที่ลงท้ายด้วย.soที่ linker หา อาจมีเพียงหนึ่งรายการที่ติดตั้งพร้อมกันสำหรับแต่ละรายการ<name>แต่นั่นหมายความว่านักพัฒนาซอฟต์แวร์ไม่สามารถกำหนดเป้าหมายไลบรารีหลายรุ่นในเวลาเดียวกันได้ ด้วยตัวจัดการแพคเกจ.sosymlink นี้เป็นส่วนหนึ่งของ-devแพคเกจแยกต่างหากซึ่งนักพัฒนาเท่านั้นที่จำเป็นต้องติดตั้ง

เมื่อลิงเกอร์พบไฟล์ที่มีชื่อลงท้ายด้วย.soและใช้มันมีลักษณะภายในห้องสมุดว่าสำหรับข้อมูลที่เรียกว่าsoname Soname ให้คำแนะนำแก่ linker ว่าชื่อไฟล์ใดที่จะฝังลงในไบนารี่ที่ได้และดังนั้นชื่อไฟล์ใดที่จะถูกเรียกใช้ในรันไทม์ soname lib<name>.so.<api-version>ควรจะถูกตั้งค่า

ดังนั้นเวลารันไทม์ตัวเชื่อมโยงแบบไดนามิกจะค้นหาlib<name>.so.<api-version>และใช้สิ่งนั้น

ความตั้งใจคือ:

  • <minor>การอัปเกรดจะไม่เปลี่ยนแปลง API ของไลบรารีและเมื่อการ<minor>ชนเข้ากับเวอร์ชันที่สูงกว่าจะปลอดภัยที่จะอนุญาตให้ไบนารีทั้งหมดอัปเกรดเป็นเวอร์ชันใหม่ เนื่องจากไบนารีทั้งหมดกำลังค้นหาไลบรารีภายใต้lib<name>.so.<api-version>ชื่อซึ่งเป็น symlink ไปยังการติดตั้งล่าสุดlib<name>.so.<api-version>.<minor>พวกเขาจะได้รับการอัพเกรด
  • <api-version>การอัพเกรดจะเปลี่ยน API ของไลบรารีและไม่ปลอดภัยที่จะอนุญาตให้แอปพลิเคชันไบนารีที่มีอยู่ใช้เวอร์ชันใหม่ ในกรณีที่<api-version>มีการเปลี่ยนแปลงเนื่องจากแอปพลิเคชันเหล่านั้นกำลังมองหาชื่อlib<name>.so.<api-version>แต่มีค่าแตกต่างกันสำหรับ<api-version>พวกเขาจะไม่รับรุ่นใหม่

ผู้จัดการแพคเกจมักจะไม่ทำแพ็กเกจมากกว่าหนึ่งเวอร์ชันของไลบรารีเดียวกันภายในเวอร์ชันการแจกจ่ายเดียวกันเนื่องจากการแจกจ่ายทั้งหมดรวมถึงไบนารีทั้งหมดที่ใช้ไลบรารีมักจะถูกคอมไพล์เพื่อใช้เวอร์ชันที่สอดคล้องกันของทุกไลบรารีก่อนการแจกจ่ายคือ การเผยแพร่. ตรวจสอบให้แน่ใจว่าทุกอย่างสอดคล้องกันและทุกอย่างในการแจกจ่ายนั้นเข้ากันได้กับทุกอย่างเป็นส่วนสำคัญของภาระงานสำหรับผู้จัดจำหน่าย

แต่คุณสามารถลงเอยด้วยไลบรารีหลายเวอร์ชันได้อย่างง่ายดายหากคุณอัพเกรดระบบของคุณจากการรบกวนรุ่นหนึ่งไปเป็นอีกเวอร์ชันหนึ่งและยังมีแพ็คเกจเก่าที่ต้องใช้เวอร์ชันไลบรารี่ที่เก่ากว่า ตัวอย่าง:

  • libmysqlclient16จากเก่าเดมีlibmysqlclient.so.16.0.0และ libmysqlclient.so.16symlink
  • libmysqlclient18จากปัจจุบันเดมีlibmysqlclient.so.18.0.0และ libmysqlclient.so.18symlink

4

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

หากใช้ชุดรูปแบบหมายเลขประ XYZ "micro" รุ่น Z มักจะเปลี่ยนแปลงในการแก้ไขข้อผิดพลาดหมายเลข "รอง" Y จะเปลี่ยนจากการเปลี่ยนแปลงที่เข้ากันได้แบบย้อนหลังและหมายเลขรุ่น "หลัก" X ต้องเปลี่ยนจากการเปลี่ยนแปลง API (และบางครั้ง ฟังก์ชั่นพิเศษที่สำคัญ)

ไม่ควรมีเหตุผลที่คุณไม่ต้องการแก้ไขข้อบกพร่องล่าสุดและการเปลี่ยนแปลงที่เข้ากันได้แบบย้อนหลังไม่ควรทำให้ซอฟต์แวร์ของคุณพัง

หากห้องสมุดได้รับการพัฒนาด้วยวิธีนี้คุณควรจะสามารถแทนที่ XYZ ด้วย X (Y + m) ได้เสมอ (Z + n) สำหรับ m และ n ที่กำหนด นั่นคือคุณควรจะสามารถแทนที่ห้องสมุดของคุณด้วยชุดหมายเลขล่าสุดที่เหมือนกันได้เสมอ และหากนักพัฒนาห้องสมุดมีความระมัดระวังและหมายเลขหลักต่อไปสามารถใช้งานร่วมกันได้ (เช่นโดยการประกาศเพื่อคัดค้านสิ่งต่าง ๆ แต่ยังไม่ได้ลบออก) คุณสามารถใช้หมายเลขหลักถัดไปได้

สำหรับนักพัฒนาแพคเกจนี่หมายความว่าพวกเขาสามารถใช้ชื่อที่มีเพียงชื่อเดียวหรือไม่มีชื่อเพื่อให้เป็นเวอร์ชั่นล่าสุดโดยเพียงแค่อัปเดตแพ็คเกจ หากพวกเขาเรือห้องสมุดในแพคเกจabc2แล้วพวกเขาก็ต้องไปผ่านห่วงที่จะย้ายซอฟต์แวร์ของพวกเขาเองที่อาศัยอยู่บนabc2ที่จะอัพเกรดไปใช้งานที่abc3บางครั้งก็มีแพคเกจการเปลี่ยนแปลง จะสะดวกกว่าที่จะทิ้งหมายเลขเวอร์ชันหลักจากไลบรารีหากใช้งานได้กับแพ็คเกจส่วนใหญ่ ดังนั้นแม้ว่าทั้งสองabc2และabc3ควรจะมีในบางจุดที่มีอยู่ในการกระจายabc3มักจะถูกเรียกว่าabc(เหมือนabc2ถูกเรียกเมื่อยังไม่มีabc3) และทันทีที่ไม่มีแพ็คเกจขึ้นอยู่กับabc2การกระจายมันเป็นไปได้ที่จะลดลงabc2 โดยสิ้นเชิง

รูปแบบการกำหนดหมายเลขไม่ได้ถูกนำมาใช้อย่างสม่ำเสมอ แต่ฉันสามารถจินตนาการได้ว่าด้วยการกำเนิดของอินเทอร์เน็ตที่เผยแพร่ข้อมูลเกี่ยวกับวิธีการใช้รูปแบบดังกล่าวและแรงกดดันจากผู้ใช้ห้องสมุด (รวมถึงผู้พัฒนาห้องสมุด) เพื่อทำให้สิ่งสำคัญเช่น เมื่อต้องอ่านไฟล์ CHANGES ที่รวมอยู่ในไลบรารีได้มีส่วนทำให้สิ่งนี้กลายเป็นเรื่องปกติไปแล้ว

ตัวอย่างตัวนับหนึ่ง แต่ไม่ใช่ของไลบรารีคือ python intpreter ซึ่งเข้ากันไม่ได้กับออบเจ็กต์ที่ใช้ร่วมกันและรูปแบบการกัดในการเปลี่ยนจำนวนเล็กน้อย ดังนั้นคุณจะเห็นแพ็คเกจสำหรับ python (ล่าสุดใน 2.7 ซีรี่ย์) และ python3 (ล่าสุดในซีรีส์ python3.4 ในปัจจุบัน) รวมถึงแพ็คเกจที่ชัดเจนสำหรับ python 2.6 (ไม่ได้รับความนิยมน้อยกว่า) และ python 3.3

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.