Generally building static is frowned upon when building for Apple and Apple especially made it hard on purpose to do so. In *theory* you can just exchange bundled dylibs with newer ones (if the version reported matches (the one you see with otool)).
Then there are things like munt that don't provide a static lib right away (no problem when you do your own prefix but once you rely on a package manager you only get dylibs) or the monster fluidsynth that pulls in a lot of libraries and if I understood correctly one of those (glib2) won't work correctly if compiled in statically.
Not to mention that patching or changing the makefile is always risky or prone to fail (maybe even silently because a new dylib dependency of one of the libs) and that's annoying for my buildbot workflow 😀
So for my big other project (Exult) I've abandoned static and with the workflow of dylibbundler it's easy to bundle.
Dominuswrote on 2021-03-11, 22:07:Generally building static is frowned upon when building for Apple and Apple especially made it hard on purpose to do so. In *the […] Show full quote
Generally building static is frowned upon when building for Apple and Apple especially made it hard on purpose to do so. In *theory* you can just exchange bundled dylibs with newer ones (if the version reported matches (the one you see with otool)).
Then there are things like munt that don't provide a static lib right away (no problem when you do your own prefix but once you rely on a package manager you only get dylibs) or the monster fluidsynth that pulls in a lot of libraries and if I understood correctly one of those (glib2) won't work correctly if compiled in statically.
Not to mention that patching or changing the makefile is always risky or prone to fail (maybe even silently because a new dylib dependency of one of the libs) and that's annoying for my buildbot workflow 😀
So for my big other project (Exult) I've abandoned static and with the workflow of dylibbundler it's easy to bundle.
Yes, I guess that all makes sense. It would actually be harder than patching the make files if were not for the availability of the dylib bundler program. Otherwise, it would all have to be done manually with install_name_tool, and that could take a long time with libraries like fluidsynth.
I have used the amended command you gave me to fix my current app package. It now has the Glide libraries in /lib but of course, it still fails to look inside the wrapper due to the underlying issue with the OpenGlide code.. at least for now I have done all I can with it. A few weeks ago I thought it was impossible to get OpenGlide working at all, so I am happy with the progress thus far.
@emendelson - thanks for the intense effort on the script this week .. I will give it a try over the weekend.
@emendelson - I did a quick test with your script on my Mojave system and it appears to work perfectly. I will try it on my Big Sur install and report back soon as possible.
@Dominus - I have solved the dylib location problem with OpenGlide. I will type up how I did it and report back as well.
The issue with OpenGlide is it insists on looking for its own copy of SDL1, and ignores the one already packaged into my app wrapper with dylibbundler.
So, I started by making a fresh non-static build of my patched SVN source, packing that into my custom app wrapper, and installing the standard dylib dependencies with dylibbundler.
My wrapper contains a launcher binary that calls a shell script, which basically redirects everything DOSBox needs to inside the wrapper, including the configuration/preferences file. This is because I like to package my games as individual apps.
I resolved the problem by first adding an extra line to the shell script that specifies a fall-back path for dylibs (i.e. if they cannot otherwise be located at the system level in usr/local.
I had tested with keeping the Glide libraries in the same /lib folder as the other dylibs, but it still showed me the Glide dylib was looking for SDL in usr/local/cellar/SDL.
But after trial and error, I found out that if I put the Glide libraries in a sub-folder of Resources/lib in my app package, it finds the Glide library in there (i.e. /lib/glide).
Lastly, I had to place a copy of libSDL-1.2.0.dylib inside the same sub-folder containing the Glide dylibs.
This means there are two copies of SDL in the app wrapper - one that DOSBox binary finds under Resources/lib and another that Glide finds under Resources/lib/glide.
With the edited shell script command, I then checked in Activity Monitor that everything was pointing to the internal locations:
The second entry is the one that DOSBox itself is using.
The correct ini and log files were generated by OpenGlide, confirming it was working correctly. I launched and tested the Glide functionality in Lands of Lore 2.
I should also add that I temporarily removed the SDL folder in usr/local/Cellar, because my script only specifies a fall-back location. If a macOS install has SDL installed, Glide will still look in there, but if it is missing, the script will ensure that it looks inside the wrapper instead.
EDIT - I have not yet uploaded the corrected wrapper to my Github site, but will do so over the weekend.
This way of loading the lib wasn't really well thought out by the OpenGlide devs back then 🙁
Another way that should work without the fallback path, is patching glide.cpp in Dosbox source (src/hardware) and hardcode the same path as being used in the dylibbundler script
I figured this out this morning when I tried to add the patch to my script, and it kept failing - and I finally took the trouble to look at the original file, and found that it didn't need the patch at all. Well done!
Dominuswrote on 2021-03-12, 11:50:This way of loading the lib wasn't really well thought out by the OpenGlide devs back then :(
Another way that should work witho […] Show full quote
This way of loading the lib wasn't really well thought out by the OpenGlide devs back then 🙁
Another way that should work without the fallback path, is patching glide.cpp in Dosbox source (src/hardware) and hardcode the same path as being used in the dylibbundler script
@almeath - I've now had closer look at your very impressive wrapper. When you get a chance, could you point me in the direction of the code for your launcher executable? That would very, very useful to have. I've been using AppleScript to do similar things, but the launcher is clearly a superior idea. I'm very impressed!
I wonder if any of you macOS guys would be interested to get OpenGlide X11 working through XQuartz. Even though XQuartz/OpenGL was deprecated (so was SDL1.2), a search from Google showed that it still works and nothing breaks including support for OpenGL/GLX, even on Apple M1. I actually share the same OpenGlide for DOSBox and QEMU on Linux with OpenGlide X11. My fork of OpenGlide has a more robust GL context initialization through X11/GLX.
Xquartz has become quite a kludge. The only reason I had to use xquartz was Exult Studio which as of this year is finally running native.
And yes, it still works, I even tried it on an Apple DTK. But getting stuff compiled against X11 and then have ot actually work not always easy.
So I pass 😉
@almeath - I've now had closer look at your very impressive wrapper. When you get a chance, could you point me in the direction of the code for your launcher executable? That would very, very useful to have. I've been using AppleScript to do similar things, but the launcher is clearly a superior idea. I'm very impressed!
Thank you - however I do not actually know much about the underlying code of the Launcher binary. I acquired it from another app package and utilized it for my wrapper. All I know is that when launched from within /Contents/MacOS of a Mac application wrapper, it calls a bash script, which must have the title "script" and be located inside /Contents/Resources.
The Launcher itself could be called anything. You could test it yourself by using the Mac application Platypus, to bundle the Launcher into a fresh app package, re-naming "Launcher" to anything you like. I tested this all out and it works fine, so you could use it for making any Mac app, not just DOSBox wrappers.
By the way, I tidied up my wrapper (now re-uploaded, linked in the post above) as I realized I had it doing a relay with the bash script ("script") launching an Apple osascript ("run.apple"), which in turn activated another bash script ("script_dos"), which is the one referenced in my post above. I have now just placed the "script_dos" information in "script" and it seems to work fine.
I wonder if any of you macOS guys would be interested to get OpenGlide X11 working through XQuartz. Even though XQuartz/OpenGL was deprecated (so was SDL1.2), a search from Google showed that it still works and nothing breaks including support for OpenGL/GLX, even on Apple M1. I actually share the same OpenGlide for DOSBox and QEMU on Linux with OpenGlide X11. My fork of OpenGlide has a more robust GL context initialization through X11/GLX.
I had a go at compiling this under Mojave. I needed to do chmod +x on bootstrap, and modify some headers to point to the correct X11 location, but then it ended up failing quite badly when dealing with the extension function declarations in openglide/Glextensions.h. Basically, most of those extensions are completely unrecognized by the latest version of X11/XQuartz which I have installed.
Hey, openglide/Glextensions.h is the common code. If you can compile it with SDL, then you should be able to do the same with X11. Perhaps SDL_opengl.h is doing something there. When you run $ ./configure --disable-sdl, did it detect support for X?
You do have autotools (automake/autoconf) to run configure, don't you?
Hey, openglide/Glextensions.h is the common code. If you can compile it with SDL, then you should be able to do the same with X11. Perhaps SDL_opengl.h is doing something there. When you run $ ./configure --disable-sdl, did it detect support for X?
You do have autotools (automake/autoconf) to run configure, don't you?
I do have automake and autoconf installed via Homebrew. Running a standard configure and make does succeed.
When running configure with SDL disabled, the full output is below.
(I will keep playing around with it - just bear in mind I am not hugely knowledgable in all this, I am largely self-taught, and always learning with the insights and assistance of others with more experience than me)
1checking build system type... x86_64-apple-darwin18.7.0 2checking host system type... x86_64-apple-darwin18.7.0 3checking target system type... x86_64-apple-darwin18.7.0 4checking for a BSD-compatible install... /usr/bin/install -c 5checking whether build environment is sane... yes 6checking for a thread-safe mkdir -p... ../openglide/install-sh -c -d 7checking for gawk... gawk 8checking whether make sets $(MAKE)... yes 9checking whether make supports nested variables... yes 10checking for g++... g++ 11checking whether the C++ compiler works... yes 12checking for C++ compiler default output file name... a.out 13checking for suffix of executables... 14checking whether we are cross compiling... no 15checking for suffix of object files... o 16checking whether we are using the GNU C++ compiler... yes 17checking whether g++ accepts -g... yes 18checking for style of include used by make... GNU 19checking dependency style of g++... gcc3 20checking how to print strings... printf 21checking for gcc... gcc 22checking whether we are using the GNU C compiler... yes 23checking whether gcc accepts -g... yes 24checking for gcc option to accept ISO C89... none needed 25checking whether gcc understands -c and -o together... yes 26checking dependency style of gcc... gcc3 27checking for a sed that does not truncate output... /usr/bin/sed 28checking for grep that handles long lines and -e... /usr/bin/grep 29checking for egrep... /usr/bin/grep -E 30checking for fgrep... /usr/bin/grep -F 31checking for ld used by gcc... /Library/Developer/CommandLineTools/usr/bin/ld 32checking if the linker (/Library/Developer/CommandLineTools/usr/bin/ld) is GNU ld... no 33checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B 34checking the name lister (/usr/bin/nm -B) interface... BSD nm 35checking whether ln -s works... yes 36checking the maximum length of command line arguments... 196608 37checking how to convert x86_64-apple-darwin18.7.0 file names to x86_64-apple-darwin18.7.0 format... func_convert_file_noop 38checking how to convert x86_64-apple-darwin18.7.0 file names to toolchain format... func_convert_file_noop 39checking for /Library/Developer/CommandLineTools/usr/bin/ld option to reload object files... -r 40checking for objdump... objdump 41checking how to recognize dependent libraries... pass_all 42checking for dlltool... dlltool 43checking how to associate runtime and link libraries... printf %s\n 44checking for ar... ar 45checking for archiver @FILE support... no 46checking for strip... strip 47checking for ranlib... ranlib 48checking command to parse /usr/bin/nm -B output from gcc object... ok 49checking for sysroot... no 50checking for a working dd... /bin/dd 51checking how to truncate binary pipes... /bin/dd bs=4096 count=1 52checking for mt... no 53checking if : is a manifest tool... no 54checking for dsymutil... dsymutil 55checking for nmedit... nmedit 56checking for lipo... lipo 57checking for otool... otool 58checking for otool64... no 59checking for -single_module linker flag... yes 60checking for -exported_symbols_list linker flag... yes
…Show last 65 lines
61checking for -force_load linker flag... yes 62checking how to run the C preprocessor... gcc -E 63checking for ANSI C header files... yes 64checking for sys/types.h... yes 65checking for sys/stat.h... yes 66checking for stdlib.h... yes 67checking for string.h... yes 68checking for memory.h... yes 69checking for strings.h... yes 70checking for inttypes.h... yes 71checking for stdint.h... yes 72checking for unistd.h... yes 73checking for dlfcn.h... yes 74checking for objdir... .libs 75checking if gcc supports -fno-rtti -fno-exceptions... yes 76checking for gcc option to produce PIC... -fno-common -DPIC 77checking if gcc PIC flag -fno-common -DPIC works... yes 78checking if gcc static flag -static works... no 79checking if gcc supports -c -o file.o... yes 80checking if gcc supports -c -o file.o... (cached) yes 81checking whether the gcc linker (/Library/Developer/CommandLineTools/usr/bin/ld) supports shared libraries... yes 82checking dynamic linker characteristics... darwin18.7.0 dyld 83checking how to hardcode library paths into programs... immediate 84checking whether stripping libraries is possible... yes 85checking if libtool supports shared libraries... yes 86checking whether to build shared libraries... yes 87checking whether to build static libraries... yes 88checking how to run the C++ preprocessor... g++ -E 89checking for ld used by g++... /Library/Developer/CommandLineTools/usr/bin/ld 90checking if the linker (/Library/Developer/CommandLineTools/usr/bin/ld) is GNU ld... no 91checking whether the g++ linker (/Library/Developer/CommandLineTools/usr/bin/ld) supports shared libraries... yes 92checking for g++ option to produce PIC... -fno-common -DPIC 93checking if g++ PIC flag -fno-common -DPIC works... yes 94checking if g++ static flag -static works... no 95checking if g++ supports -c -o file.o... yes 96checking if g++ supports -c -o file.o... (cached) yes 97checking whether the g++ linker (/Library/Developer/CommandLineTools/usr/bin/ld) supports shared libraries... yes 98checking dynamic linker characteristics... darwin18.7.0 dyld 99checking how to hardcode library paths into programs... immediate 100checking for ANSI C header files... (cached) yes 101checking size of unsigned char... 1 102checking size of unsigned short... 2 103checking size of unsigned int... 4 104checking size of unsigned long... 8 105checking size of unsigned long long... 8 106checking size of int *... 8 107checking for X... libraries , headers 108checking for gethostbyname... yes 109checking for connect... yes 110checking for remove... yes 111checking for shmat... yes 112checking for IceConnectionNumber in -lICE... no 113checking for target cpu type... x86-64 bit compatible 114checking that generated files are newer than configure... done 115configure: creating ./config.status 116config.status: creating Makefile 117config.status: creating sdk2_unix.h 118config.status: creating platform/Makefile 119config.status: creating platform/linux/Makefile 120config.status: creating platform/sdl/Makefile 121config.status: creating platform/windows/Makefile 122config.status: creating config.h 123config.status: executing depfiles commands 124config.status: executing libtool commands
- then compile, make the bundle, run the dylibbundler to place your libs.
- then place the openglide libs in the same folder as the dosbox binary is
- use install_name_tool to change the path of the SDL lib via:
(you need to adapt the path /opt/x86_64/lib/libSDL-1.2.0.dylib to whatever otool -L dosbox.app/contents/resources/dosbox/libglide2x.dylib returns 😀)
(what it does: the edit in glide.cpp makes DOSBox look for the libglide2x relative to where it got started from, in this case the same folder. This can be adapted to place the libglide2x wherever you want in your bundle but then the path needs to be adapted in glide.cpp and the install_name_tool line.
install_name_tool uses basically the same but uses loader_path that is meant for plugins that are not executed but loaded. The path is relative to the libglide2x.dylib *NOT* the dosbox binary)
While both approaches achieve the same functionality with probably no difference in real world use, your solution is cleaner in that it does not rely on having two copies of SDL dylib inside the wrapper.
There might be a use case where people want to compile DOSBox and OpenGlide from source, and access the Glide libraries from usr/local via a single install of the DOSBox app or binary. Will your patch prevent that approach from working?
Last edited by almeath on 2021-03-13, 11:51. Edited 2 times in total.