Debug flags

An important feature of tmake is the high level of introspection provided to determine what tmake is doing and why. The available debug flags can be displayed.

$ tmake -d?
Debugging can be enabled with -d...
The debugging categories are as follows:

	*	Enable all debug
	?	Display help for debug types
	d	Dynamic dependencies
	D	Dynamic dependencies (detailed)
	n	Reasons for targets NOT built
	b	Reasons for targets BUILT
	B	Reasons for targets BUILT - changed commands or targets
	r	Display rules when triggered
	g	Depencency graph for each target
	G	List goals (targets) as they are attempted
	h	Show hashing
	p	Print rules while parsing
	m	Miscellaneous (locating and parsing of files)
	l	Locating sources and targets
	c	Configuration expressions via ifconfig
	C	Cache handling
	T	Timing (add --delta for delta times)
	v	Variable definition
	j	Parallel (job-based) builds

Each of these debug flags can be useful in different situations. They are examined in turn below.

Start with our simple api project:

$ ls
api.c
api.h
build.spec
project.spec
test-api.c

Dependency Graph

g    Depencency graph for each target

This option triggers each time a target needs to be built, to show the causation chain that led to that target being built. First a normal build.

$ tmake 
    Cc           test-api.o
    Cc           api.o
    Ar           libapi.a
    Link         test-api
Built 4 of 5 target(s) in 0.24 seconds

Now modify one file and explore the causation chain.

$ touch api.h
$ tmake -dg
   13ms [g] all --> test-api --> test-api.o (changed api.h)
    Cc           test-api.o
   16ms [g] all --> test-api --> libapi.a --> api.o (changed api.h)
    Cc           api.o
   35ms [g] all --> test-api --> libapi.a (depend api.o changed api.o)
    Ar           libapi.a
   90ms [g] all --> test-api (depend test-api.o depend libapi.a changed libapi.a)
    Link         test-api
Built 4 of 5 target(s) in 0.18 seconds

We see that both api.o and test-apio depend on api.h (through dynamic dependency scanning) and these dependencies cause api.o and test-api.o to be rebuilt. Next we see that libapi.a depends on api.o and so it is rebuilt. And finally we see that test-api depends on both test-api.o and libapi.a and at least one has changed, so it is rebuilt.

The causation chain is shown for each built target from the top level target that caused it to be built (in this case the default target, all). This can be different if a specific target is given.

$ touch api.h
$ tmake -dg libapi.a
   11ms [g] libapi.a --> api.o (changed api.h)
    Cc           api.o
   28ms [g] libapi.a (depend api.o changed api.o)
    Ar           libapi.a
Built 2 of 5 target(s) in 0.06 seconds

Build goals

G    List goals (targets) as they are attempted

This option displays each goal (target) as it is examined in a hierarchical display. This is useful as it shows the entire target dependency tree as it is traversed, not just the targets that need to be built.

$ touch api.h
$ tmake -dG
   10ms [G] build all
   10ms     [G] build test-api
   10ms         [G] build test-api.o
   10ms             [G] build test-api.c
   11ms             [G] build api.h
    Cc           test-api.o
   13ms         [G] build libapi.a
   13ms             [G] build api.o
   13ms                 [G] build api.c
    Cc           api.o
   29ms [G] build all
   29ms     [G] build test-api
   30ms         [G] build libapi.a
    Ar           libapi.a
   32ms [G] build all
   32ms     [G] build test-api
   67ms [G] build all
   67ms     [G] build test-api
    Link         test-api
  153ms [G] build all
Built 4 of 5 target(s) in 0.15 seconds

Reasons built

b    Reasons for targets BUILT
B    Reasons for targets BUILT - changed commands or targets

Need some text here for -db

$ touch api.h
$ tmake -db
   11ms [b T] Building target all
   11ms [b] all is phony, so rebuilding
   12ms [b] Deps for test-api.o have changed, so rebuild
   12ms [b] Building test-api.o <= test-api <= all with rule @build.spec:10
    Cc           test-api.o
   15ms [b] Deps for api.o have changed, so rebuild
   15ms [b] Building api.o <= libapi.a <= test-api <= all with rule @build.spec:8
    Cc           api.o
   34ms [b] all is phony, so rebuilding
   35ms [b] Deps for libapi.a have changed, so rebuild
   35ms [b] Building libapi.a <= test-api <= all with rule @build.spec:8
    Ar           libapi.a
   37ms [b] all is phony, so rebuilding
   73ms [b] all is phony, so rebuilding
   74ms [b] Deps for test-api have changed, so rebuild
   74ms [b] Building test-api <= all with rule @build.spec:10
    Link         test-api
  160ms [b] all is phony, so rebuilding
