make: Niente da fare per "tutti"


98

Sto passando per un pgm ad esempio per creare un file make.

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

La mia cartella eg_make_creation contiene i seguenti file,

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

errore:

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

Per favore aiutami a capire come compilare questo programma.


12
Prova a fare un "make clean" seguito da un "make all"
Paul R

11
Non è un errore, significa solo che helloè aggiornato. Passa cleana rm -f *.o helloprima che faccia qualcosa di inaspettato, quindi corri make clean alle vedi se funziona.
Mat

1
Dovresti anche aggiungere .phony: all clean, poiché alle cleannon sono nomi di file.
Kerrek SB

3
Non mettere la -c nelle tue CFLAGS.
wildplasser

Risposte:


123

A volte l'errore "Niente da fare per tutti" può essere causato da spazi prima del comando nella regola makefile invece che da tabulazione. Assicurati di utilizzare le tabulazioni invece degli spazi all'interno delle tue regole.

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

invece di

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

Si prega di consultare il manuale GNU make per la descrizione della sintassi delle regole: https://www.gnu.org/software/make/manual/make.html#Rule-Syntax


obj-m + = hello.o all: </t> make -C / lib / modules / $ (shell uname -r) / build M = $ (PWD) moduli puliti: make -C / lib / modules / $ ( shell uname -r) / build M = $ (PWD) clean
Narendra Jaggi

il file sopra è un file valido ??
Narendra Jaggi

Nel contesto dei makefile padre-figlio, a volte l'errore "Niente da fare per tutti" può essere causato da destinazioni figlio contrassegnate in modo errato .PHONY dichiarato nel Makefile padre.
donhector

Avevo all : src/server/mod_wsgi.la, che ho cambiato all : </t> src/server/mod_wsgi.la. Ora ottengo l'errore: make: execvp: src/server/mod_wsgi.la: Permission denied Makefile:29: recipe for target 'all' failed make: *** [all] Error 127dopo sudo make. Qualsiasi aiuto?
Mooncrater

@Mooncrater Vedi gnu.org/software/make/manual/make.html#Rule-Syntax . Qui si legge: Le righe della ricetta iniziano con un carattere di tabulazione (o il primo carattere nel valore della variabile .RECIPEPREFIX; vedere Variabili speciali). La prima riga della ricetta può apparire sulla riga dopo i prerequisiti, con un carattere di tabulazione, oppure può apparire sulla stessa riga, con un punto e virgola. In ogni caso, l'effetto è lo stesso. Quindi, il tuo prerequisito è diventato semplicemente la ricetta. In questo caso non è necessaria alcuna scheda.
VirtualVDX

31

Rimuovi il hellofile dalla cartella e riprova.

Il alltarget dipende dal hellotarget. Il hellotarget cerca prima di trovare il file corrispondente nel filesystem. Se lo trova ed è aggiornato con i file dipendenti, non c'è niente da fare.


obj-m + = hello.o all: </t> make -C / lib / modules / $ (shell uname -r) / build M = $ (PWD) moduli puliti: make -C / lib / modules / $ ( shell uname -r) / build M = $ (PWD) clean
Narendra Jaggi

quello sopra è un make file valido?
Narendra Jaggi

21

Quando dai solo make, crea la prima regola nel tuo makefile, cioè "all". Hai specificato che "all" dipende da "hello", che dipende da main.o, factorial.o e hello.o. Quindi "make" cerca di vedere se quei file sono presenti.

Se sono presenti, "make" vede se le loro dipendenze, ad esempio main.o ha una dipendenza main.c, sono cambiate. Se sono cambiati, fai ricostruirli, altrimenti salta la regola. Allo stesso modo, continua a costruire in modo ricorsivo i file che sono stati modificati e alla fine esegue il comando più in alto, "all" nel tuo caso per darti un eseguibile, 'hello' nel tuo caso.

Se non sono presenti, costruisci ciecamente costruisce tutto sotto regola.

Venendo al tuo problema, non è un errore ma 'make' sta dicendo che ogni dipendenza nel tuo makefile è aggiornata e non ha bisogno di fare nulla!


16

Make si sta comportando correttamente. helloesiste già e non è più vecchio dei .cfile, quindi non c'è più lavoro da fare. Ci sono quattro scenari in cui make dovrà (ri) costruire:

  • Se modifichi uno dei tuoi .cfile, sarà più recente di hello, quindi dovrà essere ricostruito quando esegui make.
  • Se elimini hello, ovviamente dovrà ricostruirlo
  • Puoi forzare make a ricostruire tutto con l' -Bopzione.make -B all
  • make clean alleliminerà helloe richiederà una ricostruzione. (Ti suggerisco di guardare il commento di @ Mat surm -f *.o hello

4

Penso che ti sei perso una scheda nella nona riga. La riga che segue tutto: ciao deve essere una scheda vuota. Assicurati di avere una scheda vuota nella nona riga. Farà capire all'interprete che vuoi usare la ricetta predefinita per il makefile.


4

Non è un errore; il comando make in unix funziona in base ai timestamp. Ad esempio, diciamo che se hai apportato alcune modifiche factorial.cppe hai compilato usando, makemake mostra le informazioni che cc -o factorial.cppviene eseguito solo il comando. La prossima volta se esegui lo stesso comando, cioè makesenza apportare modifiche a nessun file con .cppestensione, il compilatore dice che il file di output è aggiornato. Il compilatore fornisce queste informazioni fino a quando non apportiamo determinate modifiche a any file.cpp.

Il vantaggio di makefileè che riduce il tempo di ricompilazione compilando gli unici file che vengono modificati e utilizzando direttamente i .ofile object ( ) dei file non modificati.


0

Sono arrivato a questo errore particolare e difficile da eseguire il debug attraverso un percorso diverso. Il mio problema è finito per essere che stavo usando una regola di pattern in una fase di compilazione quando l'obiettivo e la dipendenza si trovavano in directory distinte. Qualcosa come questo:

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

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

Avevo diverse dipendenze impostate in questo modo e stavo cercando di utilizzare una ricetta di pattern per tutte. Chiaramente, una singola sostituzione per "%" non funzionerà qui. Ho stabilito regole esplicite per ogni dipendenza e mi sono ritrovato tra i cuccioli e gli unicorni!

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

Spero che questo aiuti qualcuno!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.