ในขณะที่ฉันติดตั้งซอฟต์แวร์จากแพ็คเกจ (MacPorts / apt-get) ทุกครั้งที่ทำได้ ฉันมักจะพบว่าตัวเองจำเป็นต้องรวบรวมแพ็คเกจจากแหล่งที่มา ./configure && make && sudo make installปกติก็เพียงพอแล้ว แต่บางครั้งก็ใช้ไม่ได้ และเมื่อไม่ได้ ก็มักจะติดขัด สิ่งนี้มักเกี่ยวข้องกับการพึ่งพาไลบรารีอื่น ๆ ในทางใดทางหนึ่ง

ฉันต้องการเรียนรู้สิ่งต่อไปนี้:

  • ฉันจะทราบได้อย่างไรว่าข้อโต้แย้งใดที่จะส่งต่อไปยัง./configure?
  • ไลบรารีที่แชร์ทำงานอย่างไรภายใต้ OS X / Linux - ที่พวกเขาอาศัยอยู่บนระบบไฟล์./configure && makeค้นพบได้อย่างไร เกิดอะไรขึ้นเมื่อเชื่อมโยงกับ
  • อะไรคือความแตกต่างที่แท้จริงระหว่างไลบรารีที่ใช้ร่วมกันและไลบรารีที่ลิงก์แบบสแตติก ทำไมฉันไม่สามารถเชื่อมโยงทุกอย่างแบบสแตติกได้ (ทุกวันนี้ RAM และพื้นที่ดิสก์มีราคาถูก) และด้วยเหตุนี้จึงหลีกเลี่ยงข้อขัดแย้งในเวอร์ชันไลบรารีแปลก ๆ
  • ฉันจะทราบได้อย่างไรว่าฉันติดตั้งไลบรารี่ใดบ้าง และเวอร์ชันใด
  • ฉันจะติดตั้งไลบรารีมากกว่าหนึ่งเวอร์ชันโดยไม่ทำให้ระบบปกติของฉันเสียหายได้อย่างไร
  • หากฉันกำลังติดตั้งสิ่งของจากแหล่งที่มาบนระบบที่จัดการโดยใช้แพ็คเกจ วิธีใดสะอาดที่สุด
  • สมมติว่าฉันจัดการรวบรวมบางสิ่งที่เที่ยวยุ่งยิ่งจากแหล่งที่มา ฉันจะทำแพ็กเกจนั้นได้อย่างไรเพื่อให้คนอื่นไม่ต้องกระโดดข้ามห่วงเดียวกัน โดยเฉพาะบน OS X....
  • เครื่องมือบรรทัดคำสั่งใดบ้างที่ฉันต้องเชี่ยวชาญเพื่อให้ได้สิ่งนี้ อย่างเช่น otool, pkg-config เป็นต้น

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

answer

ฉันขอโทษที่ตอบทุกอย่างโดยตรง แต่ฉันไม่รู้บทเรียนที่เป็นประโยชน์ คำถามที่พบบ่อย ฯลฯ ต่อไปนี้คือ 8 ปีของการสร้างแอปเดสก์ท็อป (ที่ฉันช่วยเผยแพร่) ความหงุดหงิดและกูเกิล:

1. ฉันจะทราบได้อย่างไรว่าอาร์กิวเมนต์ใดที่จะส่งต่อไปยัง ./configure

ฝึกจริงๆ. Autotools นั้นง่ายพอเนื่องจากมีความสอดคล้องกัน แต่มีหลายสิ่งหลายอย่างที่ใช้ cmake หรือสคริปต์บิลด์แบบกำหนดเอง โดยทั่วไปแล้ว คุณไม่ควรต้องส่งต่อสิ่งใดเพื่อกำหนดค่า มันควรหาว่าระบบของคุณสามารถสร้าง foo-tool ได้หรือไม่

เครื่องมือกำหนดค่าและ GNU ทั้งหมดจะค้นหาใน /, /usr และ /usr/local สำหรับการพึ่งพา หากคุณติดตั้งอย่างอื่นที่อื่น (ซึ่งทำให้สิ่งที่เจ็บปวดหาก MacPorts หรือ Fink ติดตั้งการพึ่งพา) คุณจะต้องส่งค่าสถานะเพื่อกำหนดค่าหรือแก้ไขสภาพแวดล้อมของเชลล์เพื่อช่วยให้เครื่องมือ GNU ค้นหาการพึ่งพาเหล่านี้

2. ไลบรารีที่ใช้ร่วมกันทำงานอย่างไรภายใต้ OS X / Linux - ที่พวกเขาอาศัยอยู่บนระบบไฟล์ ./configure && ทำให้ค้นหาได้อย่างไร เกิดอะไรขึ้นเมื่อเชื่อมโยงกับ

บน Linux จำเป็นต้องติดตั้งไปยังพาธที่ไดนามิกลิงก์เกอร์สามารถค้นหาได้ ซึ่งถูกกำหนดโดยLD_LIBRARY_PATHตัวแปรสภาพแวดล้อมและเนื้อหาของ /etc/ld.conf บน Mac จะเหมือนกันสำหรับซอฟต์แวร์โอเพ่นซอร์สส่วนใหญ่เกือบทุกครั้ง (เว้นแต่จะเป็นโครงการ Xcode) ยกเว้นตัวแปร env DYLD_LIBRARY_PATHแทน

มีเส้นทางเริ่มต้นที่ตัวเชื่อมโยงค้นหาไลบรารี มันคือ /lib:/usr/lib:/usr/local/lib

คุณสามารถเสริมสิ่งนี้ได้โดยใช้ตัวแปร CPATH หรือ CFLAGS หรือตัวแปรสภาพแวดล้อมอื่น ๆ จำนวนเท่าใดก็ได้ (ซับซ้อนสะดวก) ฉันแนะนำ CFLAGS ดังนี้:

ส่งออก CFLAGS="$CFLAGS -L/new/path"

พารามิเตอร์ -L เพิ่มไปยังเส้นทางลิงก์

สิ่งสมัยใหม่ใช้เครื่องมือ pkg-config สิ่งใหม่ๆ ที่คุณติดตั้งจะติดตั้งไฟล์ .pc ที่อธิบายไลบรารีและที่มาของไลบรารี และวิธีลิงก์ไปยังไลบรารี สิ่งนี้จะทำให้ชีวิตง่ายขึ้น แต่มันไม่ได้มาพร้อมกับ OS X 10.5 ดังนั้นคุณจะต้องติดตั้งมันด้วย นอกจากนี้ยังมี deps พื้นฐานจำนวนมากที่ไม่สนับสนุน

