App Bundles Overview
An Application Bundle (opens in a new tab) is a folder with a specific structure that is interpreted by the file manager (Finder) as an executable file. It is intended to contain an application complete with all its supporting resources such that the whole application can be moved or deleted by moving or deleting the bundle folder, and can be run from any location.
ravynOS bundles are very similar to macOS bundles with three main differences:
- The executable format inside the bundle is
ELF
instead ofMach-O
and hence cannot support multiple architectures (i.e. arm64 and amd64) in one executable yet. Transition to Mach-O is planned. - The executable directory is named ravynOS instead of MacOS
- There is a symlink inside the top level to the executable under Contents/ravynOS.
A bundle can target multiple platforms (known as a "fat bundle") by including more than one executable and a set of shared config and resources. This means it is possible to package an app for both macOS and ravynOS in the same bundle.
Many applications are written using Objective-C/C++ to take advantage of Cocoa frameworks. While this is preferred, apps can be written in any language and don't need to use the Foundation or AppKit frameworks. The minimum requirements are as follows.
- Implement the minimum Bundle directory structure (see source (opens in a new tab) of this bundle).
Firefox.app
├── Contents
│ ├── ravynOS
│ │ └── Firefox
│ ├── Info.plist
│ └── Resources
│ └── firefox.icns
├── Firefox -> Contents/ravynOS/Firefox
└── Resources -> Contents/Resources
There are few rules about what goes into Resources. Essentially it should be anything your app needs to run, and your app should know how to locate these resources relative to its runtime location. Apps should never use paths to fixed resource locations like /usr/lib/myapplication/libfoo.so
; instead they should use NSBundle
, CFBundle
or an equivalent to determine their location then construct a path into the Resources folder.
- Include an icon in Resources in either
.icns
or.png
format and reference it fromInfo.plist
- Include an
Info.plist
in the Contents folder which has at least these mandatory keys:- CFBundleExecutable
- CFBundleIconFile
- CFBundleIdentifier
- CFBundleName
- CFBundlePackageType with value
APPL
- CFBundleShortVersionString
- CFBundleSignature with a 4-letter code representing your application or
OBJC
if you don't have one - NSPrincipalClass with your application's main class or
NSApplication
if it doesn't use Objective-C
You should include the CFBundleDocumentTypes dictionary as well if you want LaunchServices to know what kinds of files your application can open or to define new file types.
Other considerations
All apps should follow the Apple Human Interface Guidelines (opens in a new tab) as much as possible. You must implement the standard key bindings and menu structures for any new application. Applications being ported or packaged should make a best effort to follow these.
New applications must include an application menu titled with the app's name. This is the menu seen just to the right of the Apple logo on macOS applications. It contains standard items such as About, Preferences, Quit. This menu is created automatically for Cocoa applications using AppKit.
Menus are automatically placed into the global menu bar for applications using Cocoa. Qt, GTK, and Java support is planned as well. Some applications may need to be patched to support global menus. RavynOS uses the standard Cocoa NSMenu system, compatible with macOS. Cocoa applications that implement an NSMenu will automatically have it appear in the global menu bar when the application becomes active. Support for the dbus-menu (opens in a new tab) spec is likely to happen at some point. This is supported by Qt, GTK, and other frameworks for writing applications that are not using Cocoa.