Skip to content

Commit 9205183

Browse files
ncooke3paulb777
andauthored
[Release Tooling] Make 'zip-builder' compatible with Xcode 14 (#11522)
* Require Xcode 14.1 * [Release Tooling] Make 'zip-builder' compatible with Xcode 14 * Cleanup approach and restore disabled code * Remove unneeded comment and whitespace * Delete empty symbol link on all platforms * Fix build issue left over from previous commit * [skip ci] Remove irrelevant comment * [skip ci] Remove irrelevant newline --------- Co-authored-by: Paul Beusterien <[email protected]>
1 parent e97bc51 commit 9205183

File tree

3 files changed

+51
-41
lines changed

3 files changed

+51
-41
lines changed

.github/workflows/zip.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ jobs:
3434
- uses: mikehardy/buildcache-action@c87cea0ccd718971d6cc39e672c4f26815b6c126
3535
with:
3636
cache_key: ${{ matrix.os }}
37-
- name: Xcode 13.3.1
38-
run: sudo xcode-select -s /Applications/Xcode_13.3.1.app/Contents/Developer
37+
- name: Xcode 14.1
38+
run: sudo xcode-select -s /Applications/Xcode_14.1.app/Contents/Developer
3939
- uses: ruby/setup-ruby@v1
4040
- name: Setup Bundler
4141
run: ./scripts/setup_bundler.sh
@@ -57,8 +57,8 @@ jobs:
5757
runs-on: macos-12
5858
steps:
5959
- uses: actions/checkout@v3
60-
- name: Xcode 13.3.1
61-
run: sudo xcode-select -s /Applications/Xcode_13.3.1.app/Contents/Developer
60+
- name: Xcode 14.1
61+
run: sudo xcode-select -s /Applications/Xcode_14.1.app/Contents/Developer
6262
- name: Build
6363
run: |
6464
cd ReleaseTooling
@@ -74,8 +74,8 @@ jobs:
7474
- uses: mikehardy/buildcache-action@c87cea0ccd718971d6cc39e672c4f26815b6c126
7575
with:
7676
cache_key: ${{ matrix.os }}
77-
- name: Xcode 13.3.1
78-
run: sudo xcode-select -s /Applications/Xcode_13.3.1.app/Contents/Developer
77+
- name: Xcode 14.1
78+
run: sudo xcode-select -s /Applications/Xcode_14.1.app/Contents/Developer
7979
- uses: ruby/setup-ruby@v1
8080
- name: Setup Bundler
8181
run: ./scripts/setup_bundler.sh
@@ -444,8 +444,8 @@ jobs:
444444
FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT: 1
445445
runs-on: macos-12
446446
steps:
447-
- name: Xcode 13.3.1
448-
run: sudo xcode-select -s /Applications/Xcode_13.3.1.app/Contents/Developer
447+
- name: Xcode 14.1
448+
run: sudo xcode-select -s /Applications/Xcode_14.1.app/Contents/Developer
449449
- uses: actions/checkout@v3
450450
- name: Get framework dir
451451
uses: actions/download-artifact@v1

ReleaseTooling/Sources/ZipBuilder/CocoaPodUtils.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,9 @@ enum CocoaPodUtils {
136136
let result = Shell.executeCommandFromScript("pod cache clean --all", outputToConsole: false)
137137
switch result {
138138
case let .error(code, _):
139-
fatalError("Could not clean the pod cache, the command exited with \(code). Try running the" +
140-
"command in Terminal to see what's wrong.")
139+
fatalError("Could not clean the pod cache, the command exited with " +
140+
"\(code). Try running the command in Terminal to see " +
141+
"what's wrong.")
141142
case .success:
142143
// No need to do anything else, continue on.
143144
print("Successfully cleaned pod cache.")

ReleaseTooling/Sources/ZipBuilder/FrameworkBuilder.swift

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -346,34 +346,23 @@ struct FrameworkBuilder {
346346
"\(error)")
347347
}
348348

349-
// Find the location of the public headers, any platform will do.
350349
guard let anyPlatform = targetPlatforms.first,
351350
let archivePath = slicedFrameworks[anyPlatform] else {
352351
fatalError("Could not get a path to an archive to fetch headers in \(frameworkName).")
353352
}
354353

355-
// Get the framework Headers directory. On macOS, it's a symbolic link.
356-
let headersDir = archivePath.appendingPathComponent("Headers").resolvingSymlinksInPath()
357-
358-
// The macOS Headers directory can have a Headers file in it symbolically linked to nowhere.
359-
// Delete it here to avoid putting it in the zip or crashing the Carthage hash generation.
360-
// For example,in the 8.0.0 zip distribution see
361-
// Firebase/FirebaseAnalytics/PromisesObjC.xcframework/macos-arm64_x86_64/PromisesObjc
362-
// .framework/Headers/Headers
363-
do {
364-
try fileManager.removeItem(at: headersDir.appendingPathComponent("Headers"))
365-
} catch {
366-
// Ignore
367-
}
368-
369354
// Find CocoaPods generated umbrella header.
370355
var umbrellaHeader = ""
356+
// TODO(ncooke3): Evaluate if `TensorFlowLiteObjC` is needed?
371357
if framework == "gRPC-Core" || framework == "TensorFlowLiteObjC" {
372358
// TODO: Proper handling of podspec-specified module.modulemap files with customized umbrella
373359
// headers. This is good enough for Firebase since it doesn't need these modules.
360+
// TODO(ncooke3): Is this needed for gRPC-Core?
374361
umbrellaHeader = "\(framework)-umbrella.h"
375362
} else {
376363
var umbrellaHeaderURL: URL
364+
// Get the framework Headers directory. On macOS, it's a symbolic link.
365+
let headersDir = archivePath.appendingPathComponent("Headers").resolvingSymlinksInPath()
377366
do {
378367
let files = try fileManager.contentsOfDirectory(at: headersDir,
379368
includingPropertiesForKeys: nil)
@@ -391,14 +380,6 @@ struct FrameworkBuilder {
391380
}
392381
umbrellaHeader = umbrellaHeaderURL.lastPathComponent
393382
}
394-
// Copy the Headers over.
395-
let headersDestination = frameworkDir.appendingPathComponent("Headers")
396-
do {
397-
try fileManager.copyItem(at: headersDir, to: headersDestination)
398-
} catch {
399-
fatalError("Could not copy headers from \(headersDir) to Headers directory in " +
400-
"\(headersDestination): \(error)")
401-
}
402383
// Add an Info.plist. Required by Carthage and SPM binary xcframeworks.
403384
CarthageUtils.generatePlistContents(forName: frameworkName,
404385
withVersion: podInfo.version,
@@ -603,18 +584,46 @@ struct FrameworkBuilder {
603584
// `Both ios-arm64 and ios-armv7 represent two equivalent library definitions`
604585
var frameworksBuilt: [URL] = []
605586
for (platform, frameworkPath) in slicedFrameworks {
606-
let platformDir = platformFrameworksDir.appendingPathComponent(platform.buildName)
587+
// Create the following structure in the platform frameworks directory:
588+
// - platform_frameworks
589+
// └── $(PLATFORM)
590+
// └── $(FRAMEWORK).framework
591+
let platformFrameworkDir = platformFrameworksDir
592+
.appendingPathComponent(platform.buildName)
593+
.appendingPathComponent(fromFolder.lastPathComponent)
607594
do {
608-
try fileManager.createDirectory(at: platformDir, withIntermediateDirectories: true)
595+
try fileManager.createDirectory(at: platformFrameworkDir, withIntermediateDirectories: true)
609596
} catch {
610597
fatalError("Could not create directory for architecture slices on \(platform) for " +
611598
"\(framework): \(error)")
612599
}
613600

614-
// Package a normal .framework given the `fromFolder` and the binary from `slicedFrameworks`.
615-
let destination = platformDir.appendingPathComponent(fromFolder.lastPathComponent)
601+
// Headers from slice
602+
do {
603+
let headersSrc: URL = frameworkPath.appendingPathComponent("Headers")
604+
.resolvingSymlinksInPath()
605+
// The macOS slice's `Headers` directory may have a `Headers` file in
606+
// it that symbolically links to nowhere. For example, in the 8.0.0
607+
// zip distribution, see the `Headers` directory in the macOS slice
608+
// of the `PromisesObjC.xcframework`. Delete it here to avoid putting
609+
// it in the zip or crashing the Carthage hash generation. Because
610+
// this will throw an error for cases where the file does not exist,
611+
// the error is ignored.
612+
try? fileManager.removeItem(at: headersSrc.appendingPathComponent("Headers"))
613+
614+
try fileManager.copyItem(
615+
at: headersSrc,
616+
to: platformFrameworkDir.appendingPathComponent("Headers")
617+
)
618+
} catch {
619+
fatalError("Could not create framework directory needed to build \(framework): \(error)")
620+
}
621+
622+
// Info.plist from `fromFolder`
616623
do {
617-
try fileManager.copyItem(at: fromFolder, to: destination)
624+
let infoPlistSrc = fromFolder.appendingPathComponent("Info.plist").resolvingSymlinksInPath()
625+
let infoPlistDst = platformFrameworkDir.appendingPathComponent("Info.plist")
626+
try fileManager.copyItem(at: infoPlistSrc, to: infoPlistDst)
618627
} catch {
619628
fatalError("Could not create framework directory needed to build \(framework): \(error)")
620629
}
@@ -623,7 +632,7 @@ struct FrameworkBuilder {
623632
let binaryName = frameworkPath.lastPathComponent.replacingOccurrences(of: ".framework",
624633
with: "")
625634
let fatBinary = frameworkPath.appendingPathComponent(binaryName).resolvingSymlinksInPath()
626-
let fatBinaryDestination = destination.appendingPathComponent(framework)
635+
let fatBinaryDestination = platformFrameworkDir.appendingPathComponent(framework)
627636
do {
628637
try fileManager.copyItem(at: fatBinary, to: fatBinaryDestination)
629638
} catch {
@@ -633,9 +642,9 @@ struct FrameworkBuilder {
633642
// Use the appropriate moduleMaps
634643
packageModuleMaps(inFrameworks: [frameworkPath],
635644
moduleMapContents: moduleMapContents,
636-
destination: destination)
645+
destination: platformFrameworkDir)
637646

638-
frameworksBuilt.append(destination)
647+
frameworksBuilt.append(platformFrameworkDir)
639648
}
640649
return frameworksBuilt
641650
}

0 commit comments

Comments
 (0)