Kenapa dipikir targetnya up to date?


224

Ini Makefile saya:

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

Saya bisa berlari make compilebeberapa kali dan mendapatkan

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

Namun, untuk beberapa alasan berlari make testselalu memberi

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

bahkan jika file tidak dikompilasi. Pertanyaannya adalah, mengapa?

Menjalankan perintah yang sama secara langsung berfungsi:

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)
...

Jawaban:


460

Mungkin Anda memiliki nama file / direktori testdi direktori. Jika direktori ini ada, dan tidak memiliki dependensi yang lebih baru, maka target ini tidak dibangun kembali.

Untuk memaksa membangun kembali target semacam ini yang tidak terkait file, Anda harus membuatnya palsu sebagai berikut:

.PHONY: all test clean

Perhatikan bahwa Anda dapat mendeklarasikan semua target palsu Anda di sana.


2
Saya memiliki direktori bernama build dan lib lain yang disebut. Jika diperhatikan, ini bukan nama target yang sempurna. Ugh ..... buat.
MattD

9
* Di mana all,, testdan clearapakah nama target makefile Anda
ThorSummoner

Solusi lain adalah mengubah label. Dalam kasus Anda, mengubah testuntuk test_ruleatau sesuatu yang berbeda.
auraham

@ Matt begitu juga saya, apakah itu masalah buat?
gromit190

@Birger jika Anda memiliki target yang ingin Anda panggil seperti "make build" dan "make lib" dan Anda memiliki direktori tersebut, maka Anda perlu menggunakan strategi ini atau yang sejenisnya.
MattD

34

EDIT: Ini hanya berlaku untuk beberapa versi make- Anda harus memeriksa halaman manual Anda.

Anda juga dapat meneruskan -Bbendera ke make. Sesuai halaman manual, ini tidak:

-B, --always-make Tanpa syarat membuat semua target.

Jadi make -B testakan menyelesaikan masalah Anda jika Anda berada dalam situasi di mana Anda tidak ingin mengedit Makefileatau mengubah nama folder tes Anda.


-Badalah mode kompatibel-mundur untuk saya ... (FreeBSD, OS / GNU toolkit tampaknya tidak ditentukan dalam pertanyaan)
Gert van den Berg

Oh menarik ... Apakah --always-makeberhasil untuk Anda?
jamesc

Nggak. The .PHONYTarget tampaknya jenis meskipun portabel ... (Setidaknya untuk FreeBSD, tidak yakin tentang hal-hal seperti Solaris)
Gert van den Berg

1
Ini menentang tujuan membuat - menentukan secara otomatis potongan program mana yang perlu dibangun kembali setelah perubahan. Jika makefile Anda membutuhkan --always-makeopsi untuk bekerja, makefile Anda rusak.
osvein

1
@GertvandenBerg .PHONY akan menjadi bagian dari edisi 8 dari standar POSIX austingroupbugs.net/view.php?id=523
osvein

10

Itu terjadi ketika Anda memiliki file dengan nama yang sama dengan nama target Makefile di direktori di mana Makefile hadir.

masukkan deskripsi gambar di sini


Ini masalah saya. Terima kasih!
Aidan Rosswood

1

kesalahan saya adalah membuat nama target "filename.c:" bukan hanya "filename:"

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.