การเชื่อมโยงเป็นเพียง "แก้ไขฟังก์ชันนี้ขณะใช้งานจริง" จริงๆ แล้วมันเป็นตารางสตริงขนาดใหญ่

3. อะไรคือความแตกต่างที่แท้จริงระหว่างไลบรารีที่ใช้ร่วมกันและไลบรารีที่ลิงก์แบบสแตติก ทำไมฉันไม่สามารถเชื่อมโยงทุกอย่างแบบสแตติกได้ (ทุกวันนี้ RAM และพื้นที่ดิสก์มีราคาถูก) และด้วยเหตุนี้จึงหลีกเลี่ยงข้อขัดแย้งในเวอร์ชันไลบรารีแปลก ๆ

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

ไลบรารีไดนามิกมีโค้ดเหมือนกัน แต่เมื่อรันแอป โค้ดจะถูกโหลดลงในแอปตอนรันไทม์ (คำอธิบายแบบง่าย)

คุณสามารถเชื่อมโยงแบบคงที่กับทุกอย่างได้ อย่างไรก็ตาม ระบบบิลด์ใดๆ ที่แทบจะไม่ทำให้สิ่งนี้เป็นเรื่องง่าย คุณต้องแก้ไขไฟล์ระบบบิลด์ด้วยตนเอง (เช่น Makefile.am หรือ CMakeLists.txt) อย่างไรก็ตาม นี่อาจคุ้มค่าที่จะเรียนรู้หากคุณติดตั้งสิ่งต่าง ๆ ที่ต้องใช้ไลบรารีเวอร์ชันต่าง ๆ เป็นประจำ และคุณกำลังพบว่าการติดตั้งการพึ่งพาแบบคู่ขนานนั้นทำได้ยาก

เคล็ดลับคือเปลี่ยนบรรทัดลิงก์จาก -lfoo เป็น -l/path/to/static/foo.a

คุณอาจค้นหาและแทนที่ได้ หลังจากนั้นให้ตรวจสอบว่าเครื่องมือไม่เชื่อมโยงกับ .so หรือ dylib โดยใช้ ldd foo หรือ otool -L foo

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

4. ฉันจะทราบได้อย่างไรว่าฉันติดตั้งไลบรารี่ใดบ้าง และเวอร์ชันใด

หากคุณมีไฟล์ pkg-config สำหรับไลบรารีเหล่านั้น มันง่าย:

pkg-config --list-all

ไม่อย่างนั้นคุณมักจะทำไม่ได้ง่ายๆ dylib อาจมี soname (เช่น foo.0.1.dylib, soname คือ 0.1) ที่เหมือนกับเวอร์ชันของไลบรารี อย่างไรก็ตามสิ่งนี้ไม่จำเป็น soname เป็นคุณลักษณะการคำนวณแบบไบนารี คุณต้องชนส่วนหลักของ soname ถ้าคุณเปลี่ยนรูปแบบของฟังก์ชันในไลบรารี ดังนั้นคุณจะได้รับเช่น เวอร์ชัน 14.0.5 soname สำหรับไลบรารี 2.0 แม้ว่าสิ่งนี้จะไม่ธรรมดา

ฉันหงุดหงิดกับเรื่องแบบนี้และได้พัฒนาวิธีแก้ปัญหานี้บน Mac และฉันจะพูดถึงมันต่อไป

5. ฉันจะติดตั้งไลบรารีมากกว่าหนึ่งเวอร์ชันโดยไม่ทำลายระบบปกติของฉันได้อย่างไร

วิธีแก้ปัญหาของฉันอยู่ที่นี่: http://github.com/mxcl/homebrew/

ฉันชอบติดตั้งจากแหล่งที่มาและต้องการเครื่องมือที่ทำให้มันง่าย แต่มีการจัดการแพ็คเกจบางอย่าง ดังนั้นด้วย Homebrew ฉันจึงสร้าง เช่น รับตัวเองจากแหล่งที่มา แต่อย่าลืมติดตั้งเป็นคำนำหน้าพิเศษ:

/usr/local/Cellar/wget/1.1.4

จากนั้นฉันก็ใช้เครื่องมือ homebrew เพื่อเชื่อมโยงทุกอย่างเข้ากับ /usr/local ดังนั้นฉันจึงยังมี /usr/local/bin/wget และ /usr/local/lib/libwget.dylib

ในภายหลัง ถ้าฉันต้องการ wget เวอร์ชันอื่น ฉันสามารถติดตั้งมันแบบขนานและเพียงแค่เปลี่ยนเวอร์ชันที่เชื่อมโยงไปยัง /usr/local tree

6. หากฉันกำลังติดตั้งสิ่งต่าง ๆ จากแหล่งที่มาบนระบบที่จัดการโดยใช้แพ็คเกจ วิธีใดสะอาดที่สุด

ฉันเชื่อว่าวิธีการของ Homebrew นั้นสะอาดที่สุด ดังนั้นควรใช้หรือทำสิ่งที่เทียบเท่า ติดตั้งไปที่ /usr/local/pkgs/name/version และ symlink หรือฮาร์ดลิงก์ในส่วนที่เหลือ

ใช้ /usr/local. ทุกเครื่องมือสร้างที่มีอยู่จะค้นหาการพึ่งพาและส่วนหัวที่นั่น ชีวิตของคุณจะมากได้ง่ายขึ้น

7. สมมติว่าฉันจัดการคอมไพล์บางอย่างจากแหล่งที่มาได้ ฉันจะทำแพ็กเกจนั้นได้อย่างไรเพื่อไม่ให้คนอื่นต้องกระโดดข้ามห่วงเดียวกัน โดยเฉพาะบน OS X....

หากไม่มีการอ้างอิงใด ๆ คุณสามารถ tar ขึ้นไดเร็กทอรี build และมอบให้กับบุคคลอื่นที่สามารถ "ทำการติดตั้ง" ได้ อย่างไรก็ตาม คุณสามารถทำสิ่งนี้ได้อย่างน่าเชื่อถือสำหรับ OS X เวอร์ชันเดียวกันเท่านั้น บน Linux มันอาจจะใช้ได้กับ Linux ที่คล้ายกัน (เช่น Ubuntu) ที่มี Kernel เวอร์ชันเดียวกันและเวอร์ชันรอง libc

สาเหตุที่แจกจ่ายไบนารีบน Unix ไม่ใช่เรื่องง่ายเนื่องจากความเข้ากันได้ของไบนารี ชาว GNU และคนอื่นๆ เปลี่ยนอินเทอร์เฟซไบนารีบ่อยๆ

โดยทั่วไปไม่แจกจ่ายไบนารี สิ่งต่าง ๆ อาจจะแตกสลายด้วยวิธีที่แปลกมาก

