ฉันจะเพิกเฉยต่อการกำหนดตัวแปรบรรทัดคำสั่งในบิลด์แบบเรียกซ้ำได้อย่างไร

ฉันกำลังพยายามรวมระบบบิลด์สองระบบเข้าด้วยกัน ทั้งสองแบบเป็นแบบเรียกซ้ำ (กฎใน makefile ใช้ make เพื่อเรียก makefiles อื่น ๆ เพื่อสร้างส่วนประกอบของโครงการ)

ฉันจะเรียกพวกเขาว่า 'A' และ 'B' โดยที่ 'A' สร้างแอปพลิเคชันและ 'B' สร้างไลบรารีที่ 'A' ใช้

makefile ระดับบนสุดในการเรียก A 'make TARGET=whatever' ซึ่งหมายความว่าบิตที่เรียกใช้ซ้ำทั้งหมดของ build สืบทอดค่าของ TARGET เป็นตัวแปรแบบอ่านอย่างเดียว รวมถึงระบบ build จาก B ซึ่งถูกเรียกว่าเป็นส่วนหนึ่งของ โครงสร้างแบบเรียกซ้ำ

ฉันไม่ต้องการให้สิ่งนี้เกิดขึ้นในระบบบิลด์สำหรับ 'B' (ซึ่งมาจากโปรเจ็กต์อื่น) เนื่องจาก makefiles ที่นั่นใช้ TARGET เพื่อจุดประสงค์ของตนเองและบิลด์ล้มเหลวเนื่องจาก TARGET มีค่าผิดและเป็นแบบอ่านอย่างเดียว

ฉันมองเห็นวิธีแก้ปัญหานี้ได้เพียงสองวิธีเท่านั้น ซึ่งทั้งสองวิธีนั้นไม่สามารถทำได้

1) เปลี่ยนชื่อ TARGET เป็นอย่างอื่นใน makefile ใน A ที่ตั้งค่าและใน makefile ใน A ที่ใช้มัน เพื่อหลีกเลี่ยงการปะทะกับระดับล่างของระบบ build

2) ใช้คำสั่ง 'แทนที่' ทุกที่ใน makefiles ใน B ซึ่งมีการตั้งค่าตัวแปร TARGET เพื่อแทนที่สถานะอ่านอย่างเดียว

ใครมีความคิดที่ดีกว่านี้บ้างไหม? - โดยหลักการแล้ว ฉันต้องการให้ ไม่มีอะไร ได้รับการสืบทอดโดยระบบการสร้างของ B จาก A ยกเว้นตัวเลือกเหล่านั้นที่ฉันส่งผ่านไปยังระบบการสร้าง B จาก A อย่างชัดเจน

บังเอิญฉันใช้ GNU Make v3.80


person John Skilleter    schedule 01.06.2009    source แหล่งที่มา
comment
หากคุณไม่ต้องการตั้งค่า TARGET ใน makefile ของ B แล้วทำไมคุณถึงส่ง TARGET=whatever ใน makefile ของ A   -  person JesperE    schedule 01.06.2009
comment
makefile ระดับบนสุดของ A ส่งผ่าน TARGET=อะไรก็ตามไปยัง makefile ระดับที่สองใน A (ซึ่งต้องการมัน) และ makefile ระดับที่สองใน A จากนั้นเรียก makefile ของ B ซึ่งสืบทอด TARGET เป็นตัวแปรแบบอ่านอย่างเดียวจากสภาพแวดล้อมของวินาที - ทำระดับ   -  person John Skilleter    schedule 01.06.2009


คำตอบ (4)


คุณสามารถตั้งค่า MAKEOVERRIDES เป็นไม่มีอะไรใน makefile ระดับที่สองใน A

callb:
      cd subdir && $(MAKE) MAKEOVERRIDES=

สิ่งนี้จะส่งผ่านพารามิเตอร์บรรทัดคำสั่งปกติเช่น -k และ -s แต่ไม่ใช่คำจำกัดความของตัวแปรบรรทัดคำสั่ง

หรือคุณใช้ MFLAGS ที่ผ่านมาซึ่งเหมือนกับ MAKEFLAGS ยกเว้น MFLAGS ไม่มีคำจำกัดความตัวแปรบรรทัดคำสั่ง

callb:
     cd subdir && $(MAKE) $(MFLAGS)

รายละเอียดเกี่ยวกับสองตัวเลือกนี้สามารถอ่านได้ที่นี่: คู่มือการสร้าง GNU

person Community    schedule 03.06.2009

บางทีคุณสามารถใช้คำสั่ง "unexport" เพื่อป้องกันไม่ให้ TARGET แพร่กระจายไปยัง makefile ของ B ได้

person JesperE    schedule 01.06.2009
comment
น่าเสียดายที่คำสั่ง unexport ป้องกันไม่ให้ส่งออกตัวแปรที่ส่งออกโดยใช้การส่งออกเท่านั้น โดยจะไม่มีผลกระทบต่อตัวแปรที่ส่งผ่านบรรทัดคำสั่งไปยังกระบวนการ make ปัจจุบัน หรือสืบทอดจากบรรทัดคำสั่งของ make ระดับบนสุด ดูเหมือนว่าการตั้งค่าผ่านบรรทัดคำสั่ง make ทำให้เด็กทุกคนสร้างแบบอ่านอย่างเดียวอย่างทำลายไม่ได้ - person John Skilleter; 02.06.2009

ณ จุดที่ระบบบิลด์ A เรียกใช้ระบบบิลด์ B อย่าใช้ '${MAKE}' โดยตรง เรียกใช้เชลล์สคริปต์ที่เรียกใช้ระบบ build B (อาจเป็นไปได้หลังจากการฆ่าเชื้อสภาพแวดล้อม)

เพื่อให้บรรลุลักษณะการทำงานที่คำสั่งถูกดำเนินการโดย 'make -n' ให้นำหน้าบรรทัดคำสั่งใน makefile ด้วย '+' (คล้ายกับการขึ้นหน้าบรรทัดด้วย '@' หรือ '-')

person Jonathan Leffler    schedule 03.06.2009

ดูเหมือนว่าคุณได้แก้ไข A makefile เพื่อเรียกใช้ B makefile ซ้ำ ๆ และทำให้เกิดปัญหาของคุณ ทำไมไม่แนะนำ makefile ระดับบนสุดใหม่แทนซึ่งเรียกใช้ B makefile แบบวนซ้ำแล้วเรียกซ้ำ A makefile? ตัวอย่างเช่น integrated.mk:

all:
    $(MAKE) -f Makefile.B
    $(MAKE) -f Makefile.A

ด้วยวิธีนี้ B makefile จะไม่สืบทอดสิ่งใดจาก A makefile

person Eric Melski    schedule 09.11.2011