กลับไปหน้าบทความ

อ่าน 13 นาที

สร้าง (ซอฟต์แวร์)

ใน การพัฒนาซอฟต์แวร์ Make เป็น เครื่องมือ ซอฟต์แวร์ แบบอินเทอร์เฟซบรรทัด คำสั่งที่ดำเนินการตามลำดับ การพึ่งพา ที่กำหนดค่าไว้ใน ไฟล์การกำหนดค่า ที่เรียกว่า makefile...

สร้าง (ซอฟต์แวร์)

ทำ
กระบวนทัศน์มาโคร , แบบประกาศ
ออกแบบโดยสจวร์ต เฟลด์แมน
ปรากฏครั้งแรกเมษายน พ.ศ. 2519 ( เมษายน 1976 )
ภาษาการใช้งานซี
โอเอสคล้าย Unix , Inferno
รูปแบบไฟล์ไฟล์สร้าง
การนำไปใช้งานหลักๆ
BSD, GNU, nmake
ภาษาถิ่น
BSD make, GNU make, Microsoft nmake
ได้รับอิทธิพล
Ant , Rake , MSBuildและอื่นๆ

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

Make เป็นเครื่องมือที่ใช้กันอย่างแพร่หลาย โดยเฉพาะใน ระบบปฏิบัติการ Unixและระบบปฏิบัติการที่คล้าย Unix แม้ว่าจะมีเทคโนโลยีและเครื่องมืออื่นๆ ที่แข่งขันกันอยู่มากมาย รวมถึงเครื่องมือที่คล้ายกันซึ่งดำเนินการโดยอาศัยการพึ่งพา คอมไพเลอร์ บางตัว และการทำงานแบบโต้ตอบผ่านสภาพแวดล้อมการพัฒนาแบบบูรณาการ

นอกจากจะหมายถึง เครื่องมือ Unix ดั้งเดิม แล้ว Make ยังเป็นเทคโนโลยีอีกด้วย เนื่องจากมีการพัฒนา เครื่องมือหลายตัว ที่มีฟังก์ชันการทำงานคล้ายคลึงกัน รวมถึงไวยากรณ์และความหมาย ของไฟล์ makefile ที่คล้ายคลึงกัน ด้วย

ต้นทาง

Stuart Feldmanสร้าง Make ขณะอยู่ที่Bell Labsเวอร์ชันแรกเสร็จสมบูรณ์ในเดือนเมษายน พ.ศ. 2519 [ 1 ] [ 2 ] [ 3 ] Feldman ได้รับรางวัล ACM Software System Award ประจำปี 2546 ในฐานะผู้คิดค้น Make [ 4 ]

เฟลด์แมนอธิบายว่าแรงบันดาลใจในการเขียนหนังสือ Make เกิดจากความไม่พอใจของเพื่อนร่วมงานที่มีต่อเครื่องมือที่มีอยู่ในขณะนั้น:

จุดเริ่มต้นของ Make มาจากการที่Steve Johnson (ผู้เขียน yacc และอื่นๆ) เดินเข้ามาในห้องทำงานของผมด้วยอารมณ์ฉุนเฉียว พร้อมกับสาปแช่งโชคชะตาที่ทำให้เขาเสียเวลาช่วงเช้าไปกับการแก้ไขข้อผิดพลาดในโปรแกรมที่ควรจะใช้งานได้ปกติ (ข้อผิดพลาดได้รับการแก้ไขแล้ว ไฟล์ไม่ได้ถูกคอมไพล์cc *.oดังนั้นจึงไม่ได้รับผลกระทบ) เนื่องจากผมเองก็ใช้เวลาส่วนหนึ่งของเย็นวันก่อนหน้านั้นไปกับการรับมือกับปัญหาเดียวกันในโปรเจกต์ที่ผมกำลังทำอยู่ จึงเกิดความคิดที่จะสร้างเครื่องมือเพื่อแก้ปัญหานี้ขึ้นมา มันเริ่มต้นด้วยแนวคิดที่ซับซ้อนเกี่ยวกับการวิเคราะห์ความสัมพันธ์ของส่วนประกอบต่างๆ แต่ถูกลดทอนให้เหลือสิ่งที่ง่ายกว่ามาก และกลายเป็น Make ในช่วงสุดสัปดาห์นั้น การใช้เครื่องมือที่ยังใหม่เอี่ยมเป็นส่วนหนึ่งของวัฒนธรรมในยุคนั้น ไฟล์ Makefile เป็นไฟล์ข้อความ ไม่ใช่ไบนารีที่เข้ารหัสอย่างมหัศจรรย์ เพราะนั่นคือหลักการของ Unix : ต้องพิมพ์ได้ แก้ไขข้อผิดพลาดได้ และเข้าใจได้

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

Make ถูกใช้กันอย่างแพร่หลายส่วนหนึ่งเนื่องมาจากการรวมไว้ในUnix ตั้งแต่แรก โดยเริ่มจากPWB/UNIX 1.0 ซึ่งมีเครื่องมือพัฒนาซอฟต์แวร์หลากหลาย[ 3 ]

ตัวแปร

