Skip to content

Commit

Permalink
[Release Tooling] Make 'zip-builder' compatible with Xcode 14 (#11522)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
ncooke3 and paulb777 authored Jul 13, 2023
1 parent e97bc51 commit 9205183
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 41 deletions.
16 changes: 8 additions & 8 deletions .github/workflows/zip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ jobs:
- uses: mikehardy/buildcache-action@c87cea0ccd718971d6cc39e672c4f26815b6c126
with:
cache_key: ${{ matrix.os }}
- name: Xcode 13.3.1
run: sudo xcode-select -s /Applications/Xcode_13.3.1.app/Contents/Developer
- name: Xcode 14.1
run: sudo xcode-select -s /Applications/Xcode_14.1.app/Contents/Developer
- uses: ruby/setup-ruby@v1
- name: Setup Bundler
run: ./scripts/setup_bundler.sh
Expand All @@ -57,8 +57,8 @@ jobs:
runs-on: macos-12
steps:
- uses: actions/checkout@v3
- name: Xcode 13.3.1
run: sudo xcode-select -s /Applications/Xcode_13.3.1.app/Contents/Developer
- name: Xcode 14.1
run: sudo xcode-select -s /Applications/Xcode_14.1.app/Contents/Developer
- name: Build
run: |
cd ReleaseTooling
Expand All @@ -74,8 +74,8 @@ jobs:
- uses: mikehardy/buildcache-action@c87cea0ccd718971d6cc39e672c4f26815b6c126
with:
cache_key: ${{ matrix.os }}
- name: Xcode 13.3.1
run: sudo xcode-select -s /Applications/Xcode_13.3.1.app/Contents/Developer
- name: Xcode 14.1
run: sudo xcode-select -s /Applications/Xcode_14.1.app/Contents/Developer
- uses: ruby/setup-ruby@v1
- name: Setup Bundler
run: ./scripts/setup_bundler.sh
Expand Down Expand Up @@ -444,8 +444,8 @@ jobs:
FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT: 1
runs-on: macos-12
steps:
- name: Xcode 13.3.1
run: sudo xcode-select -s /Applications/Xcode_13.3.1.app/Contents/Developer
- name: Xcode 14.1
run: sudo xcode-select -s /Applications/Xcode_14.1.app/Contents/Developer
- uses: actions/checkout@v3
- name: Get framework dir
uses: actions/download-artifact@v1
Expand Down
5 changes: 3 additions & 2 deletions ReleaseTooling/Sources/ZipBuilder/CocoaPodUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,9 @@ enum CocoaPodUtils {
let result = Shell.executeCommandFromScript("pod cache clean --all", outputToConsole: false)
switch result {
case let .error(code, _):
fatalError("Could not clean the pod cache, the command exited with \(code). Try running the" +
"command in Terminal to see what's wrong.")
fatalError("Could not clean the pod cache, the command exited with " +
"\(code). Try running the command in Terminal to see " +
"what's wrong.")
case .success:
// No need to do anything else, continue on.
print("Successfully cleaned pod cache.")
Expand Down
71 changes: 40 additions & 31 deletions ReleaseTooling/Sources/ZipBuilder/FrameworkBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -346,34 +346,23 @@ struct FrameworkBuilder {
"\(error)")
}

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

// Get the framework Headers directory. On macOS, it's a symbolic link.
let headersDir = archivePath.appendingPathComponent("Headers").resolvingSymlinksInPath()

// The macOS Headers directory can have a Headers file in it symbolically linked to nowhere.
// Delete it here to avoid putting it in the zip or crashing the Carthage hash generation.
// For example,in the 8.0.0 zip distribution see
// Firebase/FirebaseAnalytics/PromisesObjC.xcframework/macos-arm64_x86_64/PromisesObjc
// .framework/Headers/Headers
do {
try fileManager.removeItem(at: headersDir.appendingPathComponent("Headers"))
} catch {
// Ignore
}

// Find CocoaPods generated umbrella header.
var umbrellaHeader = ""
// TODO(ncooke3): Evaluate if `TensorFlowLiteObjC` is needed?
if framework == "gRPC-Core" || framework == "TensorFlowLiteObjC" {
// TODO: Proper handling of podspec-specified module.modulemap files with customized umbrella
// headers. This is good enough for Firebase since it doesn't need these modules.
// TODO(ncooke3): Is this needed for gRPC-Core?
umbrellaHeader = "\(framework)-umbrella.h"
} else {
var umbrellaHeaderURL: URL
// Get the framework Headers directory. On macOS, it's a symbolic link.
let headersDir = archivePath.appendingPathComponent("Headers").resolvingSymlinksInPath()
do {
let files = try fileManager.contentsOfDirectory(at: headersDir,
includingPropertiesForKeys: nil)
Expand All @@ -391,14 +380,6 @@ struct FrameworkBuilder {
}
umbrellaHeader = umbrellaHeaderURL.lastPathComponent
}
// Copy the Headers over.
let headersDestination = frameworkDir.appendingPathComponent("Headers")
do {
try fileManager.copyItem(at: headersDir, to: headersDestination)
} catch {
fatalError("Could not copy headers from \(headersDir) to Headers directory in " +
"\(headersDestination): \(error)")
}
// Add an Info.plist. Required by Carthage and SPM binary xcframeworks.
CarthageUtils.generatePlistContents(forName: frameworkName,
withVersion: podInfo.version,
Expand Down Expand Up @@ -603,18 +584,46 @@ struct FrameworkBuilder {
// `Both ios-arm64 and ios-armv7 represent two equivalent library definitions`
var frameworksBuilt: [URL] = []
for (platform, frameworkPath) in slicedFrameworks {
let platformDir = platformFrameworksDir.appendingPathComponent(platform.buildName)
// Create the following structure in the platform frameworks directory:
// - platform_frameworks
// └── $(PLATFORM)
// └── $(FRAMEWORK).framework
let platformFrameworkDir = platformFrameworksDir
.appendingPathComponent(platform.buildName)
.appendingPathComponent(fromFolder.lastPathComponent)
do {
try fileManager.createDirectory(at: platformDir, withIntermediateDirectories: true)
try fileManager.createDirectory(at: platformFrameworkDir, withIntermediateDirectories: true)
} catch {
fatalError("Could not create directory for architecture slices on \(platform) for " +
"\(framework): \(error)")
}

// Package a normal .framework given the `fromFolder` and the binary from `slicedFrameworks`.
let destination = platformDir.appendingPathComponent(fromFolder.lastPathComponent)
// Headers from slice
do {
let headersSrc: URL = frameworkPath.appendingPathComponent("Headers")
.resolvingSymlinksInPath()
// The macOS slice's `Headers` directory may have a `Headers` file in
// it that symbolically links to nowhere. For example, in the 8.0.0
// zip distribution, see the `Headers` directory in the macOS slice
// of the `PromisesObjC.xcframework`. Delete it here to avoid putting
// it in the zip or crashing the Carthage hash generation. Because
// this will throw an error for cases where the file does not exist,
// the error is ignored.
try? fileManager.removeItem(at: headersSrc.appendingPathComponent("Headers"))

try fileManager.copyItem(
at: headersSrc,
to: platformFrameworkDir.appendingPathComponent("Headers")
)
} catch {
fatalError("Could not create framework directory needed to build \(framework): \(error)")
}

// Info.plist from `fromFolder`
do {
try fileManager.copyItem(at: fromFolder, to: destination)
let infoPlistSrc = fromFolder.appendingPathComponent("Info.plist").resolvingSymlinksInPath()
let infoPlistDst = platformFrameworkDir.appendingPathComponent("Info.plist")
try fileManager.copyItem(at: infoPlistSrc, to: infoPlistDst)
} catch {
fatalError("Could not create framework directory needed to build \(framework): \(error)")
}
Expand All @@ -623,7 +632,7 @@ struct FrameworkBuilder {
let binaryName = frameworkPath.lastPathComponent.replacingOccurrences(of: ".framework",
with: "")
let fatBinary = frameworkPath.appendingPathComponent(binaryName).resolvingSymlinksInPath()
let fatBinaryDestination = destination.appendingPathComponent(framework)
let fatBinaryDestination = platformFrameworkDir.appendingPathComponent(framework)
do {
try fileManager.copyItem(at: fatBinary, to: fatBinaryDestination)
} catch {
Expand All @@ -633,9 +642,9 @@ struct FrameworkBuilder {
// Use the appropriate moduleMaps
packageModuleMaps(inFrameworks: [frameworkPath],
moduleMapContents: moduleMapContents,
destination: destination)
destination: platformFrameworkDir)

frameworksBuilt.append(destination)
frameworksBuilt.append(platformFrameworkDir)
}
return frameworksBuilt
}
Expand Down

0 comments on commit 9205183

Please sign in to comment.