บน Mac ตัวเลือกที่ดีที่สุดคือสร้างแพ็คเกจ Macports ทุกคนใช้ macports บน Linux มีระบบบิลด์และชุดค่าผสมที่แตกต่างกันมากมาย ฉันไม่คิดว่าจะมีอะไรแนะนำที่ดีไปกว่าการเขียนรายการบล็อกเกี่ยวกับวิธีที่คุณประสบความสำเร็จในการสร้างเครื่องมือ x ในการกำหนดค่าแปลกๆ

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

หนึ่งในเป้าหมายในอนาคตของฉันกับ Homebrew คือการทำให้สามารถคลิกลิงก์บนเว็บไซต์ได้ (เช่น homebrew://blah และมันจะดาวน์โหลดสคริปต์ Ruby นั้น ติดตั้ง deps สำหรับแพ็คเกจนั้นแล้วสร้างแอป แต่ใช่ ยังไม่เสร็จ แต่ก็ไม่ยากเกินไปเมื่อพิจารณาจากการออกแบบที่ฉันเลือก

8. เครื่องมือบรรทัดคำสั่งใดที่ฉันต้องเชี่ยวชาญเพื่อให้เชี่ยวชาญในเรื่องนี้ อย่างเช่น otool, pkg-config เป็นต้น

otool มีประโยชน์จริง ๆ หลังจากนั้นเท่านั้น มันบอกคุณว่าไบนารีที่สร้างขึ้นเชื่อมโยงไปยังอะไร เมื่อคุณค้นหาการพึ่งพาของเครื่องมือที่คุณต้องสร้าง มันไม่มีประโยชน์ เช่นเดียวกันกับ pkg-config เนื่องจากคุณได้ติดตั้งการพึ่งพาก่อนที่คุณจะสามารถใช้งานได้

ห่วงโซ่เครื่องมือของฉันคือ อ่านไฟล์ README และ INSTALL และกำหนดค่า --help ดูผลลัพธ์ของบิลด์เพื่อตรวจสอบว่ามีเหตุผล แยกวิเคราะห์ข้อผิดพลาดในการสร้าง บางทีในอนาคต ถามบน serverfault :)

นี่เป็นหัวข้อใหญ่ ดังนั้นเรามาเริ่มด้วยไลบรารีที่ใช้ร่วมกันบน Linux (ELF บน Linux และ Mach-O บน OS X) Ulrich Drepper มีคำแนะนำที่ดีเกี่ยวกับการเขียน DSO (วัตถุที่ใช้ร่วมกันแบบไดนามิก) ซึ่งครอบคลุมประวัติบางส่วนของไลบรารีที่แชร์บน Linux ที่พร้อมใช้งาน รวมทั้งเหตุใดจึงมีความสำคัญ

Ulrich ยังอธิบายด้วยว่าเหตุใดการลิงก์แบบสแตติกจึงถือว่าเป็นอันตรายหนึ่งในประเด็นสำคัญที่นี่คือการอัปเดตความปลอดภัย บัฟเฟอร์ล้นในไลบรารีทั่วไป (เช่น zlib) ที่มีการเชื่อมโยงแบบสแตติกอย่างกว้างขวางอาจทำให้เกิดโอเวอร์เฮดขนาดใหญ่สำหรับการแจกแจง - สิ่งนี้เกิดขึ้นกับ zlib 1.1.3 ( คำแนะนำของ Red Hat )

เอลฟ์

หน้าคู่มือ linker ld.so

man ld.so 

อธิบายพาธพื้นฐานและไฟล์ที่เกี่ยวข้องกับการลิงก์รันไทม์แบบไดนามิก ในระบบ Linux สมัยใหม่ คุณจะเห็นเส้นทางเพิ่มเติมที่เพิ่มผ่าน /etc/ld.so.conf.d/ ซึ่งมักจะเพิ่มผ่าน glob ที่รวมอยู่ใน /etc/ld.so.conf

หากคุณต้องการดูว่ามีอะไรให้ใช้งานแบบไดนามิกผ่านการกำหนดค่า ld.so ของคุณ คุณสามารถเรียกใช้

ldconfig -v -N -X

การอ่านวิธีการของ DSO ควรให้ระดับความรู้พื้นฐานที่ดีแก่คุณ เพื่อทำความเข้าใจว่าหลักการเหล่านั้นนำไปใช้กับ Mach-O บน OS X อย่างไร

ผู้ชาย

บน OS X รูปแบบไบนารีคือ Mach-O เอกสารระบบโลคัลสำหรับตัวเชื่อมโยงคือ

man dyld

เอกสารรูปแบบ Machสามารถใช้ได้จากแอปเปิ้ล

เครื่องมือสร้าง UNIX

กระบวนการทั่วไปconfigure, make, make installโดยทั่วไปมีให้โดย autotools ของ GNU ซึ่งมีหนังสือออนไลน์ที่ครอบคลุมประวัติบางส่วนของการแยก configuration/build และ GNU toolchain Autoconfใช้การทดสอบเพื่อกำหนดความพร้อมใช้งานของคุณลักษณะบนระบบบิลด์เป้าหมาย โดยใช้ภาษามาโคร M4เพื่อขับเคลื่อนสิ่งนี้ โดยทั่วไปแล้วAutomakeเป็นวิธีการสร้างเทมเพลตสำหรับ Makefiles โดยทั่วไปเทมเพลตจะเรียกว่า Makefile.am ซึ่งส่งออก Makefile.in ที่เอาต์พุตของ autoconf (สคริปต์กำหนดค่า) แปลงเป็น Makefile

สวัสดี GNUโปรแกรมทำหน้าที่เป็นตัวอย่างที่ดีสำหรับการทำความเข้าใจ toolchain GNU - และคู่มือการใช้รวมถึงเอกสาร autotools

ไซม่อน! ฉันรู้ว่าคุณรู้สึกอย่างไร; ฉันยังดิ้นรนกับการเรียนรู้ Linux ส่วนนี้ด้วย ขึ้นอยู่กับประสบการณ์ของตัวเองผมเขียนสอนเกี่ยวกับบางส่วนของรายการที่คุณอยู่ (ส่วนใหญ่เป็นข้อมูลอ้างอิงสำหรับตัวเอง!): http://easyaspy.blogspot.com/2008/12/buildinginstalling-application-from.html ฉันคิดว่าคุณจะประทับใจกับบันทึกของฉันเกี่ยวกับความง่ายในการสร้าง/ติดตั้งแอปพลิเคชัน Python :)

หวังว่านี่จะช่วยได้! และมีความสุขในการรวบรวม

