และนิโคลสัน
- ภาพรวม
- ทำไม
- แนวคิด
- การเขียนไฟล์ pkg-config
- การใช้ไฟล์ pkg-config
- คำถามที่พบบ่อย
ภาพรวม
เอกสารนี้มีวัตถุประสงค์เพื่อให้ภาพรวมในการใช้ไฟล์pkg-configเครื่องมือจากมุมมองของทั้งผู้ใช้และนักพัฒนามันทบทวนแนวคิดเบื้องหลังpkg-config, เขียนอย่างไรpkg-configไฟล์เพื่อสนับสนุนโครงการของคุณและวิธีการใช้งานpkg-configเพื่อรวมเข้ากับโครงการบุคคลที่สาม
ข้อมูลเพิ่มเติมเกี่ยวกับpkg-configสามารถพบได้ที่เว็บไซต์และในpkg-config (1)หน้าคู่มือ
เอกสารนี้ถือว่าการใช้งานpkg-configในระบบปฏิบัติการที่เหมือน UNIX เช่น Linuxรายละเอียดบางอย่างอาจแตกต่างกันในแพลตฟอร์มอื่น ๆ
ทำไม
ระบบคอมพิวเตอร์ที่ทันสมัยใช้ส่วนประกอบเลเยอร์จำนวนมากเพื่อให้แอปพลิเคชันแก่ผู้ใช้หนึ่งในความยากลำบากในการประกอบชิ้นส่วนเหล่านี้คือการรวมเข้าด้วยกันอย่างเหมาะสมpkg-configรวบรวมข้อมูลเมตาเกี่ยวกับไลบรารีที่ติดตั้งในระบบและมอบให้กับผู้ใช้ได้อย่างง่ายดาย
ไม่มีระบบข้อมูลเมตาเช่นpkg-configอาจเป็นเรื่องยากมากที่จะค้นหาและรับรายละเอียดเกี่ยวกับบริการที่ให้ไว้ในคอมพิวเตอร์ที่กำหนดสำหรับนักพัฒนาการติดตั้งpkg-configไฟล์ที่มีแพ็คเกจของคุณช่วยลดการใช้ API ของคุณได้อย่างมาก
แนวคิด
การใช้งานหลักของpkg-configคือการให้รายละเอียดที่จำเป็นสำหรับการรวบรวมและเชื่อมโยงโปรแกรมกับห้องสมุดข้อมูลเมตานี้ถูกเก็บไว้ในpkg-configไฟล์.ไฟล์เหล่านี้มีคำต่อท้าย.pcและอาศัยอยู่ในสถานที่เฉพาะที่รู้จักกันในไฟล์pkg-configเครื่องมือ.สิ่งนี้จะอธิบายในรายละเอียดเพิ่มเติมในภายหลัง
รูปแบบไฟล์มีคำหลักเมตาที่กำหนดไว้ล่วงหน้าและตัวแปร freeformตัวอย่างอาจเป็นตัวอย่าง:
Prefix =/usr/localexec_prefix = $ {คำนำหน้า} incoldir = $ {คำนำหน้า}/includelibdir = $ {exec_prefix}/libname: foodescription: foo libraryversion: 1.0.0cflags: -i $}libdir} -lfoo
คำจำกัดความคำหลักเช่นชื่อ:เริ่มต้นด้วยคำหลักตามด้วยลำไส้ใหญ่และค่าตัวแปรเช่นคำนำหน้า =เป็นสตริงและค่าคั่นด้วยเครื่องหมายเท่ากับคำหลักถูกกำหนดและส่งออกโดยpkg-config-ตัวแปรไม่จำเป็น แต่สามารถใช้งานได้โดยคำจำกัดความของคำหลักเพื่อความยืดหยุ่นหรือเก็บข้อมูลที่ไม่ครอบคลุมโดยpkg-config-
นี่คือคำอธิบายสั้น ๆ ของฟิลด์คำหลักคำอธิบายเชิงลึกเพิ่มเติมของฟิลด์เหล่านี้และวิธีการใช้อย่างมีประสิทธิภาพจะได้รับในไฟล์การเขียนไฟล์ pkg-configส่วน.
- ชื่อ: ชื่อที่มนุษย์อ่านได้สำหรับไลบรารีหรือแพ็คเกจสิ่งนี้ไม่ส่งผลกระทบต่อการใช้งานไฟล์pkg-configเครื่องมือซึ่งใช้ชื่อของ.pcไฟล์.
- คำอธิบาย: คำอธิบายสั้น ๆ ของแพ็คเกจ
- url: URL ที่ผู้คนสามารถรับข้อมูลเพิ่มเติมและดาวน์โหลดแพ็คเกจ
- รุ่น: สตริงที่กำหนดเวอร์ชันของแพ็คเกจโดยเฉพาะ
- กำหนดให้มี: รายการแพ็คเกจที่ต้องการโดยแพ็คเกจนี้เวอร์ชันของแพ็คเกจเหล่านี้อาจระบุโดยใช้ตัวดำเนินการเปรียบเทียบ =, <,>, <= หรือ> =
- ต้องการ.: รายการแพ็คเกจส่วนตัวที่ต้องการโดยแพ็คเกจนี้ แต่ไม่ได้สัมผัสกับแอปพลิเคชันกฎเฉพาะของเวอร์ชันจากไฟล์กำหนดให้มีฟิลด์ยังใช้ที่นี่
- ความขัดแย้ง: ฟิลด์เสริมที่อธิบายแพ็คเกจที่หนึ่งขัดแย้งกับกฎเฉพาะของเวอร์ชันจากไฟล์กำหนดให้มีฟิลด์ยังใช้ที่นี่ฟิลด์นี้ยังใช้หลายอินสแตนซ์ของแพ็คเกจเดียวกันเช่น.,ความขัดแย้ง: bar <1.2.3, bar> = 1.3.0-
- cflags: คอมไพเลอร์แฟล็กเฉพาะสำหรับแพ็คเกจนี้และไลบรารีที่จำเป็นใด ๆ ที่ไม่รองรับpkg-config-หากห้องสมุดที่ต้องการรองรับpkg-configควรเพิ่มเข้าไปในกำหนดให้มีหรือต้องการ.-
- Libs: ลิงก์แฟล็กเฉพาะสำหรับแพ็คเกจนี้และไลบรารีที่จำเป็นใด ๆ ที่ไม่รองรับpkg-config-กฎเดียวกับcflagsใช้ที่นี่
- libs.Private: ธงลิงก์สำหรับไลบรารีส่วนตัวที่ต้องการโดยแพ็คเกจนี้ แต่ไม่ได้สัมผัสกับแอปพลิเคชันกฎเดียวกับcflagsใช้ที่นี่
การเขียนไฟล์ pkg-config
เมื่อสร้างpkg-configไฟล์สำหรับแพ็คเกจเป็นครั้งแรกที่จำเป็นในการตัดสินใจว่าจะแจกจ่ายอย่างไรแต่ละไฟล์ใช้งานได้ดีที่สุดในการอธิบายไลบรารีเดียวดังนั้นแต่ละแพ็คเกจควรมีอย่างน้อยมากpkg-configไฟล์ที่ติดตั้งไลบรารี
ชื่อแพ็คเกจจะถูกกำหนดผ่านชื่อไฟล์ของไฟล์pkg-configไฟล์ข้อมูลเมตานี่คือส่วนของชื่อไฟล์ก่อน.pcคำต่อท้ายตัวเลือกทั่วไปคือการจับคู่ชื่อไลบรารีกับไฟล์.pcชื่อ.ตัวอย่างเช่นการติดตั้งแพ็คเกจlibfoo.soจะมีความสอดคล้องlibfoo.pcไฟล์ที่มีไฟล์pkg-configข้อมูลเมตาตัวเลือกนี้ไม่จำเป็นที่.pcไฟล์ควรเป็นตัวระบุเฉพาะสำหรับไลบรารีของคุณติดตามตัวอย่างข้างต้นfoo.pcหรือfoolib.pcอาจจะใช้งานได้เช่นกัน
ที่ชื่อ-คำอธิบายและurlฟิลด์มีข้อมูลอย่างหมดจดและควรจะเติมได้ง่ายรุ่นฟิลด์ค่อนข้างยุ่งยากกว่าเล็กน้อยเพื่อให้แน่ใจว่าผู้บริโภคของข้อมูลสามารถใช้งานได้pkg-configใช้อัลกอริทึมจากรอบต่อนาทีสำหรับการเปรียบเทียบเวอร์ชันสิ่งนี้ใช้งานได้ดีที่สุดด้วยหมายเลขทศนิยมแบบด่างเช่น1.2.3เนื่องจากตัวอักษรอาจทำให้ผลลัพธ์ที่ไม่คาดคิดจำนวนควรเพิ่มขึ้นแบบ monotonically และเฉพาะเจาะจงที่สุดเท่าที่จะเป็นไปได้ในการอธิบายห้องสมุดโดยปกติแล้วจะเพียงพอที่จะใช้หมายเลขเวอร์ชันของแพ็คเกจที่นี่เนื่องจากเป็นเรื่องง่ายสำหรับผู้บริโภคที่จะติดตาม
ก่อนที่จะอธิบายเขตข้อมูลที่มีประโยชน์มากขึ้นจะมีประโยชน์ในการแสดงคำจำกัดความของตัวแปรการใช้งานที่พบบ่อยที่สุดคือการกำหนดเส้นทางการติดตั้งเพื่อไม่ให้ฟิลด์เมตาดาต้ายุ่งเหยิงเนื่องจากตัวแปรมีการขยายซ้ำสิ่งนี้มีประโยชน์มากเมื่อใช้ร่วมกับเส้นทางที่ได้รับ AutoConf
Prefix =/usr/localincludedir = $ {คำนำหน้า}/includeCflags: -i $ {incidentir}/foo
ที่สำคัญที่สุดpkg-configเมตาดาต้าฟิลด์คือกำหนดให้มี-ต้องการ.-cflags-Libsและlibs.Private-พวกเขาจะกำหนดข้อมูลเมตาที่ใช้โดยโครงการภายนอกเพื่อรวบรวมและเชื่อมโยงกับห้องสมุด
กำหนดให้มีและต้องการ.กำหนดโมดูลอื่น ๆ ที่ห้องสมุดต้องการโดยปกติแล้วจะเป็นที่ต้องการใช้ตัวแปรส่วนตัวของกำหนดให้มีเพื่อหลีกเลี่ยงการเปิดเผยห้องสมุดที่ไม่จำเป็นไปยังโปรแกรมที่เชื่อมโยงกับห้องสมุดของคุณหากโปรแกรมจะไม่ใช้สัญลักษณ์ของไลบรารีที่ต้องการก็ไม่ควรเชื่อมโยงโดยตรงกับไลบรารีนั้นดูการสนทนาของการทับซ้อนสำหรับคำอธิบายที่ละเอียดยิ่งขึ้น
เนื่องจากpkg-configจะเปิดเผยธงลิงก์ของไฟล์กำหนดให้มีห้องสมุดโมดูลเหล่านี้จะกลายเป็นพึ่งพาโดยตรงของโปรแกรมในทางกลับกันห้องสมุดจากต้องการ.จะรวมเฉพาะเมื่อการเชื่อมโยงแบบคงที่ด้วยเหตุนี้จึงมักจะเหมาะสมที่จะเพิ่มโมดูลจากแพ็คเกจเดียวกันในกำหนดให้มี-
ที่Libsฟิลด์มีธงลิงก์ที่จำเป็นในการใช้ไลบรารีนั้นนอกจากนี้,Libsและlibs.Privateมีแฟล็กลิงค์สำหรับไลบรารีอื่น ๆ ที่ไม่รองรับโดยpkg-config-คล้ายกับกำหนดให้มีฟิลด์เป็นที่ต้องการเพิ่มแฟล็กลิงค์สำหรับไลบรารีภายนอกไปยังไฟล์libs.Privateฟิลด์ดังนั้นโปรแกรมจะไม่ได้รับการพึ่งพาโดยตรงเพิ่มเติม
ในที่สุดcflagsมีธงคอมไพเลอร์สำหรับใช้ไลบรารีไม่เหมือนกับLibsสนามไม่มีตัวแปรส่วนตัวของcflags-นี่เป็นเพราะจำเป็นต้องมีประเภทข้อมูลและคำจำกัดความแมโครโดยไม่คำนึงถึงสถานการณ์การเชื่อมโยง
การใช้ไฟล์ pkg-config
สมมติว่ามี.pcไฟล์ที่ติดตั้งบนระบบpkg-configเครื่องมือใช้ในการสกัดข้อมูลเมตาสำหรับการใช้งานคำอธิบายสั้น ๆ ของตัวเลือกสามารถมองเห็นได้โดยการดำเนินการPKG-Config-ช่วยเหลือ-การสนทนาเชิงลึกมากขึ้นสามารถพบได้ในไฟล์pkg-config (1)หน้าคู่มือส่วนนี้จะให้คำอธิบายสั้น ๆ เกี่ยวกับการใช้งานทั่วไป
พิจารณาระบบที่มีสองโมดูลฟูและบาร์-ของพวกเขา.pcไฟล์อาจมีลักษณะเช่นนี้:
foo.pc: prefix =/usrexec_prefix = $ {คำนำหน้า} incoldir = $ {คำนำหน้า}/includelibdir = $ {exec_prefix}/libname: foodescription: foo libraryversion: 1.0.0cflags: -i $$ {libdir} -lfoobar.pc: คำนำหน้า =/usrexec_prefix = $ {คำนำหน้า} รวมอยู่cflags: -i $ {รวม} libs: -l $ {libdir} -lbar
รุ่นของโมดูลสามารถรับได้ด้วย-การดัดแปลงตัวเลือก.
$ pkg-config-Modversion foo1.0.0 $ pkg-config-Modversion bar2.1.2
ในการพิมพ์ธงลิงก์ที่จำเป็นสำหรับแต่ละโมดูลให้ใช้ไฟล์-libsตัวเลือก.
$ pkg-config-libs foo-lfoo $ pkg-config-libs bar-lbar
สังเกตว่าpkg-configได้ระงับส่วนหนึ่งของไฟล์Libsฟิลด์สำหรับโมดูลทั้งสองนี่เป็นเพราะมันปฏิบัติต่อไฟล์-lธงเป็นพิเศษและรู้ว่า$ {lib}ไดเรกทอรี/ usr / libเป็นส่วนหนึ่งของเส้นทางการค้นหาระบบ Linkerสิ่งนี้ช่วยได้pkg-configจากการแทรกแซงการดำเนินการของ Linker
ถึงแม้ว่าฟูเป็นสิ่งจำเป็นโดยบาร์ลิงค์ธงสำหรับฟูไม่ใช่เอาต์พุตนี้เป็นเพราะฟูไม่จำเป็นต้องใช้โดยตรงโดยแอปพลิเคชันที่ต้องการใช้ไฟล์บาร์ห้องสมุด.สำหรับการเชื่อมโยงแบบคงที่บาร์แอปพลิเคชันเราต้องการธง Linker ทั้งสองชุด:
$ pkg-config-libs-bar-lbar-lbar -lfoo แบบคงที่
pkg-configจำเป็นต้องส่งออกธงลิงก์ทั้งสองชุดในกรณีนี้เพื่อให้แน่ใจว่าแอปพลิเคชันที่เชื่อมโยงแบบคงที่จะค้นหาสัญลักษณ์ที่จำเป็นทั้งหมดในทางกลับกันมันจะส่งออกทั้งหมดcflags-
$ pkg-config--cflags bar-i/usr/include/foo $ pkg-config--cflags-bar-i/usr/include/foo แบบคงที่
อีกทางเลือกที่มีประโยชน์-มีอยู่จริงสามารถใช้เพื่อทดสอบความพร้อมใช้งานของโมดูล
$ pkg-config-exists foo $ echo $? 0
หนึ่งในคุณสมบัติที่ดีที่สุดของpkg-configกำลังให้การตรวจสอบเวอร์ชันสามารถใช้เพื่อตรวจสอบว่ามีเวอร์ชันเพียงพอหรือไม่
$ pkg-config-libs "bar> = 2.7" bar> = 2.7 'แต่แถบรุ่นคือ 2.1.2
คำสั่งบางคำจะให้เอาต์พุต verbose มากขึ้นเมื่อรวมกับไฟล์-การพิมพ์ผิดกฎหมายตัวเลือก.
$ pkg-config-exists-print-errors xoxopackage xoxo ไม่พบในเส้นทางการค้นหา pkg-config บางทีคุณควรเพิ่มไดเรกทอรีที่มี `xoxo.pc'to pkg_config_path สภาพแวดล้อม Variableno '
ข้อความด้านบนอ้างอิงไฟล์pkg_config_pathตัวแปรสภาพแวดล้อมตัวแปรนี้ใช้เพื่อเพิ่มpkg-configเส้นทางการค้นหาในระบบ UNIX ทั่วไปมันจะค้นหาในไดเรกทอรี/usr/lib/pkgconfigและ/usr/share/pkgconfig-โดยปกติจะครอบคลุมโมดูลที่ติดตั้งระบบอย่างไรก็ตามโมดูลท้องถิ่นบางตัวอาจติดตั้งในคำนำหน้าอื่นเช่น/usr/ท้องถิ่น-ในกรณีนี้จำเป็นต้องเตรียมเส้นทางการค้นหาเพื่อให้pkg-configสามารถค้นหาไฟล์.pcไฟล์.
$ pkg-config-Modversion HelloPackage Hello ไม่พบในเส้นทางการค้นหา PKG-Config บางทีคุณควรเพิ่มไดเรกทอรีที่มี `Hello.pc'to pkg_config_path package variableno 'hello' พบ $ export pkg_config_path =/local/lib/pkgconfig $ pkg-config-modversion hello1.0.0
จำนวนน้อยautoconfแมโครมีให้เพื่อความสะดวกในการรวมpkg-configโมดูลเป็นโครงการ
- PKG_PROG_PKG_CONFIG ([MIN-Version]): ค้นหาpkg-configเครื่องมือในระบบและตรวจสอบเวอร์ชันสำหรับความเข้ากันได้
- pkg_check_exists (โมดูล, [action-if-found], [action-if-not-found])): ตรวจสอบเพื่อดูว่ามีชุดโมดูลเฉพาะหรือไม่
- PKG_CHECK_MODULES (Variable-Prefix, โมดูล, [Action-IF-Found], [Action-if-Not-Found])): ตรวจสอบเพื่อดูว่ามีชุดโมดูลเฉพาะหรือไม่ถ้าเป็นเช่นนั้นมันจะตั้งค่า
_cflags และ_libs ตามผลลัพธ์จากpkg-config-clagsและpkg-config-libs-
คำถามที่พบบ่อย
- โปรแกรมของฉันใช้ห้องสมุดx-ฉันจะทำอย่างไร?
- ห้องสมุดของฉันZติดตั้งไฟล์ส่วนหัวซึ่งรวมถึงlibxส่วนหัวฉันใส่อะไรในไฟล์Z.PCไฟล์?
- ห้องสมุดของฉันZใช้libxภายใน แต่ไม่เปิดเผยlibxชนิดข้อมูลใน API สาธารณะฉันใส่อะไรในไฟล์Z.PCไฟล์?
ที่pkg-configเอาต์พุตสามารถใช้งานได้อย่างง่ายดายบนบรรทัดคำสั่งคอมไพเลอร์สมมติว่าxห้องสมุดมีx.pc pkg-configไฟล์:
cc `pkg -config --cflags -libs x` -o myapp myapp.c
การรวมสามารถแข็งแกร่งขึ้นเมื่อใช้กับautoconfและทำอัตโนมัติ-โดยใช้ที่ให้มาpkg_check_modulesมาโครเมตาดาต้าสามารถเข้าถึงได้อย่างง่ายดายในกระบวนการสร้าง
configure.ac:pkg_check_modules ([outhx], [x]) makefile.am:myapp_cflags = $ (x_cflags) myapp_ldadd = $ (x_libs)
ถ้าxพบโมดูลแมโครจะเติมและแทนที่ไฟล์x_cflagsและx_libsตัวแปรหากไม่พบโมดูลจะมีการเกิดข้อผิดพลาดสามารถจัดหาอาร์กิวเมนต์ที่ 3 และ 4 ได้pkg_check_modulesเพื่อควบคุมการกระทำเมื่อพบโมดูลหรือไม่
ถ้าxห้องสมุดมีpkg-configสนับสนุนเพิ่มลงในไฟล์ต้องการ.สนาม.หากไม่ได้เพิ่มไฟล์cflagsฟิลด์ที่มีธงคอมไพเลอร์ที่จำเป็นสำหรับการใช้ไฟล์libxส่วนหัวในทั้งสองกรณีpkg-configจะส่งออกธงคอมไพเลอร์เมื่อ--คงที่ใช้หรือไม่
เพิ่มโมดูลอีกครั้งต้องการ.หากรองรับpkg-config-ในกรณีนี้ธงคอมไพเลอร์จะถูกปล่อยออกมาโดยไม่จำเป็น แต่จะทำให้มั่นใจได้ว่าธงลิงเกอร์จะปรากฏขึ้นเมื่อเชื่อมโยงแบบคงที่ถ้าlibxไม่รองรับpkg-configเพิ่มธง linker ที่จำเป็นลงในlibs.Private-
ลิขสิทธิ์ (c) 2010 Dan Nicholson
เอกสารนี้ได้รับใบอนุญาตภายใต้ใบอนุญาตสาธารณะ GNU ทั่วไปเวอร์ชัน 2หรือเวอร์ชันใหม่ ๆ