Cross-compiling NetHack with Visual Studio from an x64 platform to an ARM64
target presents some new build challenges.
In the current nethack.sln solution, the build attempts to execute the
several just-built tools during the build of various subprojects.
For example, when cross-compiling on a typical Windows 11 x64 machine
to build a target ARM64 Windows 11 package, the build process tries to
run the following just-built target tools:
(under a Debug build)
"$(ToolsDir)\Debug\ARM64\uudecode.exe"
"$(ToolsDir)\Debug\ARM64\makedefs.exe"
"$(ToolsDir)\Debug\ARM64\tilemap.exe"
"$(ToolsDir)\Debug\ARM64\tile2bmp.exe"
"$(ToolsDir)\Debug\ARM64\dlb.exe"
(under a Release build)
"$(ToolsDir)\Release\ARM64\uudecode.exe"
"$(ToolsDir)\Release\ARM64\makedefs.exe"
"$(ToolsDir)\Release\ARM64\tilemap.exe"
"$(ToolsDir)\Release\ARM64\tile2bmp.exe"
"$(ToolsDir)\Release\ARM64\dlb.exe"
Those fail to execute successfully on Intel x64 (or x86) since they
are actually ARM64 executables, and the build attempts to execute
them on the host Intel x64 hardware.
The situation is a little different if the cross-compile is carried out
on a Windows 11 ARM64 machine (such as SnapDragon).
On an ARM64 machine, the cross-compile to build a target Intel x64
Windows 11 package, tries to execute the following:
(under a Debug build)
"$(ToolsDir)\Debug\x64\uudecode.exe"
"$(ToolsDir)\Debug\x64\makedefs.exe"
"$(ToolsDir)\Debug\x64\tilemap.exe"
"$(ToolsDir)\Debug\x64\tile2bmp.exe"
"$(ToolsDir)\Debug\x64\dlb.exe"
(under a Release build)
"$(ToolsDir)\Release\x64\uudecode.exe"
"$(ToolsDir)\Release\x64\makedefs.exe"
"$(ToolsDir)\Release\x64\tilemap.exe"
"$(ToolsDir)\Release\x64\tile2bmp.exe"
"$(ToolsDir)\Release\x64\dlb.exe"
Those actual do succeed in executing on ARM64, because of the
"prism emulation" that is available on Windows 11 ARM64 operating
systems to allow x64 and x86 executables to run.
The following change adds some detection to build environment, leading
to the definition of a "HostTools" macro that leads to the native host
tools for those steps.
There is a catch:
It means that the native build of the interim tools for Windows 11 must
be executed prior to attempting a cross-compile build to a non-native
target. That ensures that the native x64 interim uudecode, makedefs,
tilemap, tile2bmp and dlb tools are available on the disk for use by
a subsequent cross-compile.
This change consistently switches to the use of the host-native
interim tools for uudecode, makedefs, tilemap, tile2bmp and dlb tools.
Technically, this change would not be strictly necessary on an
ARM64-hosted build that was targeting x64 or x86, because of the
available prism-emulation that allows ARM64, x64, and x86 images to
execute, but this maintains consistency of the build process on
either platform. It is also likely that the native host versions execute
more quickly than versions requiring the prism emulation, although
that isn't really a concern for a NetHack build.
The use of native host uudecode, makedefs, tilemap, tile2bmp and
dlb tools is done with the Unix-hosted cross-compiles to other
target platforms as well (on Linux or macOS).
This evolves and hopefully eases the game-build requirements by
removing game-compile dependencies on any header files generated
by the makedefs utility, including:
date.h dependency and its inclusion is removed and comparable functionality
is produced at runtime via new file src/date.c.
pm.h dependency and its inclusion is removed and comparable functionality is
produced by moving the monster definitions from monst.c into new header
file called monsters.h and altering them slightly. The former pm.h header
file #define PM_ values are now replaced with appropriate emitted enum
entries during the compiler preprocessing.
onames.h dependency and its inclusion is removed and comparable functionality
is produced by moving the object definitions from objects.c into new header
file called objects.h and altering them slightly. The former onames.h header
file #define values are now replaced with appropriate emitted enum entries
during the compiler preprocessing.
artilist.h has been slightly altered, and the former onames.h artifact-related
header file #define ART_ values are now replaced with appropriate emitted enum
entries during the compiler preprocessing.
makedefs can still produce date.h (makedefs -v), pm.h (makedefs -p), and
onames.h (makedefs -o) for reference purposes. They won't be used during
the compiler.
The other uses for makedefs remain. They are used to prepare external
file content that the game utilizes, not prerequisite code for the
compile:
makedefs -d (database)
makedefs -r (rumors)
makedefs -h (oracles)
makedefs -s (epitaphs, engravings, bogusmons)
date.c
Pull the code for date/time stamping from mdlib.c into date.c.
Set date.o to be dependent on source files, header files, and .o files
so that date.o is rebuilt from date.c when any of those changes, thus
ensuring an accurate date/time stamp. It also includes git sha
functionality formerly done by makedefs writing #define directives
into include/date.h. For unix it passes the git info on
the compile line for date.c (via sys/unix/hints/linux.2020, macOS.2020)
nethack --dumpenums (optional, but on by default)
Allow developer to obtain some internal enum values from NetHack
without having to resort to an external utility such as
makedefs.
Uncomment #define NODUMPENUMS in config.h to disable this.
The updates to sys/windows/Makefile.gcc have not been tested yet.
There were multiple symbol-related lists that had to be kept
in sync in various places.
Consolidate some of that into a single new file
defsym.h
with a set of morphing macros that can be custom-called from
the various places that use the sym info without maintaining
multiple occurrences. Most maintenance can be done there.
Rename monsym.h to sym.h since it looks after some
symbols not related to monsters now too.
The defsym.h header file is included in multiple places to
produce different code depending on its use and the controlling
macro definitions in place prior to including it.
Its purpose is to have a definitive source for
pchar, objclass and mon symbol maintenance.
The controlling macros used to morph the resulting code are
used in these places:
- in include/sym.h for enums of some S_ symbol values
(define PCHAR_ENUM, MONSYMS_ENUM prior to #include defsym.h)
- in include/objclass.h for enums of some S_ symbol values
(define OBJCLASS_ENUM prior to #include defsym.h)
- in src/symbols.c for parsing S_ entries in config files
(define PCHAR_PARSE, MONSYMS_PARSE, OBJCLASS_PARSE prior
to #include defsym.h)
- in src/drawing.c for initializing some data structures/arrays
(define PCHAR_DRAWING, MONSYMS_DRAWING, OBJCLASS_DRAWING prior
to #include defsym.h)
- in win/share/tilemap.c for processing a tile file
(define PCHAR_TILES prior to #include defsym.h).
rename sys/winnt to sys/windows
move vs (visual studio) folder out of win/win32 and into sys/windows
rename include/ntconf.h to include/windconf.h
rename winnt.c to windsys.c
place visual studio projects into individual subfolders.
This will hopefully resolve GitHub issue #484 as well.