มีการพัฒนาโปรแกรม Make ขึ้น มาหลายเวอร์ชัน โดยทั่วไปจะใช้รูปแบบไฟล์ makefile เดียวกันและมีฟังก์ชันการทำงานเหมือนกัน แต่บางเวอร์ชันก็มีการปรับปรุงเพิ่มเติมจากเวอร์ชันดั้งเดิม ตัวอย่างเช่น:

  • Sun DevPro Make ปรากฏตัวในปี 1986 พร้อมกับ SunOS-3.2 โดยมาพร้อมกับโปรแกรมเสริม และใน SunOS-4.0 SunPro Make ก็กลายเป็นโปรแกรม Make เริ่มต้น[ 5 ]ในเดือนธันวาคม 2006 Sun DevPro Make ได้ถูกเปิดเผยเป็นโอเพนซอร์ส ซึ่งเป็นส่วนหนึ่งของความพยายามในการเปิดเผยSolarisเป็น โอเพนซอร์ส [ 6 ] [ 7 ]
  • dmake หรือ Distributed Make ที่มาพร้อมกับ Sun Solaris Studio เป็น Make เริ่มต้น แต่ไม่ใช่ Make เริ่มต้นบนระบบปฏิบัติการ Solaris (SunOS) เดิมทีจำเป็นต้องใช้ในการสร้าง OpenOffice แต่ในปี 2009 [ 8 ]ระบบการสร้างถูกเขียนใหม่ให้ใช้ GNU Make ในขณะที่Apache OpenOfficeยังคงมีระบบการสร้างทั้งสองแบบผสมกันอยู่[ 9 ] แต่ LibreOffice ที่ได้รับการพัฒนาอย่างต่อเนื่องมากกว่านั้นใช้เฉพาะ "gbuild" ที่ทันสมัยแล้ว[ 8 ]
  • BSD Make ( pmake [ 10 ] bmake [ 11 ] หรือ fmake [ 12 ] )ซึ่งพัฒนามาจากงานของ Adam de Boor เกี่ยวกับ Make เวอร์ชันที่สามารถสร้างเป้าหมายแบบขนาน ได้ และยังคงมีอยู่ใน FreeBSD [ 11 ] NetBSD [ 13 ]และOpenBSD [ 14 ]โดยมีการปรับเปลี่ยนในระดับต่างๆ กัน จุดเด่น คือมีเงื่อนไขและลูปแบบวนซ้ำซึ่งถูกนำไปใช้ในขั้นตอนการวิเคราะห์ และอาจใช้ในการสร้าง makefile แบบมีเงื่อนไขและตามโปรแกรม[ 15 ] รวมถึงการ สร้างเป้าหมายในระหว่างการทำงาน
  • GNU Make (เรียกสั้นๆ ว่าgmake ) คือการใช้งานมาตรฐานของ Make สำหรับ Linux และ macOS [ 16 ] มันมีส่วนขยายหลายอย่างเหนือ Make ดั้งเดิม เช่น เงื่อนไข นอกจากนี้ยังมีฟังก์ชันในตัวมากมายที่สามารถใช้เพื่อกำจัดความจำเป็นในการใช้สคริปต์เชลล์ในกฎของ makefile รวมถึงการจัดการตัวแปรที่ตั้งค่าและใช้ใน makefile [ 17 ]ตัวอย่างเช่น ฟังก์ชัน foreachสามารถใช้เพื่อวนซ้ำรายการของค่าต่างๆ เช่น ชื่อไฟล์ในไดเร็กทอรีที่กำหนด[ 18 ] GNU Make จำเป็นสำหรับการสร้างระบบซอฟต์แวร์หลายระบบ รวมถึงGNU Compiler Collection (GCC) (ตั้งแต่เวอร์ชัน 3.4 [ 19 ] ) เคอร์เนล Linux [ 20 ] [ 21 ] Apache OpenOffice [ 9 ] LibreOffice [ 8 ]และMozilla Firefox [ 22 ]
  • Remake ของ Rocky Bernstein [ 23 ]เป็นการแยกสาขาของ GNU Make และมีส่วนขยายเพิ่มเติมหลายอย่างเหนือ GNU Make เช่น การรายงานตำแหน่งและตำแหน่งข้อผิดพลาดที่ดีขึ้น การติดตามการทำงาน การวิเคราะห์โปรไฟล์การทำงาน และยังมีดีบักเกอร์อีกด้วย
  • nmakeของ Glenn Fowler [ 24 ] (ไม่เกี่ยวข้องกับเวอร์ชัน Microsoft ที่มีชื่อเดียวกัน) ไม่เข้ากันกับเวอร์ชัน UNIX แต่มีคุณสมบัติที่บางคนระบุว่าช่วยลดขนาดของ makefile ลงได้ถึง 10 เท่า
  • โดยปกติ Microsoft nmakeจะติดตั้งมาพร้อมกับVisual Studio [ 25 ] มันรองรับคำสั่งพรีโปรเซสเซอร์ เช่น includes และ conditional expressions ซึ่งใช้ตัวแปรที่ตั้งค่าไว้ในบรรทัดคำสั่งหรือภายใน makefile [ 26 ] [ 27 ]กฎการอนุมานจะแตกต่างจาก Make ตัวอย่างเช่น พวกมันสามารถรวมเส้นทางการค้นหาได้[ 28 ]
  • Embarcadero make มีตัวเลือกบรรทัดคำสั่งที่ "ทำให้ MAKE เลียนแบบ NMAKE ของ Microsoft" [ 29 ]
  • เครื่องมือ JomของQt Projectเป็นโคลนของ nmake [ 30 ]
  • Mkเข้ามาแทนที่ Make ในResearch Unixตั้งแต่เวอร์ชัน 9 เป็นต้นไป[ 31 ]ได้รับการออกแบบใหม่จากเครื่องมือเดิมโดย Andrew G. Hume โปรแกรมเมอร์ของ Bell Labs โดยมีไวยากรณ์ที่แตกต่างออกไป Mk กลายเป็นเครื่องมือสร้างมาตรฐานในPlan 9ซึ่งเป็นระบบที่ Bell Labs ตั้งใจจะใช้แทน Unix [ 32 ]
  • Kati คือสิ่งที่ Google ใช้แทน GNU Make ซึ่งใช้ในการสร้าง ระบบปฏิบัติการ Androidตั้งแต่ปี 2020 โดยจะแปลง makefile เป็นninjaเพื่อให้การสร้างแบบเพิ่มทีละส่วนเร็วขึ้น (คล้ายกับ metatool ของ cmake) [ 33 ]
  • Snakemake เป็นการใช้งานที่ขับเคลื่อนด้วย Python สำหรับการคอมไพล์และรันเวิร์กโฟลว์ชีวสารสนเทศ[ 34 ]