Built 4 of 5 target(s) in 0.16 seconds

Need some text here for -db and -dB

$ tmake CFLAGS=-g -dbB
   10ms [b T] Building target all
   10ms [b] all is phony, so rebuilding
   11ms [b B] Commands for test-api.o have changed, so forcing rebuild
=== old ===
	run  gcc -Iobjdir/publish/include -I. -Iobjdir   -c test-api.c -o objdir/test-api.o
=== new ===
	run  gcc -Iobjdir/publish/include -I. -Iobjdir -g  -c test-api.c -o objdir/test-api.o
-----------
   11ms [b] Building test-api.o <= test-api <= all with rule @build.spec:10
    Cc           test-api.o
   14ms [b B] Commands for api.o have changed, so forcing rebuild
=== old ===
	run  gcc -Iobjdir/publish/include -I. -Iobjdir   -c api.c -o objdir/api.o
=== new ===
	run  gcc -Iobjdir/publish/include -I. -Iobjdir -g  -c api.c -o objdir/api.o
-----------
   14ms [b] Building api.o <= libapi.a <= test-api <= all with rule @build.spec:8
    Cc           api.o
   32ms [b] all is phony, so rebuilding
   32ms [b] Deps for libapi.a have changed, so rebuild
   32ms [B] Changed api.o: 1661146555572364 -> 1661146555750526
   33ms [b] Building libapi.a <= test-api <= all with rule @build.spec:8
    Ar           libapi.a
   35ms [b] all is phony, so rebuilding
   70ms [b] all is phony, so rebuilding
   71ms [b] Deps for test-api have changed, so rebuild
   71ms [B] Changed libapi.a: 1661146555617471 -> 1661146555792894
   71ms [B] Changed test-api.o: 1661146555574244 -> 1661146555751266
   71ms [b] Building test-api <= all with rule @build.spec:10
    Link         test-api
  147ms [b] all is phony, so rebuilding
Built 4 of 5 target(s) in 0.15 seconds

Dynamic dependencies

d    Dynamic dependencies
D    Dynamic dependencies (detailed)

Need some text here for -dd

$ tmake -dd
   11ms [d] header-scan-regexp test-api.c (cached) => api.h
   11ms [d] Dynamic dependencies for test-api.o: api.h
    Cc           test-api.o
   13ms [d] header-scan-regexp api.c (cached) => api.h
   13ms [d] Dynamic dependencies for api.o: api.h
    Cc           api.o
    Ar           libapi.a
    Link         test-api
Built 4 of 5 target(s) in 0.14 seconds

Need some text here for -ddD and how assert.h is now considered source rather than external.

$ touch assert.h
$ tmake -ddD
    9ms [D] Scanning test-api.c for headers: incpaths=publish/include .
    9ms [D] verifying up-to-date cached results for test-api.c
    9ms [D] Not a file and not a target, stdio.h
    9ms [D] ok, stdio.h still resolves to {}
    9ms [D] Not a file and not a target, stdlib.h
    9ms [D] ok, stdlib.h still resolves to {}
    9ms [d] assert.h has changed from {} => {source assert.h 1661146556036258} -- rescan
    9ms [d] cache is out-of-date for test-api.c - rescanning
   10ms [D] header-scan-regexp test-api.c => stdio.h stdlib.h assert.h api.h
   10ms [D] header-scan-regexp assert.h => 
   10ms [D] header-scan-regexp api.h => 
   10ms [d] Dynamic dependencies for test-api.o: assert.h api.h
    Cc           test-api.o
   12ms [D] Scanning api.c for headers: incpaths=publish/include .
   12ms [D] verifying up-to-date cached results for api.c
   12ms [D] ok, api.h still resolves to {source api.h 1661146555538708}
   12ms [d] header-scan-regexp api.c (cached) => api.h
   12ms [d] Dynamic dependencies for api.o: api.h
    Link         test-api
