ทำไมถึงคิดว่าเป้าหมายเป็นปัจจุบัน?


224

นี่คือ Makefile ของฉัน:

REBAR=./rebar
REBAR_COMPILE=$(REBAR) get-deps compile

all: compile

compile:
    $(REBAR_COMPILE)

test:
    $(REBAR_COMPILE) skip_deps=true eunit

clean:
    -rm -rf deps ebin priv doc/*

docs:
    $(REBAR_COMPILE) doc

ifeq ($(wildcard dialyzer/sqlite3.plt),)
static:
    $(REBAR_COMPILE) build_plt analyze
else
static:
    $(REBAR_COMPILE) analyze
endif

ฉันสามารถวิ่งได้make compileหลายครั้งและรับ

aromanov@alexey-desktop:~/workspace/gm-controller/lib/erlang-sqlite$ make compile
./rebar get-deps compile
==> erlang-sqlite (get-deps)
==> erlang-sqlite (compile)

อย่างไรก็ตามด้วยเหตุผลบางอย่างการทำงานmake testมักจะให้

aromanov@alexey-desktop:~/workspace/gm-controller/lib/erlang-sqlite$ make test
make: `test' is up to date.

แม้ว่าไฟล์จะไม่ถูกรวบรวม คำถามคือทำไม

การรันคำสั่งเดียวกันทำงานได้โดยตรง:

aromanov@alexey-desktop:~/workspace/gm-controller/lib/erlang-sqlite$ ./rebar get-deps compile skip_deps=true eunit
==> erlang-sqlite (get-deps)
==> erlang-sqlite (compile)
Compiled src/sqlite3_lib.erl
Compiled src/sqlite3.erl
==> erlang-sqlite (eunit)
...

คำตอบ:


460

บางทีคุณอาจมีชื่อไฟล์ / ไดเรกทอรีtestในไดเรกทอรี หากไดเร็กทอรีนี้มีอยู่และไม่มีการพึ่งพาที่ล่าสุดกว่าเป้าหมายนี้จะไม่สร้างใหม่

ในการบังคับให้สร้างใหม่บนเป้าหมายที่ไม่เกี่ยวข้องกับไฟล์ประเภทนี้คุณควรทำให้มันเป็นของปลอมดังต่อไปนี้:

.PHONY: all test clean

โปรดทราบว่าคุณสามารถประกาศเป้าหมายปลอมทั้งหมดของคุณที่นั่น


2
ฉันมีไดเรกทอรีที่ชื่อว่า build และอีกอันเรียกว่า lib ในความเข้าใจย้อนหลังสิ่งเหล่านี้ไม่ใช่ชื่อเป้าหมายที่สมบูรณ์แบบ ฮึ ..... ทำให้
MattD

9
* ที่ไหนall, testและclearเป็นชื่อเป้าหมาย makefile ของคุณ
ThorSummoner

อีกวิธีคือเปลี่ยนฉลาก ในกรณีของคุณเปลี่ยนtestสำหรับtest_ruleหรือบางสิ่งบางอย่างที่แตกต่างกัน
auraham

@MattD ฉันทำแบบนั้นเป็นปัญหาไหม
gromit190

@Birger หากคุณมีเป้าหมายที่คุณต้องการเรียกเช่น "make build" และ "make lib" และคุณมีไดเรกทอรีเหล่านั้นอยู่แล้วคุณจะต้องใช้กลยุทธ์นี้หรือหนึ่งในนั้น
MattD

34

แก้ไข: สิ่งนี้ใช้ได้กับบางเวอร์ชันเท่านั้นmake- คุณควรตรวจสอบ man page ของคุณ

นอกจากนี้คุณยังสามารถผ่านธง-B makeตามหน้า man นี้จะ:

-B, --always-make สร้างเป้าหมายทั้งหมดโดยไม่มีเงื่อนไข

ดังนั้นmake -B testจะแก้ปัญหาของคุณหากคุณอยู่ในสถานการณ์ที่คุณไม่ต้องการแก้ไขMakefileหรือเปลี่ยนชื่อโฟลเดอร์ทดสอบของคุณ


-Bเป็นโหมดย้อนหลังที่เข้ากันได้สำหรับฉัน ... (FreeBSD, OS / GNU ชุดเครื่องมือไม่ได้ระบุไว้ในคำถาม)
Gert van den Berg

โอ้น่าสนใจ ... --always-makeทำงานให้คุณได้ไหม?
jamesc

Nope .PHONYเป้าหมายดูเหมือนว่าชนิดของแบบพกพา ... (อย่างน้อยเพื่อ FreeBSD, ไม่แน่ใจเกี่ยวกับสิ่งที่ชอบ Solaris)
Gert van den Berg

1
สิ่งนี้ท้าทายวัตถุประสงค์ของการพิจารณาโดยอัตโนมัติว่าโปรแกรมชิ้นใดที่จำเป็นต้องสร้างใหม่หลังจากการเปลี่ยนแปลง หาก makefile ของคุณต้องการ--always-makeตัวเลือกในการทำงาน makefile ของคุณจะไม่ทำงาน
osvein

1
@GertvandenBerg .PHONY จะเป็นส่วนหนึ่งของปัญหา 8 ของมาตรฐาน POSIX austingroupbugs.net/view.php?id=523
osvein

10

มันเกิดขึ้นเมื่อคุณมีไฟล์ที่มีชื่อเดียวกันกับชื่อเป้าหมาย Makefile ในไดเรกทอรีที่มีไฟล์ Makefile

ป้อนคำอธิบายรูปภาพที่นี่


นี่เป็นปัญหาของฉัน ขอบคุณ!
Aidan Rosswood

1

ความผิดพลาดของฉันคือทำให้ชื่อเป้าหมาย "filename.c:" แทนที่จะเป็น "filename:"

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