POSIXประกอบด้วยการกำหนดมาตรฐานของคุณสมบัติพื้นฐานและการทำงานของยูทิลิตี้ Make และถูกนำไปใช้ด้วยระดับความเข้ากันได้ที่แตกต่างกันกับเวอร์ชัน Make ที่ใช้ Unix โดยทั่วไปแล้ว สามารถใช้ไฟล์ makefile แบบง่ายๆ ระหว่างเวอร์ชันต่างๆ ของ Make ได้อย่างประสบความสำเร็จพอสมควร GNU Make, Makepp และบางเวอร์ชันของ BSD Make จะค้นหาไฟล์ที่มีชื่อ "GNUmakefile" [ 35 ] "Makeppfile" [ 36 ]และ "BSDmakefile" [ 37 ] เป็นค่าเริ่มต้น ซึ่งทำให้สามารถวางไฟล์ makefile ที่ใช้พฤติกรรมที่กำหนดโดยการใช้งานไว้ในตำแหน่งที่แยกต่างหากได้

ใช้

โดยทั่วไปแล้ว Make จะอัปเดตไฟล์เป้าหมายจากไฟล์ต้นฉบับโดยอิงจากไฟล์ makefile หากไฟล์ต้นฉบับใดมีเวลาประทับ ใหม่กว่า ไฟล์เป้าหมาย หรือไฟล์เป้าหมายไม่มีอยู่ ตัวอย่างเช่น อาจรวมถึงการคอมไพ ล์ไฟล์ C ( *.c) เป็นไฟล์อ็อบเจ็กต์จากนั้นเชื่อมโยงไฟล์อ็อบเจ็กต์เหล่านั้นเข้ากับโปรแกรมที่สามารถเรียกใช้งานได้ หรืออาจรวมถึงการคอมไพล์ ไฟล์ TypeScript ( *.ts) เป็นJavaScriptเพื่อใช้ในเบราว์เซอร์ ตัวอย่างอื่นๆ ได้แก่ การแปลงไฟล์ภาพต้นฉบับเป็นรูปแบบอื่น คัดลอกไฟล์ไปยังระบบจัดการเนื้อหา และส่งอีเมลเกี่ยวกับสถานะการสร้าง

ไฟล์ makefile กำหนดเป้าหมาย โดยแต่ละเป้าหมายจะเป็นไฟล์ที่จะสร้างขึ้น หรือเป็นแนวคิดที่ผู้ใช้กำหนดเอง ซึ่งเรียกว่า เป้าหมาย เสมือน (phony target)

ทำการอัปเดตเป้าหมายที่ส่งมาเป็นอาร์กิวเมนต์:

สร้าง[ -f makefile ] [ตัวเลือก] [เป้าหมาย]

หากไม่ได้ระบุเป้าหมายใดๆ Make จะอัปเดตเป้าหมายแรกในไฟล์ makefile ซึ่งมักจะเป็นเป้าหมายปลอมเพื่อดำเนินการตามการกระทำที่ใช้บ่อยที่สุด

Make จะข้ามการดำเนินการสร้างหากเวลาประทับของไฟล์เป้าหมายอยู่หลังจากเวลาประทับของไฟล์ต้นฉบับ[ 38 ]การทำเช่นนี้จะช่วยเพิ่มประสิทธิภาพกระบวนการสร้างโดยการข้ามการดำเนินการเมื่อไฟล์เป้าหมายเป็นปัจจุบัน แต่บางครั้งการอัปเดตจะถูกข้ามไปโดยไม่ถูกต้องเนื่องจากปัญหาเกี่ยวกับเวลาประทับของไฟล์ รวมถึงการกู้คืนเวอร์ชันเก่าของไฟล์ต้นฉบับ หรือเมื่อระบบไฟล์เครือข่ายเป็นแหล่งที่มาของไฟล์และนาฬิกาหรือเขตเวลาของระบบไฟล์นั้นไม่ตรงกับเครื่องที่เรียกใช้ Make นอกจากนี้ หากเวลาประทับของไฟล์ต้นฉบับอยู่ในอนาคต Make จะเรียกใช้การดำเนินการที่ไม่จำเป็นซ้ำ ๆ ทำให้เวลาสร้างนานขึ้น

