我喜欢 NetHack,我想和源代码一起玩一些有趣的东西。在我这样做之前,我希望能够开箱即用地编译它,但我很难做到这一点。
我从这里下载了源代码,并按照这里的说明进行操作,但是没有用。
我最终得到以下
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
我看了看它正在谈论的那一行,但它并没有真正告诉我任何事情。我确实注意到在包含目录中创建的 date.h 文件总是空的,但这对我也没有多大帮助。我阅读了 Install.nt README,其中的说明似乎非常明确。但是,由于我没有更改任何内容,因此我不知道为什么它无法编译...
我认为自己是一个称职的程序员,但在 makefile 和将 C 代码编译成可执行应用程序方面我几乎一无所知,所以我很迷失在这里。我下载并安装了 MinGW ......一切,我的意思是当我运行 MinGW 安装程序时,没有任何东西被卸载。
我在这里做错了什么?
编辑:由于 date.h 被提及:
#
# 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)
我确实注意到它似乎正在对 进行某种调用OPTIONS_FILE
,这似乎已被注释掉。我将取消注释,看看会发生什么。
#$(OPTIONS_FILE): $(U)makedefs.exe
#$(subst /,\,$(U)makedefs -v)
编辑 2那没有用。是否有可能我必须手动创建/更新 date.h 文件?如果是这样,我在里面放什么?听起来像谷歌的问题......
编辑 3我发现这是一个更旧的版本,并试图改变它,但它也没有工作......
编辑 4有人提到Makedefs这似乎是崩溃的事情。我发现似乎导致问题的 C 函数:
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;
}
另外我应该提到当它在编译过程中到达这一点时,立即有这个图像:
所以我们已经将问题(我认为?)缩小到破坏事物的 makedefs 帮助程序,所以现在我想下一步是找出原因?
编辑 5:建议在编译 Makedefs.c 时使用特殊参数。我查看了 Makefile 以找出编译发生的位置,我想我已经找到了发生的位置,但我真的不知道这里发生了什么。
$(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
我知道这$(*)
是一个变量或 Makefile 等效的变量。
$(U)
指向$(UTIL)/
,$(UTIL)
指向../util
。
$(MAKEOBJS)
指向$(O)makedefs.o $(O)monst.o $(O)objects.o
.
$(O)
考虑到我在半成功运行中观察到的行为(在大冻结之前编译了几个文件),$(OBJ)/
这o
将$(O)makedefs.o
与o/makedefs.o
which 是有意义的。
无论如何,$(link)
指向gcc
.
$(LFLAGSU)
指向$(LFLAGSBASEC)
哪个指向$(linkdebug)
哪个指向-g
。
$(CONFIG_H)
指向大量头文件:
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)
指向../include
.
$(CFLAGSU)
指向$(CFLAGSBASE) $(WINPFLAG)
.
$(CFLAGSBASE)
指向-c $(cflags) -I$(INCL) $(WINPINC) $(cdebug)
$(cflags)
指向 指向-mms-bitfields
$(WINPINC)
指向-I$(WIN32)
$(WIN32) 指向../win/win32
$(cdebug)
指向-g
$(WINPFLAG)
指向-DTILES -DMSWIN_GRAPHICS -D_WIN32_IE=0x0400
. . . 它就在那里。我认为这就是我需要修改的内容,以使其与 RossRidge -D_USE_32BIT_TIME_T 提到的内容一起工作。
但是,既然我已经走了那么远,我确实想找出其中一些东西的含义。当我看到第一行时$(U)makedefs.exe :
。对我来说,这似乎是编译输出文件的目标声明?那是对的吗?@
另外,之前$(link) $(LFLAGSU)
和之后的含义是什么-o$
?$
之后的含义是-o
什么?
无论如何,我想尝试一下我想出的东西,看看它是否有效。... Aaaand 添加-D_USE_32BIT_TIME_T
到WINPFLAG
没有工作。
最终(ish)编辑:原来罗斯里奇在他使用-D_USE_32BIT_TIME_T
旗帜的建议中是正确的。我的错误是把它放在错误的地方。如果您查看框中的 Makefile.gcc,请查看第 165 行(在 IF 语句中)。你想-D_USE_32BIT_TIME_T
在最后完成。但是您还需要在第 176 行的末尾添加它,该行位于该 IF 语句的 ELSE 末尾。所以整个块看起来像这样(不是一个巨大的变化,但如果你不这样做并且你在我的情况下运行,它仍然足以让它崩溃):
################################################
# #
# 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