Skip to content

Build from Source

RithyTep edited this page Jan 28, 2026 · 1 revision

Build from Source

Prerequisites

  • macOS 14.0 Sonoma or later
  • Xcode 15+ or Swift 5.9+ toolchain
  • create-dmg (optional, for DMG): brew install create-dmg

Quick Build

git clone https://github.com/RithyTep/KhmerCalendarBar.git
cd KhmerCalendarBar

# Debug build
swift build

# Run directly
.build/debug/KhmerCalendarBar

Release Build + App Bundle + DMG

./build-app.sh

This script:

  1. Builds a release binary via swift build -c release
  2. Creates KhmerCalendarBar.app bundle with Info.plist and icon
  3. Ad-hoc code signs the app
  4. Packages a .zip archive
  5. Creates a styled .dmg with drag-to-Applications

Install from Build

# Copy to Applications
cp -R KhmerCalendarBar.app /Applications/

# Launch
open /Applications/KhmerCalendarBar.app

Project Structure

KhmerCalendarBar/
├── Package.swift              # Swift Package Manager manifest
├── build-app.sh               # Build + bundle + DMG script
├── KhmerCalendarBar/
│   ├── KhmerCalendarBarApp.swift   # App entry point
│   ├── Models/                # Data models
│   ├── Engine/                # Chhankitek conversion engine
│   ├── Services/              # Holiday, notification, storage services
│   ├── ViewModels/            # CalendarViewModel
│   ├── Views/                 # SwiftUI views
│   ├── Utilities/             # Helpers (LaunchAtLogin, icon generators)
│   └── Resources/             # App icon, Info.plist
├── docs/                      # Website (Vercel)
└── README.md

Development Tips

  • The app is a MenuBarExtra with .window style — it renders as a popover from the menu bar
  • Dark mode is enforced via DarkModeEnforcer (NSViewRepresentable) since MenuBarExtra windows ignore .preferredColorScheme()
  • All published state lives in CalendarViewModel (marked @MainActor)
  • The Chhankitek engine uses epoch-based astronomical calculations — see Engine/ directory

Clone this wiki locally