เมื่อ Make เริ่มทำงาน มันจะใช้ไฟล์ makefile ที่ระบุไว้ในบรรทัดคำสั่ง หรือหากไม่ได้ระบุไว้ มันจะใช้ไฟล์ที่ค้นพบโดยใช้กฎการค้นหาเฉพาะ โดยทั่วไปแล้ว Make จะใช้ไฟล์ในไดเร็กทอรีการทำงานที่มีชื่อว่าMakefileเป็น ค่าเริ่มต้น GNU Make จะค้นหาไฟล์แรกที่ตรงกับ: GNUmakefile , makefileหรือMakefile

ประมวลผลตัวเลือกของบรรทัดคำสั่งโดยอิงจากไฟล์ makefile ที่โหลดไว้

ไฟล์สร้าง

ไฟล์สร้าง
ตัวระบุประเภทมาตรฐาน (UTI)public.make-source [ 39 ]

ภาษา makefile เป็นการเขียนโปรแกรมเชิงประกาศ บางส่วน โดยมีการอธิบายเงื่อนไขการสิ้นสุด แต่ไม่ได้ ระบุลำดับการดำเนินการ[ 40 ] [ 41 ] [ 42 ] [ 43 ]

Makefile สามารถมีโครงสร้างต่อไปนี้ได้: [ 44 ]

  • กฎที่ชัดเจน : กำหนดว่าเมื่อใดและอย่างไรจึงจะอัปเดตเป้าหมาย โดยระบุข้อกำหนดเบื้องต้น (เป้าหมายที่ขึ้นอยู่) และคำสั่งที่กำหนดการดำเนินการอัปเดต ซึ่งเรียกว่าสูตร
  • กฎโดยนัย : กำหนดว่าเมื่อใดและอย่างไรจึงจะสร้างไฟล์ประเภทเดียวกันขึ้นใหม่โดยพิจารณาจากชื่อของไฟล์ รวมถึงวิธีที่เป้าหมายขึ้นอยู่กับไฟล์ที่มีชื่อคล้ายกับเป้าหมาย และสูตรการอัปเดต
  • การกำหนดตัวแปร : เชื่อมโยงค่าข้อความกับชื่อที่สามารถนำไปใช้แทนในข้อความถัดไปได้
  • คำสั่ง : คำแนะนำให้ทำสิ่งพิเศษบางอย่าง เช่น การรวมไฟล์ makefile อื่นเข้าไปด้วย
  • หมายเหตุ : บรรทัดที่ขึ้นต้นด้วย#

กฎ

แต่ละกฎเริ่มต้นด้วยบรรทัดการพึ่งพา ซึ่งประกอบด้วยชื่อ เป้าหมายของกฎตามด้วยเครื่องหมายโคลอน (:) และอาจมีรายการเป้าหมาย (หรือที่เรียกว่าข้อกำหนดเบื้องต้น) ที่เป้าหมายของกฎนั้นขึ้นอยู่กับ[ 45 ]

เป้าหมาย [เป้าหมาย ...]: [ส่วนประกอบ ...] Tab ↹[คำสั่ง 1] . . . Tab ↹[คำสั่ง n] 

โดยปกติแล้ว กฎจะมีเป้าหมายเดียว ไม่ใช่หลายเป้าหมาย

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

คำสั่งแรกอาจปรากฏอยู่ในบรรทัดเดียวกันหลังจากข้อกำหนดเบื้องต้น โดยคั่นด้วยเครื่องหมายเซมิโคลอน

เป้าหมาย: ข้อกำหนดเบื้องต้น  ; คำสั่ง

ตัวอย่างเช่น,

สวัสดี: ; @ echo " สวัสดี " 

แต่ละบรรทัดคำสั่งต้องเริ่มต้นด้วยอักขระแท็บ แม้ว่าช่องว่าง ก็ถือเป็น ช่องว่างเช่นกันแต่ Make ต้องการแท็บ เนื่องจากสิ่งนี้มักนำไปสู่ความสับสนและข้อผิดพลาด ลักษณะไวยากรณ์ของ makefile นี้จึงถูกวิพากษ์วิจารณ์Eric S. Raymondอธิบายว่าเป็น "หนึ่งในข้อผิดพลาดด้านการออกแบบที่แย่ที่สุดในประวัติศาสตร์ของ Unix" [ 46 ]และThe Unix-Haters Handbookกล่าวว่า "การใช้แท็บเป็นส่วนหนึ่งของไวยากรณ์ก็เหมือนกับกับดักไม้แบบยืดหยุ่นในThe Green Berets " Feldman อธิบายว่าการเลือกนี้เกิดจากวิธีแก้ปัญหาสำหรับความยากลำบากในการใช้งานในช่วงแรก และได้รับการรักษาไว้ด้วยความปรารถนาที่จะเข้ากันได้กับผู้ใช้กลุ่มแรกสุด:

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

— สจ๊วต เฟลด์แมน[ 46 ]