Built 2 of 5 target(s) in 0.10 seconds
p    Print rules while parsing

As tmake parses project.spec and build.spec files ...

$ tmake -dp
    2ms [p] /Volumes/src/tmake/rulebase.default:2326 Phony all
    2ms [p] /Volumes/src/tmake/rulebase.default:2327 Phony libs
    2ms [p] /Volumes/src/tmake/rulebase.default:2328 Phony install all
    2ms [p] /Volumes/src/tmake/rulebase.default:2329 Phony test
    3ms [p] /Volumes/src/tmake/rulebase.default:2337 Phony clean-orphans -do 
	do-delete-orphans [get-orphan-targets]
	# Now remove the trash
	if {[file exists .trash]} {
		note Clean .trash
		file delete -force .trash
	}

    5ms [p] /Volumes/src/tmake/rulebase.default:950 IncludePaths --build publish/include
    6ms [p] /Volumes/src/tmake/rulebase.default:950 CFlags -Iobjdir/publish/include
    6ms [p] /Volumes/src/tmake/rulebase.default:338 rulebase-prolog .
    6ms [p] /Volumes/src/tmake/rulebase.default:360 IncludePaths .
    6ms [p] /Volumes/src/tmake/rulebase.default:360 CFlags -I.
    6ms [p] /Volumes/src/tmake/rulebase.default:360 CFlags -Iobjdir
    6ms [p] build.spec:8 ArchiveLib --publish api api.c
    7ms [p] build.spec:8 Glob --all api.c
    7ms [p] build.spec:8 Objects api.c
    7ms [p] build.spec:8 Object api.o api.c
    8ms [p] build.spec:8 Phony libs libapi.a
    8ms [p] build.spec:10 Executable --test test-api test-api.c
    9ms [p] build.spec:10 Glob --all test-api.c
    9ms [p] build.spec:10 Objects test-api.c
    9ms [p] build.spec:10 Object test-api.o test-api.c
   10ms [p] build.spec:10 Test test-api
   10ms [p] build.spec:10 Phony test test#1
   10ms [p] build.spec:10 Phony all test-api
   11ms [p] /Volumes/src/tmake/rulebase.default:364 rulebase-epilog .
r    Display rules when triggered
$ touch api.h
$ tmake -dr --jobs=1
    Cc           test-api.o
   11ms [r] Rule for test-api.o
-- test-api.o -------------------------------------------------
@build.spec:10
test-api.o: test-api.c
dyndep=header-scan-regexp-recursive $INCPATHS "" $CHDRPATTERN
       api.h
       assert.h
local=.
  var CC=gcc
  var C_FLAGS=-Iobjdir/publish/include -I. -Iobjdir
  var INCPATHS=publish/include .
	run $CCACHE $CC $C_FLAGS $CFLAGS $CPPFLAGS -c $inputs -o $target
    Cc           api.o
   24ms [r] Rule for api.o
-- api.o ------------------------------------------------------
@build.spec:8
api.o: api.c
dyndep=header-scan-regexp-recursive $INCPATHS "" $CHDRPATTERN
       api.h
local=.
  var CC=gcc
  var C_FLAGS=-Iobjdir/publish/include -I. -Iobjdir
  var INCPATHS=publish/include .
	run $CCACHE $CC $C_FLAGS $CFLAGS $CPPFLAGS -c $inputs -o $target
    Ar           libapi.a
   32ms [r] Rule for libapi.a
-- libapi.a ---------------------------------------------------
@build.spec:8
libapi.a: api.o
local=.
	file delete $target
	run $AR $ARFLAGS $target {*}[expand-objects $inputs]
	run $RANLIB $target
    Link         test-api
   63ms [r] Rule for test-api
-- test-api ---------------------------------------------------
@build.spec:10
test-api: test-api.o libapi.a
local=.
  var CCLD=gcc
  var LD_FLAGS=
  var PROJLIBS=
  var SYSLIBS=
	run $CCLD $LD_FLAGS $LDFLAGS -o $target $inputs $PROJLIBS $SYSLIBS
Built 4 of 5 target(s) in 0.13 seconds

Subpages:

Advanced debug flags – Using advanced debug flags

The results of the search are