Score:12

เหตุใดไบนารีในตัว 21.10 จึงเข้ากันไม่ได้กับการติดตั้ง 21.04

ธง cn

ฉันไม่เข้าใจว่าทำไมไบนารีที่สร้างขึ้นใน 21.10 จึงเข้ากันไม่ได้กับระบบ 21.04

ไบนารีเชื่อมโยงกับ libc.so.6 ซึ่งมีอยู่ในระบบปฏิบัติการเวอร์ชัน 21.04 ด้วย

เลขฐานสองเดียวกันบนระบบ 21.10:

$ldd turboledzd
    ลินุกซ์ vdso.so.1 (0x00007ffdc2595000)
    libhidapi-hidraw.so.0 => /lib/x86_64-linux-gnu/libhidapi-hidraw.so.0 (0x00007fdd64057000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdd63e2f000)
    libudev.so.1 => /lib/x86_64-linux-gnu/libudev.so.1 (0x00007fdd63e06000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fdd64085000)

และในระบบ 21.04:

$ldd turboledzd 
./turboledzd: /lib/x86_64-linux-gnu/libc.so.6: ไม่พบเวอร์ชัน `GLIBC_2.34' (จำเป็นโดย ./turboledzd)
    ลินุกซ์ vdso.so.1 (0x00007fff9c570000)
    libhidapi-hidraw.so.0 => /lib/x86_64-linux-gnu/libhidapi-hidraw.so.0 (0x00007f37ec402000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f37ec216000)
    libudev.so.1 => /lib/x86_64-linux-gnu/libudev.so.1 (0x00007f37ec1ed000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f37ec423000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f37ec1cb000)

คำถามของฉัน:

ถ้า libc.so.6 จาก 21.04 ไม่รองรับ libc.so.6 ตั้งแต่เวลา 21.10 น. เป็นต้นไป ทำไมไม่เรียก libc ใน 21.10 libc.so.7 แทน?

หรือดีกว่า ทำไมมันไม่เชื่อมโยงกับสิ่งที่เรียกว่า libglibc.so.2.34 - ถ้านั่นคือการพึ่งพา?

N0rbert avatar
zw flag
ใช้ 20.04 LTS หากคุณต้องการให้แอปพลิเคชันของคุณมีอายุการใช้งานที่ยาวนานโดยไม่ยุ่งยาก
marcelm avatar
cn flag
_"หรือดีกว่า ทำไมจึงไม่เชื่อมโยงกับสิ่งที่เรียกว่า libglibc.so.2.34"_ - คุณคิดว่าจะช่วยได้อย่างไร ในทั้งสองกรณี โปรแกรมจะไม่ทำงานจนกว่าคุณจะติดตั้ง glibc ที่อัปเดตแล้ว
cn flag
tl;dr: ใช่ มันเป็นระเบียบโง่ๆ ถ้าไม่ใช่ก็จะไม่ใช่ Linux สำหรับการเปรียบเทียบ ลองนึกดูว่ามันจะโง่แค่ไหนหากโปรแกรมที่คุณคอมไพล์บน Windows 10 20H2 ไม่ได้ทำงานบน Windows 10 20H1
cn flag
@ user541686: ไม่เฉพาะสำหรับ Linux; เป็นผลมาจากมรดกของ AT&T ที่ใช้ร่วมกันของ Unix และ Linuxโดยเฉพาะอย่างยิ่ง `libc` ถือว่าเป็นส่วนหนึ่งของระบบปฏิบัติการ บน Windows `MSVCRT*.DLL` เป็นส่วนหนึ่งของ Visual Studio ไม่ใช่ Windows และสามารถอยู่ร่วมกันได้หลายเวอร์ชัน คอมไพเลอร์อื่นๆ สำหรับ Windows สามารถจัดส่งไลบรารีของตนเองได้เช่นเดียวกัน Windows API นั้นได้รับการกำหนดเวอร์ชันอย่างเข้มงวดใน SDK และตั้งแต่ Windows 95 เป็นอย่างน้อย
Score:25
ธง us

ถ้า libc.so.6 จาก 21.04 ไม่รองรับ libc.so.6 ตั้งแต่เวลา 21.10 น. เป็นต้นไป ทำไมไม่เรียก libc ใน 21.10 libc.so.7 แทน?

libc.so เป็นแกนกลางของห้องสมุดเท่าที่มีมา เกือบทุกอย่างขึ้นอยู่กับมัน หนึ่งในเป้าหมายของ glibc คือการให้ความเข้ากันได้แบบย้อนกลับ ซึ่งเป็นโปรแกรมที่สามารถทำงานกับรุ่นเก่ากว่าได้ libc.so.6 ควร (ปกติ) จะทำงานได้ดีกับรุ่นที่ใหม่กว่า อย่างไรก็ตามหากคุณชนชื่อกับ libc.so.7 เพียงเพราะคุณเพิ่มฟังก์ชั่นใหม่เข้าไป ทั้งหมด ของโปรแกรมที่สร้างไว้ก่อนหน้านี้เหล่านี้จะต้องสร้างใหม่โดยไม่มีเหตุผลที่ดี ไม่มีอยู่จริง วิชาเอก ทำลาย API สำหรับ glibc เพื่อรับประกันสิ่งนี้

ฉันไม่เข้าใจว่าทำไมไบนารีที่สร้างขึ้นใน 21.10 จึงเข้ากันไม่ได้กับระบบ 21.04

ไม่เห็นมีใครค้ำประกัน ไปข้างหน้า ความเข้ากันได้ (ซึ่งเป็นสิ่งที่คุณคาดหวังว่าภายใน 21.04 จะสามารถเรียกใช้บางอย่างจาก 21.10 ได้) - ทำไมคุณถึงคาดหวังเช่นนั้นหากคุณไม่ใช้มาตรการป้องกันเพื่อให้มั่นใจ

st flag
Glibc อยู่ที่ไลบรารีเวอร์ชัน 6 ตั้งแต่ฉันใช้ Linux มาแล้ว ถ้าฉันจำไม่ผิด
muru avatar
us flag
ดูเหมือนว่าตั้งแต่ [1997 เมื่อการแยก Linux libc/glibc สิ้นสุดลง](https://man7.org/linux/man-pages/man7/glibc.7.html)
Bram avatar
cn flag
ดังนั้นอย่าสร้างอะไรในระบบใหม่ ถ้าคุณต้องการแจกจ่ายไบนารี ฉันจะใช้ระบบปฏิบัติการใหม่เพื่อสร้างไบนารีที่ทำงานบนระบบปฏิบัติการรุ่นเก่าได้อย่างไร
Incomputable avatar
cn flag
@Bram คุณสามารถยึดติดกับชุดคุณสมบัติที่ห้องสมุดที่เก่าแก่ที่สุดใน OSes การกระจายของคุณมีให้
Bram avatar
cn flag
@Incomputable ฉันไม่ได้ใช้ฟีเจอร์ใหม่ใดๆ ฉันเพิ่งใช้ระบบปฏิบัติการใหม่เพื่อคอมไพล์
Guntram Blohm avatar
cn flag
นี่คือเหตุผลที่ฉันเก็บเครื่องเสมือน Fedora 12 อายุ 10 ปีขึ้นไป (อาจเป็น Ubuntu 10.04 แต่ฉันเปลี่ยนเป็น Ubuntu ด้วย 14.04 เท่านั้น); เครื่องมือขนาดเล็กใดก็ตามที่ฉันสร้างขึ้นสำหรับการใช้งานของฉันเองจะถูกคอมไพล์ที่นั่น และทำงานได้กับทุกเครื่องที่ฉันคัดลอกไป ไม่ว่ามันจะเก่าหรือใหม่แค่ไหนก็ตาม
Ruslan avatar
bv flag
@Bram ใช่ อย่าคอมไพล์มันในระบบที่ใหม่กว่าเป้าหมายที่เก่าที่สุด และอย่าใช้ GCC ที่ใหม่กว่าที่เป้าหมายนั้นรองรับ อย่างน้อยก็สำหรับโค้ด C++ เพราะ `libstdc++.so` จะมีปัญหาเดียวกันทุกประการ .
Ruslan avatar
bv flag
@Incomputable ไม่ใช่เรื่องง่ายสำหรับ glibc/libstdc++ เพราะเมื่อเชื่อมโยง คุณจะใช้ ABI ล่าสุดที่ไลบรารีเหล่านี้รองรับโดยอัตโนมัติ เช่น `GLIBC_2.34` ใน OP และสิ่งนี้จำเป็นสำหรับไบนารีขั้นสุดท้ายเพื่อให้แสดงในไลบรารีที่โหลด เมื่อเริ่มต้น อาจมีเวทมนตร์เชื่อมโยงบางอย่างที่จะทำอย่างอื่น แต่ฉันไม่ทราบ
cn flag
@Bram "ฉันจะใช้ระบบปฏิบัติการใหม่เพื่อสร้างไบนารีได้อย่างไร" - นักเทียบท่าช่วยได้มากในสถานการณ์เช่นนี้ คุณสามารถใช้อิมเมจ `ubuntu:20.04` แมปไดเร็กทอรีต้นทางภายในและสร้างไบนารีที่นั่น ช่วยให้คุณติดตั้ง glibc / crosscompiling แยกต่างหาก
cn flag
@viraptor การอธิบายว่าใครจะทำอะไรได้บ้างหากไม่มี Docker จะเป็นประโยชน์ ปัญหานี้เก่าแล้ว แต่นักเทียบท่าเพิ่งมาในปี 2556
cn flag
@ user541686 หากไม่มีคำตอบนั้นเจ็บปวดและยาวเกินไปสำหรับความคิดเห็น "Google เพื่อเรียนรู้เกี่ยวกับการติดตั้ง toolchains และ crosscompiling" เป็นตัวชี้ที่สั้นที่สุด
capr avatar
cn flag
ชาว Linux ไม่สามารถเข้าใจได้ว่าทำไมทุกคนถึงต้องการสร้างไบนารีที่ควรทำงานบนระบบที่เก่ากว่า และพวกเขามีเวลา _decades_ ที่จะเข้าใจเรื่องง่ายๆ แบบนั้น แต่พวกเขาก็ยังไม่เข้าใจ
muru avatar
us flag
@capr และอะไรหยุดคุณจากการทำเช่นนั้น?
capr avatar
cn flag
สัญลักษณ์ "คุณลักษณะ" เวอร์ชันของ @muru glibc และการไม่มีตัวเลือกความเข้ากันได้ "เวอร์ชันขั้นต่ำ" ของ gcc (เช่น OSX มี)
muru avatar
us flag
@capr อา แต่การสร้างสำหรับเวอร์ชันเก่านั้นเป็นปัญหาที่แก้ไขได้ - เมื่อ 7-8 ปีที่แล้วเมื่อฉันขลุกอยู่ในบรรจุภัณฑ์ pbuilder และสิ่งที่คล้ายกันนั้นเป็นเวิร์กโฟลว์ที่โตเต็มที่แล้ว ทุกวันนี้ด้วย Docker ก็ยังง่ายยิ่งขึ้นไปอีก ฉันไม่ใช่คนใช้ macOS เลยไม่รู้ว่า macOS เทียบเท่ากับ *เหล่านั้น* หรือเปล่า
capr avatar
cn flag
@muru ความจริงที่ว่าคุณแนะนำให้ฉันสร้างด้วย Docker ซึ่งยังคงอยู่บน Linux รุ่นเก่าเพียงแค่ตอนนี้มันอยู่ใน VM แสดงให้เห็นถึงการขาดความเข้าใจในปัญหาที่ฉันพูดถึง บน Linux รุ่นเก่าคุณมี gcc แบบเก่า! นั่นไม่ใช่สิ่งที่คุณต้องการเลย นั่นเป็นเพียงแฮ็ค มันตรงกันข้ามกับวิศวกรรม
muru avatar
us flag
@capr เอ๊ะ ด้วย Docker คุณสามารถสร้างภาพด้วย glibc เก่าและ GCC ใหม่ได้อย่างง่ายดาย สิ่งที่ฉันเห็นทั้งหมดนี้คือการขาดความสนใจในการใช้วิธีแก้ปัญหาที่เป็นที่รู้จักและเข้าใจดี และแทนที่จะบ่นเมื่อสิ่งต่าง ๆ ไม่เหมือน $MY_FAVOURITE_OS
capr avatar
cn flag
@muru เพื่อกลับไปที่คำถามเดิมของคุณ สิ่งที่ "หยุด" ฉันจากการทำเช่นนั้นคือไม่ต้องการรวบรวม VM และสร้าง toolchain ของคอมไพเลอร์ทั้งหมดและสั้น ๆ ในการทำเช่นนั้นฉัน "คร่ำครวญ" เข้าใจ
Score:13
ธง us

ตาม package.ubuntu.com, 21.04 ใช้ glibc 2.33 ในขณะที่ 21.10 ใช้ glibc 2.34 ซึ่งเข้ากันไม่ได้อย่างสมบูรณ์

อย่างไรก็ตาม คุณควรจะสามารถสร้างไบนารีสำหรับ Ubuntu 21.04 จากซอร์สโค้ดได้

คุณต้องสร้างแพ็คเกจไบนารีแยกกันสำหรับ Ubuntu รุ่นต่างๆ เว้นแต่จะตีความแหล่งที่มา ยิงจรวดขีปนาวุธ สามารถดำเนินการให้คุณโดยอัตโนมัติ

เหตุใด libc ใน 21.10 จึงไม่เรียกว่า libc.so.7 แทน

นั่นเป็นการตัดสินใจที่ผู้พัฒนา glibc เท่านั้นที่สามารถทำได้

cn flag
มันเป็นการตัดสินใจที่ผู้จัดจำหน่ายสามารถทำได้ ฉันเดา - แต่มันน่าจะทำให้เกิดความสับสนและความเข้ากันไม่ได้มากกว่าที่จะแก้ไข .... และถ้าคุณต้องการระบบที่มี glibc หลายเวอร์ชัน คุณอาจต้องมีเวอร์ชัน ld -linux.so... ซึ่งจะต้องมีการสะท้อนให้เห็นในไบนารีสำหรับระบบดังกล่าว ทำให้พวกเขาเข้ากันไม่ได้กับสิ่งอื่นใดส่วนใหญ่...
Score:2
ธง ph

คำศัพท์สำหรับ Google คือ "การกำหนดเวอร์ชันสัญลักษณ์ glibc"

เนื่องจาก บทนำนี้ อธิบายว่า glibc มีหลายเวอร์ชันของสัญลักษณ์แต่ละตัวที่มีการเปลี่ยนแปลงเมื่อเวลาผ่านไป เป็นต้น libc.so.6 มีเวอร์ชัน glibc ทั้งหมดตั้งแต่ 2.0 จนถึงเวอร์ชันใดก็ตามที่มันพูด

เมื่อคุณเชื่อมโยงไลบรารีใหม่หรือไบนารีกับไลบรารีนั้น คุณกำลังใช้ .ชม ไฟล์และสัญลักษณ์ที่ส่งออกสำหรับสัญลักษณ์เวอร์ชันล่าสุด

สำหรับการเข้าถึงสัญลักษณ์ที่เก่ากว่า มีคำถามเกี่ยวกับ StackOverflow ชื่อ ฉันจะเชื่อมโยงไปยังเวอร์ชัน glibc เฉพาะได้อย่างไรแต่เนื่องจากการอ้างอิงอื่นๆ ทั้งหมดของคุณมีแนวโน้มที่จะเชื่อมโยงกับสัญลักษณ์ใหม่ล่าสุดด้วย การใช้ Docker หรือ chroot เพื่อกำหนดเป้าหมายระบบเวอร์ชันเก่าจะง่ายกว่ามาก เพราะคุณอาจเลิกสร้างสัญลักษณ์ใหม่ตั้งแต่เริ่มต้นหากคุณไม่ทำ

Python devs ดูแลชื่อคอนเทนเนอร์ Docker จริง ๆ หลายลินุกซ์... โดยเฉพาะอย่างยิ่งสำหรับการสร้างพื้นฐานที่เชื่อถือได้สำหรับการสร้างวงล้อ (แพ็คเกจไบนารีที่แจกจ่ายต่อได้) สำหรับแพ็คเกจ Python ที่มีส่วนประกอบที่คอมไพล์แล้ว

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

cn flag
**Windows** มีโปรไฟล์ที่กำหนดไว้อย่างชัดเจนหลายรายการ และยังคงจัดทำเอกสารเหล่านั้นกลับไปยัง NT 4.0: https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt แต่มันไม่ได้ถือว่าอะไรเกี่ยวกับ `malloc/free`; นั่นไม่ใช่ฟังก์ชั่นของ Windows Windows ใช้ 'HeapAlloc'/'HeapFree' และต้องการเพียงให้คุณใช้ฮีปเดียวกันสำหรับทั้งคู่
ph flag
@MSalters ไม่ว่าคุณจะใช้ Win32 API หรือ POSIX API ก็ตาม ประเด็นของฉันคือเอกสารประกอบของ Microsoft ที่ฉันอ่านมีทัศนคติแบบ "ถ้ามันพัง คุณจะต้องเก็บชิ้นส่วนทั้งหมด" ต่อการจัดสรรในสิ่งประดิษฐ์บิลด์เดียวและการปลดปล่อย ในอีก... ขอแค่อย่าหาเจออีกเลย มันเป็นยุคของ WinXP และ Microsoft ได้เปลี่ยน URL ของพวกเขาใหม่และกำหนดธีม MSDN ใหม่ตั้งแต่นั้นเป็นต้นมา
cn flag
เอกสารของ Microsoft ใน MSVC มีคำเตือนเหล่านั้น - คอมไพเลอร์ใช้ `malloc` แน่นอน

โพสต์คำตอบ

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