PureBasic + SDL + Mac ...

Mac OSX specific forum
User avatar
kenmo
Addict
Addict
Posts: 2045
Joined: Tue Dec 23, 2003 3:54 am

PureBasic + SDL + Mac ...

Post by kenmo »

Lately I have been playing with the SDL library imported into PureBasic (SDL 2.0.3 and SDL2_image, maybe in the future SDL2_mixer).

(You might ask: why bother with SDL? PureBasic already does cross-platform video, graphics, audio, keyboard, mouse, joystick... Well (A) it has some nice extras, like more Joystick functions and the GameController subsystem which translates many different gamepads to a standard XBox-like layout... also (B) I just want to learn SDL and practice importing libraries into PB!)


I just finished my first PB + SDL project, a small game for Windows and Mac. On Windows, the process was easy: import SDL functions, build the executable, package it with the necessary DLLs.

But Mac OSX doesn't use DLLs, it uses Frameworks, and the SDL2 runtime is packaged as a Disk Image (.dmg) which must be "mounted" and then installed to /Library/Frameworks. This is new and confusing to me!

I guess my ultimate question is: What is the "best" way to release a PureBasic Mac project that uses external Frameworks like SDL? I see 5 options:

1. Release the app WITHOUT the runtime, prompt the user if they need to download + install it
2. Release the app with the runtime, prompt the user if they need to install it
3. Release the app with the runtime, automatically install it if missing
4. Release the app with the runtime, load it from the local directory like a DLL, no installation to /Library/Frameworks
5. Statically link the runtime, no external framework needed


Some thoughts about each option:

1. Easiest method for me, but biggest annoyance for the user (download, mount, install)
2. Maybe the best overall method
3. I don't know if a PB program can auto-install a Framework, there might be permission issues, and you can't just copy a DMG into "Frameworks"
4. Again, I don't know how this works on Mac. I don't think you can just drop a DMG in a folder and expect it to do anything.
5. I have no idea how to statically link an open-source library written in C to a PureBasic Mac project... but I am willing to learn!


Any ideas, PureBasic and Mac and SDL experts? :?: Thanks for reading!
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: PureBasic + SDL + Mac ...

Post by wilbert »

Isn't there a .dylib (similar to a windows .dll) you can use ?
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
kenmo
Addict
Addict
Posts: 2045
Joined: Tue Dec 23, 2003 3:54 am

Re: PureBasic + SDL + Mac ...

Post by kenmo »

I don't know if there is a dylib... The SDL runtime for Mac is a DMG download, but I am on Windows right now so I can't mount it and see if there is a dylib somewhere inside.

SDL download page is here: http://www.libsdl.org/download-2.0.php

If there is a SDL dylib available, would I just put it in my PB game's directory and it would use it "automatically", like placing the right DLLs in your executable folder on Windows? (Furthermore, would I put it in the .app's parent directory, or the internal Contents/MacOS/ or Contents/Resources/ directory?? I am relatively new to OSX.)
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: PureBasic + SDL + Mac ...

Post by J. Baker »

You can make a "Frameworks" folder within your app and put the "SDL.Framework" in there. Then all you have to do is link from it there. It's only 1.4MB so it won't add much to your app. ;)
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
kenmo
Addict
Addict
Posts: 2045
Joined: Tue Dec 23, 2003 3:54 am

Re: PureBasic + SDL + Mac ...

Post by kenmo »

Is it that simple? I want to try that on a Mac ASAP. (I thought it had to be loaded from /Library/Frameworks or ~/Library/Frameworks )

Now, if I put the .Framework inside my app, do I still "Import" it in my PB code and call it like native functions, or do I need to use OpenLibrary / CallFunction ? ... Eh I guess I will find out by trying :)
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: PureBasic + SDL + Mac ...

Post by J. Baker »

kenmo wrote:Is it that simple? I want to try that on a Mac ASAP. (I thought it had to be loaded from /Library/Frameworks or ~/Library/Frameworks )

Now, if I put the .Framework inside my app, do I still "Import" it in my PB code and call it like native functions, or do I need to use OpenLibrary / CallFunction ? ... Eh I guess I will find out by trying :)
Just using the "Import" will do. Just make sure the import link is within your app. ;)
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Re: PureBasic + SDL + Mac ...

Post by jack »

just out of curiosity I downloaded the SDL source and from the terminal you can build a dylib and a static lib, but the size of the static lib is over four times as that of the dylib, makes me wonder.
btw, the source also includes project files for Xcode, the dmg builds with warnings.
User avatar
kenmo
Addict
Addict
Posts: 2045
Joined: Tue Dec 23, 2003 3:54 am

Re: PureBasic + SDL + Mac ...

Post by kenmo »

@J, have you successfully imported a library from inside a .app before? I can't get it to work :? Maybe I'm doing something wrong, or maybe there's something different about the SDL specifically. Maybe I'll put together a test project, and post it here.

@jack, I think I read that the official SDL 2.0.3 release has some accidental build issues which have since been fixed. Also I found an interesting note in the SDL OSX readme:
But beware! That is only part of the story! With the above, you end up with
a bare bone .app bundle, which is double clickable from the Finder. But
there are some more things you should do before shipping your product...

1) The bundle right now probably is dynamically linked against SDL. That
means that when you copy it to another computer, *it will not run*,
unless you also install SDL on that other computer. A good solution
for this dilemma is to static link against SDL. On OS X, you can
achieve that by linking against the libraries listed by
sdl-config --static-libs
instead of those listed by
sdl-config --libs
Depending on how exactly SDL is integrated into your build systems, the
way to achieve that varies, so I won't describe it here in detail
From: https://hg.libsdl.org/SDL/file/tip/README-macosx.txt
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: PureBasic + SDL + Mac ...

