Compiling Glulxe and Cheapglk in linux

Did you alter the Makefile other than choosing a glk lib at the top, changing CC, and changing -DOS_UNIX to -DWIN32?

It looks like the OPTIONS defined in the Makefile are only being applied to the final link command and not the individual .o compilations. So, the -DWIN32 is not being applied when compiling osdepend.c.

The implicit rule for compiling the .c’s to the .o’s on which glulxe depends should add $(CFLAGS) to the compilation, and I see that the -I$(GLKINCLUDEDIR) is incorporated. So, it looks like CFLAGS is being included, but OPTIONS isn’t included in CFLAGS, is empty, or is undefined. OPTIONS seems to be defined properly during the final link just after, though.

I’m not sure that this accounts for all of the link problems that you’re seeing, but I’d resolve this first and see if it helps.

If you want to, you can start from scratch with a fresh Makefile:

git checkout -- Makefile

The thing is I didn’t change anything else. The main line looks either like this

gcc -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wno-unused -DOS_UNIX -o glulxe main.o files.o vm.o exec.o funcs.o operand.o string.o glkop.o heap.o serial.o search.o accel.o float.o gestalt.o osdepend.o profile.o unixstrt.o -L../cheapglk -lcheapglk -lm (which works)

or this

i686-w64-mingw32-gcc -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wno-unused -DWIN32 -o glulxe main.o files.o vm.o exec.o funcs.o operand.o string.o glkop.o heap.o serial.o search.o accel.o float.o gestalt.o osdepend.o profile.o unixstrt.o -L../cheapglk -lcheapglk -lm (which doesn’t) but I don’t see any difference besides those two points.

Not sure if I got this correctly, but in the makefile, it says:

CFLAGS = $(OPTIONS) -I$(GLKINCLUDEDIR)

Oh, I see! CFLAGS is defined like this, but it isn’t used in the makefile at all. I have no idea whether CFLAGS have to be used explicitly (which they currently aren’t) or if they are passed to/used by the compiler automatically.

It’s used automatically. When make sees that glulxe depends on $(OBJS), a bunch of .o files, it uses implicit rules to create those .o files by compiling the corresponding .c files. See this explanation in the make manual. Note that it says “For example, the variable CFLAGS controls the flags given to the C compiler by the implicit rule for C compilation.”

The final link command (the one with -o glulxe) is given in the Makefile explicitly and uses $(OPTIONS), while the implicit commands to compile the individual .o files (the ones with -c -o foo.o foo.c) use $(CFLAGS), which is defined to contain both $(OPTIONS) and -I$(GLKINCLUDEDIR). But, somehow, the $(OPTIONS) defined in the Makefile, most importantly -DWIN32, aren’t making it into those commands, just the -I…/cheapglk.

It would be interesting to see the output of your compilation if you changed CFLAGS like this:

CFLAGS = -DBEFORE_OPTIONS $(OPTIONS) -DAFTER_OPTIONS -I$(GLKINCLUDEDIR)

The correspoding line in the makefile is

$(CC) $(OPTIONS) -o glulxe $(OBJS) unixstrt.o $(LIBS)

where

LIBS = -L$(GLKLIBDIR) $(GLKLIB) $(LINKLIBS) -lm

and in the actuall command we have

... -o glulxe main.o files.o vm.o exec.o funcs.o operand.o string.o glkop.o heap.o serial.o search.o accel.o float.o gestalt.o osdepend.o profile.o unixstrt.o -L../cheapglk -lcheapglk  -lm

Which means that the -o part simply correctly includes what it should include.

Now do I understand it correctly that you are saying that on top of that, it should also have CFLAGS (and thus also OPTIONS) parameters right after these? Such as:

... -o glulxe main.o files.o vm.o exec.o funcs.o operand.o string.o glkop.o heap.o serial.o search.o accel.o float.o gestalt.o osdepend.o profile.o unixstrt.o -L../cheapglk -lcheapglk -lm -DWIN32 -... ?

I can achieve this easily by manually adding the -DWIN32 or whatever is needed. However, the build still fails in the completely same way (undefined refs to glk stuff).

No. I’m saying that that command is fine, but that all of the other commands preceding it:

i686-w64-mingw32-gcc -I../cheapglk -c -o main.o main.c ... i686-w64-mingw32-gcc -I../cheapglk -c -o unixstrt.o unixstrt.c should also contain the OPTIONS.

They should look like:

i686-w64-mingw32-gcc -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wno-unused -DWIN32 -I../cheapglk   -c -o main.o main.c
...
i686-w64-mingw32-gcc -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wno-unused -DWIN32 -I../cheapglk   -c -o unixstrt.o unixstrt.c

