4.2 Read-Time Debugging

To illustrate the process of debugging a makefile, the following command was executed:

omake -ndf demo -p -#1 CV=

This is the content of makefile demo:

# List of modules, and target name.
#
TARGET = project.exe
OBJS = a.obj b.obj

# If CV is defined, compile for debug

#

%if defined(CV)

CFLAGS = -Od -Z7

# compile for debug

LINKFLAGS = -debug -debugtype:both

%else

CFLAGS = -Ox

# compile for size

LINKFLAGS =

# no special link flags

%endif

# The default target in the makefile
#
$(TARGET) : $(OBJS)

# Additional dependency informationyou think they should
#
b.obj : $(TARGET,B).h

PATH.h = .;C:\SRC\H

Output Produced by -#1

For the purposes of this example, an empty make.ini file was created. Here is the output, with annotations in italics.

First, the initialization file make.ini is read:

*** Read make.ini ***

(Start reading the make.ini file)

*** Done make.ini ***

(Done reading the make.ini file)

Next, the makefile demo is read:

*** Read demo ***

(Start reading the demo file)

+

("+" if more than one blank or comment line was skipped)

3: TARGET = project.exe

("num: " identifies current line number)

4: OBJS = a.obj b.obj

+

8: %if defined(CV)

(Conditional directive is shown

:---> true

and evaluated)

9: CFLAGS = -Od -Z7

(Conditional was true, so this line and

10: LINKFLAGS = -debug -debugtype:both

this line are processed)

11: %else

(End of first true conditional block)

14: %endif

(Lines are skipped until the "%endif")

+

18: $(TARGET) : $(OBJS)

(The default makefile target)

+

21: b.obj : $(TARGET,B).h

(An additional dependency)

+

23: .PATH.h = .;C:\SRC\H

*** Done demo ***

(Done reading the "demo" file)

Output Produced by -p

Following output by the -#1 option, -p prints out information internal to omake, including facts about macros, targets, search directories, and inference rules. The output begins with this line:

*** Begin print out ***

(Starts the -p printout)

The Macro Definitions

The first block of output is the macro definitions including the names and values of macros and the location they were defined. The location is any of the following:

built in

Defined by omake, but changeable by you

predefined

Defined by omake, but cannot be changed by you

command line

Defined by you on the omake command line

file:number

Defined by you in makefile file on line number

For brevity, most omake state macros have been omitted from this list:

.DEBUG_PRINT

=

1

# predefined

(state macro: the -p flag)

.omake

=

1

# predefined

(state macro: emulation)

BUILTINS

=

C:\Program Files\Rational\ClearCase\bin\ make.ini

# predefined

(name of the built-ins file)

CC

=

cl

# built in

(name of the C compiler)

CFLAGS

=

-Od -Z7

# demo:9

(C compiler flags)

CV

=

# command line

(command-line macro)

IMPLIB

=

lib

# built in

LINK

=

link

# built in

(name of linker)

LINKFLAGS

=

-debug -debugtype:both

# demo:10

(linker flags)

MAKE

=

C:\Program Files\Rational\ClearCase\bin\ omake.EXE

# built in

(make location)

MAKEARGS

=

-ndf demo -p -#1 CV=

# predefined

(make command line)

MAKEDIR

=

C:\SRC

# predefined

(make starting directory)

MAKEFILE

=

demo

# command line

(name of the makefile)

MAKEFLAGS

=

dnp -#1

# predefined

MAKEMACROS

=

CV=" "

# predefined

MAKEVERSION

=

200

# predefined

(make version)

MFLAGS

=

-dnp -#1

# predefined

(command-line flags)

OBJS

=

a.obj b.obj

# demo:4

OPUS

=

1

# predefined

(you know this is OPUS)

OS

=

NT

# built in

(name of OS)

TARGET

=

project.exe

# demo:3

The Search Directories

The search directories output lists both the extension-specific and nonspecific search directories. The extension-specific directories are listed first:

*** Search directories ***
for .h : .\ C:\SRC\H\
all other files : .\

A .PATH macro is not defined, so all other files are searched for only in the current directory.

The Automatic Response Definitions

Following the search directories are all automatic response file definitions. Each line of output of this section appears in exactly the form needed as if it were input to omake.

*** Automatic responses ***
.RESPONSE.WCC386: env=WCC386 pre=-u in=1024 wcc386
.RESPONSE.LINT: suf=.lnt out=76 in=1024 lint
.RESPONSE.STD: pre=@ suf=.rsp out=76 in=1024 wpp386 cl386 cl lib32 lib link32

The Inference Rules

Following the automatic response definitions is the list of inference rules:

*** Inference rules ***
* Suffix rules *
%.obj : %.c
defined in: internal
$(CC) $(CFLAGS) -c $(.SOURCE)

%.obj : %.cpp
defined in: internal
$(CPP) $(CPPFLAGS) -c $(.SOURCE)

%.obj : %.asm
defined in: internal
$(AS) $(AFLAGS) $(.SOURCE);

%.obj : %.for
defined in: internal
$(FC) $(.SOURCE) $(FFLAGS)

%.res : %.rc
defined in: internal
$(RC) $(RFLAGS) -r $(.SOURCE);

%.exe : %.obj
defined in: internal
%do %.exe

* Meta rules *
%.lib :
defined in: internal
%if ! %null(.NEWSOURCES)
%if %exists(${.TARGET})
$(IMPLIB) -OUT:$(.TARGET) $(LIBFLAGS) $(.NEWSOURCES) $(.TARGET)
%else
$(IMPLIB) -OUT:$(.TARGET) $(LIBFLAGS) $(NEWSOURCES)
%endif
%endif

%.exe :
defined in: internal
$(LINK) -OUT:$(.TARGET) $(LINKFLAGS) $(.SOURCES) $(LINKLIBS)

The *Suffix rules* are rules that can be of the form .fromExt.toExt. The *Meta rules* are all other inference rules.

The Targets and Build Scripts

A list of the targets follows the inference rules. The default target is listed first.

*** Targets and commands ***

>>> default target <<<

(The first target in the makefile)

project.exe : a.obj b.obj

(project.exe depends on a.obj & b.obj)

b.obj : project.h

(b.obj depends on project.h)

The Final -p Output

Finally, after all -p output has appeared, you see this message:

*** Done print out ***