Post by J. Baker »

I've just seen it done that way by other app/games. If you put together a test project, I'll gladly test it out and see what's going on. ;)
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
kenmo
Addict
Addict
Posts: 2045
Joined: Tue Dec 23, 2003 3:54 am

Re: PureBasic + SDL + Mac ...

Post by kenmo »

You could try messing around with this: <URL>

Includes a test PB program, Windows + Mac runtimes, a "fresh" built .app and a copy of that .app with the SDL Framework thrown in every possible sub-folder...

I can get PB Mac to BUILD the .app by putting the Framework right in the source's folder, but I cannot find a way to RUN the .app unless I drop SDL in the system's Frameworks folder :?:

(Of course this is just thinking ahead for releasing a PB+SDL project. For developing, of course I would put it in /Library/Frameworks, that way I can directly run my Mac program from the IDE -- since overwriting the .app every time would delete any internal Framework files!)
Last edited by kenmo on Fri Feb 06, 2015 3:54 am, edited 1 time in total.
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: PureBasic + SDL + Mac ...

Post by J. Baker »

It appears that only a literal string can be used after Import C. So using something like GetHomeDirectory() can not be used. Therefor we can't get the apps sub-folder location. Maybe there's a Cocoa method that can be used but not sure at the moment.

The next best thing I can think of is to include the framework as binary. Then at startup check if SDL2 is installed. If not, dump it to "/Library/Frameworks".

I'll check this out a little more to see if there's an alternative method. ;)
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: PureBasic + SDL + Mac ...

Post by wilbert »

If a Framework contains Cocoa classes, you can load it dynamically using the NSBundle class and use those classes inside the Framework afterwards.
Last edited by wilbert on Tue Jul 15, 2014 7:00 am, edited 1 time in total.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: PureBasic + SDL + Mac ...

Post by Danilo »

Copy SDL2.framework into /Library/Frameworks on your Mac. Your code works from within the PB IDE then.

To make a standalone .app, copy SDL2.framework into your app. Put it into folder:

Code: Select all

your.app/Contents/Frameworks/
Now run the following command on the command line (same directory where your .app is):

Code: Select all

install_name_tool -add_rpath @executable_path/../Frameworks ./SDL_Test.app/Contents/MacOS/SDL_Test
This adds the .app internal 'Frameworks' directory to the search path for frameworks.

Now test it is working:

Code: Select all

./SDL_Test.app/Contents/MacOS/SDL_Test
Works fine here, shows a green window for 2 seconds.

To Import and include .dylib, see: Import : EndImport - path?
Last edited by Danilo on Tue Jul 15, 2014 8:28 am, edited 2 times in total.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: PureBasic + SDL + Mac ...

Post by wilbert »

Another way would be using the PB library functions but that probably is not what you want.

Code: Select all

PrototypeC.i _SDL_Init(flags.l)
PrototypeC _SDL_Quit()
PrototypeC.i _SDL_CreateWindowAndRenderer(width.i, height.i, window_flags.l, *pWindow, *pRenderer)
PrototypeC _SDL_DestroyRenderer(*renderer)
PrototypeC _SDL_DestroyWindow(*window)
PrototypeC.i _SDL_SetRenderDrawColor(*renderer, r.a, g.a, b.a, a.a)
PrototypeC.i _SDL_RenderClear(*renderer)
PrototypeC _SDL_RenderPresent(*renderer)

If OpenLibrary(0, "SDL2.framework/SDL2")
  Global SDL_Init._SDL_Init = GetFunction(0, "SDL_Init")
  Global SDL_Quit._SDL_Quit = GetFunction(0, "SDL_Quit")
  Global SDL_CreateWindowAndRenderer._SDL_CreateWindowAndRenderer = GetFunction(0, "SDL_CreateWindowAndRenderer")
  Global SDL_DestroyRenderer._SDL_DestroyRenderer = GetFunction(0, "SDL_DestroyRenderer")
  Global SDL_DestroyWindow._SDL_DestroyWindow = GetFunction(0, "SDL_DestroyWindow")
  Global SDL_SetRenderDrawColor._SDL_SetRenderDrawColor = GetFunction(0, "SDL_SetRenderDrawColor")
  Global SDL_RenderClear._SDL_RenderClear = GetFunction(0, "SDL_RenderClear")
  Global SDL_RenderPresent._SDL_RenderPresent = GetFunction(0, "SDL_RenderPresent")
EndIf

If (SDL_Init($20) = 0)
  If (SDL_CreateWindowAndRenderer(640, 480, 0, @*win, @*ren) = 0)
    SDL_SetRenderDrawColor(*ren, 0, 255, 0, 255)
    SDL_RenderClear(*ren)
    SDL_RenderPresent(*ren)
    Delay(2000)
    SDL_DestroyRenderer(*ren)
    SDL_DestroyWindow(*win)
  EndIf
  SDL_Quit()
EndIf
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
kenmo
Addict
Addict
Posts: 2045
Joined: Tue Dec 23, 2003 3:54 am

Re: PureBasic + SDL + Mac ...

Post by kenmo »

Danilo, does that mean the end-user would have to run that commandline? A lot of game players would hate that... Also I have read about conflicting Framework paths for example if SDL is in their Library folder plus a local path.

Using OpenLibrary() and Prototypes leads to an uglier include file, but in the end... does it matter? I imagine performance is the same for Prototype calls vs a Framework/dylib link?

Thanks all. Hmmm, I've got some experimenting to do. Of course as I said this is just preparation for future projects.
Post Reply