Oh, I made a huge mistake – they do look exactly like that!

I’ve got absolutely no idea how I managed to copy the make output badly in the first post – I must have just copied output of another version of the makefile as I was messing around with it – but this is the correct full output:

pastebin.com/MXS1zpfE

I’m so sorry for the confusion :frowning: As one of my college professors likes to say, copying is a major source of mistakes (and yet I never learn).

The problem still persists, though… :slight_smile:

The output suggests that none of the glk api functions called by glulxe are able to be resolved when trying to link with cheapglk.

My intuition says that maybe the relative pathnames for the glk include and libdirs are a problem in a cross-compilation environment.

I assume that you compiled cheapglk with CC=i686-w64-mingw32-gcc also?

I actually didn’t – I did try it, but it didn’t work either and I hoped it wouldn’t be needed.

But I finally managed to make it work! As you say, I needed to compile the cheapglk in the same way (mingw32 CC and -DWIN32 option). The problem was that I got a warning for bzero function when compiling:

i686-w64-mingw32-gcc -g -Wall -DWIN32    -c -o cgdate.o cgdate.c
cgdate.c: In function ‘gli_date_to_tm’:
cgdate.c:45:5: warning: implicit declaration of function ‘bzero’ [-Wimplicit-function-declaration]
     bzero(tm, sizeof(*tm));
     ^
cgdate.c:45:5: warning: incompatible implicit declaration of built-in function ‘bzero’

But it did comopile. However, compiling glulxe then gave:

i686-w64-mingw32-gcc -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wno-unused -DWIN32 -o glulxe main.o files.o vm.o exec.o funcs.o operand.o string.o glkop.o heap.o serial.o search.o accel.o float.o gestalt.o osdepend.o profile.o unixstrt.o -L../cheapglk -lcheapglk  -lm
../cheapglk/libcheapglk.a(cgdate.o): In function `gli_date_to_tm':
/media/win_d/documents/diplomka/linux/src/cheapglk/cgdate.c:45: undefined reference to `bzero'
collect2: error: ld returned 1 exit status
Makefile:48: recipe for target 'glulxe' failed
make: *** [glulxe] Error 1

However, if I comment out the line

bzero(tm, sizeof(*tm));

it works like a charm and I can now run cheapglk+glulxe in Windows!

I’m not sure what I should do with the bzero function, though. Is it even needed, doesn’t the code set all its values anyway?

Thank you so much for the help :slight_smile:

bzero isn’t a standard C function; it was originally added to some compilers to be more efficient than memset in the case of only writing zeroes.

However, I know that gcc and clang at least can optimize memset calls automatically, including checks for writing a block of zeroes. So that reason isn’t really applicable any more, and usually isn’t worth sacrificing portability.

If there’s only the one call, you can replace it with memset(tm, 0, sizeof(*tm)). If there are a lot of them, the Open Group spec recommends putting

#define bzero(b,len) (memset((b), '\0', (len)), (void) 0) into your file to define bzero in terms of memset.

So…to jump in a bit late, I’m having trouble compiling cheapglk or getting close to it. And I want to, so I can have a way to use Zarf’s framework.

Myke, are you saying you build a binary that will allow people to stand STDIN to a text (non-windows) terminal and get game text back? If so, would you be willing to share it? It seems like you built it in a unix environment, and I just realized I’m pretty helpless without a CSPROJ or VCPROJ file or whatever.

Hello, yes, it should work exactly like this. I’ve shared the (hopefully working) binaries here: github.com/MikulasZelinka/glulx … ulxe-0.5.2

Let me know if they work for you, please – I’ve only had limited chances of testing it so far :slight_smile: Do you think I should upload the binaries to the IFArchive?

Oops. I missed your reply.

They do work on my local binaries, which is kind of awesome. I think they are VERY worth loading to the IFArchive, because I think once people know they’re there, they will be able to go about more complex testing. Which helps everyone. It means testers won’t hit game-breaking bugs, and programmers won’t have to ask testers to retry stuff they already did. So I give a big YES to that.

Thank you very much for figuring how to build the bianries! It should be a huge help to me, and I’ll encourage others to use them, too.

Since you’ve figured out all the levers and screws for building on Windows, could I ask that you also do a build with RemGlk? It should go together the same as CheapGlk did.

(RemGlk output isn’t formatted for humans to read, but it includes all the stuff that CheapGlk throws away – styles, windows, ability to accept non-line-input events, etc. If you do serious testing, you may eventually want to switch to RemGlk.)

