docs/README-macosx.md
author Ryan C. Gordon <icculus@icculus.org>
Mon, 29 Oct 2018 20:00:03 -0400
changeset 12369 68c87b40b434
parent 11400 9eefdf672499
child 12674 e2d1f4e9c323
permissions -rw-r--r--
winmain: Don't use SDL_malloc (or SDL_stack_alloc, which might be malloc).

Otherwise, we are using the allocator before the app can set up its own hooks.

Now we use VirtualAlloc, and WideCharToMultiByte (because SDL_iconv uses
SDL_malloc, too!) to get ready to call into SDL_main.

This also makes console_wmain() call into the same routines as everything
else, so we don't have to deal with those allocations, too. Hopefully we
end up with the same results from GetCommandLine() as we do in wargv.

Fixes Bugzilla #4340.
gabomdq@9023
     1
Mac OS X
gabomdq@9023
     2
==============================================================================
gabomdq@9023
     3
gabomdq@9023
     4
These instructions are for people using Apple's Mac OS X (pronounced
gabomdq@9023
     5
"ten").
gabomdq@9023
     6
gabomdq@9023
     7
From the developer's point of view, OS X is a sort of hybrid Mac and
gabomdq@9023
     8
Unix system, and you have the option of using either traditional
slouken@11400
     9
command line tools or Apple's IDE Xcode.
slouken@11400
    10
slouken@11400
    11
Command Line Build
icculus@11365
    12
==================
gabomdq@9023
    13
gabomdq@9023
    14
To build SDL using the command line, use the standard configure and make
gabomdq@9023
    15
process:
gabomdq@9023
    16
philipp@10361
    17
    ./configure
philipp@10361
    18
    make
philipp@10361
    19
    sudo make install
gabomdq@9023
    20
gabomdq@9023
    21
You can also build SDL as a Universal library (a single binary for both
gabomdq@9023
    22
32-bit and 64-bit Intel architectures), on Mac OS X 10.7 and newer, by using
icculus@9774
    23
the gcc-fat.sh script in build-scripts:
icculus@9774
    24
icculus@9774
    25
    mkdir mybuild
icculus@9774
    26
    cd mybuild
slouken@10556
    27
    CC=$PWD/../build-scripts/gcc-fat.sh CXX=$PWD/../build-scripts/g++-fat.sh ../configure
philipp@10361
    28
    make
philipp@10361
    29
    sudo make install
icculus@9774
    30
gabomdq@9023
    31
This script builds SDL with 10.5 ABI compatibility on i386 and 10.6
gabomdq@9023
    32
ABI compatibility on x86_64 architectures.  For best compatibility you
icculus@9774
    33
should compile your application the same way.
gabomdq@9023
    34
gabomdq@9023
    35
Please note that building SDL requires at least Xcode 4.6 and the 10.7 SDK
gabomdq@9023
    36
(even if you target back to 10.5 systems). PowerPC support for Mac OS X has
gabomdq@9023
    37
been officially dropped as of SDL 2.0.2.
gabomdq@9023
    38
gabomdq@9023
    39
To use the library once it's built, you essential have two possibilities:
gabomdq@9023
    40
use the traditional autoconf/automake/make method, or use Xcode.
gabomdq@9023
    41
gabomdq@9023
    42
==============================================================================
gabomdq@9023
    43
Caveats for using SDL with Mac OS X
gabomdq@9023
    44
==============================================================================
gabomdq@9023
    45
gabomdq@9023
    46
Some things you have to be aware of when using SDL on Mac OS X:
gabomdq@9023
    47
gabomdq@9023
    48
- If you register your own NSApplicationDelegate (using [NSApp setDelegate:]),
gabomdq@9023
    49
  SDL will not register its own. This means that SDL will not terminate using
gabomdq@9023
    50
  SDL_Quit if it receives a termination request, it will terminate like a 
gabomdq@9023
    51
  normal app, and it will not send a SDL_DROPFILE when you request to open a
gabomdq@9023
    52
  file with the app. To solve these issues, put the following code in your 
