macOS notes and requirements

Contents:

1. Compiling on macOS

The FPC compiler needs the XCode command-line developer tools installed. In short, open /Applications/Utilities/Terminal and execute xcode-select --install.

This is covered in more details in the FPC / Lazarus documentation:

Also, it seems that the latest macOS doesn't include gdb (a debugger, user underneath by Lazarus). Lazarus will warn you about this on the 1st run. You can install GDB e.g. using HomeBrew, just execute brew install gdb. See GDB on OS X.

2. GUI libraries: Carbon/Cocoa? X11? X11 + GTK?

You can create your macOS applications in two ways:

  1. You can use Lazarus forms, and LCL (Lazarus Component Library). To use the engine, simply drop a TCastleControlBase component on a Lazarus form.

    This, in practice, means that your applications will use Carbon or Cocoa. These are built-in native libraries on macOS. So, your programs don't require anything extra to distribute.

  2. Alternatively, you can create your windows using our own TCastleWindowBase class. Our TCastleWindowBase can use various backends under the hood:

    • The default backend on macOS is CASTLE_WINDOW_XLIB. It's easiest to setup, although it does not look pretty, and does not show a menu bar (TCastleWindowBase.MainMenu).

      It requires installing XQuartz. (On older macOS versions, install instead X11 Server from your macOS install CD. For newer macOS, XQuartz is the way to go.)

      Our programs will appear as part of "X11 server" on your desktop.

      To compile, you also need to add this line to your fpc.cfg file (see FPC documentation "Configuration file" to know where you can find your fpc.cfg file):

      -k-L/usr/X11/lib/
      
      # Old version:
      # -Fl/usr/X11/lib/
      # Should work equally well as far as I know, but it doesn't, for FPC 3.0.4/3.0.5
      

      If, when running our applications, you get an error that glX extension not found: Check do you have a /usr/X11R6 symlink (e.g. by running ls /usr/X11R6 in the terminal). Some versions of XQuartz seem to not install it (see here). You can fix it on your system by:

      sudo ln -s /usr/X11 /usr/X11R6
      

      Alternative fix (see here):

      sudo /usr/libexec/x11-select /opt/X11
      sudo chmod a+rX /usr/X11/ /usr/X11R6/
      
    • Alternatively, you can switch the backend to CASTLE_WINDOW_GTK_2. Do this by adding this line to your fpc.cfg file (see FPC documentation "Configuration file" to know where you can find your fpc.cfg file):

      -dCASTLE_WINDOW_GTK_2

      This looks better (the program will still be part of the "X11 server", but it will have a nice menu bar and dialog windows using GTK).

      In addition to X11 (see above), your application will use GTK libraries. Install them using MacPorts, Homebrew or Fink. Yes, all three options are tested and OK. Look for packages called gtk2.

    • Alternatively, you can switch the backend of TCastleWindowBase to CASTLE_WINDOW_LCL. This uses Lazarus under the hood, and this way we will use Carbon or Cocoa instead. This means that TCastleWindowBase will actually use Lazarus TForm and TOpenGLControl internally.

      This looks nice and native.

      To do this, use the package alternative_castle_window_based_on_lcl.lpk instead of castle_window.lpk. This will give you CastleWindow unit that uses LCL and requires the castle_components package. If you open an existing source code, like view3dscene, you will have to change the dependencies in Lazarus Project inspector to use alternative_castle_window_based_on_lcl instead of castle_window.

3. Advantages and disadvantages of using LCL (Carbon/Cocoa)

