mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2024-10-26 22:11:25 +03:00
Fix issue where frameworks with MACH_O_TYPE:staticlib were being embedded (#1003)
This commit is contained in:
parent
0eeb6369ec
commit
6b7ab91440
@ -17,6 +17,7 @@
|
||||
- Fixed error message output for `minimumXcodeGenVersion`. [#967](https://github.com/yonaskolb/XcodeGen/pull/967) @joshwalker
|
||||
- Remove force-unwrapping causing crash for `LegacyTarget`s [#982](https://github.com/yonaskolb/XcodeGen/pull/982) @jcolicchio
|
||||
- Fixed a race condition in an internal JSON decoder, which would occasionally fail with an error like `Parsing project spec failed: Error Domain=Unspecified error Code=0`. [#995](https://github.com/yonaskolb/XcodeGen/pull/995) @elliottwilliams
|
||||
- Fixed issue where frameworks with `MACH_O_TYPE: staticlib` were being incorrectly embedded. [#1003](https://github.com/yonaskolb/XcodeGen/pull/1003) @mrabiciu
|
||||
|
||||
#### Internal
|
||||
- Updated to Yams 4.0.0 [#984](https://github.com/yonaskolb/XcodeGen/pull/984) @swiftty
|
||||
|
@ -7,10 +7,10 @@ public enum Linkage {
|
||||
case none
|
||||
}
|
||||
|
||||
extension PBXProductType {
|
||||
extension Target {
|
||||
|
||||
public var defaultLinkage: Linkage {
|
||||
switch self {
|
||||
switch type {
|
||||
case .none,
|
||||
.appExtension,
|
||||
.application,
|
||||
@ -36,8 +36,12 @@ extension PBXProductType {
|
||||
.xpcService:
|
||||
return .none
|
||||
case .framework, .xcFramework:
|
||||
// TODO: This should check `MACH_O_TYPE` in case this is a "Static Framework"
|
||||
return .dynamic
|
||||
// Check the MACH_O_TYPE for "Static Framework"
|
||||
if settings.buildSettings.machOType == "staticlib" {
|
||||
return .static
|
||||
} else {
|
||||
return .dynamic
|
||||
}
|
||||
case .dynamicLibrary:
|
||||
return .dynamic
|
||||
case .staticLibrary, .staticFramework:
|
||||
@ -45,3 +49,10 @@ extension PBXProductType {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension BuildSettings {
|
||||
|
||||
var machOType: String? {
|
||||
self["MACH_O_TYPE"] as? String
|
||||
}
|
||||
}
|
||||
|
@ -54,17 +54,16 @@ extension PBXProductType {
|
||||
}
|
||||
|
||||
/// Function to determine when a dependendency should be embedded into the target
|
||||
public func shouldEmbed(_ dependencyType: PBXProductType) -> Bool {
|
||||
switch dependencyType {
|
||||
case .staticLibrary, .staticFramework:
|
||||
// Some dependendencies should not be embed, independently of the target type
|
||||
public func shouldEmbed(_ dependencyTarget: Target) -> Bool {
|
||||
switch dependencyTarget.defaultLinkage {
|
||||
case .static:
|
||||
// Static dependencies should never embed
|
||||
return false
|
||||
|
||||
default:
|
||||
case .dynamic, .none:
|
||||
if isApp {
|
||||
// If target is an app, all dependencies should be embed (except for the ones mentioned above)
|
||||
// If target is an app, all dependencies should be embed (unless they're static)
|
||||
return true
|
||||
} else if isTest, [.framework, .bundle].contains(dependencyType) {
|
||||
} else if isTest, [.framework, .bundle].contains(dependencyTarget.type) {
|
||||
// If target is test, some dependencies should be embed (depending on their type)
|
||||
return true
|
||||
} else {
|
||||
|
@ -690,7 +690,7 @@ public class PBXProjGenerator {
|
||||
}
|
||||
|
||||
func processTargetDependency(_ dependency: Dependency, dependencyTarget: Target, embedFileReference: PBXFileElement?) {
|
||||
let dependencyLinkage = dependencyTarget.type.defaultLinkage
|
||||
let dependencyLinkage = dependencyTarget.defaultLinkage
|
||||
let link = dependency.link ??
|
||||
((dependencyLinkage == .dynamic && target.type != .staticLibrary) ||
|
||||
(dependencyLinkage == .static && target.type.isExecutable))
|
||||
@ -707,7 +707,7 @@ public class PBXProjGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
let embed = dependency.embed ?? target.type.shouldEmbed(dependencyTarget.type)
|
||||
let embed = dependency.embed ?? target.type.shouldEmbed(dependencyTarget)
|
||||
if embed {
|
||||
let embedFile = addObject(
|
||||
PBXBuildFile(
|
||||
|
@ -786,6 +786,102 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
try expect(copyFilesPhases.count) == expectedCopyFilesPhasesCount
|
||||
}
|
||||
}
|
||||
|
||||
$0.it("ensures static frameworks are not embedded by default") {
|
||||
|
||||
let app = Target(
|
||||
name: "App",
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
dependencies: [
|
||||
Dependency(type: .target, reference: "DynamicFramework"),
|
||||
Dependency(type: .target, reference: "DynamicFrameworkNotEmbedded", embed: false),
|
||||
Dependency(type: .target, reference: "StaticFramework"),
|
||||
Dependency(type: .target, reference: "StaticFrameworkExplicitlyEmbedded", embed: true),
|
||||
Dependency(type: .target, reference: "StaticFramework2"),
|
||||
Dependency(type: .target, reference: "StaticFramework2ExplicitlyEmbedded", embed: true),
|
||||
Dependency(type: .target, reference: "StaticLibrary"),
|
||||
]
|
||||
)
|
||||
|
||||
let targets = [
|
||||
app,
|
||||
Target(
|
||||
name: "DynamicFramework",
|
||||
type: .framework,
|
||||
platform: .iOS
|
||||
),
|
||||
Target(
|
||||
name: "DynamicFrameworkNotEmbedded",
|
||||
type: .framework,
|
||||
platform: .iOS
|
||||
),
|
||||
Target(
|
||||
name: "StaticFramework",
|
||||
type: .framework,
|
||||
platform: .iOS,
|
||||
settings: Settings(buildSettings: ["MACH_O_TYPE": "staticlib"])
|
||||
),
|
||||
Target(
|
||||
name: "StaticFrameworkExplicitlyEmbedded",
|
||||
type: .framework,
|
||||
platform: .iOS,
|
||||
settings: Settings(buildSettings: ["MACH_O_TYPE": "staticlib"])
|
||||
),
|
||||
Target(
|
||||
name: "StaticFramework2",
|
||||
type: .staticFramework,
|
||||
platform: .iOS
|
||||
),
|
||||
Target(
|
||||
name: "StaticFramework2ExplicitlyEmbedded",
|
||||
type: .staticFramework,
|
||||
platform: .iOS
|
||||
),
|
||||
Target(
|
||||
name: "StaticLibrary",
|
||||
type: .staticLibrary,
|
||||
platform: .iOS
|
||||
),
|
||||
]
|
||||
|
||||
let expectedLinkedFiles = Set([
|
||||
"DynamicFramework.framework",
|
||||
"DynamicFrameworkNotEmbedded.framework",
|
||||
"StaticFramework.framework",
|
||||
"StaticFrameworkExplicitlyEmbedded.framework",
|
||||
"StaticFramework2.framework",
|
||||
"StaticFramework2ExplicitlyEmbedded.framework",
|
||||
"libStaticLibrary.a",
|
||||
])
|
||||
|
||||
let expectedEmbeddedFrameworks = Set([
|
||||
"DynamicFramework.framework",
|
||||
"StaticFrameworkExplicitlyEmbedded.framework",
|
||||
"StaticFramework2ExplicitlyEmbedded.framework"
|
||||
])
|
||||
|
||||
let project = Project(
|
||||
name: "test",
|
||||
targets: targets
|
||||
)
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
|
||||
let appTarget = try unwrap(pbxProject.nativeTargets.first(where: { $0.name == app.name }))
|
||||
let buildPhases = appTarget.buildPhases
|
||||
let frameworkPhases = pbxProject.frameworksBuildPhases.filter { buildPhases.contains($0) }
|
||||
let copyFilesPhases = pbxProject.copyFilesBuildPhases.filter { buildPhases.contains($0) }
|
||||
let embedFrameworkPhase = copyFilesPhases.first { $0.dstSubfolderSpec == .frameworks }
|
||||
|
||||
// Ensure all targets are linked
|
||||
let linkFrameworks = (frameworkPhases[0].files ?? []).compactMap { $0.file?.nameOrPath }
|
||||
let linkPackages = (frameworkPhases[0].files ?? []).compactMap { $0.product?.productName }
|
||||
try expect(Set(linkFrameworks + linkPackages)) == expectedLinkedFiles
|
||||
|
||||
// Ensure only dynamic frameworks are embedded (unless there's an explicit override)
|
||||
let embeddedFrameworks = Set((embedFrameworkPhase?.files ?? []).compactMap { $0.file?.nameOrPath })
|
||||
try expect(embeddedFrameworks) == expectedEmbeddedFrameworks
|
||||
}
|
||||
|
||||
$0.it("copies files only on install in the Embed Frameworks step") {
|
||||
let app = Target(
|
||||
|
Loading…
Reference in New Issue
Block a user