2009-11-17 5 views
61

Existe-t-il un moyen de ligne de commande dans make pour déterminer les prérequis d'une cible qui ne sont pas mis à jour?Débogage de GNU make

+0

est pas là comme un mode bavard? Et est-ce que tu ne peux pas juste entrer un débogage 'echo' sur chaque cible pour comprendre ça? – Earlz

Répondre

85
make -d 

devrait vous donner plus que suffisamment d'informations pour déboguer votre makefile.

Soyez averti: cela prendra un peu de temps et d'effort pour analyser la sortie, mais charger la sortie dans votre éditeur favori et faire des recherches vous sera très utile.

Vous pouvez réduire considérablement la quantité de sortie de débogage si vous spécifiez la cible spécifique qui vous intéresse. Donc, si vous êtes seulement intéressé par la cible dodgy, au lieu de seulement make -d qui peut faire une centaine de choses différentes, essayez :

make clean 
make -d dodgy 

(en supposant que vous avez une cible clean bien sûr).

Le make --debug est identique à make -d mais vous pouvez également spécifier:

make --debug=FLAGS 

où les drapeaux peuvent être:

  • a pour tous le débogage (comme make -d et make --debug).
  • b pour le débogage de base.
  • v pour un débogage de base légèrement plus détaillé.
  • i pour les règles implicites.
  • j pour des informations d'invocation.
  • m pour l'information pendant les remakes de makefile.

Il ressemble à make --debug=b est la meilleure option pour ce dont vous avez besoin, comme le montre la transcription suivante:

[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

Une autre suggestion que si vous voulez vous débarrasser des règles implicites intégrées, vous pouvez utiliser le drapeau '-r' à côté du simple' -d'. –

17

Vous cherchez « essai » de Marque? Il imprimera ce que fait faire sans vraiment le faire, vous permettant de voir ce qui se passe. Le drapeau est -n, utilisez-le comme make -n.

+0

Ceci est mon préféré, '-d' est beaucoup trop verbeux (même' --debug = b'). Surtout si vous êtes coincé avec make récursive (pouah!). –

7

Votre question est un peu floue. Si vous voulez voir quels fichiers prérequis n'ont pas été modifiés récemment, utilisez ls -l pour voir leur heure de modification.Si vous voulez voir ce que make est en train de faire, essayez ceci:

 
# 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

J'allais suggérer $? aussi bien –

+0

Pas vraiment une solution en ligne de commande mais utile néanmoins. Vous pouvez éventuellement faire en ligne de commande en ne faisant les echos que si un env-var est défini. – paxdiablo

1

Quelques fois J'ai également utilisé this (ancien mais fonctionne toujours) débogueur interactif par John Graham-Cumming

5

Ce que je fais habituellement ne va pas en utilisant -d comme dit les précédents répondeurs.

I soit:

  1. Utilisez -p pour imprimer la base de données, pour voir quelles règles ont été créées. C'est pratique si vous avez des règles d'expansion secondes et que vous créez des règles à la volée, en particulier des marques récursives.
  2. Utilisation intensive de la fonction $ (info).
  3. Utilisez les conseils et astuces décrites dans cet article DrDobbs Debugging Makefiles

Voici un code que je utilise pour l'impression des valeurs:

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

J'utilise gnu make faire des modèles pour définir la établir des règles par cible;

Les modèles sont comme des macros qui écrivent les règles, ils sont expliqués ici https://www.gnu.org/software/make/manual/html_node/Eval-Function.html

cette fonction est utile lorsque vous avez un système de marque qui comprend un makefile de base pour générer toutes les règles par type de projet; s'il dit de faire une bibliothèque partagée alors il écrit les règles pour compiler une bibliothèque partagée; etc. pour d'autres types de cibles.

dans cet exemple: si vous ajoutez SHOW_RULES = 1 à la ligne de commande make, il affiche également le texte des règles générées par le PROGRAM_target_setup_template; avec la génération des règles eux-mêmes (avec 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 
  • $ (appel ...) appelle le modèle
  • $ (info ...) affiche le résultat de substitution de modèle; (Eval aurait invoqué l'analyse syntaxique de la sortie et l'ajout du fichier en cours make)

En savoir plus sur mon make fichiers ici: http://mosermichael.github.io/cstuff/all/projects/2011/06/17/make-system.html

Questions connexes