Compiling Glulxe and Cheapglk in linux

(bg) #5

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

0 Likes

(bg) #6

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?

0 Likes

(Andrew Plotkin) #7

Yes.

0 Likes

(bg) #8

Thank you!

0 Likes

#9

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.

0 Likes

#10

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.

0 Likes

#11

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.)

0 Likes

#12

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.

0 Likes

(Andrew Plotkin) #13

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.)

0 Likes

#14

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).

0 Likes

#15

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
0 Likes

#16

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.

0 Likes

#17

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)
0 Likes

#18

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).

0 Likes

#19

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
0 Likes

#20

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:

0 Likes

#21

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?

0 Likes

#22

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:

0 Likes

(Daniel Stelzer) #23

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.

0 Likes

#24

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.

0 Likes