ตั้งแต่เวอร์ชัน 3.82 เป็นต้นไป GNU Make อนุญาตให้เลือกสัญลักษณ์ใดก็ได้ (อักขระตัวเดียว) เป็นคำนำหน้าสูตรโดยใช้ตัวแปรพิเศษ .RECIPEPREFIX:

.RECIPEPREFIX := : all : :@echo "สัญลักษณ์คำนำหน้าสูตรถูกตั้งค่าเป็น '$(.RECIPEPREFIX)'"

แต่ละคำสั่งจะถูกเรียกใช้ในเชลล์ ที่แยกจากกัน เนื่องจากระบบปฏิบัติการใช้เชลล์ที่แตกต่างกัน จึงอาจทำให้ไฟล์ makefile ไม่สามารถใช้งานได้บนระบบปฏิบัติการอื่น ตัวอย่างเช่น GNU Make (และ Make ทุกเวอร์ชันที่ใช้ POSIX) จะเรียกใช้คำสั่งด้วย/bin/shเป็นค่าเริ่มต้น ซึ่ง โดยปกติจะใช้คำสั่ง Unixเช่นcpในทางตรงกันข้ามnmake ของ Microsoft จะเรียกใช้คำสั่งด้วย cmd.exe ซึ่ง มีคำสั่ง แบตช์เช่นcopyแต่ไม่จำเป็นต้องมี cp

เนื่องจากสูตรการสร้างนั้นเป็นตัวเลือกเสริม บรรทัดการพึ่งพาจึงสามารถประกอบด้วยส่วนประกอบที่อ้างอิงถึงเป้าหมายอื่น ๆ เท่านั้น:

เรียลคลีน: ทำความสะอาดดิสคลีน

กฎตัวอย่างต่อไปนี้จะถูกประเมินเมื่อทำการอัปเดตไฟล์เป้าหมาย file.txt ผ่านทางmake file.txt. ถ้า file.html ใหม่กว่า file.txt หรือ file.txt ไม่มีอยู่ คำสั่งจะถูกเรียกใช้เพื่อสร้าง file.txt จาก file.html

file.txt : file . html lynx -dump file.html > file.txt 

คำสั่งหนึ่งๆ สามารถมีคำนำหน้าอย่างน้อยหนึ่งคำต่อไปนี้ (หลังแท็บ):

  • เครื่องหมายลบ (-) ระบุให้ละเว้นข้อผิดพลาดจากคำสั่ง
  • คำสั่ง `at (@)` ระบุว่าจะไม่แสดงคำสั่งก่อนที่จะดำเนินการ
  • เครื่องหมายบวก (+) ระบุให้ดำเนินการคำสั่งนั้นแม้ว่า Make จะถูกเรียกใช้ในโหมด "ห้ามดำเนินการ" ก็ตาม

การเพิกเฉยต่อข้อผิดพลาดและการปิดเสียงสะท้อนสามารถทำได้โดยผ่านเป้าหมายพิเศษ.IGNOREและ.SILENT. [ 47 ]

NMAKE ของ Microsoft มีกฎที่กำหนดไว้ล่วงหน้าซึ่งสามารถละเว้นได้จากไฟล์ makefile เหล่านี้ เช่น. c.obj$(CC)$(CFLAGS)

มาโคร

ไฟล์ makefile สามารถกำหนดและใช้งานมาโครได้ โดยปกติแล้ว มาโครจะถูกเรียกว่าตัวแปรเมื่อมันเก็บค่าที่เป็นสตริงอย่างง่าย เช่น`<br>` มาโครในไฟล์ makefile สามารถถูกแทนที่ได้ในอาร์กิวเมนต์บรรทัดคำสั่งที่ส่งไปยังยูทิลิตี้ Make นอกจาก นี้ ตัวแปรสภาพแวดล้อมยังสามารถใช้งานเป็นมาโครได้อีกด้วย CC=clang

ตัวอย่างเช่น มาโครนี้CCมักใช้ในไฟล์ makefile เพื่ออ้างอิงถึงตำแหน่งของ คอมไพเลอร์ภาษา Cหากใช้มาโครนี้อย่างสม่ำเสมอทั่วทั้งไฟล์ makefile คอมไพเลอร์ที่ใช้จะสามารถเปลี่ยนแปลงได้โดยการเปลี่ยนค่าของมาโครแทนที่จะเปลี่ยนคำสั่งกฎแต่ละคำสั่งที่เรียกใช้คอมไพเลอร์

โดยทั่วไปแล้ว มาโครมักตั้งชื่อด้วยตัวพิมพ์ใหญ่ทั้งหมด :

มาโคร=คำจำกัดความ 

ค่ามาโครสามารถประกอบด้วยค่ามาโครอื่นๆ ได้ ค่าของมาโครจะถูกขยายโดยอัตโนมัติทุกครั้งที่ใช้ งาน

การใช้มาโครทำได้โดยการขยายผ่านทาง $ NAMEหรือ $( NAME ) วิธีหลังปลอดภัยกว่า เพราะการละเว้นวงเล็บจะทำให้ Make ตีความตัวอักษรตัวถัดไปหลัง $ $เป็นชื่อตัวแปรทั้งหมด รูปแบบที่เทียบเท่ากันคือการใช้วงเล็บปีกกาแทนวงเล็บธรรมดา เช่น `$(NAME)` ซึ่ง ${}เป็นรูปแบบที่ใช้ในBSD