Oops, I jumped the gun here. The compiled cheapglk app worked, and I assumed everything would be good for Python.

When I run Zarf’s Adventure example through Python, I get the following error:

error: (10093, ‘Either the application has not called WSAStartup, or WSAStartup failed’)

This seems to indicate we need a Windows ifdef for how we handle sockets on windows for Cheapglulxe. Googling WSAStartup gives something like this:

stackoverflow.com/questions/3359 … link-error

Which doesn’t look too bad, if we’re able to compile on Windows and poke around in Visual Studio Community or whatever. But it looks like there is some porting work to make things available for testing.

Sure, I’ll try doing that (not until next week, though) :slight_smile: It might be worth noting that I can now build it for Windows (on Unix), not on Windows (which is something Andrew is struggling with and I, perhaps luckily, decided not to even go to the trouble of trying to make it work.

This looks troublesome – but to me it seems like a Python error (i.e. independent of the binary), or am I wrong? I know that a lot of stuff doesn’t work for Windows in Python but it does work on Unix, isn’t this the case too?

That was my initial guess, but the thing is–googling the specific error seemed to indicate a socket wasn’t getting open.

It may be easier, ultimately, to open up a Linux VM on my Windows machine and try things from there. That’s not something I’ve done, but it’s important enough for me to try. And if it works, that is more than good enough.

I don’t see why compiling for windows wouldn’t work, and so I suspected your solution was okay. But I wouldn’t be surprised if windows and unix handle sockets differently. WSAStartup is a Windows specific function, and as such, I suspect the problem is that the Unix code would need an Ifdef. There was no way to see this in advance.

Still, emulation seems like the simplest solution. Waiting for a 30mb download or whatever seems like it will take less time than figuring what is wrong and how to build on Windows, so I want to try that. Any solution that works is fine by me, and I’ve always needed the motivation to install Linux or a VM on my machine anyway. Something like this is well worth it.

Somehow I lost my way on getting Frotz + RemGlk (or CheapGlk) to build on Linux. Anyone know the magic?

Adapted the Glulxe Makefile, this seems to work for linking with RemGlk on desktop:

[spoiler][code]

Unix Makefile for Frotz, adapted from Glulxe.

WARNING: This is made by someone who really doesn’t grasp Makefiles

GLKINCLUDEDIR = …/cheapglk

GLKLIBDIR = …/cheapglk

GLKMAKEFILE = Make.cheapglk

#GLKINCLUDEDIR = …/glkterm
#GLKLIBDIR = …/glkterm
#GLKMAKEFILE = Make.glkterm

#GLKINCLUDEDIR = …/xglk
#GLKLIBDIR = …/xglk
#GLKMAKEFILE = Make.xglk

GLKINCLUDEDIR = …/remglk
GLKLIBDIR = …/remglk
GLKMAKEFILE = Make.remglk

#GLKINCLUDEDIR = …/gtkglk/src
#GLKLIBDIR = …/gtkglk
#GLKMAKEFILE = …/Make.gtkglk

Pick a C compiler.

#CC = cc
CC = gcc

OPTIONS = -g

include $(GLKINCLUDEDIR)/$(GLKMAKEFILE)

CFLAGS = $(OPTIONS) -I$(GLKINCLUDEDIR) $(XMLLIBINCLUDEDIR)
LIBS = -L$(GLKLIBDIR) $(GLKLIB) $(LINKLIBS) -lm

OBJS = buffer.o files.o input.o
object.o random.o stream.o variable.o
err.o glkmisc.o main.o process.o redirect.o table.o
fastmem.o glkscreen.o math.o quetzal.o sound.o text.o

all: frotz

frotz: $(OBJS) main.o
$(CC) $(OPTIONS) -o frotz $(OBJS) $(LIBS)

clean:
rm -f *~ *.o frotz

[/code][/spoiler]

Does the frotz that is built this way actually work, though?

Also, if anyone’s having trouble compiling glulxe (or simply too lazy :)), here are the compiled binaries for glulxe with cheapglk and remglk (cheapglulxe, remglulxe) for Linux: github.com/MikulasZelinka/glulx … ses/latest

Feel free to share them/post them anywhere (on ifarchive, for example).

Sure, it work, you can link it with Glk libs just like Glulxe. Son of Hunky Punk has been published and compiled frotz that same basic way. The Makefile for Android’s Linux (cross-compiler) is pretty similar: github.com/retrobits/son_of_hun … Android.mk

Thanks! This was very helpful