makefile รันเป้าหมายอื่น


123

ฉันมี makefile ที่มีโครงสร้างดังนี้:

all : 
    compile executable

clean :
    rm -f *.o $(EXEC)

ฉันตระหนักว่าฉันกำลังเรียกใช้ "make clean" อย่างสม่ำเสมอตามด้วย "clear" ในเทอร์มินัลของฉันก่อนที่จะเรียกใช้ "make all" ฉันชอบที่จะมีเทอร์มินัลที่สะอาดก่อนที่ฉันจะพยายามกรองข้อผิดพลาดในการคอมไพล์ C ++ ที่น่ารังเกียจ ดังนั้นฉันจึงพยายามเพิ่มเป้าหมายที่ 3:

fresh :
    rm -f *.o $(EXEC)
    clear
    make all

วิธีนี้ใช้งานได้ แต่นี่เป็นตัวอย่างที่สองของ make (ฉันเชื่อว่า) มีวิธีที่ถูกต้องในการรับฟังก์ชั่นเดียวกันโดยไม่ต้องใช้ make อินสแตนซ์ที่ 2 หรือไม่?

คำตอบ:


172

จริงๆแล้วคุณพูดถูกมันเรียกใช้ make อีกแบบ ทางออกที่เป็นไปได้คือ:

.PHONY : clearscr fresh clean all

all :
    compile executable

clean :
    rm -f *.o $(EXEC)

fresh : clean clearscr all

clearscr:
    clear

โดยการโทรหาmake freshคุณจะได้รับcleanเป้าหมายก่อนจากนั้นสิ่งclearscreenที่ทำงานclearและในที่สุดก็allทำงานได้

แก้ไข 4 ส.ค.

จะเกิดอะไรขึ้นในกรณีของการสร้างแบบขนานพร้อม-jตัวเลือกของ make ? มีวิธีแก้ไขคำสั่งซื้อ จากคู่มือการจัดทำส่วน 4.2:

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

ส่วนข้อกำหนดเบื้องต้นปกติอาจว่างเปล่า นอกจากนี้คุณยังสามารถประกาศข้อกำหนดเบื้องต้นหลายบรรทัดสำหรับเป้าหมายเดียวกันได้: มีการต่อท้ายอย่างเหมาะสม โปรดสังเกตว่าถ้าคุณประกาศว่าไฟล์เดียวกันเป็นทั้งสิ่งที่จำเป็นต้องมีตามปกติและตามคำสั่งเท่านั้นข้อกำหนดเบื้องต้นตามปกติจะมีความสำคัญเหนือกว่า (เนื่องจากเป็นส่วนเหนือที่เข้มงวดของลักษณะการทำงานของสิ่งที่จำเป็นต้องมีคำสั่งเท่านั้น)

ดังนั้น makefile จึงกลายเป็น

.PHONY : clearscr fresh clean all

all :
    compile executable

clean :
    rm -f *.o $(EXEC)

fresh : | clean clearscr all

clearscr:
    clear

แก้ไข 5 ธ.ค.

ไม่ใช่เรื่องใหญ่ที่จะรันมากกว่าหนึ่งอินสแตนซ์ makefile เนื่องจากแต่ละคำสั่งภายในงานจะเป็นsub-shellอย่างไรก็ตาม แต่คุณสามารถมีวิธีการที่นำมาใช้ใหม่โดยใช้ฟังก์ชั่นการโทร

log_success = (echo "\x1B[32m>> $1\x1B[39m")
log_error = (>&2 echo "\x1B[31m>> $1\x1B[39m" && exit 1)

install:
  @[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
  command1  # this line will be a subshell
  command2  # this line will be another subshell
  @command3  # Use `@` to hide the command line
  $(call log_error, "It works, yey!")

uninstall:
  @[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
  ....
  $(call log_error, "Nuked!")

6
@ sas4740: โดยพื้นฐานแล้วทุกอย่างต่อไปนี้.PHONY : จะถือว่าเป็นคำหลักบางคำที่ได้รับการดำเนินการเสมอในขณะที่เป้าหมายที่ไม่ใช่ของปลอมมีจุดมุ่งหมายเพื่อเป็นไฟล์
Dacav

"ข้อกำหนดเบื้องต้นสำหรับคำสั่งซื้อเท่านั้น" มีเงื่อนไขหรือไม่ สำหรับเป้าหมาย t2 ฉันต้องการทำ t0 ก่อนมากกว่าก็ต่อเมื่อ t0 ประสบความสำเร็จในการรัน t1 และเฉพาะในกรณีที่ทั้งสองประสบความสำเร็จรันงานบางอย่างใน t3
fantastory

1
@fantastory ไม่ฉันคิดว่าพวกเขาเป็นอิสระ t2จะขึ้นอยู่กับt0, และt1 t3หากคุณต้องการนี้คุณควรใส่ t3ตามที่กำหนดไว้t2, t1ตามที่กำหนดไว้t3และตามที่กำหนดไว้t0 t1ซึ่งหมายถึงกฎ 3 ข้อที่แตกต่างกัน คุณควรตรวจสอบสิ่งนี้อย่างไรก็ตาม ฉันไม่แน่ใจ 100%
Dacav

3
"ข้อกำหนดเบื้องต้นสำหรับคำสั่งซื้อเท่านั้น" เป็นอิสระ
เพ้อฝัน

2
ฉันไม่เห็นการรับประกันว่า 'สะอาด' มีประสิทธิภาพก่อน 'ทั้งหมด' อยู่ที่ไหน ความจริงที่ว่าคุณนำมาจาก | ไม่ทำให้พวกเขาดำเนินการตามลำดับ การพึ่งพาคำสั่งซื้อเท่านั้นหมายความว่าเป้าหมายไม่จำเป็นต้องได้รับการอัพเดตหลังจากการดำเนินการดังกล่าว ไม่มีอะไรเกี่ยวข้องกับการจัดลำดับองค์ประกอบที่ขึ้นต่อกัน ... หรือ?
CygnusX1

6

หากคุณลบmake allบรรทัดออกจากเป้าหมาย "ใหม่" ของคุณ:

fresh :
    rm -f *.o $(EXEC)
    clear

คุณสามารถเรียกใช้คำสั่งmake fresh allซึ่งจะดำเนินการเป็นmake fresh; make allไฟล์.

บางคนอาจคิดว่านี่เป็นตัวอย่างที่สองของการทำ แต่ก็ไม่ใช่ตัวอย่างย่อยของการทำ (make inside of a make) ซึ่งเป็นความพยายามของคุณที่ดูเหมือนจะเป็นผล

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.