SDL license change AND MacOS X dynamic linking

The whole statically linked licensing issue had me intrigued because I
don’t know how to distribute a commercial release the correct way on
MacOS X.

I have been unable to find a way to make a dynamically linked
executable with MacOS X.
The setup for SDL was effortless. It even creates an SDL Application
option when starting a new Project with Project Builder, but there is
no .dll it links with or anything similar that I can see.
Does anyone have experience creating a dynamically linked app for MacOS
X that can share the process with me?

As close as I can tell I would have to have the user install the SDL
frameworks in their local library folder. (?)

Aaron

Helpful Tips:

http://fink.sourceforge.net/doc/porting/index.phpOn Thu, 2003-01-16 at 15:55, Aaron Sullivan wrote:

The whole statically linked licensing issue had me intrigued because I
don’t know how to distribute a commercial release the correct way on
MacOS X.

I have been unable to find a way to make a dynamically linked
executable with MacOS X.
The setup for SDL was effortless. It even creates an SDL Application
option when starting a new Project with Project Builder, but there is
no .dll it links with or anything similar that I can see.
Does anyone have experience creating a dynamically linked app for MacOS
X that can share the process with me?

As close as I can tell I would have to have the user install the SDL
frameworks in their local library folder. (?)

Message: 1

The whole statically linked licensing issue had me intrigued because I
don’t know how to distribute a commercial release the correct way on
MacOS X.

I have been unable to find a way to make a dynamically linked
executable with MacOS X.

If you don’t want to install SDL.framework separately (you could bundle
the installer with the application), there is an easy alternative that
avoids this extra step.

All you have to do is copy SDL.framework to
YourApp.app/Contents/Frameworks

HTH,
DarrellOn Friday, January 17, 2003, at 03:01 PM, sdl-request at libsdl.org wrote:

Date: Thu, 16 Jan 2003 16:55:00 -0500
From: Aaron Sullivan
To: sdl at libsdl.org
Subject: [SDL] SDL license change AND MacOS X dynamic linking
Reply-To: sdl at libsdl.org

allow: postAm Donnerstag, 16.01.03 um 22:55 Uhr schrieb Aaron Sullivan:

The whole statically linked licensing issue had me intrigued because I
don’t know how to distribute a commercial release the correct way on
MacOS X.

I have been unable to find a way to make a dynamically linked
executable with MacOS X.
The setup for SDL was effortless. It even creates an SDL Application
option when starting a new Project with Project Builder, but there is
no .dll it links with or anything similar that I can see.
Does anyone have experience creating a dynamically linked app for
MacOS X that can share the process with me?

As close as I can tell I would have to have the user install the SDL
frameworks in their local library folder. (?)

Aaron

Look at your Project Builder project: under Targets/Linker settings,
you should find a “-framework SDL” in the box “other Mach-O Linker
Flags”. This links your executable against the SDL.framework. Note that
you should not have the SDL.framework installed in your user
directory for this: it should be in /Library/Frameworks. Otherwise, the
path will be hardcoded to your home dir in the executable, which is not
what you want. (The SDL package installs the framework into the home
dir by default; this should be changed, perhaps).

You can examine the dynamically linked libraries in Terminal by
changing to build/AppName.app/Contents/MacOS and doing an otool -L
AppName . This gives you an output like this:

