Skip to content

Commit

Permalink
Merge pull request #14 from sergeykhliustin/vendored_libraries
Browse files Browse the repository at this point in the history
Better vendored static libraries handing
  • Loading branch information
sergeykhliustin authored Dec 28, 2022
2 parents 84ed221 + 2660c57 commit de6dc77
Show file tree
Hide file tree
Showing 9 changed files with 301 additions and 77 deletions.
22 changes: 15 additions & 7 deletions Sources/PodToBUILD/BuildFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,20 @@ public struct PodBuildFile: StarlarkConvertible {

let extraDeps: [BazelTarget] = makeResourceBundles(spec: podSpec, subspecs: subspecs, options: buildOptions)
let frameworks = AppleFrameworkImport.vendoredFrameworks(withPodspec: podSpec, subspecs: subspecs, options: buildOptions)
.sorted(by: { $0.name < $1.name })
let conditionalDeps = frameworks.reduce([String: [Arch]]()) { partialResult, target in
guard let target = target as? AppleFrameworkImport else { return partialResult }
var result = partialResult
result[target.name] = Arch.archs(for: target.frameworkImport, options: buildOptions)
return result
let libraries = ObjcImport.vendoredLibraries(withPodspec: podSpec, subspecs: subspecs, options: buildOptions)
let conditionalDeps = (frameworks + libraries).reduce([String: [Arch]]()) { partialResult, target in
if let target = target as? AppleFrameworkImport {
var result = partialResult
let path = frameworkExecutablePath(target.frameworkImport, options: buildOptions)
result[target.name] = Arch.archs(forExecutable: path, options: buildOptions)
return result
} else if let target = target as? ObjcImport {
var result = partialResult
let path = URL(fileURLWithPath: target.library, relativeTo: URL(fileURLWithPath: buildOptions.podTargetAbsoluteRoot)).path
result[target.name] = Arch.archs(forExecutable: path, options: buildOptions)
return result
}
return partialResult
}

let sourceLibs = makeSourceLibs(spec: podSpec,
Expand All @@ -104,7 +112,7 @@ public struct PodBuildFile: StarlarkConvertible {
conditionalDeps: conditionalDeps,
options: buildOptions)

var output: [BazelTarget] = sourceLibs + extraDeps + frameworks
var output: [BazelTarget] = sourceLibs + extraDeps + frameworks + libraries

output = UserConfigurableTransform.transform(convertibles: output,
options: buildOptions,
Expand Down
68 changes: 34 additions & 34 deletions Sources/PodToBUILD/Convertible/XCFramework.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,40 +55,40 @@ struct XCFramework: StarlarkConvertible {
return nil
}
}
/// Wrap dynamic framework into xcframework.
/// Assume that framework can be either device + simulator (x86_64 + arm*) or only for device (arm*).
init?(framework: String, options: BuildOptions) {
guard framework.hasSuffix(".framework") else { return nil }
let isDynamic = isDynamicFramework(framework, options: options)
let archs = frameworkArchs(framework, options: options)
guard !archs.isEmpty else { return nil }

let frameworkURL = URL(fileURLWithPath: framework,
relativeTo: URL(fileURLWithPath: options.podTargetAbsoluteRoot))
name = frameworkURL.deletingPathExtension().lastPathComponent
var libraries: [InputData.Library] = []
let deviceArchs = archs.filter({ $0 != "x86_64" }).sorted()
libraries.append(InputData.Library(LibraryIdentifier: "ios-\(deviceArchs.joined(separator: "_"))",
LibraryPath: framework,
SupportedArchitectures: deviceArchs,
SupportedPlatform: "ios",
SupportedPlatformVariant: nil,
path: framework,
linkage: isDynamic ? .dynamic : .static))
// TODO: Fix this
if archs.contains("x86_64") {
libraries.append(InputData.Library(LibraryIdentifier: "ios-x86_64-simulator",
LibraryPath: framework,
SupportedArchitectures: ["x86_64"],
SupportedPlatform: "ios",
SupportedPlatformVariant: "simulator",
path: framework,
linkage: isDynamic ? .dynamic : .static))

}

input = InputData(AvailableLibraries: libraries)
}
// /// Wrap dynamic framework into xcframework.
// /// Assume that framework can be either device + simulator (x86_64 + arm*) or only for device (arm*).
// init?(framework: String, options: BuildOptions) {
// guard framework.hasSuffix(".framework") else { return nil }
// let isDynamic = isDynamicFramework(framework, options: options)
// let archs = frameworkArchs(framework, options: options)
// guard !archs.isEmpty else { return nil }
//
// let frameworkURL = URL(fileURLWithPath: framework,
// relativeTo: URL(fileURLWithPath: options.podTargetAbsoluteRoot))
// name = frameworkURL.deletingPathExtension().lastPathComponent
// var libraries: [InputData.Library] = []
// let deviceArchs = archs.filter({ $0 != "x86_64" }).sorted()
// libraries.append(InputData.Library(LibraryIdentifier: "ios-\(deviceArchs.joined(separator: "_"))",
// LibraryPath: framework,
// SupportedArchitectures: deviceArchs,
// SupportedPlatform: "ios",
// SupportedPlatformVariant: nil,
// path: framework,
// linkage: isDynamic ? .dynamic : .static))
// // TODO: Fix this
// if archs.contains("x86_64") {
// libraries.append(InputData.Library(LibraryIdentifier: "ios-x86_64-simulator",
// LibraryPath: framework,
// SupportedArchitectures: ["x86_64"],
// SupportedPlatform: "ios",
// SupportedPlatformVariant: "simulator",
// path: framework,
// linkage: isDynamic ? .dynamic : .static))
//
// }
//
// input = InputData(AvailableLibraries: libraries)
// }

func toStarlark() -> StarlarkNode {
let slices = input.AvailableLibraries.map({
Expand Down
11 changes: 1 addition & 10 deletions Sources/PodToBUILD/RuleUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ public func xcconfigSettingToList(_ value: String) -> [String] {
.components(separatedBy: .whitespaces)
.map { $0.removingPercentEncoding ?? "" }
.map { $0.replacingOccurrences(of: "\"", with: "") }
.map { $0.replacingOccurrences(of: "\\", with: "") }
.filter({ $0 != "$(inherited)"})
.filter({ !$0.isEmpty })
}
Expand All @@ -150,13 +151,3 @@ public func isDynamicFramework(_ framework: String, options: BuildOptions) -> Bo
let output = SystemShellContext().command("/usr/bin/file", arguments: [path]).standardOutputAsString
return output.contains("dynamically")
}

public func frameworkArchs(_ framework: String, options: BuildOptions) -> [String] {
let path = frameworkExecutablePath(framework, options: options)
let archs = SystemShellContext().command("/usr/bin/lipo",
arguments: ["-archs", path])
.standardOutputAsString
.trimmingCharacters(in: .whitespacesAndNewlines)
.components(separatedBy: " ")
return archs.filter({ !$0.isEmpty })
}
5 changes: 0 additions & 5 deletions Sources/PodToBUILD/Targets/AppleFramework.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ struct AppleFramework: BazelTarget, UserConfigurable {
let vendoredXCFrameworks: AttrSet<[XCFramework]>
let vendoredStaticFrameworks: AttrSet<Set<String>>
let vendoredDynamicFrameworks: AttrSet<Set<String>>
let vendoredStaticLibraries: AttrSet<[String]>

let objcDefines: AttrSet<[String]>
let swiftDefines: AttrSet<[String]>
Expand Down Expand Up @@ -119,8 +118,6 @@ struct AppleFramework: BazelTarget, UserConfigurable {
self.vendoredDynamicFrameworks = .empty
self.vendoredStaticFrameworks = .empty

self.vendoredStaticLibraries = spec.collectAttribute(with: subspecs, keyPath: \.vendoredLibraries)

self.swiftDefines = AttrSet(basic: ["COCOAPODS"])
self.objcDefines = AttrSet(basic: ["COCOAPODS=1"])

Expand Down Expand Up @@ -246,7 +243,6 @@ struct AppleFramework: BazelTarget, UserConfigurable {
let vendoredXCFrameworks = vendoredXCFrameworks.multi.ios ?? []
let vendoredStaticFrameworks = vendoredStaticFrameworks.multi.ios ?? []
let vendoredDynamicFrameworks = vendoredDynamicFrameworks.multi.ios ?? []
let vendoredStaticLibraries = vendoredStaticLibraries.multi.ios ?? []

let lines: [StarlarkFunctionArgument] = [
.named(name: "name", value: name.toStarlark()),
Expand All @@ -265,7 +261,6 @@ struct AppleFramework: BazelTarget, UserConfigurable {
.named(name: "vendored_xcframeworks", value: vendoredXCFrameworks.toStarlark()),
.named(name: "vendored_static_frameworks", value: vendoredStaticFrameworks.toStarlark()),
.named(name: "vendored_dynamic_frameworks", value: vendoredDynamicFrameworks.toStarlark()),
.named(name: "vendored_static_libraries", value: vendoredStaticLibraries.toStarlark()),
.named(name: "objc_defines", value: objcDefines),
.named(name: "swift_defines", value: swiftDefines),
.named(name: "sdk_dylibs", value: sdkDylibs.toStarlark()),
Expand Down
2 changes: 1 addition & 1 deletion Sources/PodToBUILD/Targets/AppleFrameworkImport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,6 @@ struct AppleFrameworkImport: BazelTarget {
frameworkImport: $0)
} as [AppleFrameworkImport]
}
return (frameworks.basic ?? []) + (frameworks.multi.ios ?? [])
return (frameworks.basic ?? []) + (frameworks.multi.ios ?? []).sorted(by: { $0.name < $1.name })
}
}
34 changes: 19 additions & 15 deletions Sources/PodToBUILD/Targets/Base/Arch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,26 @@ enum Arch: String, CaseIterable {
case ios_i386
case ios_x86_64

static func archs(for framework: String, options: BuildOptions) -> [Arch] {
let path = frameworkExecutablePath(framework, options: options)
let archs = frameworkArchs(framework, options: options).map({
// TODO: Implement resolver
if $0 == "arm64" {
let output = SystemShellContext()
.shellOut("otool -l -arch arm64 \(path) | grep -m 1 'LC_VERSION_MIN_'")
.standardOutputAsString
if !output.contains("IPHONEOS") {
return "sim_arm64"
} else {
return $0
static func archs(forExecutable path: String, options: BuildOptions) -> [Arch] {
let archs = SystemShellContext().command("/usr/bin/lipo",
arguments: ["-archs", path])
.standardOutputAsString
.trimmingCharacters(in: .whitespacesAndNewlines)
.components(separatedBy: " ")
.filter({ !$0.isEmpty })
.map({
if $0 == "arm64" {
let output = SystemShellContext()
.shellOut("otool -l -arch arm64 \(path) | grep -m 1 'LC_VERSION_MIN_'")
.standardOutputAsString
if !output.contains("IPHONEOS") {
return "sim_arm64"
} else {
return $0
}
}
}
return $0
} as (String) -> String)
return $0
})

return archs.compactMap({ Self.init(rawValue: "ios_" + $0) })
}
Expand Down
17 changes: 12 additions & 5 deletions Sources/PodToBUILD/Targets/ObjcImport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,27 @@ import Foundation
struct ObjcImport: BazelTarget {
let loadNode = ""
let name: String // A unique name for this rule.
let archives: AttrSet<[String]> // The list of .a files provided to Objective-C targets that depend on this target.
let library: String // The list of .a files provided to Objective-C targets that depend on this target.

func toStarlark() -> StarlarkNode {
return StarlarkNode.functionCall(
name: "objc_import",
arguments: [
.named(name: "name", value: name.toStarlark()),
.named(name: "archives", value: archives.toStarlark())
.named(name: "archives", value: [library].toStarlark())
]
)
}

static func vendoredLibraries(withPodspec spec: PodSpec, subspecs: [PodSpec]) -> [BazelTarget] {
let libraries = spec.collectAttribute(with: subspecs, keyPath: \.vendoredLibraries)
return libraries.isEmpty ? [] : [ObjcImport(name: "\(spec.moduleName ?? spec.name)_VendoredLibraries", archives: libraries)]
static func vendoredLibraries(withPodspec spec: PodSpec, subspecs: [PodSpec], options: BuildOptions) -> [BazelTarget] {
let vendoredLibraries = spec.collectAttribute(with: subspecs, keyPath: \.vendoredLibraries)
let libraries = vendoredLibraries.map {
$0.compactMap {
let libraryName = URL(fileURLWithPath: $0).deletingPathExtension().lastPathComponent
return ObjcImport(name: "\(spec.moduleName ?? spec.name)_\(libraryName)_VendoredLibraries",
library: $0)
} as [ObjcImport]
}
return (libraries.basic ?? []) + (libraries.multi.ios ?? []).sorted(by: { $0.name < $1.name })
}
}
1 change: 1 addition & 0 deletions TestTools/TopPods.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"FDFullscreenPopGesture" : "",
"Firebase" : "",
"FirebaseAnalytics" : "9.5.0",
"FirebaseCrashlytics": "",
"fishhook" : "",
"FLAnimatedImage" : "",
"FLEX" : "",
Expand Down
Loading

0 comments on commit de6dc77

Please sign in to comment.