Skip to content

Commit d03c60d

Browse files
authored
ios : add support for Swift Package Manager (#1370)
* Add support for Swift * Make it build in Xcode * Use the SPM package in the SwiftUI example app
1 parent 6a5d195 commit d03c60d

File tree

7 files changed

+109
-76
lines changed

7 files changed

+109
-76
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ build-no-accel/
1818
build-sanitize-addr/
1919
build-sanitize-thread/
2020

21+
# SPM
22+
.build/
23+
.swiftpm
24+
*.metallib
25+
2126
/main
2227
/stream
2328
/command

Package.swift

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// swift-tools-version:5.5
2+
3+
import PackageDescription
4+
5+
#if arch(arm) || arch(arm64)
6+
let platforms: [SupportedPlatform]? = [
7+
.macOS(.v12),
8+
.iOS(.v14),
9+
.watchOS(.v4),
10+
.tvOS(.v14)
11+
]
12+
let exclude: [String] = []
13+
let resources: [Resource] = [
14+
.process("ggml-metal.metal")
15+
]
16+
let additionalSources: [String] = ["ggml-metal.m"]
17+
let additionalSettings: [CSetting] = [
18+
.unsafeFlags(["-fno-objc-arc"]),
19+
.define("GGML_USE_METAL")
20+
]
21+
#else
22+
let platforms: [SupportedPlatform]? = nil
23+
let exclude: [String] = ["ggml-metal.metal"]
24+
let resources: [Resource] = []
25+
let additionalSources: [String] = []
26+
let additionalSettings: [CSetting] = []
27+
#endif
28+
29+
let package = Package(
30+
name: "whisper",
31+
platforms: platforms,
32+
products: [
33+
.library(name: "whisper", targets: ["whisper"]),
34+
],
35+
targets: [
36+
.target(
37+
name: "whisper",
38+
path: ".",
39+
exclude: exclude + [
40+
"bindings",
41+
"cmake",
42+
"coreml",
43+
"examples",
44+
"extra",
45+
"models",
46+
"samples",
47+
"tests",
48+
"CMakeLists.txt",
49+
"ggml-cuda.cu",
50+
"ggml-cuda.h",
51+
"Makefile"
52+
],
53+
sources: [
54+
"ggml.c",
55+
"whisper.cpp",
56+
"ggml-alloc.c",
57+
"ggml-backend.c",
58+
"ggml-quants.c"
59+
] + additionalSources,
60+
resources: resources,
61+
publicHeadersPath: "spm-headers",
62+
cSettings: [
63+
.unsafeFlags(["-Wno-shorten-64-to-32", "-O3", "-DNDEBUG"]),
64+
.define("GGML_USE_ACCELERATE")
65+
// NOTE: NEW_LAPACK will required iOS version 16.4+
66+
// We should consider add this in the future when we drop support for iOS 14
67+
// (ref: ref: https://developer.apple.com/documentation/accelerate/1513264-cblas_sgemm?language=objc)
68+
// .define("ACCELERATE_NEW_LAPACK"),
69+
// .define("ACCELERATE_LAPACK_ILP64")
70+
] + additionalSettings,
71+
linkerSettings: [
72+
.linkedFramework("Accelerate")
73+
]
74+
)
75+
],
76+
cxxLanguageStandard: .cxx11
77+
)

examples/whisper.swiftui/whisper.cpp.swift/LibWhisper.swift

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Foundation
2+
import whisper
23

34
enum WhisperError: Error {
45
case couldNotInitializeContext

examples/whisper.swiftui/whisper.cpp.swift/WhisperCppDemo-Bridging-Header.h

-4
This file was deleted.

examples/whisper.swiftui/whisper.swiftui.xcodeproj/project.pbxproj

+24-72
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,9 @@
1515
0AAC5D9B29539CCF003032C3 /* WhisperCppDemoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAC5D9A29539CCF003032C3 /* WhisperCppDemoApp.swift */; };
1616
0AAC5D9D29539CCF003032C3 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAC5D9C29539CCF003032C3 /* ContentView.swift */; };
1717
0AAC5D9F29539CD0003032C3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0AAC5D9E29539CD0003032C3 /* Assets.xcassets */; };
18-
0AAC5DA329539CD0003032C3 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0AAC5DA229539CD0003032C3 /* Preview Assets.xcassets */; };
19-
0AAC5DCB29539EB1003032C3 /* whisper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0AAC5DC729539EB0003032C3 /* whisper.cpp */; settings = {COMPILER_FLAGS = "-DGGML_USE_METAL -Wno-shorten-64-to-32"; }; };
20-
0AAC5DCC29539EB1003032C3 /* ggml.c in Sources */ = {isa = PBXBuildFile; fileRef = 0AAC5DC929539EB0003032C3 /* ggml.c */; settings = {COMPILER_FLAGS = "-DGGML_USE_ACCELERATE -DGGML_USE_METAL -Wno-shorten-64-to-32"; }; };
2118
0AAC5DCE2953A05C003032C3 /* WhisperState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAC5DCD2953A05C003032C3 /* WhisperState.swift */; };
2219
0AAC5DD12953A394003032C3 /* LibWhisper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAC5DD02953A394003032C3 /* LibWhisper.swift */; };
23-
18ABE1522AF555FA0044A204 /* ggml-backend.c in Sources */ = {isa = PBXBuildFile; fileRef = 18ABE14C2AF555FA0044A204 /* ggml-backend.c */; };
24-
18ABE1532AF555FA0044A204 /* ggml-quants.c in Sources */ = {isa = PBXBuildFile; fileRef = 18ABE1512AF555FA0044A204 /* ggml-quants.c */; };
25-
18AED4812AB21F2B009D854F /* ggml-alloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 18AED47F2AB21F2B009D854F /* ggml-alloc.c */; };
26-
7FCB08262ACFA3A400AF3530 /* ggml-metal.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FCB08252ACFA3A400AF3530 /* ggml-metal.m */; settings = {COMPILER_FLAGS = "-framework Foundation -framework Metal -framework MetalKit -fno-objc-arc"; }; };
27-
7FCB08282ACFA48500AF3530 /* ggml-metal.metal in Sources */ = {isa = PBXBuildFile; fileRef = 7FCB08272ACFA48500AF3530 /* ggml-metal.metal */; };
20+
E3F92DC52AFA8E3800A6A9D4 /* whisper in Frameworks */ = {isa = PBXBuildFile; productRef = E3F92DC42AFA8E3800A6A9D4 /* whisper */; };
2821
/* End PBXBuildFile section */
2922