ทิม โจนส์


การสร้าง/การติดตั้งแอปพลิเคชันจากแหล่งที่มาใน Ubuntu Linux

ในขณะที่ที่เก็บของ Ubuntu นั้นเต็มไปด้วยแอปพลิเคชั่นที่ยอดเยี่ยม แต่ในคราวเดียวคุณต้องเจอเครื่องมือ "ต้องมี" ที่ไม่ได้อยู่ในที่เก็บ (หรือไม่มีแพ็คเกจ Debian) หรือคุณต้องการ เวอร์ชันใหม่กว่าในที่เก็บ คุณทำงานอะไร? คุณต้องสร้างแอปพลิเคชันจากแหล่งที่มา! ไม่ต้องกังวล มันไม่ได้ซับซ้อนอย่างที่คิดจริงๆ นี่คือเคล็ดลับบางส่วนจากประสบการณ์ของฉันในการก้าวจากการเป็นมือสมัครเล่นระดับมือสมัครเล่น! (ในขณะที่ฉันใช้ Ubuntu สำหรับตัวอย่างนี้ แนวคิดทั่วไปควรใช้ได้กับการแจกจ่าย Unix/Linux ส่วนใหญ่ เช่น Fedora และแม้แต่แพลตฟอร์ม Cygwin บน Windows)

กระบวนการพื้นฐานในการสร้าง (คอมไพล์) แอปพลิเคชันส่วนใหญ่จากซอร์สจะมีลำดับดังนี้: configuration --> compile --> install โดยทั่วไป Unix / Linux คำสั่งที่จะทำสิ่งเหล่านี้คือ: config-> ->make make installในบางกรณี คุณจะพบหน้าเว็บที่แสดงว่าสิ่งเหล่านี้สามารถรวมเป็นคำสั่งเดียวได้:

$ config && make && make install

แน่นอน คำสั่งนี้ถือว่าไม่มีปัญหาในขั้นตอนเหล่านี้ นี่คือที่มาของความสนุก!

เริ่มต้น

หากคุณไม่เคยคอมไพล์แอปพลิเคชันจากแหล่งที่มาบนระบบของคุณมาก่อน คุณอาจต้องตั้งค่าด้วยเครื่องมือการพัฒนาทั่วไปบางอย่าง เช่นgccชุดคอมไพเลอร์ ไฟล์ส่วนหัวทั่วไปบางไฟล์ (คิดว่านี่เป็นโค้ดที่เขียนไปแล้ว โดยบุคคลอื่นที่ใช้โดยโปรแกรมที่คุณกำลังติดตั้ง) และเครื่องมือสร้าง โชคดีที่ใน Ubuntu มี metapackage ที่เรียกbuild-essentialว่าจะติดตั้งสิ่งนี้ ในการติดตั้ง (หรือเพียงแค่แน่ใจว่าคุณมีอยู่แล้ว!) ให้รันคำสั่งนี้ในเทอร์มินัล:

$ sudo apt-get install build-essential

เมื่อคุณมีการตั้งค่าพื้นฐานแล้ว ให้ดาวน์โหลดไฟล์แหล่งที่มาของแอปพลิเคชันและบันทึกลงในไดเร็กทอรีที่คุณมีสิทธิ์ในการอ่าน/เขียน เช่น ไดเร็กทอรี "home" ของคุณ โดยทั่วไป ไฟล์เหล่านี้จะอยู่ในไฟล์เก็บถาวรที่มีนามสกุลไฟล์อย่างใดอย่างหนึ่ง.tar.gzหรือ.tar.bz2. ความ.tarหมายง่ายๆ ก็คือ มันคือ "ไฟล์เก็บถาวร" ซึ่งเป็นกลุ่มของไฟล์ที่รักษาโครงสร้างไดเร็กทอรีสัมพัทธ์.gzย่อมาจาก gzip (GNU ไปรษณีย์) ซึ่งเป็นรูปแบบที่นิยม Unix / Linux การบีบอัด ในทำนองเดียวกัน.bz2ย่อมาจาก bzip2 ซึ่งเป็นรูปแบบการบีบอัดที่ใหม่กว่าที่ให้การบีบอัดที่สูงกว่า (ขนาดไฟล์บีบอัดที่เล็กกว่า) กว่า gzip

หลังจากที่คุณดาวน์โหลดไฟล์ต้นฉบับแล้ว ให้เปิดหน้าต่างเทอร์มินัล (เทอร์มินัลระบบจากเมนู Ubuntu) และเปลี่ยนเป็นไดเร็กทอรีที่คุณบันทึกไฟล์ของคุณ (ฉันจะใช้~/downloadในตัวอย่างนี้ '~' เป็นทางลัดไปยังไดเร็กทอรี "home" ของคุณ) ใช้คำสั่ง tar เพื่อแยกไฟล์ออกจากไฟล์เก็บถาวรที่ดาวน์โหลด:

หากไฟล์ของคุณเป็นไฟล์เก็บถาวร gzip (เช่น ลงท้ายด้วย.tar.gz) ให้ใช้คำสั่ง:

            $ tar -zxvf filename.tar.gz

หากไฟล์ของคุณเป็นไฟล์เก็บถาวร bzip2 (เช่น ลงท้ายด้วย.tar.bz2) ให้ใช้คำสั่ง:

            $ tar -jxvf filename.tar.gz

Tip: If you don't want to have to remember all of the command line switches for extracting archives, I recommend getting one (or both) of these utilities: dtrx (my favorite!) or deco (more popular). With either of these utilities, you just enter the name of the utility (dtrx or deco) and the filename, it it does all of the rest. Both of these "know" how to handle most any archive format that you are likely to run across and they have great error handling.

เมื่อสร้างจากแหล่งที่มา มีข้อผิดพลาดทั่วไปสองประเภทที่คุณมักจะพบ:

  1. ข้อผิดพลาดในการกำหนดค่าเกิดขึ้นเมื่อคุณเรียกใช้สคริปต์การกำหนดค่า (ปกติจะมีชื่อว่า config หรือ configuration) เพื่อสร้าง makefile เฉพาะสำหรับการตั้งค่าของคุณ
  2. ข้อผิดพลาดของคอมไพเลอร์เกิดขึ้นเมื่อคุณรันคำสั่ง make (หลังจากที่สร้างไฟล์แล้ว) และคอมไพเลอร์ไม่สามารถค้นหาโค้ดที่ต้องการได้

เราจะพิจารณาแต่ละข้อและหารือถึงวิธีแก้ไข

ข้อผิดพลาดในการกำหนดค่าและการกำหนดค่า

