Compiling Glulxe and Cheapglk in linux

These instructions say:

I’ve tried to compile this without changing the makefile at all. Although it doesn’t compile with “./make”, it does seem to compile with “make”. But I’m getting error messages when I try to launch a game (permissions denied) so I’m revisiting the variables in case that’s causing the problem.

The readme here github.com/erkyrath/glulxe/blob/master/README says

And the instructions in the Makefile say

I’m new to linux, python, and virtual machines, and I’ve been struggling with file paths and permissions. Can someone please give an example of what these variables should look like? Apparently a / at the beginning of a file path, or not, makes a difference with permissions? And my virtual machine doesn’t seem to have any obvious drive letter, so I can’t start with C:, as far as I know. I’m also not sure what the “…” is in the Makefile.

Also, there a particular place I should look for an include directory? The Makefile for Cheapglk says

I see a lib directory in the virtualenv, but no include directory…

The intended (simplistic) setup is that the “glulxe” and “cheapglk” directories are children of the same parent directory. The “…” in the Makefile means “parent directory”, so Glulxe will look for a sibling directory called “cheapglk” and find its files there.

Do “make” in the cheapglk directory, then “make” in the glulxe directory. If this succeeds without errors, then you have built a working interpreter. Type “./glulxe” to run it.

Thank you!

Well, for glulxe there was a warning…I’m not sure if any of this is errors though.

That warning is a valid one, but you can ignore it: there are a few edge cases where it’s important to use mkstemp instead of tmpnam to pick temporary file names, but tmpnam is in the Standard Library and mkstemp is POSIX. No errors.

Ok, thanks. If that’s working, then I guess the problem must be with something else.

Clarification question: once the “glulxe” file is built, it’s then independent of all the other files/folders (the cheapglk folder, accel.c, accel.o, exec.c, exec.o, etc.) and can move anywhere, correct?

Yes.

Thank you!

I’m trying to build cheapglk+glulxe on Windows using Cygwin (i.e., build for Unix – I’ll try to build for Windows once I can at least build it for Unix), but with no luck so far.

The problem is that after making cheapglk, glulxe library uses some time functions from glibc which aren’t a part of whatever cygwin has:

