Files
nethack/sys/unix/depend.awk
PatR f9f209bb49 Qt 5 vs Qt 6 revisited plus 'make depend' update
Rename the recently added timestamp file used to throw away old qt
'moc' files from moc.qt5 or moc.qt6 to Qt5.h-t or Qt6.h-t and use
that to also throw away old qt_*.o when switching from Qt 5 to Qt 6
or vice versa.  Temporarily the old names remain in Makefile.src's
'clean' target and in src/.gitignore but those will be removed soon.

Update 'make depend' to add the timestamp file to qt_*.o dependencies.
Have it generate rules to build qt_*.moc from ../win/Qt/qt_*.h instead
of using a template rule in hints/include/compiler.370.  So building
the Qt interface doesn't require use of that hints file anymore and
someone reading Makefile.src won't have to know about it, but using
those hints will make their life easier.

Simplify the Qt timestamp handling portion of compiler.370.  Only one
extra rule gets added when creating src/Makefile.

src/Makefile generated from sys/unix/Makefile.src that's been rebuilt
with 'make depend' got broken by uncommenting '#include "amiconf.h"'
in global.h.  That file isn't in include/ but every object file now
depended on it and make didn't know what to do about that.  Have
depend.awk treat it as a special case so that no object files depend
on it.  That means that actually modifying it won't trigger a rebuild;
anyone fiddling with that will have to always do 'make clean' or
'touch config.h-t' after changing it.  The alternative is to move it
from outdated/include/ back to include/.

In depend.awk, recent gawk complained that "\." wasn't a defined
escape sequence in regular expressions so it would be treated as ".".
That's exactly what is intended but change it to "[.]" to avoid the
warning.  Similarly for one instance each of "\#" and '\"'.  I also
tried changing "\/" to "[/]" even though that is a defined sequence
and doesn't trigger any warning.  gawk accepted it but the awk that
comes with OSX choked on it so I changed it back to "\/".
2022-02-05 04:15:51 -08:00

192 lines
7.3 KiB
Awk

# depend.awk -- awk script used to construct makefile dependencies
# for nethack's source files (`make depend' support for Makefile.src).
# $NHDT-Date: 1612127123 2021/01/31 21:05:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $
#
# usage:
# cd src ; nawk -f depend.awk ../include/*.h list-of-.c/.cpp-files
#
# This awk program scans each file in sequence, looking for lines beginning
# with `#include "' and recording the name inside the quotes. For .h files,
# that's all it does. For each .c file, it writes out a make rule for the
# corresponding .o file; dependencies in nested header files are propagated
# to the .o target.
#
# config.h and hack.h get special handling because of their heavy use;
# timestamps for them allow make to avoid rechecking dates on
# subsidiary headers for every source file;
# extern.h gets special handling to avoid excessive recompilation
# during development;
# patchlev.h gets special handling because it only exists on systems
# which consider filename patchlevel.h to be too long;
# amiconf.h moved from ../include/ to ../outdated/include/ so skip it
# interp.c gets special handling because it usually doesn't exist; it's
# assumed to be the last #include in the file where it occurs.
# win32api.h gets special handling because it only exists for some ports;
# it's assumed to be the last #include in the file where it occurs
# zlib.h ditto
#
BEGIN { FS = "\"" #for `#include "X"', $2 is X
special[++sp_cnt] = "../include/config.h"
special[++sp_cnt] = "../include/hack.h"
alt_deps["../include/extern.h"] = ""
alt_deps["../include/patchlev.h"] = ""
alt_deps["../include/amiconf.h"] = ""
alt_deps["interp.c"] = " #interp.c" #comment it out
alt_deps["../include/win32api.h"] = " #../include/win32api.h"
alt_deps["../include/zlib.h"] = " #zlib.h" #comment it out
}
FNR == 1 { output_dep() #finish previous file
file = FILENAME #setup for current file
}
/^[#][ \t]*include[ \t]+["]/ { #find `#include "X"'
incl = $2
#[3.4.0: gnomehack headers currently aren't in include]
#[3.6.2: Qt4 headers aren't in include either]
#[3.6.2: curses headers likewise]
#[3.7.0: Qt headers have moved; process 'moc' files]
if (incl ~ /[.]h$/) {
if (incl ~ "curses[.]h")
incl = "" # skip "curses.h"; it should be <curses.h>
else if (incl ~ /^..\/lib\/lua-.*\/src\/l/)
incl = "" # skip lua headers
else if (incl ~ /^curs/) # curses special case
incl = "../win/curses/" incl
else if (incl ~ /(.*\/)*qt_/) { # Qt special cases
# Qt v3 headers are in ../win/Qt3
# Qt v4/v5/v6 headers are in ../win/Qt
# *.moc files have path in their #include
if (file ~ /[.]moc$/)
; # keep 'incl' as-is
else if (file ~ /^[.][.]\/win\/Qt3\/.*/)
incl = "../win/Qt3/" incl
else # Qt v4/v5/v6
incl = "../win/Qt/" incl
} else if (incl ~ /^gn/) # gnomehack special case
incl = "../win/gnome/" incl
else
incl = "../include/" incl
}
deps[file] = deps[file] " " incl
}
END { output_dep() } #finish the last file
#
# `file' has been fully scanned, so process it now; for .h files,
# don't do anything (we've just been collecting their dependencies);
# for .c files, output the `make' rule for corresponding .o file
#
function output_dep( base, targ, moc)
{
#get the file's base name (including suffix)
base = file; sub("^.+/", "", base)
#for qt source files, add qt timestamp file as extra dependency
moc = (base ~ /[.]moc$/)
if (moc || base ~ /(.+\/)*qt_.*[.]cpp$/) {
deps[file] = deps[file] " $(QTn_H)"
}
if (base ~ /[.]cp*$/ || moc) {
#prior to very first .c|.cpp file, handle some special header file cases
if (!c_count++)
output_specials()
#construct object filename from source filename
targ = base; sub("[.]cp*$", ".o", targ)
#format and write the collected dependencies
format_dep(targ, file)
}
}
#
# handle some targets (config.h, hack.h) via special timestamping rules
#
function output_specials( i, sp, alt_sp)
{
for (i = 1; i <= sp_cnt; i++) {
sp = special[i]
#change "../include/foo.h" first to "foo.h", then ultimately to "$(FOO_H)"
alt_sp = sp; sub("^.+/", "", alt_sp)
print "#", alt_sp, "timestamp" #output a `make' comment
#- sub("[.]", "_", alt_sp); alt_sp = "$(" toupper(alt_sp) ")"
#+ Some nawks don't have toupper(), so hardwire these instead.
sub("config.h", "$(CONFIG_H)", alt_sp); sub("hack.h", "$(HACK_H)", alt_sp)
format_dep(alt_sp, sp) #output the target
print "\ttouch " alt_sp #output a build command
alt_deps[sp] = alt_sp #alternate dependency for depend()
}
print "#"
}
#
# write a target and its dependency list in pretty-printed format;
# if target's primary source file has a path prefix, also write build command
#
function format_dep(target, source, col, n, i, list, prefix, moc)
{
split("", done) #``for (x in done) delete done[x]''
moc = (target ~ /[.]moc$/)
prefix = (moc || substr(target,1,1) == "$") ? "" : "$(TARGETPFX)"
printf("%s%s:", prefix, target); col = length(target) + 1 + length(prefix)
#- printf("\t"); col += 8 - (col % 8);
#- if (col == 8) { printf("\t"); col += 8 }
source = depend("", source, 0)
n = split(source, list, " +")
#first: leading whitespace yields empty 1st element; not sure why moc
#files duplicate the target as next element but we need to skip that too
first = moc ? 3 : 2
for (i = first; i <= n; i++) {
if (col + length(list[i]) >= (i < n ? 78 : 80) - 1) {
printf(" \\\n\t\t"); col = 16 #make a backslash+newline split
} else {
printf(" "); col++;
}
printf("%s", list[i]); col += length(list[i])
}
printf("\n") #terminate
#write build command if first source entry has non-include path prefix
source = list[first]
if (moc) {
print "\t$(MOCPATH) -o $@ " source
} else if (source ~ /\// && substr(source, 1, 11) != "../include/") {
if (source ~ /[.]cpp$/ )
print "\t$(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ " source
else if (source ~ /\/X11\//) # "../win/X11/foo.c"
print "\t$(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ " source
else if (source ~ /\/gnome\//) # "../win/gnome/foo.c"
print "\t$(TARGET_CC) $(TARGET_CFLAGS) $(GNOMEINC) -c -o $@ " source
else
print "\t$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ " source
}
}
#
# recursively add the dependencies for file `name' to string `inout'
# (unless `skip', in which case we're only marking files as already done)
#
function depend(inout, name, skip, n, i, list)
{
if (!done[name]++) {
if (name in alt_deps) { #some names have non-conventional dependencies
if (!skip) inout = inout " " alt_deps[name]
skip = 1
} else { #ordinary name
if (!skip) inout = inout " " name
}
if (name in deps) {
#- n = split(deps[name], list, " +")
#- for (i = 2; i <= n; i++) #(leading whitespace yields empty 1st element)
#- inout = depend(inout, list[i], skip)
#+ At least one implementation of nawk handles the local array `list' wrong,
#+ so the clumsier substitute code below is used as a workaround.
list = deps[name]; sub("^ +", "", list)
while (list) {
match((list " "), " +"); i = RSTART; n = RLENGTH
inout = depend(inout, substr(list, 1, i-1), skip)
list = substr(list, i+n)
}
}
}
return inout
}
#depend.awk#