On macOS, the default LCL widgetset is Carbon right now.

  • Good: native look, application has a normal menu bar, shows native dialog boxes (to open/save file, choose color and such) and generally looks and feels like every other macOS application. Lazarus compiles it into a bundle like view3dscene.app that can be easily installed by dragging to your Applications directory.

  • Good: no extra dependencies, Carbon and Cocoa are already part of every macOS installation. (No dependencies on X11, GTK.)

  • Bad: Carbon is deprecated by Apple. It is available only for 32-bit applications.

    You can alternatively use the Cocoa widgetset, but it is not as stable. As of Lazarus 1.8, CastleWindow + LCL backend + Cocoa widgetset doesn't work reliably. So, in practice, you are stuck with 32-bit applications if you want native look on macOS.

    In time, this will be resolved in LCL when Cocoa widgetset will be more complete. Right now, Carbon implementation is just more complete than Cocoa in LCL, see also Choice of Lazarus LCL widgetsets (for macOS).

    It may also be resolved on our side if we ever make direct CastleWindow backend based on Cocoa (without using Lazarus LCL):

    • It's a matter of creating and implementing a file castle_game_engine/src/window/castlewindow_cocoa.inc, based on castle_game_engine/src/window/castlewindow_backend_template.inc. See engine sources. See at other "backends" (like GTK, WinAPI, Xlib, LCL) for examples how to implement such thing, everything is inside src/window/ dir.

    • Alternatively, send Michalis a simple and clear example of FPC program using Cocoa that 1. creates and shows a window 2. with menu bar 3. and with OpenGL context area covering the window. I should be able to port such example to my "CastleWindow" then.

    • See e.g. FPC "OS_X Programming Tips" for pointers. If you're a developer familiar with macOS native toolkit and Free Pascal Compiler, your help will be much appreciated.

  • Bad: There are issues with LCL event loop. Some of them (not being able to get Update events continuously) are in bare LCL, some of them (the need to call Application.Run, not just loop using Application.ProcessMessages) are specific to LCL-Carbon. The former (Update issues when using mouse look or dragging with mouse) is somewhat workarounded on our side now (to not "stutter" when using mouse look), but the problem is still noticeable (mouse look under other TCastleWindowBase backends is much smoother).

    For the above reasons:

    • If you make normal game (that doesn't need any menu or dialog boxes) consider using the (default) CASTLE_WINDOW_XLIB backend on macOS. Using X11 (Xlib) is not a problem on macOS. And this way you get a perfect speed and smoothly working event loop (with smooth mouse look).

      Although full-screen is ugly on Xlib, there's no way to hide dock over fullscreen application in this situation... Easiest solution in this case is to keep your game windowed on macOS.

    • Only if you make tool-like program (that needs menu and dialog boxes) then CASTLE_WINDOW_LCL is a good choice. It will look perfectly native. Although at the cost of not perfect mouse look. Alternatively, you can use CASTLE_WINDOW_GTK_2 on macOS, that has both nice menu/dialogs and a smooth mouse look, but it requires installation of some special libraries (GTK etc. from fink).

4. Other libraries that may be required

  • For macOS older than Tiger (that is, 10.3 or older): install OpenAL to have game sounds. It may be downloaded from Creative, see download links from openal.org downloads. For macOS since Tiger, OpenAL comes already preinstalled. Even without OpenAL installed, all our programs will still work fine, you just will not get any sound.

  • Install vorbisfile library to read OggVorbis sound/music files. It may be installed using MacPorts, Homebrew or Fink.

    Without vorbisfile, all our programs will still work fine, but you will not hear OggVorbis music.

  • If you want to use external libpng implementation in your programs, that you will also need libpng to open and save images and textures in PNG format. It may be installed using MacPorts, Homebrew or Fink.

    Note that this is not necessary. If we don't find libpng, we will fallback to reading PNG using FpImage, which works too (but is slower, which may be significant if you load a lot of PNG files).

5. Notes specific to particular macOS package managers

5.1. Consider installing FPC and Lazarus through them too

To actually compile our programs on macOS, you need the Free Pascal Compiler. For comfortable RAD development, install also Lazarus (FPC is already included inside Lazarus installations, if you choose normal packages).

You can install them by downloading from their respective webpages, or you can install them by a macOS package manager like MacPorts, Homebrew or Fink.

Besides easy upgrades, the advantage of using the package manager to install the compiler is that it's easier then to install the libraries (like GTK2) with the same architecture (32-bit vs 64-bit). Otherwise, be careful to watch for it yourself: your system may host both 32-bit and 64-bit binaries and libraries, but to compile a 64-bit application, you will need a compiler (FPC) that targets 64-bit processors and 64-bit libraries.

On modern macOS versions, you usually just want to install x86_64 libraries, and the FPC compiler for Darwin+x86_64.

5.2. MacPorts

To install GTK and FPC, simply do:

sudo port install gtkglext # TODO: update this command to only install gtk2
sudo port install fpc

Then create your local FPC config, and add there macports libraries:

  • Copy /opt/local/lib/fpc/etc/fpc.cfg to ~/.fpc.cfg.
    Or, you can create an empty file ~/.fpc.cfg and paste there
    #INCLUDE /opt/local/lib/fpc/etc/fpc.cfg
    
  • At the end of ~/.fpc.cfg add this line:
    -Fl/opt/local/lib
    
  • We also advice adding FPC compiler and tools to your $PATH, to make it easier to use. Macports install them to /opt/local/lib/fpc/bin, so add something like this to your ~/.bashrc:
    export PATH=/opt/local/lib/fpc/bin:"$PATH"
    

5.3. Homebrew

To install FPC with Homebrew, you simply do

brew install fpc

The fpc is already on $PATH, so it's comfortable out-of-the-box.

Installing additional libraries, like GTK, is equally trivial.

5.4. Fink

  • To use the libraries installed by fink, you may have to add them to your libraries path. Execute a command like this (in the same shell (terminal), before executing our programs):

    export LD_LIBRARY_PATH=/sw/lib:"$LD_LIBRARY_PATH"
    

    You can add this line to your ~/.bashrc to have it automatically done.

  • To compile applications using GTK (CASTLE_WINDOW_GTK_2 backend), you should additionally install the fink "pango1-xft2-shlibs" package. Simple "fink install pango1-xft2-shlibs" should do the trick. This is necessary for successful linking.

  • If you use any libraries from fink, the linker must know their locations. Add this line to your fpc.cfg file (see FPC documentation "Configuration file" to know where you can find your fpc.cfg file):

    -Fl/sw/lib/
    

6. Creating macOS applications

A bunch of information about packaging your programs for macOS follows.

  1. Make "macOS bundle". It's basically a directory pretending to be an application.

    You can use Lazarus to create macOS bundle. Or you can use our create_macosx_bundle.sh script. The example usage is inside view3dscene and castle-view-image sources.

  2. Optionally, add libraries (like libpng and vorbisfile) to the bundle. If you link to them dynamically (e.g. using our TDynLib.Load), you should load them from a path relative to BundlePath, like BundlePath + 'Contents/MacOS/libpng.dylib'.

    See macOS Libraries on FPC wiki for general instructions how to include library inside a bundle.

  3. Pack into a nice .dmg file. See Building Fancy DMG Images on macOS for nice description how to make the directories inside dmg look pretty, so you can visually suggest user to drag your application in the Applications folder.

    Alternative method of distribution macOS applications is the package manager (.pkg). For normal applications (like games) the simpler .dmg is a better choice.