mk@mpc /cygdrive/d/documents/diplomka/glulxe
$ make glulxe
gcc -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wno-unused -I../cheapglk   -c -o main.o main.c
...
gcc -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wno-unused -I../cheapglk   -c -o unixstrt.o unixstrt.c
gcc -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wno-unused -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':
D:\documents\diplomka\cheapglk/cgdate.c:45: undefined reference to `bzero'
../cheapglk/libcheapglk.a(cgdate.o): In function `glk_time_to_date_utc':
D:\documents\diplomka\cheapglk/cgdate.c:148: undefined reference to `gmtime_r'
../cheapglk/libcheapglk.a(cgdate.o): In function `glk_time_to_date_local':
D:\documents\diplomka\cheapglk/cgdate.c:164: undefined reference to `localtime_r'
../cheapglk/libcheapglk.a(cgdate.o): In function `glk_simple_time_to_date_utc':
D:\documents\diplomka\cheapglk/cgdate.c:176: undefined reference to `gmtime_r'
../cheapglk/libcheapglk.a(cgdate.o): In function `glk_simple_time_to_date_local':
D:\documents\diplomka\cheapglk/cgdate.c:188: undefined reference to `localtime_r'
../cheapglk/libcheapglk.a(cgdate.o): In function `glk_date_to_time_utc':
D:\documents\diplomka\cheapglk/cgdate.c:205: undefined reference to `timegm'
../cheapglk/libcheapglk.a(cgdate.o): In function `glk_date_to_simple_time_utc':
D:\documents\diplomka\cheapglk/cgdate.c:238: undefined reference to `timegm'
collect2: ld returned 1 exit status
make: *** [Makefile:47: glulxe] Error 1

So I figured I would simply avoid Cygwin and build it on Ubuntu.

What is worse, though, is that I can’t even make this work on Ubuntu. After successfully making cheapglk and running make glulxe, I get:

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
/usr/bin/ld: skipping incompatible ../cheapglk/libcheapglk.a when searching for -lcheapglk
/usr/bin/ld: cannot find -lcheapglk
collect2: error: ld returned 1 exit status
Makefile:47: recipe for target 'glulxe' failed
make: *** [glulxe] Error 1

For some reason (and for some reason, it doesn’t really say for what reason), the compiled library is seen as incompatible… Funny thing is that when I make cheapglk and then make glulxe on Windows using Cygwin (as above), this error does not appear and it only fails because Cygwin doesn’t have the glibc time functions. Whereas on Linux, it fails even sooner. I left everything as it is in the GitHub repositories.

Any ideas what might be the problem here (besides me, of course)? :slight_smile:

As a sidenote, I don’t really need (or want) to build this on my own (I already spent a good few hours on it), I simply need a working (compiled) version of glulxe with cheapglk for Linux and Windows – if anyone had a working latest version for any of these, it would be hugely appreciated.

Alright, so I managed to solve the problem. I’ll keep my first post there in case someone has a similar problem.

I still have no idea why the above didn’t work but now I at least know how to make it work. The Vince’s post was a great help.

To build glulxe with cheapglk/remglk in an ifstuff folder, you need to do this (all credit to Vince, I only added the folder removal if you need to build both versions):

rm -rf ifstuff # this needs to be done, since once you build glulxe with one of {cheapglk|remglk}, you can't build it with the other unless you clean the folder
mkdir ifstuff
cd ifstuff
git clone https://github.com/erkyrath/glulxe
git clone https://github.com/erkyrath/{cheapglk|remglk}
cd {cheapglk|remglk}
make
cd ../glulxe
edit Makefile # toggle comments on {cheapglk|remglk} lines and save
make
mv glulxe {cheap|rem}glulxe

Now I have no idea why what I did before didn’t work. The issues might include: I used Windows to get the files from git and edit makefiles. Maybe that broke them. I also used one glulxe folder while trying to build it with cheap/remglk.

If you want to rebuild glulxe with another glk lib (let’s call it otherglk), you should be able to get away with the less drastic:

cd ifstuff/glulxe make clean edit Makefile to select otherglk and save make instead of blowing away everything with rm -rf.

(This assumes that you’ve already placed otherglk in ifstuff and built it.)

Yeah, that’s certainly better :slight_smile:

Now I’m trying to achieve the same for Windows using mingw (cross-compiling from Linux).

In the makefile, I changed

CC = gcc
[/code] to [code]
CC = i686-w64-mingw32-gcc

However, I get errors:

myke@myke-VirtualBox:/media/win_d/Documents/diplomka/linux/src/glulxe$ make
i686-w64-mingw32-gcc -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wno-unused -DOS_UNIX=1 -DOS_WIN=0 -I../cheapglk   -c -o main.o main.c
...
i686-w64-mingw32-gcc -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wno-unused -DOS_UNIX=1 -DOS_WIN=0 -I../cheapglk   -c -o osdepend.o osdepend.c
osdepend.c: In function ‘glulx_setrandom’:
osdepend.c:48:3: warning: implicit declaration of function ‘srandom’ [-Wimplicit-function-declaration]
   srandom(seed);
   ^
osdepend.c: In function ‘glulx_random’:
osdepend.c:54:3: warning: implicit declaration of function ‘random’ [-Wimplicit-function-declaration]
   return (random() << 16) ^ random();
   ^
osdepend.c: At top level:
osdepend.c:111:7: error: redefinition of ‘glulx_malloc’
 void *glulx_malloc(glui32 len)
       ^
osdepend.c:23:7: note: previous definition of ‘glulx_malloc’ was here
 void *glulx_malloc(glui32 len)
       ^
osdepend.c:119:7: error: redefinition of ‘glulx_realloc’
 void *glulx_realloc(void *ptr, glui32 len)
       ^
...
osdepend.c:140:8: error: redefinition of ‘glulx_random’
 glui32 glulx_random()
        ^
osdepend.c:52:8: note: previous definition of ‘glulx_random’ was here
 glui32 glulx_random()
        ^
<builtin>: recipe for target 'osdepend.o' failed
make: *** [osdepend.o] Error 1

This happens because all these functions are defined twice in osdepend.c (once in #ifdef OS_UNIX and then in #ifdef WIN32) (or three times, once for Mac too).

But why does the compiler look into both of them? How is it possible that it thinks it is compiling for both UNIX and WIN32 (or is it even the case)?

I was wondering what the option DOS_UNIX does and wasn’t able to google it at all. Nevertheless, I tried changing it to -DOS_UNIX=0 -DOS_WIN=1 but this didn’t change anything.

Also, I tried deleting the UNIX or WIN32 parts of osdepend.c (I don’t think I’m supposed to do that), but that didn’t help either – undefined references to glk stuff started popping up instead (but that might be another error? no idea).

Do you have any idea what I might be doing wrong, please? I’ll start a different topic if this turns out to be a more complicated problem.

The OS_ options are either present (in the Makefile) or not. It’s not a 0/1 situation. You probably want

OPTIONS = -g -Wall -Wmissing-prototypes -Wstrict-prototypes -Wno-unused -DWIN32

(But I’ve never built it on Windows, so someone may have more of a clue.)

Thank you! :slight_smile:

When I googled it, I found usages such as those I posted, but -DWin32 does indeed help. Or does it? Now it produces a different error, a bunch of undefined references to glk_anything (or possibly glk_everything) in all the files:

myke@myke-VirtualBox:/media/win_d/Documents/diplomka/linux/src/glulxe$ make
i686-w64-mingw32-gcc -I../cheapglk   -c -o main.o main.c
...
i686-w64-mingw32-gcc -I../cheapglk   -c -o unixstrt.o unixstrt.c
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
main.o:main.c:(.text+0x66): undefined reference to `glulx_setrandom'
main.o:main.c:(.text+0xdd): undefined reference to `glk_exit'
main.o:main.c:(.text+0x111): undefined reference to `glk_window_get_root'
main.o:main.c:(.text+0x146): undefined reference to `glk_window_open'
...
accel.o:accel.c:(.text+0x454): undefined reference to `glk_put_char'
unixstrt.o:unixstrt.c:(.text+0x82): undefined reference to `glkunix_stream_open_pathname'
unixstrt.o:unixstrt.c:(.text+0xc9): undefined reference to `glk_stream_set_position'
unixstrt.o:unixstrt.c:(.text+0xe5): undefined reference to `glk_get_buffer_stream'
/usr/lib/gcc/i686-w64-mingw32/4.9-win32/../../../../i686-w64-mingw32/lib/../lib/libmingw32.a(lib32_libmingw32_a-crt0_c.o): In function `main':
/build/buildd/mingw-w64-4.0.2/build/i686-w64-mingw32-i686-w64-mingw32-crt/../../mingw-w64-crt/crt/crt0_c.c:18: undefined reference to `WinMain@16'
collect2: error: ld returned 1 exit status
Makefile:46: recipe for target 'glulxe' failed
make: *** [glulxe] Error 1

The ‘only’ difference between this error and the working version is CC = gcc (in the working version, works with either DOS_UNIX or DWIN32) and CC = i686-w64-mingw32-gcc (which produces these errors with DWIN32).

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: