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
Print commands during parsing
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 .
Print target rules when building
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
The results of the search are