หลังจากที่คุณแตกไฟล์เก็บถาวรซอร์สโค้ดแล้ว ในเทอร์มินัล คุณควรเปลี่ยนเป็นไดเร็กทอรีที่มีไฟล์ที่แตกออกมา โดยทั่วไป ชื่อไดเร็กทอรีนี้จะเหมือนกับชื่อของไฟล์ (ไม่มี.tar.gzหรือ.tar.bz2นามสกุล) อย่างไรก็ตาม บางครั้งชื่อไดเร็กทอรีเป็นเพียงชื่อของแอปพลิเคชัน โดยไม่มีข้อมูลเวอร์ชันใดๆ

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

หลังจากที่คุณได้อ่านREADMEและ/หรือINSTALLไฟล์ (และหวังว่าจะดูเอกสารออนไลน์ที่เกี่ยวข้องสำหรับแอปพลิเคชัน) ให้มองหาไฟล์ปฏิบัติการ (มีการตั้งค่าการอนุญาต "x" ในไฟล์) configหรือชื่อไฟล์configure. บางครั้งไฟล์อาจมีนามสกุล เช่น.sh(เช่นconfig.sh) โดยปกติแล้วจะเป็นเชลล์สคริปต์ที่รันยูทิลิตีอื่นๆ เพื่อยืนยันว่าคุณมีสภาพแวดล้อมที่ "เหมาะสม" สำหรับการรวบรวม กล่าวอีกนัยหนึ่งคือจะตรวจสอบเพื่อให้แน่ใจว่าคุณได้ติดตั้งทุกอย่างที่คุณต้องการ

Tip: If this is a Python-based application, instead of a config file, you should find a file named setup.py. Python applications are typically very simple to install. To install this application, as root (e.g., put sudo in front of the following command under Ubuntu), run this command:

    $ python setup.py install

That should be all that you need to do. You can skip the remainder of this tutorial and proceed directly to using and enjoying your application.

รันสคริปต์การกำหนดค่าในเทอร์มินัล โดยปกติ คุณสามารถ (และควร!) เรียกใช้สคริปต์การกำหนดค่าด้วยบัญชีผู้ใช้ปกติของคุณ

$ ./config

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

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

ตัวอย่าง

ในบทช่วยสอนนี้ ฉันจะใช้โปรแกรมอ่าน RSS แบบข้อความที่เรียกว่า Newsbeuter เป็นตัวอย่างสำหรับประเภทของข้อผิดพลาดที่คุณอาจพบเมื่อสร้างแอปพลิเคชันของคุณ สำหรับ Newsbeuter config.shชื่อของสคริปต์การกำหนดค่าที่เป็น ในระบบของฉัน เมื่อฉันเรียกใช้config.shข้อผิดพลาดต่อไปนี้เกิดขึ้น:

[email protected]:~/download/newsbeuter-1.3$ ./config.sh
Checking for package sqlite3... not found

You need package sqlite3 in order to compile this program.
Please make sure it is installed.

เมื่อทำการค้นคว้า ฉันพบว่าอันที่จริงsqlite3แอปพลิเคชันได้รับการติดตั้งแล้ว อย่างไรก็ตาม เนื่องจากฉันพยายามสร้างจากแหล่งที่มา นี่คือเคล็ดลับที่config.shกำลังมองหาคือไลบรารีการพัฒนา (ส่วนหัว) สำหรับsqlite3ไฟล์ . ใน Ubuntu แพ็คเกจส่วนใหญ่มีแพ็คเกจการพัฒนาที่เกี่ยวข้องซึ่งลงท้าย-devด้วย . (แพลตฟอร์มอื่นๆ เช่น Fedora มักใช้ส่วนต่อท้ายของแพ็คเกจ-develสำหรับแพ็คเกจการพัฒนา)

ในการค้นหาแพ็คเกจที่เหมาะสมสำหรับแพ็คเกจการsqlite3พัฒนา เราสามารถใช้apt-cacheยูทิลิตี้นี้ใน Ubuntu (และในทำนองเดียวกันyumยูทิลิตี้ใน Fedora):

[email protected]:~/download/newsbeuter-1.3$ sudo apt-cache search sqlite

คำสั่งนี้ส่งคืนรายการผลลัพธ์ที่ค่อนข้างใหญ่ ดังนั้นเราจึงต้องทำงานนักสืบเล็กน้อยเพื่อพิจารณาว่าแพ็คเกจใดเหมาะสม ในกรณีนี้ แพ็คเกจที่เหมาะสมจะกลายเป็นlibsqlite3-dev. ขอให้สังเกตว่าบางครั้งแพคเกจที่เรากำลังมองหาจะมีคำนำหน้าแทนเพียงแค่ชื่อแพคเกจเดียวกันบวกlib -devเนื่องจากบางครั้งเราแค่มองหาไลบรารีที่ใช้ร่วมกันซึ่งอาจใช้โดยแอปพลิเคชันต่างๆ มากมาย ในการติดตั้งlibsqlite3-devให้รันคำสั่ง apt-get install ทั่วไปในเทอร์มินัล:

[email protected]:~/download/newsbeuter-1.3$ sudo apt-get install libsqlite3-dev

ตอนนี้ เราต้องเรียกใช้config.shอีกครั้งเพื่อให้แน่ใจว่าเราได้แก้ไขปัญหาการพึ่งพานี้แล้ว และเราไม่มีปัญหาการพึ่งพาอีกต่อไป (ในขณะที่ฉันจะไม่แสดงที่นี่ ในกรณีของ Newsbeuter ฉันต้องติดตั้งlibcurl4-openssl-devแพ็คเกจด้วย) นอกจากนี้ หากคุณติดตั้งแพ็คเกจการพัฒนา (เช่นlibsqlite3-dev) และแพ็คเกจแอปพลิเคชันที่เกี่ยวข้อง (เช่นsqlite3) ไม่ใช่ ติดตั้งแล้ว ระบบส่วนใหญ่จะติดตั้งแพ็คเกจแอปพลิเคชันที่เกี่ยวข้องโดยอัตโนมัติพร้อมกัน

เมื่อการกำหนดค่าทำงานสำเร็จ ผลลัพธ์จะเป็นการสร้างไฟล์ make หนึ่งไฟล์ขึ้นไป โดยทั่วไปแล้วไฟล์เหล่านี้จะมีชื่อMakefile(โปรดจำไว้ว่าชื่อไฟล์มีความสำคัญใน Unix/Linux!) หากแพ็คเกจบิลด์มีไดเร็กทอรีย่อย เช่นsrcฯลฯ แต่ละไดเร็กทอรีย่อยเหล่านี้จะมี a Makefileเช่นกัน

