@@ -21,8 +21,10 @@ import (
21
21
)
22
22
23
23
type archBuildResult struct {
24
- libraryPath string
25
- headerPath string
24
+ libraryPath string
25
+ headerPath string
26
+ titlePath string
27
+ frameworkPath string
26
28
27
29
targetInfo
28
30
}
@@ -59,6 +61,7 @@ func goAppleBind(gobind string, pkgs []*packages.Package, targets []targetInfo)
59
61
}
60
62
61
63
var buildResults []archBuildResult
64
+ var platformBuildResults = make (map [string ][]archBuildResult )
62
65
targetBuildResultMutex := & sync.Mutex {}
63
66
64
67
var waitGroup sync.WaitGroup
@@ -78,6 +81,10 @@ func goAppleBind(gobind string, pkgs []*packages.Package, targets []targetInfo)
78
81
79
82
targetBuildResultMutex .Lock ()
80
83
buildResults = append (buildResults , * buildResult )
84
+ if platformBuildResults [target .platform ] == nil {
85
+ platformBuildResults [target .platform ] = []archBuildResult {}
86
+ }
87
+ platformBuildResults [target .platform ] = append (platformBuildResults [target .platform ], * buildResult )
81
88
targetBuildResultMutex .Unlock ()
82
89
83
90
log .Println ("finish building for target" , target )
@@ -90,79 +97,31 @@ func goAppleBind(gobind string, pkgs []*packages.Package, targets []targetInfo)
90
97
// Finally combine all frameworks to an XCFramework
91
98
xcframeworkArgs := []string {"-create-xcframework" }
92
99
93
- // for _, buildResult := range buildResults {
94
- // xcframeworkArgs = append(xcframeworkArgs, "-library", buildResult.libraryPath, "-headers", buildResult.headerPath)
95
- // }
96
-
97
- xcframeworkArgs = append (xcframeworkArgs , "-output" , buildO )
98
-
99
- simulatorPayload := simulatorFrameworkPayload (buildResults , "iossimulator" )
100
- if simulatorPayload != nil {
101
- xcframeworkArgs = append (xcframeworkArgs , "-library" , simulatorPayload .libraryPath , "-headers" , simulatorPayload .headerPath )
102
- }
103
- catalystPayload := simulatorFrameworkPayload (buildResults , "maccatalyst" )
104
- if catalystPayload != nil {
105
- xcframeworkArgs = append (xcframeworkArgs , "-library" , catalystPayload .libraryPath , "-headers" , catalystPayload .headerPath )
100
+ refinedBuildResults := []archBuildResult {}
101
+
102
+ // Merge binary for single target
103
+ for _ , buildResults := range platformBuildResults {
104
+ if len (buildResults ) == 2 {
105
+ mergeArchsForSinglePlatform (buildResults [0 ].titlePath , buildResults [1 ].titlePath )
106
+ refinedBuildResults = append (refinedBuildResults , buildResults [0 ])
107
+ } else if len (buildResults ) == 1 {
108
+ refinedBuildResults = append (refinedBuildResults , buildResults [0 ])
109
+ } else {
110
+ log .Fatalln ("unexpected number of build results" , len (buildResults ))
111
+ }
106
112
}
107
113
108
- for _ , buildResult := range buildResults {
109
- if ! isPlatformNameSimulatorOrCatalyst (buildResult .platform ) {
110
- xcframeworkArgs = append (xcframeworkArgs , "-library" , buildResult .libraryPath , "-headers" , buildResult .headerPath )
111
- }
114
+ for _ , result := range refinedBuildResults {
115
+ xcframeworkArgs = append (xcframeworkArgs , "-framework" , result .frameworkPath )
112
116
}
113
117
118
+ xcframeworkArgs = append (xcframeworkArgs , "-output" , buildO )
114
119
cmd := exec .Command ("xcodebuild" , xcframeworkArgs ... )
115
120
log .Println ("running: xcodebuild" , strings .Join (xcframeworkArgs , " " ))
116
121
err = runCmd (cmd )
117
122
return err
118
123
}
119
124
120
- func isPlatformNameSimulatorOrCatalyst (platformName string ) bool {
121
- return platformName == "iossimulator" || platformName == "maccatalyst"
122
- }
123
-
124
- func simulatorFrameworkPayload (buildResults []archBuildResult , platformName string ) * xcframeworkPayload {
125
- if ! isPlatformNameSimulatorOrCatalyst (platformName ) {
126
- log .Fatalf ("unsupported platform %q" , platformName )
127
- return nil
128
- }
129
-
130
- var filteredStaticLibPaths []string
131
- for _ , buildResult := range buildResults {
132
- if buildResult .platform == platformName {
133
- filteredStaticLibPaths = append (filteredStaticLibPaths , buildResult .libraryPath )
134
- }
135
- }
136
-
137
- if len (filteredStaticLibPaths ) == 0 {
138
- return nil
139
- } else if len (filteredStaticLibPaths ) == 1 {
140
- return & xcframeworkPayload {
141
- headerPath : buildResults [0 ].headerPath ,
142
- libraryPath : buildResults [0 ].libraryPath ,
143
- }
144
- }
145
-
146
- outputPath := filepath .Dir (filepath .Dir (filteredStaticLibPaths [0 ])) + "/" + "univesal.a"
147
- if err := lipoCreate (outputPath , filteredStaticLibPaths ); err != nil {
148
- log .Fatalln (err )
149
- }
150
-
151
- return & xcframeworkPayload {
152
- headerPath : buildResults [0 ].headerPath ,
153
- libraryPath : outputPath ,
154
- }
155
- }
156
-
157
- func lipoCreate (outputPath string , libPaths []string ) error {
158
- args := []string {"lipo" , "-create" }
159
- args = append (args , libPaths ... )
160
- args = append (args , "-output" , outputPath )
161
- cmd := exec .Command ("xcrun" , args ... )
162
- log .Println ("running: lipo" , strings .Join (args , " " ))
163
- return runCmd (cmd )
164
- }
165
-
166
125
const appleBindInfoPlist = `<?xml version="1.0" encoding="UTF-8"?>
167
126
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
168
127
<plist version="1.0">
@@ -187,7 +146,19 @@ func goAppleBindArchive(name string, env []string, gosrc string) (string, error)
187
146
return archive , nil
188
147
}
189
148
149
+ func mergeArchsForSinglePlatform (from string , to string ) error {
150
+ fatCmd := exec .Command (
151
+ "xcrun" ,
152
+ "lipo" , from , to , "-create" , "-output" , to ,
153
+ )
154
+ if err := runCmd (fatCmd ); err != nil {
155
+ return err
156
+ }
157
+ return nil
158
+ }
159
+
190
160
func buildTargetArch (t targetInfo , gobindCommandPath string , pkgs []* packages.Package , title string , name string , modulesUsed bool ) (err error , buildResult * archBuildResult ) {
161
+ log .Println ("build for target:" , t )
191
162
// Catalyst support requires iOS 13+
192
163
v , _ := strconv .ParseFloat (buildIOSVersion , 64 )
193
164
if t .platform == "maccatalyst" && v < 13.0 {
@@ -223,7 +194,7 @@ func buildTargetArch(t targetInfo, gobindCommandPath string, pkgs []*packages.Pa
223
194
env := appleEnv [t .String ()][:]
224
195
sdk := getenv (env , "DARWIN_SDK" )
225
196
226
- frameworkDir := filepath .Join (tmpdir , t .platform , t . arch + "_framework" , sdk , title + ".framework" )
197
+ frameworkDir := filepath .Join (tmpdir , t .platform , sdk , title + "_" + t . arch + ".framework" )
227
198
228
199
fileBases := make ([]string , len (pkgs )+ 1 )
229
200
for i , pkg := range pkgs {
@@ -247,19 +218,37 @@ func buildTargetArch(t targetInfo, gobindCommandPath string, pkgs []*packages.Pa
247
218
}
248
219
}
249
220
221
+ // staticLibPath, err := goAppleBindArchive(name+"-"+t.platform+"-"+t.arch, env, outSrcDir)
250
222
staticLibPath , err := goAppleBindArchive (name + "-" + t .platform + "-" + t .arch , env , outSrcDir )
251
223
if err != nil {
252
224
return fmt .Errorf ("%s/%s: %v" , t .platform , t .arch , err ), nil
253
225
}
254
226
255
227
versionsDir := filepath .Join (frameworkDir , "Versions" )
256
228
versionsADir := filepath .Join (versionsDir , "A" )
257
- //titlePath := filepath.Join(versionsADir, title)
258
-
229
+ titlePath := filepath .Join (versionsADir , title )
259
230
versionsAHeadersDir := filepath .Join (versionsADir , "Headers" )
260
231
if err := mkdir (versionsAHeadersDir ); err != nil {
261
232
return err , nil
262
233
}
234
+ if err := symlink ("A" , filepath .Join (versionsDir , "Current" )); err != nil {
235
+ return err , nil
236
+ }
237
+ if err := symlink ("Versions/Current/Headers" , filepath .Join (frameworkDir , "Headers" )); err != nil {
238
+ return err , nil
239
+ }
240
+ if err := symlink (filepath .Join ("Versions/Current" , title ), filepath .Join (frameworkDir , title )); err != nil {
241
+ return err , nil
242
+ }
243
+
244
+ log .Println ("staticLibPath:" + staticLibPath )
245
+ lipoCmd := exec .Command (
246
+ "xcrun" ,
247
+ "lipo" , staticLibPath , "-create" , "-o" , titlePath ,
248
+ )
249
+ if err := runCmd (lipoCmd ); err != nil {
250
+ return err , nil
251
+ }
263
252
264
253
// Copy header file next to output archive.
265
254
var headerFiles []string
@@ -301,10 +290,22 @@ func buildTargetArch(t targetInfo, gobindCommandPath string, pkgs []*packages.Pa
301
290
}
302
291
}
303
292
293
+ if err := mkdir (filepath .Join (versionsADir , "Resources" )); err != nil {
294
+ return err , nil
295
+ }
296
+
304
297
if err := symlink ("Versions/Current/Resources" , filepath .Join (frameworkDir , "Resources" )); err != nil {
305
298
return err , nil
306
299
}
307
300
301
+ err = writeFile (filepath .Join (frameworkDir , "Resources" , "Info.plist" ), func (w io.Writer ) error {
302
+ _ , err := w .Write ([]byte (appleBindInfoPlist ))
303
+ return err
304
+ })
305
+ if err != nil {
306
+ return err , nil
307
+ }
308
+
308
309
var mmVals = struct {
309
310
Module string
310
311
Headers []string
@@ -324,9 +325,11 @@ func buildTargetArch(t targetInfo, gobindCommandPath string, pkgs []*packages.Pa
324
325
}
325
326
frameworkHeaderPath := filepath .Join (frameworkDir , "Versions" , "A" , "Headers" )
326
327
return err , & archBuildResult {
327
- headerPath : frameworkHeaderPath ,
328
- libraryPath : staticLibPath ,
329
- targetInfo : t ,
328
+ headerPath : frameworkHeaderPath ,
329
+ libraryPath : staticLibPath ,
330
+ titlePath : titlePath ,
331
+ targetInfo : t ,
332
+ frameworkPath : frameworkDir ,
330
333
}
331
334
}
332
335
0 commit comments