2009-11-17 24 views
61

Esiste un modo riga di comando in make per scoprire quale dei prerequisiti di una destinazione non viene aggiornato?Debugging GNU make

+0

non è lì come una modalità dettagliata? E non puoi semplicemente inserire un po 'di echo' di debug su ciascun target per capirlo? – Earlz

risposta

85
make -d 

dovrebbe darvi ulteriori di informazioni sufficienti per eseguire il debug del makefile.

Attenzione: ci vorrà un po 'di tempo e fatica per analizzare l'output ma caricare l'output nel tuo editor preferito e fare ricerche sarà di grande aiuto.

È possibile ridurre notevolmente la quantità di output di debug se si specifica l'obiettivo specifico che ti interessa. Quindi, se siete interessati solo alla dodgy bersaglio, invece di make -d che può rendere un centinaio di cose diverse, provare :

make clean 
make -d dodgy 

(ammesso che abbiate un clean bersaglio ovviamente).

Il make --debug è identico a make -d, ma è anche possibile specificare:

make --debug=FLAGS 

dove le bandiere possono essere:

  • a per tutti debug (lo stesso make -d e make --debug).
  • b per il debug di base.
  • v per un debug di base leggermente più dettagliato.
  • i per le regole implicite.
  • j per informazioni di chiamata.
  • m per informazioni durante i remake del makefile.

Sembra make --debug=b è l'opzione migliore per quello che ti serve, come mostrato nella seguente trascrizione:

[email protected]> cat makefile 
c:a b 
    touch c 

[email protected]> touch a b ; make 
touch c 

[email protected]> make 
make: 'c' is up to date. 

[email protected]> touch a ; make --debug=b 
GNU Make 3.81 
Copyright (C) 2006 Free Software Foundation, Inc. Blah, blah, blah. 
Reading makefiles... 
Updating goal targets.... 
Prerequisite 'a' is newer than target 'c'. 
Must remake target 'c'. 
touch c 
Successfully remade target file 'c'. 
+4

Un altro suggerimento che se vuoi eliminare regole implicite incorporate, puoi usare il flag '-r' a fianco di' -d'. –

17

Sei alla ricerca di "prova generale" del Marchio? Stamperà ciò che fa il fare senza farlo, permettendoti di vedere cosa succede.

La bandiera è -n, utilizzare come make -n.

+0

Questo è il mio preferito, '-d' è troppo prolisso (anche' --debug = b'). Soprattutto se sei bloccato con fare ricorsivo (ugh!). –

7

La tua domanda non è chiara. Se vuoi vedere quali file prerequisiti non sono stati modificati di recente, usa ls -l per vedere il loro tempo di modifica.Se volete vedere che cosa rendere sta facendo, provate questo:

 
# Make will announce when it is making this target, and why. 
sometarget: preq1 preq2 preq3 
    @echo making [email protected] 
    @echo The following preqs are newer than the target: $? 
    do_things 
+0

Stavo per suggerire $? pure –

+0

Non proprio una soluzione da riga di comando ma utile comunque. Si potrebbe creare una riga di comando basandosi solo sugli echos solo se è impostato un env-var. – paxdiablo

1

Poche volte Ho anche usato this (vecchio ma funzionante) debugger di make interattivo di John Graham-Cumming

5

Quello che faccio di solito non va usando -d come hanno detto i precedenti rispondenti.

mi sia:

  1. Usa -p per stampare il database, per vedere quali sono state create regole. Questo è utile se si hanno le seconde regole di espansione e si stanno creando regole al volo, specialmente per la marca ricorsiva.
  2. Uso pesante della funzione $ (info).
  3. Utilizzare i suggerimenti e trucco descritti in questo articolo DrDobbs Debugging Makefiles

Di seguito è riportato un codice che sto utilizzando per la stampa di valori:

define pv 
$(info $(1) [$(origin $(1))] : >|$($(1))|<) 
endef 

define pva 
$(foreach t,$(1),$(call pv,$(t))) 
endef 

define itemizer 
$(foreach t,$($(1)),$(info $(t))) 
endef 
0

sto usando rendere GNU make modelli per definire la fare regole per target;

I modelli sono come le macro che scrivono le regole, che sono spiegati qui https://www.gnu.org/software/make/manual/html_node/Eval-Function.html

questa funzione è utile quando si dispone di un sistema di marca che include un makefile nucleo di generare tutte le regole per tipo di progetto; se dice di fare una libreria condivisa, scrive le regole per compilare una libreria condivisa; ecc. per altri tipi di obiettivi.

in questo esempio: se si aggiunge SHOW_RULES = 1 alla riga di comando make, viene visualizzato anche il testo delle regole generate da PROGRAM_target_setup_template; insieme a generare le regole stesse (con eval).

# this one defines the target for real 
$(foreach prog, $(TARGETS), $(eval $(call PROGRAM_target_setup_template,$(prog)))) 

ifneq "$(SHOW_RULES)" "" 
$(foreach prog, $(TARGETS), $(info $(call PROGRAM_target_setup_template,$(prog)))) 
endif 
  • $ (chiamare ...) richiama il modello
  • $ (info ...) stampa il risultato della sostituzione del modello; (Eval avrebbe invocato l'analisi della produzione e oltre al file make corrente)

di più sulla mia rendere i file qui: http://mosermichael.github.io/cstuff/all/projects/2011/06/17/make-system.html

Problemi correlati