make: "Hepsi" için yapılacak bir şey yok


99

Bir make dosyası oluşturmak için örneğin bir pgm'den geçiyorum.

http://mrbook.org/tutorials/make/

Klasörüm eg_make_creation aşağıdaki dosyaları içerir,

desktop:~/eg_make_creation$ ls
factorial.c  functions.h  hello  hello.c  main.c  Makefile

Makefile

# I am a comment, and I want to say that the variable CC will be
# the compiler to use.
CC=gcc
# Hwy!, I am comment no.2. I want to say that CFLAGS will be the
#options I'll pass to the compiler
CFLAGS=-c -Wall

all:hello

hello:main.o factorial.o hello.o
  $(CC) main.o factorial.o hello.o -o hello

main.o:main.c
  $(CC) $(CFLAGS) main.c

factorial.o:factorial.c
  $(CC) $(CFLAGS) factorial.c

hello.o:hello.c
  $(CC) $(CFLAGS) hello.c

clean:
  rm -rf *o hello

hata:

desktop:~/eg_make_creation$ make all
make: Nothing to be done for `all'.

Lütfen bu programı derlemeyi anlamama yardım edin.


13
Önce "temizleme" ve ardından "tümünü yapma" yapmayı deneyin
Paul R

11
Bu bir hata değil, sadece hellogüncel olduğu anlamına geliyor . Değişim cleaniçin rm -f *.o hellobeklenmedik bir şey yapmadan önce, sonra çalıştırın make clean allve bu eserlerin bakın.
Mat

1
Ayrıca eklemek gerekir .phony: all clean, çünkü allve cleandosya adları değildir.
Kerrek SB

3
CFLAGS'nize -c koymayın.
wildplasser

Yanıtlar:


126

Bazen "Hepsi için hiçbir şey yapılmayacak" hatası tab yerine makefile kuralındaki komuttan önceki boşluklardan kaynaklanabilir. Lütfen kurallarınızın içinde boşluklar yerine sekmeler kullandığınızdan emin olun.

all:
<\t>$(CC) $(CFLAGS) ...

onun yerine

all:
    $(CC) $(CFLAGS) ...

Kural söz dizimi açıklaması için lütfen GNU yapma kılavuzuna bakın: https://www.gnu.org/software/make/manual/make.html#Rule-Syntax


obj-m + = merhaba.o all: </t> make -C / lib / modüller / $ (shell uname -r) / build M = $ (PWD) modülleri temizle: make -C / lib / module / $ ( kabuk uname -r) / build M = $ (PWD) temiz
Narendra Jaggi

yukarıdaki dosya geçerli bir dosya mı?
Narendra Jaggi

Üst-alt makefiles bağlamında, bazen "Hiçbir şey için yapılmayacak bir şey" hatası, alt Makefile dosyasında alt hedeflerin yanlış bir şekilde .PHONY olarak işaretlenmesinden kaynaklanabilir.
donhector

Ben de all : src/server/mod_wsgi.ladeğiştirdim all : </t> src/server/mod_wsgi.la. Şimdi şu hatayı alıyorum: make: execvp: src/server/mod_wsgi.la: Permission denied Makefile:29: recipe for target 'all' failed make: *** [all] Error 127sonra sudo make. Herhangi bir yardım?
Mooncrater

@Mooncrater Bkz. Gnu.org/software/make/manual/make.html#Rule-Syntax . Burada okur: Tarif satırları bir sekme karakteri ile başlar (veya .RECIPEPREFIX değişkeninin değerindeki ilk karakter; bkz. Özel Değişkenler). İlk tarif satırı, ön koşullardan sonraki satırda sekme karakteriyle veya aynı satırda noktalı virgülle görünebilir. Her iki durumda da etki aynıdır. Yani, ön koşulunuz basitçe tarif haline geldi. Bu durumda sekmeye ihtiyacınız yok.
VirtualVDX

31

helloDosyayı klasörünüzden kaldırın ve tekrar deneyin.

allHedef bağlıdır hellohedefin. helloHedef ilk dosya sisteminde karşılık gelen dosyayı bulmaya çalışır. Bulursa ve bağımlı dosyalarla güncelse, yapacak bir şey yoktur.


obj-m + = merhaba.o all: </t> make -C / lib / modüller / $ (shell uname -r) / build M = $ (PWD) modülleri temiz: make -C / lib / module / $ kabuk uname -r) / build M = $ (PWD) temiz
Narendra Jaggi

Yukarıdakiler geçerli bir yapım dosyası mı?
Narendra Jaggi

21

Sadece make komutunu verdiğinizde, makefile'nızdaki ilk kuralı yani "tümü" olur. "Hepsi" nin main.o, factorial.o ve hello.o'ya bağlı olan "merhaba" ya bağlı olduğunu belirttiniz. Yani 'make' bu dosyaların mevcut olup olmadığını görmeye çalışır.

Eğer mevcutlarsa, 'make' bağımlılıklarının, örneğin main.o'nun bir main.c bağımlılığı olup olmadığını görür. Değişmişlerse, onları yeniden inşa et, yoksa kuralı atlar. Benzer şekilde, değişen dosyaları oluşturmaya devam eder ve sonunda en üstteki komutu çalıştırır, sizin durumunuzda size bir yürütülebilir dosya, sizin durumunuzda 'merhaba' vermek için "hepsi".

Mevcut değillerse, her şeyi körü körüne kural altında inşa eder.

Sorununuza gelince, bu bir hata değil ama 'make', makefile'ınızdaki her bağımlılığın güncel olduğunu ve hiçbir şey yapmasına gerek olmadığını söylüyor!


16

Make doğru davranıyor. hellozaten var ve .cdosyalardan daha eski değil ve bu nedenle yapılacak daha fazla iş yok. Make'in (yeniden) inşa etmesi gereken dört senaryo vardır:

  • .cDosyalarınızdan birini değiştirirseniz , daha yeni olur hellove make'i çalıştırdığınızda yeniden oluşturulması gerekir.
  • Silerseniz hello, açıkça yeniden inşa etmesi gerekecektir.
  • Bu -Bseçenekle her şeyi yeniden oluşturmaya zorlayabilirsiniz .make -B all
  • make clean allsilinecek hellove yeniden oluşturma gerektirecek. (@ Mat'ın şu konu hakkındaki yorumuna bakmanızı öneririm.rm -f *.o hello

4

Sanırım 9. satırdaki bir sekmeyi kaçırdınız. Tümünü takip eden satır : merhaba boş bir sekme olmalıdır. 9. satırda boş bir sekmeniz olduğundan emin olun. Yorumlayıcının makefile için varsayılan tarifi kullanmak istediğinizi anlamasını sağlayacaktır.


4

Bu bir hata değildir; unix'teki make komutu zaman damgalarına göre çalışır. Diyelim ki üzerinde belirli değişiklikler yaptıysanız factorial.cppve kullanarak makederlediyseniz make sadece cc -o factorial.cppkomutun çalıştırıldığı bilgisini gösterir . Bir dahaki sefere aynı komutu, yani uzantıya makesahip herhangi bir dosyada herhangi bir değişiklik yapmadan .cppyürütürseniz, derleyici çıktı dosyasının güncel olduğunu söyler. Derleyici, biz herhangi birinde belirli değişiklikler yapana kadar bu bilgileri verir file.cpp.

Bunun avantajı makefile, yalnızca değiştirilen dosyaları derleyerek ve değiştirilmemiş .odosyaların object ( ) dosyalarını doğrudan kullanarak yeniden derleme süresini kısaltmasıdır .


0

Bu tuhaf, hata ayıklaması zor hataya farklı bir yoldan ulaştım. Benim sorunum, hedef ve bağımlılık farklı dizinlerde bulunduğunda bir oluşturma adımında bir kalıp kuralı kullanıyor olmamdı. Bunun gibi bir şey:

foo/apple.o: bar/apple.c $(FOODEPS)

%.o: %.c
    $(CC) $< -o $@

Bu şekilde birkaç bağımlılığım vardı ve hepsi için tek bir kalıp tarifi kullanmaya çalışıyordum. Açıkçası, "%" yerine tek bir ikame burada işe yaramayacak. Her bağımlılık için açık kurallar koydum ve kendimi yeniden yavru köpeklerin ve tek boynuzlu atların arasında buldum!

foo/apple.o: bar/apple.c $(FOODEPS)
    $(CC) $< -o $@

Umarım bu birine yardımcı olur!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.