ค้นหาเว็บไซต์

ทำความเข้าใจไลบรารีที่ใช้ร่วมกันใน Linux


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

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

ตัวอย่างของไลบรารีใน Linux ได้แก่ libc (ไลบรารี C มาตรฐาน) หรือ Glibc (ไลบรารี C มาตรฐานเวอร์ชัน GNU), libcurl (ไฟล์ multiprotocol ถ่ายโอนไลบรารี), libcrypt (ไลบรารีที่ใช้สำหรับการเข้ารหัส การแฮช และการเข้ารหัสในภาษา C) และอื่นๆ อีกมากมาย

Linux รองรับไลบรารี่สองคลาส ได้แก่ :

  • ไลบรารีแบบคงที่ – เชื่อมโยงกับโปรแกรมแบบคงที่ ณ เวลาคอมไพล์
  • ไลบรารีไดนามิกหรือไลบรารีที่ใช้ร่วมกัน – ถูกโหลดเมื่อมีการเรียกใช้โปรแกรมและโหลดลงในหน่วยความจำ และการเชื่อมโยงเกิดขึ้นเมื่อรันไทม์

ไลบรารีแบบไดนามิกหรือแบบแบ่งใช้สามารถแบ่งได้เป็น:

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

แบบแผนการตั้งชื่อไลบรารีที่ใช้ร่วมกัน

ไลบรารีที่แบ่งใช้มีการตั้งชื่อได้สองวิธี: ชื่อไลบรารี (a.k.a soname) และ “ชื่อไฟล์ ” (พาธสัมบูรณ์ไปยังไฟล์ซึ่งจัดเก็บโค้ดไลบรารี)

ตัวอย่างเช่น soname สำหรับ libc คือ libc.so.6 โดยที่ lib คือคำนำหน้า >c เป็นชื่อที่สื่อความหมาย ดังนั้น หมายถึงวัตถุที่ใช้ร่วมกัน และ 6 คือเวอร์ชัน และชื่อไฟล์คือ: /lib64/libc.so.6 โปรดทราบว่าจริงๆ แล้ว soname เป็นลิงก์สัญลักษณ์ไปยังชื่อไฟล์

การค้นหาไลบรารีที่ใช้ร่วมกันใน Linux

ไลบรารีที่ใช้ร่วมกันถูกโหลดโดย ld.so (หรือ ld.so.x) และ ld-linux.so (หรือ ld- linux.so.x) โดยที่ x คือเวอร์ชัน ใน Linux /lib/ld-linux.so.x จะค้นหาและโหลดไลบรารีที่แบ่งใช้ทั้งหมดที่ใช้โดยโปรแกรม

โปรแกรมสามารถเรียกไลบรารี่โดยใช้ชื่อไลบรารีหรือชื่อไฟล์ และพาธไลบรารีจะเก็บไดเร็กทอรีที่ซึ่งไลบรารีสามารถพบได้ในระบบไฟล์ ตามค่าเริ่มต้น ไลบรารีจะอยู่ใน /usr/local/lib, /usr/local/lib64, /usr/lib และ /usr/lib64; ไลบรารีการเริ่มต้นระบบอยู่ใน /lib และ /lib64 อย่างไรก็ตามโปรแกรมเมอร์สามารถติดตั้งไลบรารี่ในตำแหน่งที่กำหนดเองได้

เส้นทางไลบรารีสามารถกำหนดได้ในไฟล์ /etc/ld.so.conf ซึ่งคุณสามารถแก้ไขได้ด้วยโปรแกรมแก้ไขบรรทัดคำสั่ง

vi /etc/ld.so.conf 

บรรทัดในไฟล์นี้แนะนำให้เคอร์เนลโหลดไฟล์ใน /etc/ld.so.conf.d ด้วยวิธีนี้ ผู้ดูแลแพ็คเกจหรือโปรแกรมเมอร์สามารถเพิ่มไดเร็กทอรีไลบรารีแบบกำหนดเองลงในรายการค้นหาได้

หากคุณดูในไดเรกทอรี /etc/ld.so.conf.d คุณจะเห็นไฟล์ .conf สำหรับแพ็คเกจทั่วไปบางแพ็คเกจ (เคอร์เนล, mysql และ postgresql ใน กรณีนี้):

ls /etc/ld.so.conf.d

kernel-2.6.32-358.18.1.el6.x86_64.conf  kernel-2.6.32-696.1.1.el6.x86_64.conf  mariadb-x86_64.conf
kernel-2.6.32-642.6.2.el6.x86_64.conf   kernel-2.6.32-696.6.3.el6.x86_64.conf  postgresql-pgdg-libs.conf

หากคุณดูที่ mariadb-x86_64.conf คุณจะเห็นเส้นทางที่แน่นอนไปยังไลบรารีแพ็คเกจ

cat mariadb-x86_64.conf

/usr/lib64/mysql

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

export LD_LIBRARY_PATH=/path/to/library/file

การจัดการไลบรารีที่ใช้ร่วมกันใน Linux

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

library name =>  filename (some hexadecimal value)
OR
filename (some hexadecimal value)  #this is shown when library name can’t be read

คำสั่งนี้แสดงการพึ่งพาไลบรารีที่แบ่งใช้ทั้งหมดสำหรับคำสั่ง ls

ldd /usr/bin/ls
OR
ldd /bin/ls
ผลลัพธ์ตัวอย่าง
	linux-vdso.so.1 =>  (0x00007ffebf9c2000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003b71e00000)
	librt.so.1 => /lib64/librt.so.1 (0x0000003b71600000)
	libcap.so.2 => /lib64/libcap.so.2 (0x0000003b76a00000)
	libacl.so.1 => /lib64/libacl.so.1 (0x0000003b75e00000)
	libc.so.6 => /lib64/libc.so.6 (0x0000003b70600000)
	libdl.so.2 => /lib64/libdl.so.2 (0x0000003b70a00000)
	/lib64/ld-linux-x86-64.so.2 (0x0000561abfc09000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003b70e00000)
	libattr.so.1 => /lib64/libattr.so.1 (0x0000003b75600000)

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

ตามค่าเริ่มต้น ldconfig อ่านเนื้อหาของ /etc/ld.so.conf สร้างลิงก์สัญลักษณ์ที่เหมาะสมในไดเร็กทอรีลิงก์แบบไดนามิก จากนั้นจึงเขียนแคชไปที่ /etc/ld.so.cache ซึ่งจะทำให้โปรแกรมอื่นนำไปใช้ได้อย่างง่ายดาย

สิ่งนี้สำคัญมากโดยเฉพาะอย่างยิ่งเมื่อคุณเพิ่งติดตั้งไลบรารีที่แบ่งใช้ใหม่หรือสร้างขึ้นเอง หรือสร้างไดเร็กทอรีไลบรารีใหม่ คุณต้องเรียกใช้คำสั่ง ldconfig เพื่อให้การเปลี่ยนแปลงมีผล

ldconfig
OR
ldconfig -v 	#shows files and directories it works with

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

หรือเรียกใช้คำสั่งต่อไปนี้เพื่อสร้างลิงก์สัญลักษณ์จาก soname ไปยังชื่อไฟล์:

ldconfig -n /path/to/your/shared/libraries

หากต้องการเริ่มต้นสร้างไลบรารีของคุณเอง โปรดดูคู่มือนี้จาก The Linux Documentation Project (TLDP)

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