3023
/* Begin PBXFileReference section */
@@ -38,32 +31,17 @@
3831
0AAC5D9C29539CCF003032C3 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
3932
0AAC5D9E29539CD0003032C3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
4033
0AAC5DA029539CD0003032C3 /* WhisperCppDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WhisperCppDemo.entitlements; sourceTree = "<group>"; };
41-
0AAC5DA229539CD0003032C3 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
42-
0AAC5DC629539EAF003032C3 /* WhisperCppDemo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WhisperCppDemo-Bridging-Header.h"; sourceTree = "<group>"; };
43-
0AAC5DC729539EB0003032C3 /* whisper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = whisper.cpp; sourceTree = "<group>"; };
44-
0AAC5DC829539EB0003032C3 /* whisper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = whisper.h; sourceTree = "<group>"; };
45-
0AAC5DC929539EB0003032C3 /* ggml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ggml.c; sourceTree = "<group>"; };
46-
0AAC5DCA29539EB0003032C3 /* ggml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ggml.h; sourceTree = "<group>"; };
4734
0AAC5DCD2953A05C003032C3 /* WhisperState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WhisperState.swift; sourceTree = "<group>"; };
4835
0AAC5DD02953A394003032C3 /* LibWhisper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibWhisper.swift; sourceTree = "<group>"; };
49-
18ABE14C2AF555FA0044A204 /* ggml-backend.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ggml-backend.c"; sourceTree = "<group>"; };
50-
18ABE14D2AF555FA0044A204 /* ggml-backend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ggml-backend.h"; sourceTree = "<group>"; };
51-
18ABE14E2AF555FA0044A204 /* ggml-backend-impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ggml-backend-impl.h"; sourceTree = "<group>"; };
52-
18ABE14F2AF555FA0044A204 /* ggml-quants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ggml-quants.h"; sourceTree = "<group>"; };
53-
18ABE1502AF555FA0044A204 /* ggml-impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ggml-impl.h"; sourceTree = "<group>"; };
54-
18ABE1512AF555FA0044A204 /* ggml-quants.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ggml-quants.c"; sourceTree = "<group>"; };
55-
18AED47F2AB21F2B009D854F /* ggml-alloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "ggml-alloc.c"; sourceTree = "<group>"; };
56-
18AED4802AB21F2B009D854F /* ggml-alloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ggml-alloc.h"; sourceTree = "<group>"; };
57-
7FCB081E2ACFA04400AF3530 /* ggml-metal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ggml-metal.h"; sourceTree = "<group>"; };
58-
7FCB08252ACFA3A400AF3530 /* ggml-metal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ggml-metal.m"; sourceTree = "<group>"; };
59-
7FCB08272ACFA48500AF3530 /* ggml-metal.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = "ggml-metal.metal"; sourceTree = "<group>"; };
36+
E3F92DC22AFA8DD800A6A9D4 /* whisper.cpp */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = whisper.cpp; path = ../..; sourceTree = "<group>"; };
6037
/* End PBXFileReference section */
6138