gabomdq@9023
    53
  NSApplicationDelegate implementation:
gabomdq@9023
    54
gabomdq@9023
    55
philipp@9066
    56
    - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
philipp@9066
    57
    {
philipp@9066
    58
        if (SDL_GetEventState(SDL_QUIT) == SDL_ENABLE) {
philipp@9066
    59
            SDL_Event event;
philipp@9066
    60
            event.type = SDL_QUIT;
philipp@9066
    61
            SDL_PushEvent(&event);
philipp@9066
    62
        }
philipp@9066
    63
    
philipp@9066
    64
        return NSTerminateCancel;
philipp@9066
    65
    }
philipp@9066
    66
    
philipp@9066
    67
    - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
philipp@9066
    68
    {
philipp@9066
    69
        if (SDL_GetEventState(SDL_DROPFILE) == SDL_ENABLE) {
philipp@9066
    70
            SDL_Event event;
philipp@9066
    71
            event.type = SDL_DROPFILE;
philipp@9066
    72
            event.drop.file = SDL_strdup([filename UTF8String]);
philipp@9066
    73
            return (SDL_PushEvent(&event) > 0);
philipp@9066
    74
        }
philipp@9066
    75
    
philipp@9066
    76
        return NO;
philipp@9066
    77
    }
gabomdq@9023
    78
gabomdq@9023
    79
==============================================================================
gabomdq@9023
    80
Using the Simple DirectMedia Layer with a traditional Makefile
gabomdq@9023
    81
==============================================================================
gabomdq@9023
    82
gabomdq@9023
    83
An existing autoconf/automake build system for your SDL app has good chances
gabomdq@9023
    84
to work almost unchanged on OS X. However, to produce a "real" Mac OS X binary
gabomdq@9023
    85
that you can distribute to users, you need to put the generated binary into a
gabomdq@9023
    86
so called "bundle", which basically is a fancy folder with a name like
gabomdq@9023
    87
"MyCoolGame.app".
gabomdq@9023
    88
gabomdq@9023
    89
To get this build automatically, add something like the following rule to
gabomdq@9023
    90
your Makefile.am:
gabomdq@9023
    91
philipp@10361
    92
    bundle_contents = APP_NAME.app/Contents
philipp@10361
    93
    APP_NAME_bundle: EXE_NAME
philipp@10361
    94
    	mkdir -p $(bundle_contents)/MacOS
philipp@10361
    95
    	mkdir -p $(bundle_contents)/Resources
philipp@10361
    96
    	echo "APPL????" > $(bundle_contents)/PkgInfo
philipp@10361
    97
    	$(INSTALL_PROGRAM) $< $(bundle_contents)/MacOS/
gabomdq@9023
    98
gabomdq@9023
    99
You should replace EXE_NAME with the name of the executable. APP_NAME is what
gabomdq@9023
   100
will be visible to the user in the Finder. Usually it will be the same
gabomdq@9023
   101
as EXE_NAME but capitalized. E.g. if EXE_NAME is "testgame" then APP_NAME 
philipp@10092
   102
usually is "TestGame". You might also want to use `@PACKAGE@` to use the package
gabomdq@9023
   103
name as specified in your configure.in file.
gabomdq@9023
   104
gabomdq@9023
   105
If your project builds more than one application, you will have to do a bit
gabomdq@9023
   106
more. For each of your target applications, you need a separate rule.
gabomdq@9023
   107
gabomdq@9023
   108
If you want the created bundles to be installed, you may want to add this
gabomdq@9023
   109
rule to your Makefile.am:
gabomdq@9023
   110
philipp@10361
   111
    install-exec-hook: APP_NAME_bundle
philipp@10361
   112
    	rm -rf $(DESTDIR)$(prefix)/Applications/APP_NAME.app
philipp@10361
   113
    	mkdir -p $(DESTDIR)$(prefix)/Applications/
philipp@10361
   114
    	cp -r $< /$(DESTDIR)$(prefix)Applications/
gabomdq@9023
   115
gabomdq@9023
   116
This rule takes the Bundle created by the rule from step 3 and installs them
philipp@10361
   117
