Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 100 additions & 19 deletions bindings/swift/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,113 @@ import PackageDescription

// This source-checkout package compiles the workspace's `core` submodule
// directly (Sources/CNativeAPI/core is a symlink), so it needs no CMake step
// and no separate native library at runtime. The package targets macOS, the
// platform this binding is built and tested on; the core also supports Windows
// and Linux, where SwiftPM would need each platform's own setup.
// and no separate native library at runtime. It builds on macOS, Linux and
// Windows; each host compiles only its own platform layer.
//
// The SwiftPM target rules below keep the platform split honest:
// * macOS links the Apple frameworks and compiles platform/macos.
// * Linux compiles platform/linux and gets its include/link flags from the
// gtk+-3.0, x11 and xi pkg-config modules through systemLibrary targets.
// pkg-config is used instead of unsafeFlags so the package stays usable as
// a SwiftPM dependency.
// * Windows compiles platform/windows (without the optional WinUI 3 layer)
// and links the Win32 libraries the core imports. WindowsManifest.c makes
// the linker embed the Common Controls v6 dependency the core needs.
//
// `core/build` only exists after someone configures the core with CMake; the
// package never needs it, but exclude it when present so SwiftPM does not
// discover CMake's own sources.
var excludes = [
// Other platforms' implementations; the host's are compiled below.
"core/src/platform/android",
"core/src/platform/ios",
"core/src/platform/linux",
"core/src/platform/ohos",
"core/src/platform/wasm",
"core/src/platform/windows",
// Not part of the library.
"core/tests",
"core/examples",
"core/docs",
"core/cmake",
]

let platformExcludes: [String]
let nativeDependencies: [Target.Dependency]
let nativeLinkerSettings: [LinkerSetting]
let systemTargets: [Target]

#if os(macOS)
platformExcludes = ["android", "ios", "linux", "ohos", "wasm", "windows"]
nativeDependencies = []
nativeLinkerSettings = [
.linkedFramework("Cocoa"),
.linkedFramework("CoreServices"),
.linkedFramework("QuartzCore"),
.linkedFramework("Carbon"),
.linkedFramework("IOKit"),
.linkedFramework("ServiceManagement"),
]
systemTargets = []
#elseif os(Linux)
platformExcludes = ["android", "ios", "macos", "ohos", "wasm", "windows"]
nativeDependencies = ["CGTK3", "CX11", "CXI"]
nativeLinkerSettings = [
.linkedLibrary("pthread"),
.linkedLibrary("dl"),
.linkedLibrary("m"),
]
systemTargets = [
.systemLibrary(
name: "CGTK3",
path: "Sources/CGTK3",
pkgConfig: "gtk+-3.0",
providers: [.apt(["libgtk-3-dev"]), .yum(["gtk3-devel"])]
),
.systemLibrary(
name: "CX11",
path: "Sources/CX11",
pkgConfig: "x11",
providers: [.apt(["libx11-dev"]), .yum(["libX11-devel"])]
),
.systemLibrary(
name: "CXI",
path: "Sources/CXI",
pkgConfig: "xi",
providers: [.apt(["libxi-dev"]), .yum(["libXi-devel"])]
),
]
#elseif os(Windows)
platformExcludes = ["android", "ios", "linux", "macos", "ohos", "wasm"]
nativeDependencies = []
nativeLinkerSettings = [
.linkedLibrary("user32"),
.linkedLibrary("shell32"),
.linkedLibrary("ole32"),
.linkedLibrary("oleaut32"),
.linkedLibrary("uuid"),
.linkedLibrary("comctl32"),
.linkedLibrary("dwmapi"),
.linkedLibrary("gdi32"),
.linkedLibrary("gdiplus"),
.linkedLibrary("crypt32"),
.linkedLibrary("advapi32"),
.linkedLibrary("version"),
.linkedLibrary("psapi"),
.linkedLibrary("shlwapi"),
]
systemTargets = []
// WinUI 3 is opt-in in the core's CMake build; the Swift package ships the
// plain Win32 backend, so leave the XAML layer out.
excludes += [
"core/src/platform/windows/menu_winui3_windows.cpp",
"core/src/platform/windows/message_dialog_winui3_windows.cpp",
"core/src/platform/windows/view_winui3_windows.cpp",
"core/src/platform/windows/window_winui3_windows.cpp",
"core/src/platform/windows/winui3_runtime_windows.cpp",
]
#else
platformExcludes = ["android", "ios", "linux", "macos", "ohos", "wasm", "windows"]
nativeDependencies = []
nativeLinkerSettings = []
systemTargets = []
#endif