6239
/* Begin PBXFrameworksBuildPhase section */
6340
0AAC5D9429539CCF003032C3 /* Frameworks */ = {
6441
isa = PBXFrameworksBuildPhase;
6542
buildActionMask = 2147483647;
6643
files = (
44+
E3F92DC52AFA8E3800A6A9D4 /* whisper in Frameworks */,
6745
);
6846
runOnlyForDeploymentPostprocessing = 0;
6947
};
@@ -99,11 +77,12 @@
9977
0AAC5D8E29539CCF003032C3 = {
10078
isa = PBXGroup;
10179
children = (
80+
E3F92DC22AFA8DD800A6A9D4 /* whisper.cpp */,
10281
0A8E48FF2954B3F100704C1B /* README.md */,
103-
0AAC5DC529539E89003032C3 /* whisper.cpp */,
10482
0AAC5DCF2953A36C003032C3 /* whisper.cpp.swift */,
10583
0AAC5D9929539CCF003032C3 /* whisper.swiftui.demo */,
10684
0AAC5D9829539CCF003032C3 /* Products */,
85+
E3F92DC32AFA8E3800A6A9D4 /* Frameworks */,
10786
);
10887
sourceTree = "<group>";
10988
};
@@ -128,42 +107,9 @@
128107
path = whisper.swiftui.demo;
129108
sourceTree = "<group>";
130109
};
131-
0AAC5DA129539CD0003032C3 /* Preview Content */ = {
132-
isa = PBXGroup;
133-
children = (
134-
0AAC5DA229539CD0003032C3 /* Preview Assets.xcassets */,
135-
);
136-
name = "Preview Content";
137-
path = "../Preview Content";
138-
sourceTree = "<group>";
139-
};
140-
0AAC5DC529539E89003032C3 /* whisper.cpp */ = {
141-
isa = PBXGroup;
142-
children = (
143-
7FCB08272ACFA48500AF3530 /* ggml-metal.metal */,
144-
7FCB081E2ACFA04400AF3530 /* ggml-metal.h */,
145-
7FCB08252ACFA3A400AF3530 /* ggml-metal.m */,
146-
18ABE14E2AF555FA0044A204 /* ggml-backend-impl.h */,
147-
18ABE14C2AF555FA0044A204 /* ggml-backend.c */,
148-
18ABE14D2AF555FA0044A204 /* ggml-backend.h */,
149-
18ABE1502AF555FA0044A204 /* ggml-impl.h */,
150-
18ABE1512AF555FA0044A204 /* ggml-quants.c */,
151-
18ABE14F2AF555FA0044A204 /* ggml-quants.h */,
152-
18AED47F2AB21F2B009D854F /* ggml-alloc.c */,
153-
18AED4802AB21F2B009D854F /* ggml-alloc.h */,
154-
0AAC5DC929539EB0003032C3 /* ggml.c */,
155-
0AAC5DCA29539EB0003032C3 /* ggml.h */,
156-
0AAC5DC729539EB0003032C3 /* whisper.cpp */,
157-
0AAC5DC829539EB0003032C3 /* whisper.h */,
158-
);
159-
name = whisper.cpp;
160-
path = ../..;
161-
sourceTree = "<group>";
162-
};
163110
0AAC5DCF2953A36C003032C3 /* whisper.cpp.swift */ = {
164111
isa = PBXGroup;
165112
children = (
166-
0AAC5DC629539EAF003032C3 /* WhisperCppDemo-Bridging-Header.h */,
167113
0AAC5DD02953A394003032C3 /* LibWhisper.swift */,
168114
);
169115
path = whisper.cpp.swift;
@@ -182,11 +128,17 @@
182128
children = (
183129
0AAC5D9E29539CD0003032C3 /* Assets.xcassets */,
184130
0AAC5DA029539CD0003032C3 /* WhisperCppDemo.entitlements */,
185-
0AAC5DA129539CD0003032C3 /* Preview Content */,
186131
);
187132
path = "Supporting files";
188133
sourceTree = "<group>";
189134
};
135+
E3F92DC32AFA8E3800A6A9D4 /* Frameworks */ = {
136+
isa = PBXGroup;
137+
children = (
138+
);
139+
name = Frameworks;
140+
sourceTree = "<group>";
141+
};
190142
/* End PBXGroup section */
191143

