1 # depend.awk -- awk script used to construct makefile dependencies
2 # for anethack's source files (`make depend' support for Makefile.src).
3 # $ANH-Date$ $ANH-Branch$:$ANH-Revision$
6 # cd src ; nawk -f depend.awk ../include/*.h list-of-.c/.cpp-files
8 # This awk program scans each file in sequence, looking for lines beginning
9 # with `#include "' and recording the name inside the quotes. For .h files,
10 # that's all it does. For each .c file, it writes out a make rule for the
11 # corresponding .o file; dependencies in nested header files are propagated
14 # config.h and hack.h get special handling because of their heavy use;
15 # timestamps for them allow make to avoid rechecking dates on
16 # subsidiary headers for every source file;
17 # extern.h gets special handling to avoid excessive recompilation
19 # patchlev.h gets special handling because it only exists on systems
20 # which consider filename patchlevel.h to be too long;
21 # interp.c gets special handling because it usually doesn't exist; it's
22 # assumed to be the last #include in the file where it occurs.
23 # win32api.h gets special handling because it only exists for some ports;
24 # it's assumed to be the last #include in the file where it occurs
27 BEGIN { FS =
"\"" #for `#include "X"', $2 is X
28 special
[++sp_cnt
] =
"../include/config.h"
29 special
[++sp_cnt
] =
"../include/hack.h"
30 alt_deps
["../include/extern.h"] =
""
31 alt_deps
["../include/patchlev.h"] =
""
32 alt_deps
["interp.c"] =
" #interp.c" #comment it out
33 alt_deps
["../include/win32api.h"] =
" #../include/win32api.h"
34 alt_deps
["../include/zlib.h"] =
" #zlib.h" #comment it out
36 FNR ==
1 { output_dep
() #finish previous file
37 file =
FILENAME #setup for current file
39 /^\
#[ \t]*include[ \t]+\"/ { #find `#include "X"'
41 #[3.4.0: gnomehack headers currently aren't in include]
43 if (incl ~
/^gn
/) # gnomehack special case
44 incl =
"../win/gnome/" incl
46 incl =
"../include/" incl
48 deps
[file
] = deps
[file
] " " incl
50 END { output_dep
() } #finish the last file
54 # `file' has been fully scanned, so process it now; for .h files,
55 # don't do anything (we've just been collecting their dependencies);
56 # for .c files, output the `make' rule for corresponding .o file
58 function output_dep
( targ
)
60 if (file ~
/\.cp
*$
/) {
61 #prior to very first .c|.cpp file, handle some special header file cases
64 #construct object filename from source filename
65 targ = file
; sub("^.+/", "", targ
); sub("\\.cp*$", ".o", targ
)
66 #format and write the collected dependencies
67 format_dep
(targ
, file
)
72 # handle some targets (config.h, hack.h) via special timestamping rules
74 function output_specials
( i
, sp
, alt_sp
)
76 for (i =
1; i
<= sp_cnt
; i
++) {
78 #change "../include/foo.h" first to "foo.h", then ultimately to "$(FOO_H)"
79 alt_sp = sp
; sub("^.+/", "", alt_sp
)
80 print "#", alt_sp
, "timestamp" #output a `make' comment
81 #- sub("\\.", "_", alt_sp); alt_sp = "$(" toupper(alt_sp) ")"
82 #+ Some nawks don't have toupper(), so hardwire these instead.
83 sub("config.h", "$(CONFIG_H)", alt_sp
); sub("hack.h", "$(HACK_H)", alt_sp
);
84 format_dep
(alt_sp
, sp
) #output the target
85 print "\ttouch " alt_sp
#output a build command
86 alt_deps
[sp
] = alt_sp
#alternate dependency for depend()
92 # write a target and its dependency list in pretty-printed format;
93 # if target's primary source file has a path prefix, also write build command
95 function format_dep
(target
, source
, n
, i
, list
)
97 split("", done
) #``for (x in done) delete done[x]''
98 printf("%s:", target
); col =
length(target
) + 1
99 #- printf("\t"); col += 8 - (col % 8);
100 #- if (col == 8) { printf("\t"); col += 8 }
101 source = depend
("", source
, 0)
102 n =
split(source
, list
, " +")
103 for (i =
2; i
<= n
; i
++) { #(leading whitespace yields empty 1st element)
104 if (col
+ length(list
[i
]) >=
(i
< n ?
78 : 80)) {
105 printf(" \\\n\t\t"); col =
16 #make a backslash+newline split
109 printf("%s", list
[i
]); col
+=
length(list
[i
])
111 printf("\n") #terminate
112 #write build command if first source entry has non-include path prefix
114 if (source ~
/\
// && substr(source
, 1, 11) != "../include/") {
115 if (source ~
/\.cpp$
/ )
116 print "\t$(CXX) $(CXXFLAGS) -c " source
117 else if (source ~
/\
/gnome\
//) # "../win/gnome/foo.c"
118 print "\t$(CC) $(CFLAGS) $(GNOMEINC) -c " source
120 print "\t$(CC) $(CFLAGS) -c " source
125 # recursively add the dependencies for file `name' to string `inout'
126 # (unless `skip', in which case we're only marking files as already done)
128 function depend
(inout
, name
, skip
, n
, i
, list
)
131 if (name in alt_deps
) { #some names have non-conventional dependencies
132 if (!skip
) inout = inout
" " alt_deps
[name
]
134 } else { #ordinary name
135 if (!skip
) inout = inout
" " name
138 #- n = split(deps[name], list, " +")
139 #- for (i = 2; i <= n; i++) #(leading whitespace yields empty 1st element)
140 #- inout = depend(inout, list[i], skip)
141 #+ At least one implementation of nawk handles the local array `list' wrong,
142 #+ so the clumsier substitute code below is used as a workaround.
143 list = deps
[name
]; sub("^ +", "", list
)
145 match((list
" "), " +"); i =
RSTART; n =
RLENGTH
146 inout = depend
(inout
, substr(list
, 1, i
-1), skip
)
147 list =
substr(list
, i
+n
)