excludes += platformExcludes.map { "core/src/platform/\($0)" }

let packageDirectory = URL(fileURLWithPath: #filePath).deletingLastPathComponent()
if FileManager.default.fileExists(
atPath: packageDirectory.appendingPathComponent("Sources/CNativeAPI/core/build").path
Expand All @@ -37,20 +124,14 @@ let package = Package(
products: [
.library(name: "NativeAPI", targets: ["NativeAPI"])
],
targets: [
targets: systemTargets + [
.target(
name: "CNativeAPI",
dependencies: nativeDependencies,
path: "Sources/CNativeAPI",
exclude: excludes,
publicHeadersPath: "include",
linkerSettings: [
.linkedFramework("Cocoa"),
.linkedFramework("CoreServices"),
.linkedFramework("QuartzCore"),
.linkedFramework("Carbon"),
.linkedFramework("IOKit"),
.linkedFramework("ServiceManagement"),
]
linkerSettings: nativeLinkerSettings
),
.target(name: "NativeAPI", dependencies: ["CNativeAPI"], path: "Sources/NativeAPI"),
.testTarget(
Expand Down
5 changes: 5 additions & 0 deletions bindings/swift/Sources/CGTK3/module.modulemap
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module CGTK3 [system] {
header "shim.h"
link "gtk-3"
export *
}
1 change: 1 addition & 0 deletions bindings/swift/Sources/CGTK3/shim.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <gtk/gtk.h>
14 changes: 14 additions & 0 deletions bindings/swift/Sources/CNativeAPI/WindowsManifest.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* The core's Win32 view layer imports GetWindowSubclass(), which only
* ComCtl32 v6 exports. Without a manifest that asks for v6, the loader binds
* the executable to the v5 DLL and terminates with STATUS_ENTRYPOINT_NOT_FOUND
* before main() runs. Embed the dependency from an object file so every
* executable that links this package gets it, with no manifest flag in
* Package.swift (which would have to be an unsafeFlag).
*/
#if defined(_WIN32)
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif

/* Keep the translation unit non-empty on every compiler. */
int nativeapi_swift_windows_manifest_anchor(void) { return 0; }
5 changes: 5 additions & 0 deletions bindings/swift/Sources/CX11/module.modulemap
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module CX11 [system] {
header "shim.h"
link "X11"
export *
}
4 changes: 4 additions & 0 deletions bindings/swift/Sources/CX11/shim.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
5 changes: 5 additions & 0 deletions bindings/swift/Sources/CXI/module.modulemap
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module CXI [system] {
header "shim.h"
link "Xi"
export *
}
1 change: 1 addition & 0 deletions bindings/swift/Sources/CXI/shim.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <X11/extensions/XInput2.h>
2 changes: 1 addition & 1 deletion bindings/swift/Sources/NativeAPI/Application.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public enum Brightness: CInt {
}

var raw: native_brightness_t {
native_brightness_t(rawValue: UInt32(self.rawValue))
native_brightness_t(rawValue: numericCast(self.rawValue))
}
}

Expand Down
4 changes: 2 additions & 2 deletions bindings/swift/Sources/NativeAPI/Clipboard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extension ClipboardData {
raw.image = self.image?.nativeHandle ?? 0
if !self.filePaths.isEmpty {
let pointers = self.filePaths.map { strdup($0) }
raw.file_paths.count = pointers.count
raw.file_paths.count = numericCast(pointers.count)
raw.file_paths.items = UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>.allocate(capacity: pointers.count)
for (index, pointer) in pointers.enumerated() { raw.file_paths.items[index] = pointer }
}
Expand Down Expand Up @@ -157,7 +157,7 @@ public final class Clipboard: Sendable {
let filePathsPointers = filePaths.map { strdup($0) }
defer { filePathsPointers.forEach { free($0) } }
var filePathsList = native_string_list_t()
filePathsList.count = filePathsPointers.count
filePathsList.count = numericCast(filePathsPointers.count)
if !filePathsPointers.isEmpty {
filePathsList.items = UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>.allocate(capacity: filePathsPointers.count)
for (index, pointer) in filePathsPointers.enumerated() { filePathsList.items[index] = pointer }
Expand Down
2 changes: 1 addition & 1 deletion bindings/swift/Sources/NativeAPI/Dialog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ public enum DialogModality: CInt {
}

var raw: native_dialog_modality_t {
native_dialog_modality_t(rawValue: UInt32(self.rawValue))
native_dialog_modality_t(rawValue: numericCast(self.rawValue))
}
}
2 changes: 1 addition & 1 deletion bindings/swift/Sources/NativeAPI/Display.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public enum DisplayOrientation: CInt {
}

var raw: native_display_orientation_t {
native_display_orientation_t(rawValue: UInt32(self.rawValue))
native_display_orientation_t(rawValue: numericCast(self.rawValue))
}
}

Expand Down
4 changes: 2 additions & 2 deletions bindings/swift/Sources/NativeAPI/DragSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public enum DragOperation: CInt {
}

var raw: native_drag_operation_t {
native_drag_operation_t(rawValue: UInt32(self.rawValue))
native_drag_operation_t(rawValue: numericCast(self.rawValue))
}
}

Expand Down Expand Up @@ -89,7 +89,7 @@ public class DragSource {
let filePathsPointers = filePaths.map { strdup($0) }
defer { filePathsPointers.forEach { free($0) } }
var filePathsList = native_string_list_t()
filePathsList.count = filePathsPointers.count
filePathsList.count = numericCast(filePathsPointers.count)
if !filePathsPointers.isEmpty {
filePathsList.items = UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>.allocate(capacity: filePathsPointers.count)
for (index, pointer) in filePathsPointers.enumerated() { filePathsList.items[index] = pointer }
Expand Down
6 changes: 3 additions & 3 deletions bindings/swift/Sources/NativeAPI/FileDialog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public enum FileDialogMode: CInt {
}

var raw: native_file_dialog_mode_t {
native_file_dialog_mode_t(rawValue: UInt32(self.rawValue))
native_file_dialog_mode_t(rawValue: numericCast(self.rawValue))
}
}

Expand All @@ -43,7 +43,7 @@ public enum FileDialogResult: CInt {
}

var raw: native_file_dialog_result_t {
native_file_dialog_result_t(rawValue: UInt32(self.rawValue))
native_file_dialog_result_t(rawValue: numericCast(self.rawValue))
}
}

Expand Down Expand Up @@ -94,7 +94,7 @@ public class FileDialog {
let extensionsPointers = extensions.map { strdup($0) }
defer { extensionsPointers.forEach { free($0) } }
var extensionsList = native_string_list_t()
extensionsList.count = extensionsPointers.count
extensionsList.count = numericCast(extensionsPointers.count)
if !extensionsPointers.isEmpty {
extensionsList.items = UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>.allocate(capacity: extensionsPointers.count)
for (index, pointer) in extensionsPointers.enumerated() { extensionsList.items[index] = pointer }
Expand Down
4 changes: 2 additions & 2 deletions bindings/swift/Sources/NativeAPI/Foundation/Keyboard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ public struct ModifierKey: OptionSet, Sendable {
}

init(raw: native_modifier_key_t) {
self.init(rawValue: UInt32(raw.rawValue))
self.init(rawValue: numericCast(raw.rawValue))
}

var raw: native_modifier_key_t {
native_modifier_key_t(rawValue: rawValue)
native_modifier_key_t(rawValue: numericCast(rawValue))
}

public static let shift = ModifierKey(rawValue: 1)
Expand Down
2 changes: 1 addition & 1 deletion bindings/swift/Sources/NativeAPI/LaunchAtLogin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public class LaunchAtLogin {
let argumentsPointers = arguments.map { strdup($0) }
defer { argumentsPointers.forEach { free($0) } }
var argumentsList = native_string_list_t()
argumentsList.count = argumentsPointers.count
argumentsList.count = numericCast(argumentsPointers.count)
if !argumentsPointers.isEmpty {
argumentsList.items = UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>.allocate(capacity: argumentsPointers.count)
for (index, pointer) in argumentsPointers.enumerated() { argumentsList.items[index] = pointer }
Expand Down
6 changes: 3 additions & 3 deletions bindings/swift/Sources/NativeAPI/Menu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public enum MenuBackend: CInt {
}

var raw: native_menu_backend_t {
native_menu_backend_t(rawValue: UInt32(self.rawValue))
native_menu_backend_t(rawValue: numericCast(self.rawValue))
}
}

Expand All @@ -45,7 +45,7 @@ public enum MenuItemType: CInt {
}

var raw: native_menu_item_type_t {
native_menu_item_type_t(rawValue: UInt32(self.rawValue))
native_menu_item_type_t(rawValue: numericCast(self.rawValue))
}
}

Expand All @@ -64,7 +64,7 @@ public enum MenuItemState: CInt {
}

var raw: native_menu_item_state_t {
native_menu_item_state_t(rawValue: UInt32(self.rawValue))
native_menu_item_state_t(rawValue: numericCast(self.rawValue))
}
}

Expand Down
2 changes: 1 addition & 1 deletion bindings/swift/Sources/NativeAPI/MessageDialog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public enum MessageDialogResult: CInt {
}

var raw: native_message_dialog_result_t {
native_message_dialog_result_t(rawValue: UInt32(self.rawValue))
native_message_dialog_result_t(rawValue: numericCast(self.rawValue))
}
}

Expand Down
2 changes: 1 addition & 1 deletion bindings/swift/Sources/NativeAPI/Placement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ public enum Placement: CInt {
}

var raw: native_placement_t {
native_placement_t(rawValue: UInt32(self.rawValue))
native_placement_t(rawValue: numericCast(self.rawValue))
}
}
2 changes: 1 addition & 1 deletion bindings/swift/Sources/NativeAPI/PositioningStrategy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public enum PositioningStrategyType: CInt {
}

var raw: native_positioning_strategy_type_t {
native_positioning_strategy_type_t(rawValue: UInt32(self.rawValue))
native_positioning_strategy_type_t(rawValue: numericCast(self.rawValue))
}
}

Expand Down
2 changes: 1 addition & 1 deletion bindings/swift/Sources/NativeAPI/Shortcut.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public enum ShortcutScope: CInt {
}

var raw: native_shortcut_scope_t {
native_shortcut_scope_t(rawValue: UInt32(self.rawValue))
native_shortcut_scope_t(rawValue: numericCast(self.rawValue))
}
}

Expand Down
4 changes: 2 additions & 2 deletions bindings/swift/Sources/NativeAPI/TrayIcon.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public enum ContextMenuTrigger: CInt {
}

var raw: native_context_menu_trigger_t {
native_context_menu_trigger_t(rawValue: UInt32(self.rawValue))
native_context_menu_trigger_t(rawValue: numericCast(self.rawValue))
}
}

Expand All @@ -41,7 +41,7 @@ public enum TrayIconPosition: CInt {
}

var raw: native_tray_icon_position_t {
native_tray_icon_position_t(rawValue: UInt32(self.rawValue))
native_tray_icon_position_t(rawValue: numericCast(self.rawValue))
}
}

Expand Down
2 changes: 1 addition & 1 deletion bindings/swift/Sources/NativeAPI/UrlOpener.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public enum UrlOpenErrorCode: CInt {
}

var raw: native_url_open_error_code_t {
native_url_open_error_code_t(rawValue: UInt32(self.rawValue))
native_url_open_error_code_t(rawValue: numericCast(self.rawValue))
}
}

Expand Down
Loading
Loading