import AppKit import Darwin @main @MainActor enum TerebiBootstrap { static func main() { let app = Bundle.main.bundleURL if let error = FFmpegRuntime.error(for: app) { fail(error) } let payload = app.appendingPathComponent("Contents/Frameworks/libterebi-player.dylib") guard let library = dlopen(payload.path, RTLD_NOW | RTLD_LOCAL) else { let detail = dlerror().map { String(cString: $0) } ?? "The dynamic loader could not load the player." fail("Could not load the player: \(detail)\n\nPlayer library: \(payload.path)\nRebuild and reinstall terebi.") } guard let entry = dlsym(library, "terebi_app_main") else { fail("The player library is missing its application entry point. Rebuild and reinstall terebi.") } // Keep the declared app executable alive so LaunchServices retains its identity. typealias PlayerMain = @convention(c) () -> Void unsafeBitCast(entry, to: PlayerMain.self)() } private static func fail(_ message: String) -> Never { FileHandle.standardError.write(Data("terebi: \(message)\n".utf8)) let application = NSApplication.shared application.setActivationPolicy(.regular) application.activate(ignoringOtherApps: true) let alert = NSAlert() alert.alertStyle = .critical alert.messageText = "terebi could not start" alert.informativeText = message alert.addButton(withTitle: "Quit") alert.runModal() exit(69) } }