I like NetHack and I want to dink around with the source a bit for fun. Before I do that I would like to be able to get it to compile out of the box but I'm having no small amount of difficulty getting that to happen.
I downloaded the source code from here and I followed the instructions here but it didn't work.
I ended up getting the following
C:\nethack-3.4.3\src>mingw32-make -f Makefile.gcc install
creating directory o
gcc -c -mms-bitfields -I../include -g -DWIN32CON -oo/makedefs.o ../util/makedefs.c
gcc -c -mms-bitfields -I../include -g -DWIN32CON -DDLB -oo/monst.o ../src/monst.c
gcc -c -mms-bitfields -I../include -g -DWIN32CON -DDLB -oo/objects.o ../src/objects.c
..\util\makedefs -v
Makefile.gcc:655: recipe for target '../include/date.h' failed
mingw32-make: *** [../include/date.h] Error -1073741819
I looked at the line it was talking about but it didn't really tell me anything. I did notice that the date.h file being created in the include directory was always empty but that doesn't help me very much either. I read the Install.nt README and the directions seemed pretty clear-cut. However since I didn't change anything I don't know why it would fail to compile...
I consider myself to be a competent programmer but I know next to nothing when it comes to makefiles and compiling C code into an executable application so I'm pretty well lost here. I downloaded and installed the MinGW... everything, by which I mean that there is nothing left uninstalled when I run the MinGW installer.
What am I doing wrong here?
EDIT : As date.h was being mentioned:
#
# date.h should be remade every time any of the source or include
# files is modified.
#
$(INCL)/date.h $(OPTIONS_FILE): $(U)makedefs.exe
$(subst /,\,$(U)makedefs -v)
I did notice it seems to be making some kind of call to OPTIONS_FILE
, which seems to be commented out. I will uncomment it and see what happens.
#$(OPTIONS_FILE): $(U)makedefs.exe
#$(subst /,\,$(U)makedefs -v)
EDIT 2 That didn't work. Is it possible that I have to manually create/update the date.h file? If so, what do I put into it? Sounds like a question for Google...
EDIT 3 I found this for a much older version and tried to change it up but it didn't work either...
EDIT 4 Someone mentioned Makedefs which seems to be the thing crashing. I found the C function that appears to be causing the problem:
void
do_date()
{
long clocktim = 0;
char *c, cbuf[60], buf[BUFSZ];
const char *ul_sfx;
filename[0]='\0';
#ifdef FILE_PREFIX
Strcat(filename,file_prefix);
#endif
Sprintf(eos(filename), INCLUDE_TEMPLATE, DATE_FILE);
if (!(ofp = fopen(filename, WRTMODE))) {
perror(filename);
exit(EXIT_FAILURE);
}
Fprintf(ofp,"/*\tSCCS Id: @(#)date.h\t3.4\t2002/02/03 */\n\n");
Fprintf(ofp,Dont_Edit_Code);
#ifdef KR1ED
(void) time(&clocktim);
Strcpy(cbuf, ctime(&clocktim));
#else
(void) time((time_t *)&clocktim);
Strcpy(cbuf, ctime((time_t *)&clocktim));
#endif
for (c = cbuf; *c; c++) if (*c == '\n') break;
*c = '\0'; /* strip off the '\n' */
Fprintf(ofp,"#define BUILD_DATE \"%s\"\n", cbuf);
Fprintf(ofp,"#define BUILD_TIME (%ldL)\n", clocktim);
Fprintf(ofp,"\n");
#ifdef NHSTDC
ul_sfx = "UL";
#else
ul_sfx = "L";
#endif
Fprintf(ofp,"#define VERSION_NUMBER 0x%08lx%s\n",
version.incarnation, ul_sfx);
Fprintf(ofp,"#define VERSION_FEATURES 0x%08lx%s\n",
version.feature_set, ul_sfx);
#ifdef IGNORED_FEATURES
Fprintf(ofp,"#define IGNORED_FEATURES 0x%08lx%s\n",
(unsigned long) IGNORED_FEATURES, ul_sfx);
#endif
Fprintf(ofp,"#define VERSION_SANITY1 0x%08lx%s\n",
version.entity_count, ul_sfx);
Fprintf(ofp,"#define VERSION_SANITY2 0x%08lx%s\n",
version.struct_sizes, ul_sfx);
Fprintf(ofp,"\n");
Fprintf(ofp,"#define VERSION_STRING \"%s\"\n", version_string(buf));
Fprintf(ofp,"#define VERSION_ID \\\n \"%s\"\n",
version_id_string(buf, cbuf));
Fprintf(ofp,"\n");
#ifdef AMIGA
{
struct tm *tm = localtime((time_t *) &clocktim);
Fprintf(ofp,"#define AMIGA_VERSION_STRING ");
Fprintf(ofp,"\"\\0$VER: NetHack %d.%d.%d (%d.%d.%d)\"\n",
VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL,
tm->tm_mday, tm->tm_mon+1, tm->tm_year+1900);
}
#endif
Fclose(ofp);
return;
}
Also I should mention when it gets to this point in the compile process, immediately there is this image:
So we've narrowed down the problem (I think?) to the makedefs helper program that is breaking things so now I guess the next step would be to find out why?
EDIT 5: It's been suggested that a special parameter should be used when compiling Makedefs.c. I've taken a look at the Makefile to find out where the compile takes place and I think I've found where that is happening but I don't really know what's going on here.
$(U)makedefs.exe: $(MAKEOBJS)
@$(link) $(LFLAGSU) -o$@ $(MAKEOBJS)
$(O)makedefs.o: $(CONFIG_H) $(INCL)/monattk.h $(INCL)/monflag.h \
$(INCL)/objclass.h $(INCL)/monsym.h $(INCL)/qtext.h \
$(INCL)/patchlevel.h $(U)makedefs.c $(O)obj.tag
$(cc) $(CFLAGSU) -o$@ $(U)makedefs.c
I know that $(*)
is a variable or the Makefile equivalent of a variable.
$(U)
points to $(UTIL)/
, and $(UTIL)
points to ../util
.
$(MAKEOBJS)
points to $(O)makedefs.o $(O)monst.o $(O)objects.o
.
$(O)
points to $(OBJ)/
which points to o
so that would make $(O)makedefs.o
be the same as o/makedefs.o
which makes sense considering the behavior I've observed on semi-successful runs (Several files are compiled before the big freeze).
Anyway, $(link)
points to gcc
.
$(LFLAGSU)
points to $(LFLAGSBASEC)
which points to $(linkdebug)
which points to -g
.
$(CONFIG_H)
points to a large number of header files:
CONFIG_H = $(INCL)/config.h $(INCL)/config1.h $(INCL)/tradstdc.h \
$(INCL)/global.h $(INCL)/coord.h $(INCL)/vmsconf.h \
$(INCL)/system.h $(INCL)/unixconf.h $(INCL)/os2conf.h \
$(INCL)/micro.h $(INCL)/pcconf.h $(INCL)/tosconf.h \
$(INCL)/amiconf.h $(INCL)/macconf.h $(INCL)/beconf.h \
$(INCL)/ntconf.h $(INCL)/nhlan.h
$(INCL)
points to ../include
.
$(CFLAGSU)
points to $(CFLAGSBASE) $(WINPFLAG)
.
$(CFLAGSBASE)
points to -c $(cflags) -I$(INCL) $(WINPINC) $(cdebug)
$(cflags)
points to -mms-bitfields
$(WINPINC)
points to -I$(WIN32)
$(WIN32) points to ../win/win32
$(cdebug)
points to -g
$(WINPFLAG)
points to -DTILES -DMSWIN_GRAPHICS -D_WIN32_IE=0x0400
. . .
And there it is. I think that's what I need to modify to make this work with what was mentioned by RossRidge -D_USE_32BIT_TIME_T.
However since I've come that far I do want to find out what some of this stuff means.
When looking at the first line I see $(U)makedefs.exe :
. To me that appears to be a declaration of the target for the compiled output file? Is that correct? Also, what is the meaning of the @
before the $(link) $(LFLAGSU)
and after the -o$
? And what is the meaning of the $
after the -o
?
Anyway, I want to try what I figured out and see if it works at all.
... Aaaand adding -D_USE_32BIT_TIME_T
to WINPFLAG
didn't work.
FINAL(ish) EDIT: Turns out RossRidge was correct in his suggestion to use the -D_USE_32BIT_TIME_T
flag. MY mistake was putting it in the wrong place. If you take a look at the Makefile.gcc that comes in the box, look at line 165 (which is in an IF statement). You want to tack -D_USE_32BIT_TIME_T
at the end of that. BUT you will also want to tack it at the end of line 176 which is on the ELSE end of that IF statement. So that entire block would look something like this instead (Not a huge change, but still significant enough to make it crash if you don't do it and you're running under my situation):
################################################
# #
# Nothing below here should have to be changed.#
# #
################################################
ifeq "$(GRAPHICAL)" "Y"
WINPORT = $(O)tile.o $(O)mhaskyn.o $(O)mhdlg.o \
$(O)mhfont.o $(O)mhinput.o $(O)mhmain.o $(O)mhmap.o \
$(O)mhmenu.o $(O)mhmsgwnd.o $(O)mhrip.o $(O)mhsplash.o \
$(O)mhstatus.o $(O)mhtext.o $(O)mswproc.o $(O)winhack.o
WINPFLAG = -DTILES -DMSWIN_GRAPHICS -D_WIN32_IE=0x0400 -D_USE_32BIT_TIME_T
NHRES = $(O)winres.o
WINPINC = -I$(WIN32)
WINPHDR = $(WIN32)/mhaskyn.h $(WIN32)/mhdlg.h $(WIN32)/mhfont.h \
$(WIN32)/mhinput.h $(WIN32)/mhmain.h $(WIN32)/mhmap.h \
$(WIN32)/mhmenu.h $(WIN32)/mhmsg.h $(WIN32)/mhmsgwnd.h \
$(WIN32)/mhrip.h $(WIN32)/mhstatus.h \
$(WIN32)/mhtext.h $(WIN32)/resource.h $(WIN32)/winMS.h
WINPLIBS = -lcomctl32 -lwinmm
else
WINPORT = $(O)nttty.o
WINPFLAG= -DWIN32CON -D_USE_32BIT_TIME_T
WINPHDR =
NHRES = $(O)console.o
WINPINC =
WINPLIBS = -lwinmm
endif