Skip to content
Parracodea edited this page Nov 29, 2024 · 2 revisions

Build ‐ macOS

Be sure to check Build for generic instructions.

EmptyEpsilon supports building on both Intel and M-series ARM (M1, M2, etc.) architectures.

If you're building and running EmptyEpsilon locally for development purposes, follow the instructions in the "Basic app target" section.

If you intend to build a DMG for distribution to players that includes all necessary dependencies, follow the instructions in the "DMG packaging" section.

Basic app target

The result of these steps builds a standard macOS .app, but might require external dependencies.

  1. Install XCode:

    xcode-select --install
  2. Install the Homebrew package manager to install some dependencies before compiling EmptyEpsilon.

  3. Install cmake to compile your code, and the sdl2 dependency that EmptyEpsilon needs. You can also install git via brew if necessary.

    brew install cmake sdl2

    You can also compile or install pre-compiled SDL2 libraries yourself. Refer to the official documentation.

  4. Create a new directory named emptyepsilon where the game sources will be fetched, and download SeriousProton (game engine) and EmptyEpsilon (the actual game).

    mkdir -p emptyepsilon && cd emptyepsilon
    
    git clone [email protected]:daid/SeriousProton.git
    git clone [email protected]:daid/EmptyEpsilon.git

    NOTE: To get the source anonymously (if you don't have a GitHub account), use these two commands instead:

    git clone https://github.com/daid/SeriousProton.git
    git clone https://github.com/daid/EmptyEpsilon.git

    If you're building a specific release of EmptyEpsilon, remember to checkout the correct tag in both repositories as mentioned in the generic Build instructions!

  5. Go to the EmptyEpsilon directory and compile the game.

    cd EmptyEpsilon
    mkdir _build
    cd _build
    cmake .. -DCMAKE_INSTALL_PREFIX=. -DSERIOUS_PROTON_DIR=../../SeriousProton/
    make && make install

    make builds the binary executable only, while make install copies necessary assets into the .app bundle.

Once it's built, you can open the game normally by double-clicking the app bundle, or by running it:

EmptyEpsilon.app

To output log information to a terminal window, run the executable within the bundle:

EmptyEpsilon.app/Contents/MacOS/EmptyEpsilon

Game assets, including models, scripts, and music, are stored within the bundle at EmptyEpsilon.app/Contents/Resources/. The Preferences file is saved to ~/.emptyepsilon/options.ini.

NOTE: The compiled app still requires SDL2 libraries, such as the Homebrew sdl2 package, to be installed locally. See DMG packaging to add SDL2 to the app bundle.

Targeting a minimum OS X/macOS version (optional)

To aid compatibility with specific older versions of OS X/macOS, use the MACOSX_DEPLOYMENT_TARGET environment variable to set a minimum Mac OS X/macOS target version. Setting this lower than 10.15 (EE's default since may 2021) might cause problems when compiling with newer versions of XCode, and SDL2 does not support targeting OS X 10.5 and older.

You can also set this in EmptyEpsilon's CMakeLists.txt, around the top:

set(ENV{MACOSX_DEPLOYMENT_TARGET} "11.0")

DMG packaging

Since May 2021, EE supports packaging a DMG directly through CMake that contains all necessary dependencies for distribution to players.

  1. Install the Homebrew package manager to install some dependencies before compiling EmptyEpsilon.
  2. Install cmake and ninja to be installed, which you can do via homebrew:
    • brew install cmake ninja
  3. Create a folder to put all of your EmptyEpsilon files. For example, ~/Documents/emptyepsilon-compile
  4. Download SDL2
    • To generate a DMG package, you cannot use the sdl2 package from homebrew!. Relocatable packages require Frameworks, which homebrew does not install.
    • NOTE: Frameworks and homebrew-installed libraries for SDL2 should not be installed simultaneously. However, brew's sdl2 package might be installed as a dependency of other homebrew packages, particularly ffmpeg. If you have issues building EmptyEpsilon, you might need to remove all such homebrew package dependencies so you can remove the sdl2 package.

    1. Create a folder to put your SDL2 .dmg file. For example, ~/Documents/emptyepsilon-compile/SDL2-dmg
    2. Download the official SDL2 DMG release and save it in ~/Documents/emptyepsilon-compile/SDL2-dmg.
  5. Open a terminal and change directories to ~/Documents/emptyepsilon-compile/SDL2-dmg
  6. Run the following:
    • # Update the following version number to the version you downloaded
      cd ~/Documents/emptyepsilon-compile/SDL2-dmg
      export SDL2_VERSION=2.30.9
      hdiutil attach SDL2-${SDL2_VERSION}.dmg
  7. Clone a copy of the EmptyEpsilon and SeriousProton source code in ~/Documents/emptyepsilon-compile
    • cd ~/Documents/emptyepsilon-compile
      git clone https://github.com/daid/SeriousProton
      git clone https://github.com/daid/EmptyEpsilon
  8. Decide which version of EmptyEpsilon you'd like to compile. Check out the appropriate git tag:
    • cd ~/Documents/emptyepsilon-compile/SeriousProton
      git checkout EE-2024.08.09
      cd ~/Documents/emptyepsilon-compile/EmptyEpsilon
      git checkout EE-2024.08.09
  9. Create a sdl2-config.cmake file which targets the framework. Save it as ~/Documents/emptyepsilon-compile/sdl2-config.cmake
    • # sdl2-config.cmake
      
      # By default, hdiutil will attach to /Volumes/SDL2
      set(_SDL2_mountpoint /Volumes/SDL2)
      find_library(SDL2_LIBRARIES SDL2 PATHS "${_SDL2_mountpoint}")
      find_path(SDL2_INCLUDE_DIRS SDL.h PATHS "${SDL2_LIBRARIES}" PATH_SUFFIXES Headers)
      set(SDL2_FRAMEWORK_PATH "${_SDL2_mountpoint}/SDL2.framework")
      set(SDL2_INCLUDE_DIR  "${SDL2_FRAMEWORK_PATH}/Headers")
      set(SDL2_INCLUDE_DIRS "${SDL2_INCLUDE_DIR};${SDL2_FRAMEWORK_PATH}")
  10. Change directories to your EmptyEpsilon source code directory:
    • cd ~/Documents/emptyepsilon-compile/EmptyEpsilon
  11. Run the following commands:
    1. # Run this from your EmptyEpsilon source code directory: ~/Documents/emptyepsilon-compile/EmptyEpsilon
      
      SDL2_CONFIG_DIR=..
    2. # Run this from your EmptyEpsilon source code directory: ~/Documents/emptyepsilon-compile/EmptyEpsilon
      
      # Be sure to update `DCPACK_PACKAGE_VERSION_MAJOR`, `DCPACK_PACKAGE_VERSION_MINOR`,
      # and `DCPACK_PACKAGE_VERSION_PATCH` to match the version number you've selected to compile
      
      cmake -G Ninja \
         -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo \
         -DCPACK_GENERATOR:STRING=DragNDrop \
         -DSDL2_DIR:PATH=$SDL2_CONFIG_DIR \
         -DSERIOUS_PROTON_DIR=../SeriousProton \
         -DCPACK_PACKAGE_VERSION_MAJOR=2024 \
         -DCPACK_PACKAGE_VERSION_MINOR=08 \
         -DCPACK_PACKAGE_VERSION_PATCH=09 \
         -B _build
    3. # Run this from your EmptyEpsilon source code directory: ~/Documents/emptyepsilon-compile/EmptyEpsilon
      
      cmake --build _build --target package --parallel
  12. If compilation finishes successfully, you should have an EmptyEpsilon .dmg in your ~/Documents/emptyepsilon-compile/EmptyEpsilon/_build/ directory, that can be used to install the game or shared with others.

Troubleshooting

If the build fails with an error about the freetype framework being missing:

CMake Error at /usr/local/Cellar/cmake/3.22.1/share/cmake/Modules/BundleUtilities.cmake:458 (message):
  otool -l failed: 1

  error: /Library/Developer/CommandLineTools/usr/bin/otool-classic: can't
  open file: @rpath/../Frameworks/freetype.framework/Versions/A/freetype (No
  such file or directory)

You may need to install it using homebrew, and also manually link it to a path being searched during the build:

brew install freetype
ln -s /usr/local/lib/freetype.framework /Library/Frameworks/

If this still doesn't work, you may need to specify the homebrew path as a CMAKE_PREFIX_PATH when running the cmake --build command:

CMAKE_PREFIX_PATH=/usr/local/lib/freetype.framework cmake --build _build --target package --parallel

This might build the DMG, but the resulting app might still fail with a missing freetype library error, in which case ?? please help

Legacy

The content below is old, kept for posterity. Dive in at your own risk!

  • Before October 2021, the project used SFML. Be sure to check the previous instructions if building for an older version.

  • In macOS/OS X 10.14 (Mojave) and earlier, Windows binaries also perform well on macOS as both clients and server, including station transparency effects, when run with Wine 4+ (brew cask install wine-stable if Homebrew is installed).

    As of macOS 10.15 (Catalina), 32-bit applications are no longer supported. wine does not run on Catalina and wine64 will not run Windows builds of EmptyEpsilon.

Bundling dependencies (optional)

By using the above process, end users who try to run your app bundle builds must also install sfml in order to play. To avoid this, you can bundle the required dependencies using dylibbundler, which copies the libraries into the app bundle and updates the EmptyEpsilon executable within the bundle to link them.

You'll need to build dylibbundler from source to get the --search-path feature, which as of Feb. 2020 is not yet in a released version.

If you've followed the steps to build EmptyEpsilon, you already have everything you need to build dylibbundler:

git clone https://github.com/auriamg/macdylibbundler.git
cd macdylibbundler
make && make install

Once dylibbundler is built and installed, go to the EmptyEpsilon build directory containing your newly built EmptyEpsilon.app bundle and run:

dylibbundler \
  --overwrite-dir \
  --bundle-deps \
  --search-path "/usr/local/lib" \
  --fix-file "EmptyEpsilon.app/Contents/MacOS/EmptyEpsilon" \
  --dest-dir "EmptyEpsilon.app/Contents/libs"

This will output many warnings that you can disregard. The changes this makes to EmptyEpsilon.app will increase the bundle's size slightly but should allow you to run the app bundle on Macs that do not have SFML libraries installed.

Packaging into a DMG disk image (optional)

To compress the EmptyEpsilon.app bundle and other useful files (such as script_reference.html), you can build a disk image (DMG).

Copy EmptyEpsilon.app and any other files you want on the image into a staging directory. For example, from the directory where you built EmptyEpsilon, you can run:

mkdir _staging
cp -r EmptyEpsilon.app script_reference.html _staging

Then use hdiutil to create a temporary image using that directory as the source:

hdiutil \
  create "/tmp/tmp.dmg" \
  -ov \
  -volname "EmptyEpsilon" \
  -fs HFS+ \
  -srcfolder "_staging"

Finally, convert the image to a read-only distributible image:

hdiutil \
  convert "/tmp/tmp.dmg" \
  -format UDZO \
  -o "EmptyEpsilon.dmg"
Clone this wiki locally