into "$(DESTDIR)$(prefix)/Applications/".
gabomdq@9023
   118
gabomdq@9023
   119
Again, if you want to install multiple applications, you will have to augment
gabomdq@9023
   120
the make rule accordingly.
gabomdq@9023
   121
gabomdq@9023
   122
gabomdq@9023
   123
But beware! That is only part of the story! With the above, you end up with
gabomdq@9023
   124
a bare bone .app bundle, which is double clickable from the Finder. But
gabomdq@9023
   125
there are some more things you should do before shipping your product...
gabomdq@9023
   126
gabomdq@9023
   127
1) The bundle right now probably is dynamically linked against SDL. That 
gabomdq@9023
   128
   means that when you copy it to another computer, *it will not run*,
gabomdq@9023
   129
   unless you also install SDL on that other computer. A good solution
gabomdq@9023
   130
   for this dilemma is to static link against SDL. On OS X, you can
gabomdq@9023
   131
   achieve that by linking against the libraries listed by
philipp@10361
   132
philipp@10361
   133
       sdl-config --static-libs
philipp@10361
   134
gabomdq@9023
   135
   instead of those listed by
philipp@10361
   136
philipp@10361
   137
       sdl-config --libs
philipp@10361
   138
gabomdq@9023
   139
   Depending on how exactly SDL is integrated into your build systems, the
gabomdq@9023
   140
   way to achieve that varies, so I won't describe it here in detail
philipp@10361
   141
gabomdq@9023
   142
2) Add an 'Info.plist' to your application. That is a special XML file which
gabomdq@9023
   143
   contains some meta-information about your application (like some copyright
gabomdq@9023
   144
   information, the version of your app, the name of an optional icon file,
gabomdq@9023
   145
   and other things). Part of that information is displayed by the Finder
gabomdq@9023
   146
   when you click on the .app, or if you look at the "Get Info" window.
gabomdq@9023
   147
   More information about Info.plist files can be found on Apple's homepage.
gabomdq@9023
   148
gabomdq@9023
   149
gabomdq@9023
   150
As a final remark, let me add that I use some of the techniques (and some
gabomdq@9023
   151
variations of them) in Exult and ScummVM; both are available in source on
gabomdq@9023
   152
the net, so feel free to take a peek at them for inspiration!
gabomdq@9023
   153
gabomdq@9023
   154
gabomdq@9023
   155
==============================================================================
gabomdq@9023
   156
Using the Simple DirectMedia Layer with Xcode
gabomdq@9023
   157
==============================================================================
gabomdq@9023
   158
gabomdq@9023
   159
These instructions are for using Apple's Xcode IDE to build SDL applications.
gabomdq@9023
   160
gabomdq@9023
   161
- First steps
gabomdq@9023
   162
gabomdq@9023
   163
The first thing to do is to unpack the Xcode.tar.gz archive in the
gabomdq@9023
   164
top level SDL directory (where the Xcode.tar.gz archive resides).
gabomdq@9023
   165
Because Stuffit Expander will unpack the archive into a subdirectory,
gabomdq@9023
   166
you should unpack the archive manually from the command line:
philipp@10361
   167
philipp@10361
   168
    cd [path_to_SDL_source]
philipp@10361
   169
    tar zxf Xcode.tar.gz
philipp@10361
   170
gabomdq@9023
   171
This will create a new folder called Xcode, which you can browse
gabomdq@9023
   172
normally from the Finder.
gabomdq@9023
   173
gabomdq@9023
   174
- Building the Framework
gabomdq@9023
   175
gabomdq@9023
   176
The SDL Library is packaged as a framework bundle, an organized
gabomdq@9023
   177
relocatable folder hierarchy of executable code, interface headers,
gabomdq@9023
   178
and additional resources. For practical purposes, you can think of a 
gabomdq@9023
   179
framework as a more user and system-friendly shared library, whose library
gabomdq@9023
   180
file behaves more or less like a standard UNIX shared library.
gabomdq@9023
   181
gabomdq@9023
   182