ข้อผิดพลาดในการสร้างและการรวบรวม

ตอนนี้เราพร้อมที่จะคอมไพล์แอปพลิเคชันแล้ว นี้มักจะเรียกว่าอาคารและชื่อนี้ยืมมาจากกระบวนการจริงในการสร้างบางสิ่งบางอย่าง "ชิ้นส่วน" ต่างๆ ของแอปพลิเคชัน ซึ่งโดยทั่วไปแล้วจะเป็นไฟล์ซอร์สโค้ดหลายไฟล์ ถูกรวมเข้าด้วยกันเพื่อสร้างแอปพลิเคชันโดยรวม ยูทิลิตี make จัดการกระบวนการบิลด์และเรียกแอปพลิเคชันอื่นๆ เช่น คอมไพเลอร์และลิงเกอร์ ให้ทำงานจริง ในกรณีส่วนใหญ่ คุณเพียงแค่เรียกใช้ make (ด้วยบัญชีผู้ใช้ทั่วไปของคุณ) จากไดเร็กทอรีที่คุณรันการกำหนดค่า (ในบางกรณี เช่น การรวบรวมแอปพลิเคชันที่เขียนด้วยไลบรารี Qt คุณจะต้องเรียกใช้แอปพลิเคชัน "wrapper" อื่น เช่น qmake แทน โปรดตรวจสอบรายละเอียดในเอกสารREADMEและ/หรือINSTALLเอกสารทุกครั้ง)

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

[email protected]:~/download/newsbeuter-1.3$ make
...
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/configparser.o -c src/configparser.cpp
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/colormanager.o -c src/colormanager.cpp
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:5:18: error: stfl.h: No such file or directory
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:33: error: ISO C++ forbids declaration of \u2018stfl_form\u2019 with no type
./include/stflpp.h:33: error: expected \u2018;\u2019 before \u2018*\u2019 token
./include/stflpp.h:34: error: ISO C++ forbids declaration of \u2018stfl_ipool\u2019 with no type
./include/stflpp.h:34: error: expected \u2018;\u2019 before \u2018*\u2019 token
make: *** [src/colormanager.o] Error 1

กระบวนการทำจะหยุดทันทีที่พบข้อผิดพลาดครั้งแรก การจัดการข้อผิดพลาดของคอมไพเลอร์ในบางครั้งอาจเป็นเรื่องยุ่งยาก คุณต้องดูข้อผิดพลาดเพื่อหาเบาะแสเกี่ยวกับปัญหา โดยทั่วไป ปัญหาคือไฟล์ส่วนหัวบางไฟล์ ซึ่งมักจะมีนามสกุล.hหรือ.hppหายไป ในกรณีของข้อผิดพลาดข้างต้น เป็นที่ชัดเจนว่า (หรือควรจะเป็น!) ปัญหาคือstfl.hไม่พบไฟล์ส่วนหัว ตามตัวอย่างนี้ คุณต้องการดูบรรทัดแรกของข้อความแสดงข้อผิดพลาดและค้นหาสาเหตุที่แท้จริงของปัญหา

หลังจากดูเอกสารของ Newsbeuter (ซึ่งฉันควรจะทำก่อนที่จะเริ่ม แต่บทช่วยสอนส่วนนี้ก็ไม่มีความหมายอะไรมาก!) ฉันพบว่าต้องใช้ไลบรารีของบุคคลที่สามชื่อ STFL ในกรณีนี้เราจะทำอย่างไร? โดยพื้นฐานแล้ว เราทำซ้ำขั้นตอนเดียวกันนี้สำหรับไลบรารีที่จำเป็นนั้น: รับไลบรารีและดำเนินการตามกระบวนการ configuration-build-install จากนั้นจึงดำเนินการสร้างแอปพลิเคชันที่ต้องการต่อ ตัวอย่างเช่น ในกรณีของ STFL ฉันต้องติดตั้งlibncursesw5-devแพ็คเกจเพื่อให้สร้างได้อย่างถูกต้อง (โดยปกติ ไม่จำเป็นต้องทำซ้ำขั้นตอนการกำหนดค่าในแอปพลิเคชันเดิมของเราหลังจากติดตั้งแอปพลิเคชันอื่นที่จำเป็นแล้ว แต่จะไม่ทำให้เกิดปัญหาใดๆ เช่นกัน)

หลังจากติดตั้งชุดเครื่องมือ STFL เรียบร้อยแล้ว กระบวนการ make สำหรับ Newsbeuter ก็ทำงานสำเร็จ กระบวนการสร้างมักจะหยิบขึ้นมาจากจุดที่เกิดข้อผิดพลาด (ณ จุดที่เกิดข้อผิดพลาด) ดังนั้น ไฟล์ใดๆ ที่คอมไพล์สำเร็จแล้วจะไม่ถูกคอมไพล์ใหม่ หากคุณต้องการคอมไพล์ทุกอย่างใหม่ คุณสามารถเรียกใช้ make clean all เพื่อลบอ็อบเจ็กต์ที่คอมไพล์แล้วเรียกใช้ make อีกครั้ง

กำลังติดตั้ง

หลังจากกระบวนการสร้างเสร็จสมบูรณ์ คุณก็พร้อมที่จะติดตั้งแอปพลิเคชัน ในกรณีส่วนใหญ่ ในการติดตั้งแอปพลิเคชันลงในพื้นที่ทั่วไปของระบบไฟล์ (เช่น/usr/binหรือ/usr/share/binเป็นต้น) คุณจะต้องเรียกใช้การติดตั้งในฐานะรูท การติดตั้งเป็นขั้นตอนที่ง่ายที่สุดในกระบวนการทั้งหมด ในการติดตั้ง ให้รันเทอร์มินัล:

$ make install

ตรวจสอบผลลัพธ์ของกระบวนการนี้เพื่อหาข้อผิดพลาด หากทุกอย่างสำเร็จ คุณควรจะสามารถเรียกใช้ชื่อคำสั่งในเทอร์มินัลแล้วระบบจะเริ่มทำงาน (ผนวก & ต่อท้ายบรรทัดคำสั่ง หากเป็นแอปพลิเคชัน GUI หรือคุณจะไม่สามารถใช้เทอร์มินัลเซสชันได้จนกว่าแอปพลิเคชันจะทำงานเสร็จ)

เมื่อคุณสร้างแอปพลิเคชันจากแหล่งที่มา โดยทั่วไปจะไม่เพิ่มไอคอนหรือทางลัดไปยังเมนู GUI ใน Ubuntu คุณจะต้องเพิ่มสิ่งนี้ด้วยตนเอง

