EXL / Gish

A port of the Gish game for Android OS using SDL2, OpenAL, Ogg Vorbis and GL4ES libraries.
https://exlmoto.ru/gish-droid/
GNU General Public License v2.0
45 stars 4 forks source link

Errors linking a GNU/Linux version #7

Open vanfanel opened 2 years ago

vanfanel commented 2 years ago

Hi there, @EXL

I have just discovered this Gish SDL2 port you have done, which I believe is the only SDL2 version available of the sources (correct me if I am wrong on this).

I have tried to build a GNU/Linux version (not Android, but plain GNU/Linux) using gish/src/main/cpp/CMakeLists.txt, and the game builds, but it fails during the final linking phase:

[ 98%] Linking C executable Gish
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/custom.c.o:(.bss+0x0): multiple definition of `fread2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x0): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/custom.c.o:(.bss+0x8): multiple definition of `fwrite2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x8): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/game.c.o:(.bss+0x0): multiple definition of `numofobjectrenders'; CMakeFiles/Gish.dir/Gish/game/editor.c.o:(.bss+0x0): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/game.c.o:(.bss+0x20): multiple definition of `objectrender'; CMakeFiles/Gish.dir/Gish/game/editor.c.o:(.bss+0x20): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/gametexture.c.o:(.bss+0x0): multiple definition of `fread2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x0): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/gametexture.c.o:(.bss+0x8): multiple definition of `fwrite2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x8): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/high.c.o:(.bss+0x0): multiple definition of `fread2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x0): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/high.c.o:(.bss+0x8): multiple definition of `fwrite2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x8): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/level.c.o:(.bss+0x0): multiple definition of `fread2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x0): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/level.c.o:(.bss+0x8): multiple definition of `fwrite2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x8): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/lighting.c.o:(.bss+0x0): multiple definition of `numofobjectrenders'; CMakeFiles/Gish.dir/Gish/game/editor.c.o:(.bss+0x0): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/lighting.c.o:(.bss+0x20): multiple definition of `objectrender'; CMakeFiles/Gish.dir/Gish/game/editor.c.o:(.bss+0x20): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/music.c.o:(.bss+0x0): multiple definition of `fread2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x0): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/music.c.o:(.bss+0x8): multiple definition of `fwrite2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x8): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/player.c.o:(.bss+0x0): multiple definition of `fread2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x0): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/player.c.o:(.bss+0x8): multiple definition of `fwrite2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x8): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/prerender.c.o:(.bss+0x0): multiple definition of `numofobjectrenders'; CMakeFiles/Gish.dir/Gish/game/editor.c.o:(.bss+0x0): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/prerender.c.o:(.bss+0x20): multiple definition of `objectrender'; CMakeFiles/Gish.dir/Gish/game/editor.c.o:(.bss+0x20): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/render.c.o:(.bss+0x0): multiple definition of `numofobjectrenders'; CMakeFiles/Gish.dir/Gish/game/editor.c.o:(.bss+0x0): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/render.c.o:(.bss+0x20): multiple definition of `objectrender'; CMakeFiles/Gish.dir/Gish/game/editor.c.o:(.bss+0x20): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/replay.c.o:(.bss+0x0): multiple definition of `fread2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x0): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/game/replay.c.o:(.bss+0x8): multiple definition of `fwrite2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x8): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/sdl/endian.c.o:(.bss+0x0): multiple definition of `fread2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x0): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/sdl/endian.c.o:(.bss+0x8): multiple definition of `fwrite2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x8): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/sdl/file.c.o:(.bss+0x0): multiple definition of `fread2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x0): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/sdl/file.c.o:(.bss+0x8): multiple definition of `fwrite2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x8): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/video/texture.c.o:(.bss+0x0): multiple definition of `fread2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x0): first defined here
/usr/bin/ld: CMakeFiles/Gish.dir/Gish/video/texture.c.o:(.bss+0x8): multiple definition of `fwrite2'; CMakeFiles/Gish.dir/Gish/game/block.c.o:(.bss+0x8): first defined here
collect2: error: ld returned 1 exit status

So almost there, but not quite there! Do you have an idea on why is this happening? Seems like some simple omission, but I don't know what it could be. Any ideas?

EXL commented 2 years ago

Hello, @vanfanel

This is one of the problems in legacy C code with globals in the header files.

GCC now defaults to -fno-common. As a result, global variable accesses are more efficient on various targets. In C, global variables with multiple tentative definitions now result in linker errors. With -fcommon such definitions are silently merged during linking.

https://gcc.gnu.org/gcc-10/changes.html

Quickfix here: 9fd9253cb2b58f8f6294f427776e9c227bef289a.

Cheers!

vanfanel commented 2 years ago

@EXL Whoa, that was fast! I understand the issue now... Thanks! Time to try this on the Pi! :D

vanfanel commented 2 years ago

@EXL Ooops, I think there was a typo on your fix, look:


[  1%] Building C object CMakeFiles/Gish.dir/Gish/audio/audio.c.o
cc: fatal error: no input files
compilation terminated.
/bin/sh: 1: -fcommon: not found
EXL commented 2 years ago

@vanfanel Hmm, I tested this on Ubuntu 22.04 LTS and it worked.

Please run make in such way for more information about failed command:

make VERBOSE=1

And try to quote the options in CMakeLists.txt:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon")
vanfanel commented 2 years ago

@EXL Ah, I see, it works if I simply run cmake. But if I pass CFLAGS like this, it fails:

cmake -DCMAKE_C_FLAGS="-march=native -mtune=native" ..

This is the relevant part in verbose make:


Scanning dependencies of target Gish
make[2]: Leaving directory '/home/manuel/src/Gish/gish/src/main/cpp/b4'
make  -f CMakeFiles/Gish.dir/build.make CMakeFiles/Gish.dir/build
make[2]: Entering directory '/home/manuel/src/Gish/gish/src/main/cpp/b4'
[  1%] Building C object CMakeFiles/Gish.dir/Gish/audio/audio.c.o
/usr/bin/cc  -I/home/manuel/src/Gish/gish/src/main/cpp/Gish -I/usr/include/SDL2 -I/usr/include/AL -march=native -mtune=native;-fcommon -o CMakeFiles/Gish.dir/Gish/audio/audio.c.o -c /home/manuel/src/Gish/gish/src/main/cpp/Gish/audio/audio.c
cc: fatal error: no input files
compilation terminated.
/bin/sh: 1: -fcommon: not found
EXL commented 2 years ago

@vanfanel yep, looks like the quotes are needed. Damn, I hate CMake.

Please try again with 3a8af8a.

EXL commented 2 years ago

I will be very happy if it works on RPi.

BTW, there was an OpenGL ES renderer which can be enabled by the -DGLES=ON option for CMake.

vanfanel commented 2 years ago

@EXL Now it works with the added CFLAGS!

And yes, it works on the Pi4, too, both in OpenGL and GLES renderers. OpenGL needs MESA built with GLVND support, since I don't have/want the old GLX.

Performance is very good, too!

EDIT: Forgot to mention I had to disable GLX package searching so it builds on my system (which as I said uses GLVND, not GLX). Can you please disable mandatory GLX? GLX is a semi-deprecated implementation. Full OpenGL is -lOpenGL (=GLVND) today, not -lGL (GLX) anymore.

vanfanel commented 2 years ago

I am also trying to make this run without X11 (no GLX, no X11) using KMS/DRM on GNU/Linux. SDL2 has support for KMS/DRM, but you seem to be manually creating an EGL context here: https://github.com/EXL/Gish/blob/3a8af8a72b3c25a49c15ca15303913a0d3198636/gish/src/main/cpp/Gish/main.c#L242

I think you should let SDL2 create the context, because by doing the manual EGL context creation you are tying the game to the old X11 API.

In other words, PC_GLES is not X11 anymore: it's Wayland, direct KMS/DRM... And SDL2 should take care of it as you do in: https://github.com/EXL/Gish/blob/3a8af8a72b3c25a49c15ca15303913a0d3198636/gish/src/main/cpp/Gish/main.c#L246

EXL commented 2 years ago

@vanfanel

Now it works with the added CFLAGS!

Ok, nice!

Can you please disable mandatory GLX? GLX is a semi-deprecated implementation. Full OpenGL is -lOpenGL (=GLVND) today, not -lGL (GLX) anymore.

I think you should let SDL2 create the context, because by doing the manual EGL context creation you are tying the game to the old X11 API.

There is a lot of ancient code in this project. You can make some PRs to update these things if you have the time and desire for that.

I myself want to update the Android build when I have enough time to do so and make it possible for this application to work on modern versions of Android OS without any warnings. Also I want to get rid of some of the bad practices in this code that involve constantly changing the working directory with chdir() to load datafiles.

vanfanel commented 2 years ago

@EXL There's a LOT of Windows-centric code there, and missing Linux stuff.

For example, for non-GLX OpenGL to work on Linux, you must retrieve the function address for glMultiTexCoord2fARB and glActiveTextureARB in opengl.c, as you do on the Windows #ifdefs for these and other extensions. ...But then, glMultiTexCoord2fARB and glActiveTextureARB appear as redefined because opengl.h has the OpenGL includes directly, so I would have to define someting like glMultiTexCoord2fARBEXT and glActiveTextureARBEXT and store the extension addresses there, but that would break the Windows code...

So, the problem with all this has deep roots. I would remove all Windows specific code, and do everything via SDL2, but I couldn't even test if Windows still works because I don't have a single Windows computer or interest in one.

So, you see, I would happily modernize it myself, but I don't know how broken other OSes would be after that.

EXL commented 2 years ago

@vanfanel I think that the priority here is only Linux and Android platforms. The code for Android will someday also be updated, so there is no problem if something breaks there.

I can give you r/w access to this repository so you don't have to bother with PRs and can push commits directly if that's more convenient for you.

vanfanel commented 2 years ago

@EXL I have fixed non-GLX OpenGL, but as I said I had to store the glActiveTextureARB function pointer in a pointer called glActiveTextureARBEXT, because if I use I declare PFNGLACTIVETEXTUREARBPROC glActiveTextureARB=NULL; as you do on Windows, I get an error from gcc saying that it's previously defined on gl.h. Do you, by a chance, know how to get around this on GNU/Linux? I don't want to rename all the extension function pointers... I have also asked this on the SDL discord channel, but o far I didn't get an answer.

After I get that sorted, sure, I will update the code on your repo, you can give me the premissions if you want.

EXL commented 2 years ago

Do you, by a chance, know how to get around this on GNU/Linux?

IDK. I would probably also look for a solution to this problem on the forums or among various code on GitHub if I ran into this.

After I get that sorted, sure, I will update the code on your repo, you can give me the premissions if you want.

Access granted.

vanfanel commented 2 years ago

@EXL Since SDL2 now manages context, the x11-specific code is redundant. Can I have the pleasure to remove that "supposedly dead" code?

It means removing anything inside a PC_GLES ifdef

EXL commented 2 years ago

@vanfanel Yes. AFAIR code inside PC_GLES was used to debug GLES render. It was more convenient to run the debug builds on a PC than on Android.

vanfanel commented 2 years ago

@EXL Ah! While we are at it, do you remember if there's some way to control the game aspect ratio? Running it on a modern 16:9 screen totally ruins it by stretching the graphics, since Gish is designed to run on 4:3

Seems like glViewPort() call in setuporthoviewport is where I can adjust the aspect ratio, but it doesn't affect the sorrounding graphics....

EDIT: To set the size of the menus, etc... the glViewPort() call in setuptextdisplay() is used.

EXL commented 2 years ago

@vanfanel If you keep the aspect ratio at 4:3 will there be black bars on the sides?

There is also a zoom parameter perhaps with its help this aspect ratio troubles somehow be solved.