NEW_MACRO = $( MACRO ) - $( MACRO2 )

มาโครสามารถประกอบขึ้นจากคำสั่งเชลล์โดยใช้ตัวดำเนินการแทนที่คำสั่ง[ 48 ]!=

YYYYMMDD ไม่เท่ากับวันที่ 

ไวยากรณ์คำสั่งบรรทัดคำสั่งสำหรับการแทนที่มาโครมีดังนี้:

สร้างMACRO = "value" [ MACRO = "value" ... ] TARGET [ TARGET ... ]

ไฟล์ Makefile สามารถเข้าถึงมาโครภายใน ที่กำหนดไว้ล่วงหน้าได้ โดยมาโคร `makefile` และ `makefile` เป็น ?ตัวอย่าง@ที่ใช้กันทั่วไป

เป้าหมาย: ส่วนประกอบ 1 ส่วนประกอบ 2  # แสดงส่วนประกอบที่อายุน้อยกว่าเป้าหมายแสดง$?  # แสดงชื่อเป้าหมายแสดง$@

ไวยากรณ์ทั่วไปเมื่อกำหนดมาโครซึ่งใช้งานได้บน BSD และ GNU Make คือการใช้+= , ?=และ!=แทนเครื่องหมายเท่ากับ ( = ) [ 49 ]

กฎคำต่อท้าย

กฎคำต่อท้ายมี "เป้าหมาย" ที่มีชื่อในรูปแบบ.FROM.TOและใช้เพื่อเริ่มการกระทำตามนามสกุลไฟล์ ในบรรทัดคำสั่งของกฎคำต่อท้าย POSIX ระบุ[ 50 ]ว่ามาโครภายใน$<จะอ้างอิงถึงข้อกำหนดเบื้องต้นข้อแรกและ$@อ้างอิงถึงเป้าหมาย ในตัวอย่างนี้ ซึ่งแปลงไฟล์ HTML ใดๆ ให้เป็นข้อความ โทเค็นการเปลี่ยนเส้นทางเชลล์>เป็นส่วนหนึ่งของบรรทัดคำสั่ง ในขณะที่$<เป็นมาโครที่อ้างอิงถึงไฟล์ HTML:

คำต่อท้าย: .txt .html# จากไฟล์ .html เป็น .txt .html.txt : lynx -dump $< > $@

เมื่อเรียกใช้จากบรรทัดคำสั่ง ตัวอย่างข้างต้นจะขยายความดังนี้:

$ make -n file.txt lynx -dump file.html > file.txt

กฎของรูปแบบ

กฎคำต่อท้ายไม่สามารถมีข้อกำหนดเบื้องต้นใดๆ ของตัวเองได้[ 51 ]หากมี ข้อกำหนดเบื้องต้นใดๆ จะถูกถือว่าเป็นไฟล์ปกติที่มีชื่อผิดปกติ ไม่ใช่กฎคำต่อท้าย GNU Make รองรับกฎคำต่อท้ายเพื่อความเข้ากันได้กับ makefile เก่า แต่โดยทั่วไปแล้วจะสนับสนุนให้ใช้กฎรูปแบบ[ 52 ]

กฎรูปแบบมีลักษณะเหมือนกฎทั่วไป ยกเว้นว่าเป้าหมายของกฎนั้นมี %อักขระเพียงตัวเดียวในสตริง เป้าหมายถือเป็นรูปแบบสำหรับการจับคู่ชื่อไฟล์: %สามารถจับคู่สตริงย่อยใดๆ ที่มีอักขระศูนย์ตัวขึ้นไป[ 53 ]ในขณะที่อักขระอื่นๆ จะจับคู่เฉพาะตัวมันเองเท่านั้น ข้อกำหนดเบื้องต้นก็ใช้%เพื่อแสดงว่าชื่อของพวกมันเกี่ยวข้องกับชื่อเป้าหมายอย่างไร

ตัวอย่างกฎคำต่อท้ายข้างต้นจะมีลักษณะตามกฎรูปแบบต่อไปนี้:

# จาก %.html ไปยัง %.txt %.txt : % .html lynx -dump $< > $@

ความคิดเห็น