และนั่นเป็นขั้นตอนโดยพื้นฐาน แม้ว่าจะทำซ้ำได้ เพื่อสร้างและติดตั้งแอปพลิเคชันจากแหล่งที่มาในอูบุนตู หลังจากที่คุณทำสิ่งนี้ไปไม่กี่ครั้ง มันจะกลายเป็นเรื่องปกติสำหรับคุณ!

./configure --help จะให้ข้อมูลมากมายแก่คุณ สำหรับเครื่องมืออัตโนมัติของ GNU ที่สร้างไฟล์กำหนดค่า ส่วนใหญ่ลงมาที่ --with/- โดยไม่ต้องเปิดใช้งานคุณสมบัติ (สิ่งเหล่านี้อาจใช้พารามิเตอร์พิเศษ เช่น "แชร์" เพื่อบอกว่าจะค้นหาไลบรารีได้จากที่ใด)

สิ่งสำคัญอื่น ๆ คือ --prefix (ซึ่งค่าเริ่มต้นเป็น /usr/local/ เกือบตลอดเวลา) เพื่อบอกว่าจะติดตั้งที่ไหน (หากคุณกำลังสร้างแพ็คเกจ คุณมักจะต้องการให้เป็น --prefix=/usr หรือ --prefix =/opt/YourPackage)

บน Linux, /lib, /usr/lib และ /usr/local/lib มักจะค้นหา gcc ของฉัน และรวมอยู่ในการกำหนดค่าเริ่มต้นของ ldconfig เว้นแต่คุณจะมีเหตุผลที่ดี นี่คือที่ที่คุณต้องการห้องสมุดของคุณ /etc/ld.so.conf อาจแสดงรายการเพิ่มเติมอย่างไรก็ตาม

กำหนดค่าและค้นหาโดยพยายามเรียกใช้ "gcc -l" และดูว่ามีข้อผิดพลาดหรือไม่ คุณสามารถเพิ่ม "-L" ให้กับพารามิเตอร์ CFLAGS ของคุณเพื่อเพิ่มเส้นทางพิเศษในการค้นหา

คุณสามารถติดตั้งได้หลายเวอร์ชัน และซอฟต์แวร์ที่เชื่อมโยงกับเวอร์ชันเก่าจะยังคงเชื่อมโยงกับเวอร์ชันนั้น (เรียกใช้ ldd เพื่อค้นหาการเชื่อมโยงบน Linux) แต่การคอมไพล์ใหม่โดยทั่วไปจะกำหนดเป้าหมายเวอร์ชันล่าสุดของไลบรารีไดนามิกบนระบบของคุณ

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

ls -l เป็นทางออกที่ดีที่สุดในการค้นหาไลบรารีที่ติดตั้ง

และนั่นคือที่ที่ฉันไม่มีข้อมูล เล่นแพกเกจยังไงไม่รู้ เมื่อเป็นไปได้ ฉันจะพยายามห่อของให้เป็นแพ็คเกจเพื่อหลีกเลี่ยงปัญหา

"ฉันจะทราบได้อย่างไรว่าข้อโต้แย้งใดที่จะส่งผ่านไปยัง ./configure"

โดยปกติ: ./configure --help จะบอกคุณว่าคุณต้องการอะไรที่นั่น

"ฉันจะทราบได้อย่างไรว่าฉันติดตั้งไลบรารี่ใด และเวอร์ชันใด"

ขึ้นอยู่กับระบบ วิธีหนึ่งคือทำ a find /|grep libname|lessตามปกติไฟล์ไลบรารีจะมีเวอร์ชันในชื่อไฟล์

"ฉันจะติดตั้งไลบรารีมากกว่าหนึ่งเวอร์ชันโดยไม่ทำลายระบบปกติได้อย่างไร"

อีกครั้งขึ้นอยู่กับระบบและห้องสมุด sudo make altinstallจะสร้างชื่อรุ่นสำหรับคุณ ไฟล์ไลบรารีมักจะเป็นเวอร์ชันเอง อย่างไรก็ตาม พึงระลึกไว้เสมอว่า เนื่องจากเวอร์ชันต่างๆ มักสร้างการเชื่อมโยงไปยังชื่อ "ปกติ" จึงสามารถทำลายสิ่งต่างๆ ได้

"หากฉันกำลังติดตั้งสิ่งของจากแหล่งที่มาบนระบบที่จัดการโดยใช้แพ็คเกจ วิธีใดสะอาดที่สุด"

การใช้พารามิเตอร์ --prefix ใน ./configure และวางไว้ที่ใดที่หนึ่ง/optเป็นแนวทางปฏิบัติที่ดี

ข้อจำกัดความรับผิดชอบ:ฉันไม่ใช่ผู้เชี่ยวชาญ แต่ฉันใช้ linux มานานกว่า 5 ปีจากบรรทัด cmd (slackware, CentOS, redhat, ubuntu, misc อื่น ๆ และ OS X)

เพื่อตอบคำถามของคุณเล็กน้อย ฉันพบวิธีที่ดีเมื่อวันก่อนเพื่อดูว่าคุณติดตั้งไลบรารีใดและเวอร์ชันใด (นี่คือบน Linux Debian ดังนั้นควรทำงานกับเวอร์ชันอื่นด้วย)

dpkg --list

คุณควรจะได้รายการยาวๆ ที่มีผลลัพธ์แบบนี้

ii  libssl0.9.8    0.9.8c-4etch5  SSL shared libraries
ii  libssp0        4.1.1-21       GCC stack smashing protection library
ii  libstdc++5     3.3.6-15       The GNU Standard C++ Library v3
ii  libstdc++5-3.3 3.3.6-15       The GNU Standard C++ Library v3 (development
ii  libstdc++6     4.1.1-21       The GNU Standard C++ Library v3

ไซม่อน

1.) ./configure --help ให้ข้อมูลจำนวนมาก ฉันขอแนะนำให้ตรวจสอบออก โดยทั่วไปจะมีตัวเลือกสำหรับการคอมไพล์ไลบรารี่แบบสแตติก/ไดนามิกตามความเหมาะสม

2. ) Libaries อยู่ในเส้นทางของตัวเชื่อมโยงแบบไดนามิก โดยปกติแล้วจะตั้งค่าใน /etc/ld.so.conf ตัวเชื่อมโยงค้นหาไลบรารีที่เหมาะสมเหมือนกับตัวแปรสภาพแวดล้อม PATH ที่ตรงกับตัวแปรแรกที่พบ

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

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

เช่น libssh2.so.1 -> libssh2.so.1.0.0

