Debugging the Makefile / part 2 /

Debugging methods



In this part, we will talk about common debugging techniques and problems. Ultimately, debugging is a hodgepodge of everything that works in a given situation. These methods work for me and have to rely on them even in case of problems with the simplest makefiles . Maybe they will help you too.







Debugging the Makefile / part 1 /







One very annoying bugs in make



3.80 was the error message in the makefile , where make



the line number and usually the line number was incorrect. I didn't bother to investigate why this problem occurs: because of imported files, assignments to multi-line variables, or because of custom macros. Usually, make



gives a line number greater than it should. In complex makefiles, it happens that the number does not coincide by 20 lines.







Often the easiest way to see the value of a variable is to print it out during the execution of the target. While it is easy to print with help warning



, in the long run it can save a lot of time a little effort adding a general purpose debug



for outputting variables. Here's some example target code debug



:







debug:
       $(for v,$(V), \
         $(warning $v = $($v)))
      
      





, debug



:







$ make V="USERNAME SHELL" debug
makefile:2: USERNAME = Owner
makefile:2: SHELL = /bin/sh.exe
make: debug is up to date.
      
      





, MAKECMDGOALS



, V



:







debug:
       $(for v,$(V) $(MAKECMDGOALS), \
         $(if $(filter debug,$v),,$(warning $v = $($v))))
      
      





. , , make



( ) :







$ make debug PATH SHELL
makefile:2: USERNAME = Owner
makefile:2: SHELL = /bin/sh.exe
make: debug is up to date.
make: *** No rule to make target USERNAME. Stop.
      
      





make



, shell



. , , , . โ€” :







DATE := $(shell date +%F)
OUTPUT_DIR = out-$(DATE)
make-directories := $(shell [ -d $(OUTPUT_DIR) ] || mkdir -p $(OUTPUT_DIR))
all: ;
      
      





sh



, :







$ make SHELL="sh -x"
+ date +%F
+ '[' -d out-2004-05-11 ']'
+ mkdir -p out-2004-05-11
      
      





, .







, , :







FIND_TOOL = $(firstword $(wildcard $(addsuffix /$(1).exe,$(TOOLPATH))))
      
      





. :







$(warning $(TOOLPATH))
$(warning $(addsuffix /$(1).exe,$(TOOLPATH)))
$(warning $(wildcard $(addsuffix /$(1).exe,$(TOOLPATH))))
      
      





, ( ) .









make



make



. . , , make



, , . .







make



:







    makefile:n: *** message. Stop
      
      





:







    make:n: *** message. Stop.
      
      





makefile โ€” . โ€” , , , , , .







, make



, , makefile . , - , - . , โ€” . , make



.









: , , .







make



:







foo:
     for f in $SOURCES; \
     do                 \
        โ€ฆ               \
     done
      
      





, make



$S



, OURCES



f



. , f



, :







    OURCES: No such file or directory
      
      





. โ€” .







missing separator



:







    makefile:2:missing separator. Stop.
      
      





( GNU make โ€” .):







    makefile:2:missing separator (did you mean TAB instead of 8 spaces?). Stop.
      
      





make



, :, =, . , - .







commands commence before first target



makefile, ( ). make



, , , , make



.







unterminated variable reference



, . , . make



Lisp! , , Emacs.









: , , , .







" ", .







:







    bash: foo: command not found
      
      





, foo



. , PATH



. , PATH



, .profile (Bourne shell), .bashrc (bash) .cshrc (C shell). , PATH



makefile, PATH



make



.







, . , make



:







$ make
touch /foo/bar
touch: creating /foo/bar: No such file or directory
make: *** [all] Error 1
      
      





touch



, . โ€” make



. makefile , . , , make



.







, @



. .







make



, make



.







No Rule to Make Target



:







    make: *** No rule to make target XXX. Stop.
      
      





:







    make: *** No rule to make target XXX, needed by YYY. Stop.
      
      





, make



XXX, make



. make



.







:







  • makefile . .
  • makefile โ€” . make



    . makefile , . make



    .
  • , make



    - , , make



    . , make



    . โ€” VCS. , make



    - , - . , .







    Overriding Commands for Target



    make



    ( ยซ::ยป , ). , make



    :







    makefile:5: warning: overriding commands for target foo
          
          





    :







    makefile:2: warning: ignoring old commands for target foo
          
          





    , ; .









makefile , . , , .







, :







# Create a jar file.
$(jar_file):
        $(JAR) $(JARFLAGS) -f $@ $^
      
      





makefile . makefile:







# Set the target for creating the jar and add prerequisites
jar_file = parser.jar
$(jar_file): $(class_files)
      
      





If you inadvertently add a command script to such a makefile , an make



override warning will be issued.








All Articles