Skip to content

Commit 606085b

Browse files
committed
fix: support Xcode 26
1 parent f9e15f7 commit 606085b

File tree

2 files changed

+90
-28
lines changed

2 files changed

+90
-28
lines changed

Sources/BuildScripts/XCFrameworkBuild/base.swift

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ class BaseBuild {
229229
"-DCMAKE_SYSTEM_PROCESSOR=\(arch.rawValue)",
230230
"-DCMAKE_INSTALL_PREFIX=\(thinDirPath)",
231231
"-DBUILD_SHARED_LIBS=0",
232+
"-DCMAKE_POLICY_VERSION_MINIMUM=3.5",
232233
]
233234
arguments.append(contentsOf: self.arguments(platform: platform, arch: arch))
234235
try Utility.launch(path: cmake, arguments: arguments, currentDirectoryURL: buildURL, environment: environ)
@@ -425,9 +426,65 @@ class BaseBuild {
425426
"""
426427
FileManager.default.createFile(atPath: frameworkDir.path + "/Modules/module.modulemap", contents: modulemap.data(using: .utf8), attributes: nil)
427428
createPlist(path: frameworkDir.path + "/Info.plist", name: framework, minVersion: platform.minVersion, platform: platform.sdk)
429+
try fixShallowBundles(framework: framework, platform: platform, frameworkDir: frameworkDir)
428430
return frameworkDir.path
429431
}
430432

433+
// Fix shallow bundles for Xcode 26, only for macOS frameworks
434+
func fixShallowBundles(framework: String, platform: PlatformType, frameworkDir: URL) throws {
435+
guard platform == .macos else { return }
436+
437+
let infoPlistPath = frameworkDir + "Info.plist"
438+
let versionsPath = frameworkDir + "Versions"
439+
440+
// Check if this is a shallow bundle that needs fixing
441+
var isDirectory: ObjCBool = false
442+
let frameworkExists = FileManager.default.fileExists(atPath: frameworkDir.path, isDirectory: &isDirectory)
443+
let hasInfoPlist = FileManager.default.fileExists(atPath: infoPlistPath.path)
444+
let hasVersions = FileManager.default.fileExists(atPath: versionsPath.path, isDirectory: &isDirectory) && isDirectory.boolValue
445+
446+
if frameworkExists && hasInfoPlist && !hasVersions {
447+
print("Fixing \(framework).framework bundle structure...")
448+
449+
// Create proper bundle structure
450+
let versionAResourcesPath = frameworkDir + ["Versions", "A", "Resources"]
451+
try FileManager.default.createDirectory(at: versionAResourcesPath, withIntermediateDirectories: true, attributes: nil)
452+
453+
// Move Info.plist to proper location
454+
let newInfoPlistPath = versionAResourcesPath + "Info.plist"
455+
try FileManager.default.moveItem(at: infoPlistPath, to: newInfoPlistPath)
456+
457+
// Move framework binary to proper location
458+
let binaryPath = frameworkDir + framework
459+
let newBinaryPath = frameworkDir + ["Versions", "A", framework]
460+
if FileManager.default.fileExists(atPath: binaryPath.path) {
461+
try FileManager.default.moveItem(at: binaryPath, to: newBinaryPath)
462+
}
463+
464+
// Move LICENSE if exists
465+
let licensePath = frameworkDir + "LICENSE"
466+
if FileManager.default.fileExists(atPath: licensePath.path) {
467+
let newLicensePath = frameworkDir + ["Versions", "A", "LICENSE"]
468+
try FileManager.default.moveItem(at: licensePath, to: newLicensePath)
469+
}
470+
471+
// Create symbolic links
472+
let currentLinkPath = frameworkDir + ["Versions", "Current"]
473+
try? FileManager.default.removeItem(at: currentLinkPath)
474+
try FileManager.default.createSymbolicLink(atPath: currentLinkPath.path, withDestinationPath: "A")
475+
476+
let binaryLinkPath = frameworkDir + framework
477+
try? FileManager.default.removeItem(at: binaryLinkPath)
478+
try FileManager.default.createSymbolicLink(atPath: binaryLinkPath.path, withDestinationPath: "Versions/Current/\(framework)")
479+
480+
let resourcesLinkPath = frameworkDir + "Resources"
481+
try? FileManager.default.removeItem(at: resourcesLinkPath)
482+
try FileManager.default.createSymbolicLink(atPath: resourcesLinkPath.path, withDestinationPath: "Versions/Current/Resources")
483+
484+
print("\(framework).framework structure fixed")
485+
}
486+
}
487+
431488
func thinDir(library: Library, platform: PlatformType, arch: ArchType) -> URL {
432489
URL.currentDirectory + [library.rawValue, platform.rawValue, "thin", arch.rawValue]
433490
}
@@ -595,14 +652,19 @@ class BaseBuild {
595652
}
596653
}
597654
for framework in frameworks {
598-
// clean old files
599-
try Utility.launch(path: "/bin/rm", arguments: ["-rf", "\(framework)*.xcframework.zip"], currentDirectoryURL: releaseDirPath)
600-
try Utility.launch(path: "/bin/rm", arguments: ["-rf", "\(framework)*.checksum.txt"], currentDirectoryURL: releaseDirPath)
655+
// clean old zip files
656+
let directoryContents = try FileManager.default.contentsOfDirectory(atPath: releaseDirPath.path)
657+
for item in directoryContents {
658+
if item.hasPrefix(framework) && (item.hasSuffix(".xcframework.zip") || item.hasSuffix(".checksum.txt")) {
659+
let itemPath = releaseDirPath.appendingPathComponent(item)
660+
try? FileManager.default.removeItem(at: itemPath)
661+
}
662+
}
601663

602664
let XCFrameworkFile = framework + ".xcframework"
603665
let zipFile = releaseDirPath + [framework + ".xcframework.zip"]
604666
let checksumFile = releaseDirPath + [framework + ".xcframework.checksum.txt"]
605-
try Utility.launch(path: "/usr/bin/zip", arguments: ["-qr", zipFile.path, XCFrameworkFile], currentDirectoryURL: self.xcframeworkDirectoryURL)
667+
try Utility.launch(path: "/usr/bin/zip", arguments: ["-qry", zipFile.path, XCFrameworkFile], currentDirectoryURL: self.xcframeworkDirectoryURL)
606668
Utility.shell("swift package compute-checksum \(zipFile.path) > \(checksumFile.path)")
607669

608670
if BaseBuild.options.enableSplitPlatform {
@@ -613,7 +675,7 @@ class BaseBuild {
613675
if FileManager.default.fileExists(atPath: XCFrameworkPath.path) {
614676
let zipFile = releaseDirPath + [XCFrameworkName + ".xcframework.zip"]
615677
let checksumFile = releaseDirPath + [XCFrameworkName + ".xcframework.checksum.txt"]
616-
try Utility.launch(path: "/usr/bin/zip", arguments: ["-qr", zipFile.path, XCFrameworkFile], currentDirectoryURL: self.xcframeworkDirectoryURL)
678+
try Utility.launch(path: "/usr/bin/zip", arguments: ["-qry", zipFile.path, XCFrameworkFile], currentDirectoryURL: self.xcframeworkDirectoryURL)
617679
Utility.shell("swift package compute-checksum \(zipFile.path) > \(checksumFile.path)")
618680
}
619681
}

Sources/BuildScripts/XCFrameworkBuild/main.swift

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -52,45 +52,45 @@ enum Library: String, CaseIterable {
5252
case .FFmpeg:
5353
return "n8.0"
5454
case .openssl:
55-
return "3.2.0"
55+
return "3.3.2-xcode26"
5656
case .gnutls:
57-
return "3.8.3"
57+
return "3.8.8-xcode26"
5858
case .nettle:
59-
return "3.8.3"
59+
return "3.8.8-xcode26"
6060
case .gmp:
61-
return "3.8.3"
61+
return "3.8.8-xcode26"
6262
case .libass:
63-
return "0.17.3"
63+
return "0.17.3-xcode26"
6464
case .libunibreak:
65-
return "0.17.3"
65+
return "0.17.3-xcode26"
6666
case .libfreetype:
67-
return "0.17.3"
67+
return "0.17.3-xcode26"
6868
case .libfribidi:
69-
return "0.17.3"
69+
return "0.17.3-xcode26"
7070
case .libharfbuzz:
71-
return "0.17.3"
71+
return "0.17.3-xcode26"
7272
case .libsmbclient:
73-
return "4.15.13"
73+
return "4.15.13-xcode26"
7474
case .libdav1d: // AV1 decoding
75-
return "1.4.3"
75+
return "1.5.2-xcode26"
7676
case .lcms2:
77-
return "7.349.0"
77+
return "2.16.0-xcode26"
7878
case .libplacebo:
79-
return "7.351.0-fix"
79+
return "7.351.0-xcode26"
8080
case .libdovi:
81-
return "3.3.0"
81+
return "3.3.1-xcode26"
8282
case .vulkan:
83-
return "1.4.0-fix"
83+
return "1.4.0-xcode26"
8484
case .libshaderc: // compiling GLSL (OpenGL Shading Language) shaders into SPIR-V (Standard Portable Intermediate Representation - Vulkan) code
85-
return "2025.4.0"
85+
return "2025.4.0-xcode26"
8686
case .libuchardet:
87-
return "0.0.8"
87+
return "0.0.8-xcode26"
8888
case .libbluray:
89-
return "1.3.4"
89+
return "1.3.4-xcode26"
9090
case .libluajit:
91-
return "2.1.0"
91+
return "2.1.0-xcode26"
9292
case .libuavs3d:
93-
return "1.2.1"
93+
return "1.2.1-xcode26"
9494
}
9595
}
9696

@@ -121,7 +121,7 @@ enum Library: String, CaseIterable {
121121
case .libsmbclient:
122122
return "https://github.com/mpvkit/libsmbclient-build/releases/download/\(self.version)/libsmbclient-all.zip"
123123
case .lcms2:
124-
return "https://github.com/mpvkit/libplacebo-build/releases/download/\(self.version)/lcms2-all.zip"
124+
return "https://github.com/mpvkit/lcms2-build/releases/download/\(self.version)/lcms2-all.zip"
125125
case .libplacebo:
126126
return "https://github.com/mpvkit/libplacebo-build/releases/download/\(self.version)/libplacebo-all.zip"
127127
case .libdav1d:
@@ -286,8 +286,8 @@ enum Library: String, CaseIterable {
286286
return [
287287
.target(
288288
name: "lcms2",
289-
url: "https://github.com/mpvkit/libplacebo-build/releases/download/\(self.version)/lcms2.xcframework.zip",
290-
checksum: "https://github.com/mpvkit/libplacebo-build/releases/download/\(self.version)/lcms2.xcframework.checksum.txt"
289+
url: "https://github.com/mpvkit/lcms2-build/releases/download/\(self.version)/lcms2.xcframework.zip",
290+
checksum: "https://github.com/mpvkit/lcms2-build/releases/download/\(self.version)/lcms2.xcframework.checksum.txt"
291291
),
292292
]
293293
case .libplacebo:

0 commit comments

Comments
 (0)