โดยทั่วไปแล้ว ผู้คนจะจัดการไลบรารีและโปรแกรมที่พวกเขาติดตั้งโดยใช้แพ็คเกจเดเบียนของตนเองหรือใช้เทคนิคอื่น ฉันจัดการซอฟต์แวร์ที่ติดตั้งโดยใช้ stow ( http://www.gnu.org/software/stow/ ) ซึ่งง่ายมากและติดตั้งไลบรารีโดยใช้ลิงก์สัญลักษณ์ ฉันพบว่ามันง่ายกว่าเพราะฉันไม่ต้องสร้าง/ติดตั้ง/ทดสอบแพ็คเกจ deb/rpm

5.) สามารถติดตั้งไลบรารีหลายเวอร์ชันได้ตามปกติในไดเร็กทอรีไลบรารี ไลบรารี่ที่เชื่อมโยงกับไฟล์เรียกทำงานจะยังคงเชื่อมโยงกับเวอร์ชันที่ลิงก์ไว้ การรัน ldd บนไฟล์ปฏิบัติการจะบอกคุณว่าไลบรารีใดที่ไฟล์ปฏิบัติการนั้นเชื่อมโยงกับ

6. ) อย่างที่ฉันได้กล่าวไว้ก่อนหน้านี้ การกลิ้งแพ็คเกจเดเบียนของคุณเองหรือใช้ stow อาจเป็นวิธีแก้ปัญหาที่สะอาดที่สุด

7.) ฉันไม่สามารถพูดสำหรับ Mac OSX ได้ แต่สำหรับ Linux ระบบบรรจุภัณฑ์ของการแจกจ่ายเป็นวิธีที่ดีที่สุด

8. ) อาจมีความยุ่งยากมากมายที่จะแก้ไขได้โดยใช้ ldd และค้นหาว่ามีการเชื่อมโยงกับเวอร์ชันใดหรือไม่พบไลบรารีใดที่เชื่อมโยงกับโปรแกรมปฏิบัติการ pkg-config จะช่วยคุณได้มาก แต่สำหรับซอฟต์แวร์ที่ใช้งานเท่านั้น มันไม่ได้เป็นส่วนหนึ่งของระบบสร้าง autotools เริ่มต้นแม้ว่าจะเป็นที่นิยมในทุกวันนี้

ไลบรารีสแตติกไม่ใช่ความคิดที่ดี หากคุณต้องการอัปเกรดไลบรารี (เช่น เพื่อแก้ไขปัญหาด้านความปลอดภัย) คุณจะต้องคอมไพล์ทุกอย่างใหม่โดยอาศัยไลบรารีนั้น

ฉันไม่ชอบความคิดที่ว่า "ทำการติดตั้ง" ที่อาจทำให้ระบบของฉันยุ่งเหยิง แต่อย่างที่คนอื่น ๆ บอก การติดตั้งใน /usr/local ไม่ใช่เรื่องยากเลย แทนที่จะใช้ --prefix เพื่อติดตั้งที่อื่น ดังนั้นฉันจึงเรียก /usr/local กับผู้ใช้ปกติของฉัน (ไม่ได้รับสิทธิพิเศษ) ด้วยวิธีนี้ "ทำการติดตั้ง" ค่อนข้างรับประกันว่าจะไม่ยุ่งกับไฟล์ระบบที่สำคัญ (เห็นได้ชัดว่าวิธีนี้ใช้ไม่ได้กับระบบที่มีผู้ใช้หลายคน แต่เหมาะสำหรับเซิร์ฟเวอร์เสมือน)

แม้ว่าจะไม่ได้ระบุไว้อย่างชัดเจนในรายการคำถามของคุณ แต่คุณพูดถึงในคำนำของคุณ:

./configure && make && sudo make install is usually enough, but sometimes it doesn't work - and when it doesn't, I frequently get stuck.

เมื่อฉันติดอยู่กับ Debian หรือ Ubuntu ฉันจะใช้ auto-apt ซึ่งจะติดตั้งแพ็คเกจที่มีไฟล์ที่กำหนดค่าไม่พบโดยอัตโนมัติ

ดู:

เครื่องมืออื่นที่คุณอาจพบว่าสะดวกคือ CheckInstall ซึ่งจะเพิ่มแอปพลิเคชันที่ติดตั้งmake installในรายการแพ็คเกจที่ติดตั้งของคุณ: https://help.ubuntu.com/community/CheckInstall

สำหรับ OS X:

  • ฉันจะทราบได้อย่างไรว่าอาร์กิวเมนต์ใดที่จะส่งผ่านไปยัง ./configure

./configure --help

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

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

  • ไลบรารีที่แชร์ทำงานอย่างไรภายใต้ OS X / Linux - ที่พวกเขาอาศัยอยู่บนระบบไฟล์ ./configure && ทำให้ค้นหาได้อย่างไร เกิดอะไรขึ้นเมื่อเชื่อมโยงกับ

ไลบรารีระบบอยู่ใน /usr/lib

ไลบรารี่ที่คุณคอมไพล์ตัวเองอยู่ใน /usr/local/lib (/usr/local เป็นค่าเริ่มต้น --prefix flag สำหรับ ./configure)

ตัวแปรสภาพแวดล้อม DYLD_FALLBACK_LIBRARY_PATH และ LD_LIBRARY_PATH ให้คุณระบุโฟลเดอร์ที่จะค้นหา ดังนั้น /usr/local/lib ควรอยู่ที่จุดเริ่มต้นของรายการ

  • ฉันจะติดตั้งไลบรารีมากกว่าหนึ่งเวอร์ชันโดยไม่ทำให้ระบบปกติของฉันเสียหายได้อย่างไร

ติดตั้งทุกอย่างลงใน /usr/local - ด้วยตัวแปรสภาพแวดล้อมด้านบน เวอร์ชันใน /usr/local/lib จะมีความสำคัญเหนือกว่าเวอร์ชันใน /usr/lib ในสภาพแวดล้อมของคุณ

  • หากฉันกำลังติดตั้งสิ่งของจากแหล่งที่มาบนระบบที่จัดการโดยใช้แพ็คเกจ วิธีใดสะอาดที่สุด

ติดตั้งไปที่ /usr/local. ใน Ubuntu ฉันลองใช้ checkinstall ก่อนเพื่อสร้างแพ็คเกจ deb

  • สมมติว่าฉันจัดการรวบรวมบางสิ่งที่เที่ยวยุ่งยิ่งจากแหล่งที่มา ฉันจะทำแพ็กเกจนั้นได้อย่างไรเพื่อให้คนอื่นไม่ต้องกระโดดข้ามห่วงเดียวกัน โดยเฉพาะบน OS X....

เอกสารขั้นตอนการรวบรวมในโพสต์บล็อกฉันจะพูด