ข้อความแสดงความคิดเห็นแบบบรรทัดเดียวเริ่มต้นด้วยเครื่องหมายแฮช (#)

คำสั่ง

คำสั่งนี้ระบุพฤติกรรมพิเศษ เช่นการรวมไฟล์ makefile อื่น เข้ามา

เส้นต่อเนื่อง

การต่อบรรทัดจะระบุด้วย\เครื่องหมายแบ็กสแลช (/) ที่ท้ายบรรทัด

 เป้าหมาย: ส่วนประกอบ \ ส่วนประกอบ Tab ↹สั่งการ ; \ คำสั่งอื่น | \ คำสั่งแบบท่อ 

ตัวอย่าง

คำสั่งต่อไปนี้อยู่ในบริบทของไฟล์ makefile ที่อยู่ถัดไป

make # อัปเดตเป้าหมายแรก 'all' make help # อัปเดตเป้าหมาย 'help' เพื่อแสดงรายการเป้าหมาย make dist # อัปเดตเป้าหมาย 'dist' เพื่อสร้างสำหรับการแจกจ่าย
แพ็คเกจ=แพ็คเกจ เวอร์ชัน= `วันที่"+%Y.%m%d%" ` ไดเร็กทอรีการเผยแพร่= .. ไฟล์การเผยแพร่= $(แพ็คเกจ) - $(เวอร์ชัน)# เป้าหมายเริ่มต้น# หมายเหตุ: ตัวแปร LOGNAME มาจากสภาพแวดล้อมall : echo "สวัสดี$( LOGNAME ) ไม่มีอะไรให้ทำโดยค่าเริ่มต้น" echo "ลองใช้ 'make help'"# แสดงเป้าหมายโดยการค้นหาในไฟล์นี้help : egrep "^# target:" [ Mm ] akefile# สร้างไฟล์สำหรับ เผยแพร่ : tar -cf $( RELEASE_DIR ) / $( RELEASE_FILE ) && \ gzip -9 $( RELEASE_DIR ) / $( RELEASE_FILE ) .tar 

ด้านล่างนี้คือไฟล์ makefile อย่างง่ายที่โดยค่าเริ่มต้น (กฎ "all" จะแสดงเป็นอันดับแรก) จะคอมไพล์ไฟล์ต้นฉบับชื่อ "helloworld.c" โดยใช้คอมไพเลอร์ C ของระบบ และยังมีเป้าหมาย "clean" เพื่อลบไฟล์ที่สร้างขึ้นหากผู้ใช้ต้องการเริ่มต้นใหม่$@และ$<เป็นมาโครภายในสองตัว (หรือที่เรียกว่าตัวแปรอัตโนมัติ) ซึ่งหมายถึงชื่อเป้าหมายและแหล่งที่มา "โดยนัย" ตามลำดับ ในตัวอย่างด้านล่าง$^จะขยายเป็นรายการข้อกำหนดเบื้องต้นที่คั่นด้วยช่องว่าง มีมาโครภายในอื่นๆ อีกจำนวนหนึ่ง[ 50 ] [ 54 ]

CFLAGS ?= -g LDLIBS += -lmทั้งหมด: ออก . txtOut.txt : helloworld ./$< > $@helloworld : helloworld . o $( CC ) $( LDFLAGS ) -o $@ $^ $( LDLIBS )helloworld.o : สวัสดีโลก$( CC ) $( CFLAGS ) -c -o $@ $<clean : $( RM ) Out.txt helloworld helloworld.o 

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

ทั้งหมด: สวัสดีโลกhelloworld : helloworld . o $( CC ) $( CFLAGS ) $( LDFLAGS ) -o $@ $^ทำความสะอาด: $( RM ) helloworld helloworld.o# กฎคำต่อท้าย.co : $( CC ) $( CFLAGS ) -c $<คำต่อท้าย: .c

ตอนนี้ Make จัดการเรื่องการพึ่งพาไฟล์ "helloworld.o" กับ "helloworld.c" โดยอัตโนมัติแล้ว ในตัวอย่างง่ายๆ อย่างที่แสดงให้เห็นนี้ แทบจะไม่สำคัญ แต่พลังที่แท้จริงของกฎการต่อท้ายจะปรากฏชัดเมื่อจำนวนไฟล์ต้นฉบับในโครงการซอฟต์แวร์เริ่มเพิ่มขึ้น เราเพียงแค่เขียนกฎสำหรับขั้นตอนการเชื่อมโยงและประกาศไฟล์ออบเจ็กต์เป็นข้อกำหนดเบื้องต้น จากนั้น Make จะกำหนดวิธีการสร้างไฟล์ออบเจ็กต์ทั้งหมดและตรวจสอบการเปลี่ยนแปลงในไฟล์ต้นฉบับทั้งหมดโดยอัตโนมัติ

กฎการต่อท้ายแบบง่ายๆ ใช้ได้ผลดีตราบใดที่ไฟล์ต้นฉบับไม่ขึ้นต่อกันและไม่ขึ้นต่อไฟล์อื่นๆ เช่น ไฟล์เฮดเดอร์ อีกวิธีหนึ่งในการทำให้กระบวนการสร้างง่ายขึ้นคือการใช้กฎการจับคู่รูปแบบ (pattern matching) ซึ่งสามารถใช้ร่วมกับการสร้างการพึ่งพาโดยคอมไพเลอร์ได้ ตัวอย่างสุดท้ายที่ต้องใช้คอมไพเลอร์ gcc และ GNU Make คือไฟล์ makefile ทั่วไปที่คอมไพล์ไฟล์ C ทั้งหมดในโฟลเดอร์ให้เป็นไฟล์ออบเจ็กต์ที่เกี่ยวข้อง แล้วเชื่อมโยงเข้ากับไฟล์ปฏิบัติการสุดท้าย ก่อนที่จะมีการคอมไพล์ การพึ่งพาจะถูกรวบรวมในรูปแบบที่ใช้งานง่ายสำหรับ makefile ลงในไฟล์ที่ซ่อนอยู่ ".depend" ซึ่งจะถูกรวมไว้ใน makefile โปรแกรมที่พกพาได้ควรหลีกเลี่ยงโครงสร้างที่ใช้ด้านล่างนี้

# ไฟล์ GNUMakefile ทั่วไป# ส่วนย่อยที่จะทำให้เกิดข้อผิดพลาดหากไม่ใช่ GNU ifneq (,) ไฟล์ makefile นี้ต้องการGNU Make endifPROGRAM = foo C_FILES := $( wildcard *.c ) OBJS := $( patsubst %.c, %.o, $( C_FILES )) CC = cc CFLAGS = -Wall -pedantic LDFLAGS = LDLIBS = -lmทั้งหมด: $( โปรแกรม)$(PROGRAM) : . ขึ้นอยู่กับ$( OBJS ) $( CC ) $( CFLAGS ) $( OBJS ) $( LDFLAGS ) -o $( PROGRAM ) $( LDLIBS )ขึ้นอยู่กับ: . ขึ้นอยู่กับ.depend : cmd = gcc - MM - MF depend $( var ) ; cat depend >> . depend ; .depend : @echo "กำลังสร้าง dependency..." @ $( foreach var, $( C_FILES ) , $( cmd )) @rm -f depend-รวม .depend# นี่คือกฎการจับคู่รูปแบบ นอกเหนือจากตัวแปรอัตโนมัติที่ใช้ในที่นี้แล้ว ตัวแปร $* ที่ตรงกับสิ่งที่ % แทนนั้นอาจมีประโยชน์ในกรณีพิเศษ%.o : %. c $( CC ) $( CFLAGS ) -c $< -o $@% : %. o $( CC ) $( CFLAGS ) -o $@ $<ล้าง: rm -f .depend $( OBJS ).ปลอม: พึ่งพาความสะอาด

การติดตามการพึ่งพา

ไฟล์ Makefile ประกอบด้วยส่วนประกอบที่ต้องพึ่งพา (dependencies) และการลืมใส่ส่วนประกอบที่ไม่จำเป็น อาจทำให้ผู้ใช้ไม่ทันสังเกตเห็น และอาจส่งผลให้เกิดข้อผิดพลาดเล็กๆ น้อยๆ ในซอฟต์แวร์ที่สร้างขึ้น ซึ่งยากต่อการตรวจจับ มีหลายวิธีที่สามารถใช้เพื่อหลีกเลี่ยงปัญหานี้และทำให้ส่วนประกอบในซอร์สโค้ดและไฟล์ Makefile ตรงกัน วิธีหนึ่งคือการใช้คอมไพเลอร์ในการติดตามการเปลี่ยนแปลงของส่วนประกอบ GCC สามารถวิเคราะห์ซอร์สโค้ดแบบคงที่และสร้างกฎสำหรับไฟล์ที่กำหนดโดยอัตโนมัติโดยใช้-MMสวิตช์ อีกวิธีหนึ่งคือการใช้ไฟล์ Makefile หรือเครื่องมือของบุคคลที่สามที่สร้างไฟล์ Makefile พร้อมส่วนประกอบที่ต้องพึ่งพา (เช่น ชุดเครื่องมือ Automakeของโครงการ GNUสามารถทำได้โดยอัตโนมัติ)

อีกแนวทางหนึ่งคือการใช้เครื่องมือสร้างแบบเมตา เช่นCMake , Mesonเป็นต้น

ดูเพิ่มเติม

  • หน้าแรกของ GNU Make
  • Make — โปรแกรมสำหรับบำรุงรักษาโปรแกรมคอมพิวเตอร์บทความของ Stuart Feldman ปี 1978 ที่อธิบายเกี่ยวกับโปรแกรม make
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Make_(software)&oldid=1355632689 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ สร้าง (ซอฟต์แวร์)

ใน การพัฒนาซอฟต์แวร์ Make เป็น เครื่องมือ ซอฟต์แวร์ แบบอินเทอร์เฟซบรรทัด คำสั่งที่ดำเนินการตามลำดับ การพึ่งพา ที่กำหนดค่าไว้ใน ไฟล์การกำหนดค่า ที่เรียกว่า makefile...

ต้นทาง

Stuart Feldman สร้าง Make ขณะอยู่ที่ Bell Labs เวอร์ชันแรกเสร็จสมบูรณ์ในเดือนเมษายน พ.ศ. 2519 [ 1 ] [ 2 ] [ 3 ] Feldman ได้รับ รางวัล ACM Software System Award ประจำปี 2546 ในฐานะผู้คิดค้น Make [ 4 ]

ใช้

โดยทั่วไปแล้ว Make จะอัปเดตไฟล์เป้าหมายจากไฟล์ต้นฉบับโดยอิงจากไฟล์ makefile หากไฟล์ต้นฉบับใดมี เวลาประทับ ใหม่กว่า ไฟล์เป้าหมาย หรือไฟล์เป้าหมายไม่มีอยู่ ตัวอย่างเช่น อาจรวมถึงการคอมไพ ล์ไฟล์ C ( *.

กฎ

แต่ละกฎเริ่มต้นด้วย บรรทัดการพึ่งพา ซึ่งประกอบด้วยชื่อ เป้าหมาย ของกฎตามด้วยเครื่องหมายโคลอน (:) และอาจมีรายการเป้าหมาย (หรือที่เรียกว่าข้อกำหนดเบื้องต้น) ที่เป้าหมายของกฎนั้นขึ้นอยู่กับ [ 45 ]