$ otool -L chromium
chromium:
/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL
(compatibility version 1.0.0, current version 1.0.0)
/Users/jobi/Library/Frameworks/SDL.framework/Versions/A/SDL
(compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libz.1.1.3.dylib (compatibility version 1.0.0, current
version 1.1.3)

/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
(compatibility version 300.0.0, current version 425.0.0)
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
(compatibility version 45.0.0, current version 620.0.0)
/System/Library/Frameworks/AGL.framework/Versions/A/AGL
(compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon
(compatibility version 2.0.0, current version 122.0.0)

Note that I linked this app with SDL in my home dir. With SDL in
/Library/Frameworks, this would look like

$ otool -L enigma
enigma:
@executable_path/…/Frameworks/SDL.framework/Versions/A/SDL
(compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa
(compatibility version 1.0.0, current version 8.0.0)

@executable_path/…/Frameworks/SDL_image.framework/Versions/A/SDL_image
(compatibility version 1.0.0, current version 1.0.0)

@executable_path/…/Frameworks/SDL_mixer.framework/Versions/A/SDL_mixer
(compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0,
current version 63.0.0)

(here I linked with SDL_image and SDL_mixer additionally). You see that
the hard coded path for SDL.framework refers to …/Frameworks: this
means that you can put SDL.framework into you .app bundle in
AppName.app/Contents/Frameworks, and have it both “statically linked”
(i.e. always distributed with the .app) and exchangeable. The system
will, according to documentation, always use the framework bundle with
the highest version. You want to read
/Developer/Documentation/Essentials/SystemOverview/index.html . (Come
on. You know you do :slight_smile: )

When porting your app, don’t forget that Mac users expect your
application to be a single bundle. The standard SDLMain.m that comes
with SDL sadly does the following:
if (shouldChdir)
{
assert ( chdir (parentdir) == 0 ); /* chdir to the binary app’s
parent /
assert ( chdir ("…/…/…/") == 0 ); /
chdir to the .app’s
parent /
}
which motivates to store the data in the .app’s parent directory. I
always change this to
if (shouldChdir)
{
assert ( chdir (parentdir) == 0 ); /
chdir to the binary app’s
parent /
assert ( chdir ("…/Resources/") == 0 ); /
chdir to the
Resources folder in the .app bundle */
}
and put my stuff into AppName.app/Contents/Resources.

HTH,

Johannes Fortmann
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: text/enriched
Size: 4965 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20030118/8d3c60cc/attachment.bin

Thank you Johannes for the great response. I’ve also
been wondering how I will
ultimately package my SDL based app for OSX without
making it painful
for the user to install.

But can you go into a little more detail about how you
can bundle frameworks inside
an app using Project Builder? I’m still a little
confused on the issue.
I think I see the Targets/Linker section you
described. I see a section
for “Search paths”, where directories for headers,
frameworks, libraries,
and java classes can be entered.If I try placing
…/Frameworks in the box
for Frameworks, I get an error that the Framework
cannot be found
when I try building. I thought this box was to tell
the system where
to locate things on your system. And I can’t drop it
into the App yet
because it isn’t built. It seems like a
chicken-and-egg problem. Is there
a separate box to tell it where to look at Run-time?
And is Project Builder
supposed to create the …/Frameworks (or
…/SharedFrameworks)
for you, or do you have to create everything manually.

And is there a way to bundle Frameworks within
frameworks? I would like to build
a framework (library) that uses SDL and lots of other
libs.

Thank you,
Eric

dynamic linking

Does anyone have experience creating a dynamically
linked app for
MacOS X that can share the process with me?

As close as I can tell I would have to have the
user install the SDL
frameworks in their local library folder. (?)

Aaron

Look at your Project Builder project: under
Targets/Linker settings,
you should find a “-framework SDL” in the box “other
Mach-O Linker
Flags”. This links your executable against the
SDL.framework. Note that
you should not have the SDL.framework installed in
your user
directory for this: it should be in
/Library/Frameworks. Otherwise, the
path will be hardcoded to your home dir in the
executable, which is not
what you want. (The SDL package installs the
framework into the home
dir by default; this should be changed, perhaps).

You can examine the dynamically linked libraries in
Terminal by
changing to build/AppName.app/Contents/MacOS and
doing an otool -L
AppName . This gives you an output like this:

$ otool -L chromium
chromium:

/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL

(compatibility version 1.0.0, current version 1.0.0)

/Users/jobi/Library/Frameworks/SDL.framework/Versions/A/SDL

(compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libz.1.1.3.dylib (compatibility
version 1.0.0, current
version 1.1.3)

/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation

(compatibility version 300.0.0, current version
425.0.0)

/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit

(compatibility version 45.0.0, current version
620.0.0)

/System/Library/Frameworks/AGL.framework/Versions/A/AGL

(compatibility version 1.0.0, current version 1.0.0)

/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon

(compatibility version 2.0.0, current version
122.0.0)

Note that I linked this app with SDL in my home dir.
With SDL in
/Library/Frameworks, this would look like

$ otool -L enigma
enigma:

@executable_path/…/Frameworks/SDL.framework/Versions/A/SDL

(compatibility version 1.0.0, current version 1.0.0)

/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa

(compatibility version 1.0.0, current version 8.0.0)

@executable_path/…/Frameworks/SDL_image.framework/Versions/A/SDL_image

(compatibility version 1.0.0, current version 1.0.0)

@executable_path/…/Frameworks/SDL_mixer.framework/Versions/A/SDL_mixer

(compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility
version 1.0.0,
current version 63.0.0)

(here I linked with SDL_image and SDL_mixer
additionally). You see that
the hard coded path for SDL.framework refers to
…/Frameworks: this
means that you can put SDL.framework into you .app
bundle in
AppName.app/Contents/Frameworks, and have it both
"statically linked"
(i.e. always distributed with the .app) and
exchangeable. The system
will, according to documentation, always use the
framework bundle with
the highest version. You want to read

/Developer/Documentation/Essentials/SystemOverview/index.html> Subject: Re: [SDL] SDL license change AND MacOS X

From: Johannes Fortmann <J.Fortmann at gmx.de>
. (Come
on. You know you do :slight_smile: )

When porting your app, don’t forget that Mac users
expect your
application to be a single bundle. The standard
SDLMain.m that comes
with SDL sadly does the following:
if (shouldChdir)
{
assert ( chdir (parentdir) == 0 ); /* chdir
to the binary app’s
parent /
assert ( chdir ("…/…/…/") == 0 ); /
chdir
to the .app’s
parent /
}
which motivates to store the data in the .app’s
parent directory. I
always change this to
if (shouldChdir)
{
assert ( chdir (parentdir) == 0 ); /
chdir
to the binary app’s
parent /
assert ( chdir ("…/Resources/") == 0 ); /

chdir to the
Resources folder in the .app bundle */
}
and put my stuff into
AppName.app/Contents/Resources.

HTH,

Johannes Fortmann


Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

Thank you Johannes for the great response. I’ve also
been wondering how I will
ultimately package my SDL based app for OSX without
making it painful
for the user to install.

But can you go into a little more detail about how you
can bundle frameworks inside
an app using Project Builder? I’m still a little
confused on the issue.
I think I see the Targets/Linker section you
described. I see a section
for “Search paths”, where directories for headers,
frameworks, libraries,
and java classes can be entered.If I try placing
…/Frameworks in the box
for Frameworks, I get an error that the Framework
cannot be found
when I try building. I thought this box was to tell
the system where
to locate things on your system.

It is. This box tells the compiler where to find your private
framework directory. Since you placed SDL.framework into
/Library/Frameworks, which is the standard location, you shouldn’t have
any problem with this, anyway. What you really want is to tell the
compiler to link with the framework. Either drag the framework in way
down, under “Frameworks & Libraries”, or select “Add Frameworks?” from
the “Project” menu. A third way would be to specify “-framework SDL” in
the linker settings.
Note that all this still doesn’t change your header search path: if
you do #include “SDL.h”, you’ll have to add
"$(LOCAL_LIBRARY_DIR)/Frameworks/SDL.framework/Versions/A/Headers" to
your header search paths. #include’ing “SDL/SDL.h” should work fine,
though I haven’t verified this.
The resulting app first searches for the framework in your .app bundle
(under “Frameworks”, “PrivateFrameworks” and “SharedFrameworks”, just
as documented in the link from my last mail), and if it’s not there, in
/Library/Frameworks, /Users/yourusername/Library/Frameworks and
/System/Library/Frameworks.
To have Project Builder automatically copy the Framework to your .app
bundle, add a new “Copy files” build phase (“Project/New Build
Phase/New copy files build phase”). You seem to have an active
selection in the “Build Phases” list GUI to do this. Under "Where"
select “Frameworks”, no subpath; drag the framework bundle into the box
down there.

(snip)

And is there a way to bundle Frameworks within
frameworks? I would like to build
a framework (library) that uses SDL and lots of other
libs.

I guess not. This would, of course, also defeat the whole purpose of
this exercise: to still be able to easily exchange (e.g.) the
SDL.framework with a newer version, on a per-app basis, if needed.
If you really want to do this, you could look into “Umbrella
frameworks”.
/Developer/Documentation/Essentials/SystemOverview/Umbrella/
_Umbrella_Frameworks.html

HTH, and sorry to Sam, who has to approve of all my mails, because my
"From" header is getting garbled by the mail server :frowning:

Johannes FortmannAm Montag, 20.01.03 um 15:20 Uhr schrieb Eric Wing:

Thanks again for the great response Johannes. Sorry
for the delay in follow up, but it took me awhile to
try everything.

So I think I have one last set of followup questions
:slight_smile:

I read the disclaimer about Umbrella Frameworks and it
sounds like Apple doesn’t want you to use them, so
I’ll avoid those for now.

So one of the things I’m working with right now is
SDL_sound. The current SDL_sound project doesn’t work
for me because I think it’s too old, so I’ve tried
creating a new one. SDL_sound depends on a whole lot
of external codecs (Smpeg, Ogg Vorbis, Mikmod, etc)
which I also have to build projects for. Furthermore,
I am building a library that depends on SDL_sound. And
finally, my application depends on SDL_sound and my
library.

So one thing I’ve been trying to understand is this
field in Target called: "Install Location"
I noticed all the SDL frameworks select:

Path: @executable_path/…/Frameworks

This looks a lot like the otool -L data you displayed
in a previous message.

So I decided to copy this field on all my Frameworks
that I was building. I put it in Ogg, Vorbis, Mikmod,
SDL_sound, and my app.

However, when I did this, I was able to compile Ogg,
Vorbis, Mikmod, and SDL_sound okay. But when I got to
compiling my library, I got an error message like:
Can’t find @executable_path/…/Frameworks (does not
exist) for the codecs (Ogg,Vorbis,Mikmod)

But if I remove the
Path: @executable_path/…/Frameworks
from Ogg,Vorbis,Mikmod (and I forgot what about
SDL_sound) then my stuff compiles.

So I’m confused about this field and what I’m supposed
to do with it. Why do all the SDL projects set it to
this path? And does it hurt to leave it to none (i.e.
can I still drop Frameworks into any of the bundle
subdirectories)?

And also, even though everything otool -L says
@executable_path/…/Frameworks,
is it possible to drop it into SharedFrameworks
instead? To me it seems that I would typically want
the user to use a newer version of SDL if they already
had it on their system instead of being locked down by
mine.

And can you recommend a good system of testing if the
Frameworks subdirectories work. (It’s really hard to
verify since everything is installed in my regular
/Library/Frameworks folder too.)

Thanks,
Eric

But can you go into a little more detail about how
you
can bundle frameworks inside
an app using Project Builder? I’m still a little
confused on the issue.

It is. This box tells the compiler where to find
your private =20
framework directory. Since you placed SDL.framework
into =20
/Library/Frameworks, which is the standard location,
you shouldn’t have =20=

any problem with this, anyway. What you really want
is to tell the =20
compiler to link with the framework. Either drag
the framework in way =20=

down, under “Frameworks & Libraries”, or select “Add
Frameworks=85” from =
=20
the “Project” menu. A third way would be to specify
"-framework SDL" in =20=

the linker settings.
Note that all this still doesn’t change your
header search path: if =20=

you do #include “SDL.h”, you’ll have to add =20

“$(LOCAL_LIBRARY_DIR)/Frameworks/SDL.framework/Versions/A/Headers”

to =20=

your header search paths. #include’ing “SDL/SDL.h"
should work fine, =20
though I haven’t verified this.
The resulting app first searches for the framework
in your .app bundle =
=20
(under “Frameworks”, “PrivateFrameworks” and
"SharedFrameworks”, just =20=

as documented in the link from my last mail), and if
it’s not there, in =20=

/Library/Frameworks,
/Users/yourusername/Library/Frameworks and =20
/System/Library/Frameworks.
To have Project Builder automatically copy the
Framework to your .app =20=

bundle, add a new “Copy files” build phase
(“Project/New Build =20
Phase/New copy files build phase”). You seem to have
an active =20
selection in the “Build Phases” list GUI to do this.
Under “Where” =20
select “Frameworks”, no subpath; drag the framework
bundle into the box =20=

down there.

(snip)

And is there a way to bundle Frameworks within
frameworks? I would like to build
a framework (library) that uses SDL and lots of
other
libs.

I guess not. This would, of course, also defeat the
whole purpose of =20
this exercise: to still be able to easily exchange
(e.g.) the =20
SDL.framework with a newer version, on a per-app
basis, if needed.
If you really want to do this, you could look into
"Umbrella =20
frameworks".

/Developer/Documentation/Essentials/SystemOverview/Umbrella/=20> _Umbrella_Frameworks.html

HTH, and sorry to Sam, who has to approve of all my
mails, because my =20=

“From” header is getting garbled by the mail server
:frowning:

Johannes Fortmann=


Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

First, let me list some things you might want to read:

Manpages:
dyld, ld

HTML docs:
/Developer/Documentation/ReleaseNotes/Prebinding.html
/Developer/Documentation/ReleaseNotes/TwoLevelNamespaces.htmlOn Friday, January 24, 2003, at 03:01 PM, sdl-request at libsdl.org wrote:

Message: 35
Date: Fri, 24 Jan 2003 09:33:13 -0800 (PST)
From: Eric Wing
To: sdl at libsdl.org, Johannes Fortmann <J.Fortmann at gmx.de>
Subject: [SDL] Re: SDL & Project Builder
Reply-To: sdl at libsdl.org

So one of the things I’m working with right now is
SDL_sound. The current SDL_sound project doesn’t work
for me because I think it’s too old, so I’ve tried
creating a new one. SDL_sound depends on a whole lot
of external codecs (Smpeg, Ogg Vorbis, Mikmod, etc)
which I also have to build projects for. Furthermore,
I am building a library that depends on SDL_sound. And
finally, my application depends on SDL_sound and my
library.

So one thing I’ve been trying to understand is this
field in Target called: "Install Location"
I noticed all the SDL frameworks select:

Path: @executable_path/…/Frameworks

This corresponds to the -install_name option to ld (see the manpage),
minus the library name (hence, “install path” rather than “install
name”.

So I decided to copy this field on all my Frameworks
that I was building. I put it in Ogg, Vorbis, Mikmod,
SDL_sound, and my app.

However, when I did this, I was able to compile Ogg,
Vorbis, Mikmod, and SDL_sound okay. But when I got to
compiling my library, I got an error message like:
Can’t find @executable_path/…/Frameworks (does not
exist) for the codecs (Ogg,Vorbis,Mikmod)

That’s strange. I didn’t think the install path was checked for
existence or not at link time. Did you try cleaning the targets and
recompiling?

So I’m confused about this field and what I’m supposed
to do with it. Why do all the SDL projects set it to
this path?

So that you can bundle the shared libraries in
MyApp.app/Contents/Frameworks.

And does it hurt to leave it to none (i.e.
can I still drop Frameworks into any of the bundle
subdirectories)?

You won’t be able to drop it in. The dyld manpage explains how dynamic
libraries are discovered at runtime. The order of the search is (off
the top of my head, you should check to make sure this is right):

  1. The install path (which is linked into the executable, visible with
    otool -L)
  2. The standard directories: ~/Library/Frameworks then
    /Library/Frameworks then /System/Library/Frameworks

And also, even though everything otool -L says
@executable_path/…/Frameworks,
is it possible to drop it into SharedFrameworks
instead?

No. Not without changing the install path to
@executable_path/…/SharedFrameworks.

To me it seems that I would typically want
the user to use a newer version of SDL if they already
had it on their system instead of being locked down by
mine.

In that case, you can just bundle the library installers with your app.

To get what you want would be more complicated (since you’re
customizing the way dyld works), but it is possible. One thing I can
think of is putting your application code into a framework, and then
using a bootstrap program to set the DYLD_FRAMEWORK_PATH before you
load the bundle that contains your program and execute the main
procedure.

And can you recommend a good system of testing if the
Frameworks subdirectories work. (It’s really hard to
verify since everything is installed in my regular
/Library/Frameworks folder too.)

I tested by installing everything in ~/Library/Frameworks instead
(which is what you get if you install just the development runtimes).
Then create a new user, and log in as that user for testing.