To build the framework, simply open the framework project and build it. 
gabomdq@9023
   183
By default, the framework bundle "SDL.framework" is installed in 
gabomdq@9023
   184
/Library/Frameworks. Therefore, the testers and project stationary expect
gabomdq@9023
   185
it to be located there. However, it will function the same in any of the
gabomdq@9023
   186
following locations:
gabomdq@9023
   187
gabomdq@9023
   188
    ~/Library/Frameworks
gabomdq@9023
   189
    /Local/Library/Frameworks
gabomdq@9023
   190
    /System/Library/Frameworks
gabomdq@9023
   191
gabomdq@9023
   192
- Build Options
gabomdq@9023
   193
    There are two "Build Styles" (See the "Targets" tab) for SDL.
gabomdq@9023
   194
    "Deployment" should be used if you aren't tweaking the SDL library.
gabomdq@9023
   195
    "Development" should be used to debug SDL apps or the library itself.
gabomdq@9023
   196
gabomdq@9023
   197
- Building the Testers
gabomdq@9023
   198
    Open the SDLTest project and build away!
gabomdq@9023
   199
gabomdq@9023
   200
- Using the Project Stationary
gabomdq@9023
   201
    Copy the stationary to the indicated folders to access it from
gabomdq@9023
   202
    the "New Project" and "Add target" menus. What could be easier?
gabomdq@9023
   203
gabomdq@9023
   204
- Setting up a new project by hand
gabomdq@9023
   205
    Some of you won't want to use the Stationary so I'll give some tips:
gabomdq@9023
   206
    * Create a new "Cocoa Application"
gabomdq@9023
   207
    * Add src/main/macosx/SDLMain.m , .h and .nib to your project
gabomdq@9023
   208
    * Remove "main.c" from your project
gabomdq@9023
   209
    * Remove "MainMenu.nib" from your project
gabomdq@9023
   210
    * Add "$(HOME)/Library/Frameworks/SDL.framework/Headers" to include path
gabomdq@9023
   211
    * Add "$(HOME)/Library/Frameworks" to the frameworks search path
gabomdq@9023
   212
    * Add "-framework SDL -framework Foundation -framework AppKit" to "OTHER_LDFLAGS"
gabomdq@9023
   213
    * Set the "Main Nib File" under "Application Settings" to "SDLMain.nib"
gabomdq@9023
   214
    * Add your files
gabomdq@9023
   215
    * Clean and build
gabomdq@9023
   216
gabomdq@9023
   217
- Building from command line
gabomdq@9023
   218
    Use pbxbuild in the same directory as your .pbproj file
gabomdq@9023
   219
gabomdq@9023
   220
- Running your app
gabomdq@9023
   221
    You can send command line args to your app by either invoking it from
gabomdq@9023
   222
    the command line (in *.app/Contents/MacOS) or by entering them in the
gabomdq@9023
   223
    "Executables" panel of the target settings.
gabomdq@9023
   224
    
gabomdq@9023
   225
- Implementation Notes
gabomdq@9023
   226
    Some things that may be of interest about how it all works...
gabomdq@9023
   227
    * Working directory
gabomdq@9023
   228
        As defined in the SDL_main.m file, the working directory of your SDL app
gabomdq@9023
   229
        is by default set to its parent. You may wish to change this to better
gabomdq@9023
   230
        suit your needs.
gabomdq@9023
   231
    * You have a Cocoa App!
gabomdq@9023
   232
        Your SDL app is essentially a Cocoa application. When your app
gabomdq@9023
   233
        starts up and the libraries finish loading, a Cocoa procedure is called,
gabomdq@9023
   234
        which sets up the working directory and calls your main() method.
gabomdq@9023
   235
        You are free to modify your Cocoa app with generally no consequence 
gabomdq@9023
   236
        to SDL. You cannot, however, easily change the SDL window itself.
gabomdq@9023
   237
        Functionality may be added in the future to help this.
gabomdq@9023
   238
gabomdq@9023
   239
philipp@10184
   240
Known bugs are listed in the file "BUGS.txt".