192144
/* Begin PBXNativeTarget section */
@@ -203,6 +155,9 @@
203155
dependencies = (
204156
);
205157
name = whisper.swiftui;
158+
packageProductDependencies = (
159+
E3F92DC42AFA8E3800A6A9D4 /* whisper */,
160+
);
206161
productName = WhisperCppDemo;
207162
productReference = 0AAC5D9729539CCF003032C3 /* whisper.swiftui.app */;
208163
productType = "com.apple.product-type.application";
@@ -247,7 +202,6 @@
247202
buildActionMask = 2147483647;
248203
files = (
249204
0AA751482953AC2E001EE061 /* samples in Resources */,
250-
0AAC5DA329539CD0003032C3 /* Preview Assets.xcassets in Resources */,
251205
0A8E49002954B3F100704C1B /* README.md in Resources */,
252206
0AA751492953AC2E001EE061 /* models in Resources */,
253207
0AAC5D9F29539CD0003032C3 /* Assets.xcassets in Resources */,
@@ -263,17 +217,10 @@
263217
files = (
264218
0AAC5D9D29539CCF003032C3 /* ContentView.swift in Sources */,
265219
0AAC5D9B29539CCF003032C3 /* WhisperCppDemoApp.swift in Sources */,
266-
0AAC5DCC29539EB1003032C3 /* ggml.c in Sources */,
267-
18ABE1532AF555FA0044A204 /* ggml-quants.c in Sources */,
268220
0AAC5DCE2953A05C003032C3 /* WhisperState.swift in Sources */,
269-
7FCB08282ACFA48500AF3530 /* ggml-metal.metal in Sources */,
270221
0AAC5DD12953A394003032C3 /* LibWhisper.swift in Sources */,
271222
0AA7514C2953B569001EE061 /* RiffWaveUtils.swift in Sources */,
272-
0AAC5DCB29539EB1003032C3 /* whisper.cpp in Sources */,
273223
0AA7514E2953D958001EE061 /* Recorder.swift in Sources */,
274-
7FCB08262ACFA3A400AF3530 /* ggml-metal.m in Sources */,
275-
18AED4812AB21F2B009D854F /* ggml-alloc.c in Sources */,
276-
18ABE1522AF555FA0044A204 /* ggml-backend.c in Sources */,
277224
);
278225
runOnlyForDeploymentPostprocessing = 0;
279226
};
@@ -401,7 +348,7 @@
401348
CODE_SIGN_STYLE = Automatic;
402349
CURRENT_PROJECT_VERSION = 1;
403350
DEVELOPMENT_ASSET_PATHS = "\"whisper.swiftui.demo/Supporting files/Preview Content\"";
404-
DEVELOPMENT_TEAM = P8JZH34X63;
351+
DEVELOPMENT_TEAM = "";
405352
ENABLE_HARDENED_RUNTIME = YES;
406353
ENABLE_PREVIEWS = YES;
407354
GENERATE_INFOPLIST_FILE = YES;
@@ -425,7 +372,6 @@
425372
SDKROOT = auto;
426373
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
427374
SWIFT_EMIT_LOC_STRINGS = YES;
428-
SWIFT_OBJC_BRIDGING_HEADER = "whisper.cpp.swift/WhisperCppDemo-Bridging-Header.h";
429375
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
430376
SWIFT_VERSION = 5.0;
431377
TARGETED_DEVICE_FAMILY = "1,2";
@@ -442,7 +388,7 @@
442388
CODE_SIGN_STYLE = Automatic;
443389
CURRENT_PROJECT_VERSION = 1;
444390
DEVELOPMENT_ASSET_PATHS = "\"whisper.swiftui.demo/Supporting files/Preview Content\"";
445-
DEVELOPMENT_TEAM = P8JZH34X63;
391+
DEVELOPMENT_TEAM = "";
446392
ENABLE_HARDENED_RUNTIME = YES;
447393
ENABLE_PREVIEWS = YES;
448394
GENERATE_INFOPLIST_FILE = YES;
@@ -471,7 +417,6 @@
471417
SDKROOT = auto;
472418
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
473419
SWIFT_EMIT_LOC_STRINGS = YES;
474-
SWIFT_OBJC_BRIDGING_HEADER = "whisper.cpp.swift/WhisperCppDemo-Bridging-Header.h";
475420
SWIFT_VERSION = 5.0;
476421
TARGETED_DEVICE_FAMILY = "1,2";
477422
};
@@ -499,6 +444,13 @@
499444
defaultConfigurationName = Release;
500445
};
501446
/* End XCConfigurationList section */
447+
448+
/* Begin XCSwiftPackageProductDependency section */
449+
E3F92DC42AFA8E3800A6A9D4 /* whisper */ = {
450+
isa = XCSwiftPackageProductDependency;
451+
productName = whisper;
452+
};
453+
/* End XCSwiftPackageProductDependency section */
502454
};
503455
rootObject = 0AAC5D8F29539CCF003032C3 /* Project object */;
504456
}

spm-headers/ggml.h

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../ggml.h

spm-headers/whisper.h

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../whisper.h

0 commit comments

Comments
 (0)