mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2026-03-18 20:02:25 +00:00
Merge pull request #411 from alvarhansen/weak-link
Add framework weak linking setting
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
# Change Log
|
||||
|
||||
## Master
|
||||
|
||||
#### Added
|
||||
- Added `weak` Weak linking setting for dependencies [411](https://github.com/yonaskolb/XcodeGen/pull/411) @alvarhansen
|
||||
|
||||
|
||||
## 1.11.2
|
||||
|
||||
If XcodeGen is compiled with Swift 4.2, then UUID's in the generated project will not be deterministic. This will be fixed in an upcoming release with an update to xcodeproj 6.0
|
||||
|
||||
@@ -328,6 +328,7 @@ These only applied to `target` and `framework` dependencies.
|
||||
- [ ] **link**: **Bool** - Whether to link the dependency. Defaults to `true` depending on the type of the dependency and the type of the target (e.g. static libraries will only link to executables by default).
|
||||
- [ ] **codeSign**: **Bool** - Whether the `codeSignOnCopy` setting is applied when embedding framework. Defaults to true
|
||||
- [ ] **removeHeaders**: **Bool** - Whether the `removeHeadersOnCopy` setting is applied when embedding the framework. Defaults to true
|
||||
- [ ] **weak**: **Bool** - Whether the `Weak` setting is applied when linking the framework. Defaults to false
|
||||
|
||||
**Implicit Framework options**:
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ public struct Dependency: Equatable {
|
||||
public var removeHeaders: Bool = true
|
||||
public var link: Bool?
|
||||
public var implicit: Bool = false
|
||||
public var weakLink: Bool = false
|
||||
|
||||
public init(
|
||||
type: DependencyType,
|
||||
@@ -18,7 +19,8 @@ public struct Dependency: Equatable {
|
||||
embed: Bool? = nil,
|
||||
codeSign: Bool? = nil,
|
||||
link: Bool? = nil,
|
||||
implicit: Bool = false
|
||||
implicit: Bool = false,
|
||||
weakLink: Bool = false
|
||||
) {
|
||||
self.type = type
|
||||
self.reference = reference
|
||||
@@ -26,6 +28,7 @@ public struct Dependency: Equatable {
|
||||
self.codeSign = codeSign
|
||||
self.link = link
|
||||
self.implicit = implicit
|
||||
self.weakLink = weakLink
|
||||
}
|
||||
|
||||
public enum DependencyType {
|
||||
@@ -61,5 +64,8 @@ extension Dependency: JSONObjectConvertible {
|
||||
if let bool: Bool = jsonDictionary.json(atKeyPath: "implicit") {
|
||||
implicit = bool
|
||||
}
|
||||
if let bool: Bool = jsonDictionary.json(atKeyPath: "weak") {
|
||||
weakLink = bool
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,6 +459,14 @@ public class PBXProjGenerator {
|
||||
return ["ATTRIBUTES": embedAttributes]
|
||||
}
|
||||
|
||||
func getDependencyFrameworkSettings(dependency: Dependency) -> [String: Any]? {
|
||||
var linkingAttributes: [String] = []
|
||||
if dependency.weakLink {
|
||||
linkingAttributes.append("Weak")
|
||||
}
|
||||
return !linkingAttributes.isEmpty ? ["ATTRIBUTES": linkingAttributes] : nil
|
||||
}
|
||||
|
||||
for dependency in targetDependencies {
|
||||
|
||||
let embed = dependency.embed ?? target.shouldEmbedDependencies
|
||||
@@ -482,7 +490,10 @@ public class PBXProjGenerator {
|
||||
let dependencyBuildFile = targetBuildFiles[dependencyTargetName]!
|
||||
let buildFile = createObject(
|
||||
id: dependencyBuildFile.reference + target.name,
|
||||
PBXBuildFile(fileRef: dependencyBuildFile.object.fileRef!)
|
||||
PBXBuildFile(
|
||||
fileRef: dependencyBuildFile.object.fileRef!,
|
||||
settings: getDependencyFrameworkSettings(dependency: dependency)
|
||||
)
|
||||
)
|
||||
targetFrameworkBuildFiles.append(buildFile.reference)
|
||||
|
||||
@@ -538,7 +549,10 @@ public class PBXProjGenerator {
|
||||
|
||||
let buildFile = createObject(
|
||||
id: "framework" + fileReference + target.name,
|
||||
PBXBuildFile(fileRef: fileReference)
|
||||
PBXBuildFile(
|
||||
fileRef: fileReference,
|
||||
settings: getDependencyFrameworkSettings(dependency: dependency)
|
||||
)
|
||||
)
|
||||
|
||||
targetFrameworkBuildFiles.append(buildFile.reference)
|
||||
@@ -569,7 +583,10 @@ public class PBXProjGenerator {
|
||||
|
||||
let buildFile = createObject(
|
||||
id: "carthage" + fileReference + target.name,
|
||||
PBXBuildFile(fileRef: fileReference)
|
||||
PBXBuildFile(
|
||||
fileRef: fileReference,
|
||||
settings: getDependencyFrameworkSettings(dependency: dependency)
|
||||
)
|
||||
)
|
||||
|
||||
carthageFrameworksByPlatform[target.platform.carthageDirectoryName, default: []].insert(fileReference)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -73,6 +73,8 @@ targets:
|
||||
- target: Framework_iOS
|
||||
- target: StaticLibrary_ObjC_iOS
|
||||
- carthage: Result
|
||||
- target: Framework2_iOS
|
||||
weak: true
|
||||
- target: App_watchOS
|
||||
- target: iMessageApp
|
||||
- framework: Vendor/SomeFramework.framework
|
||||
@@ -160,6 +162,15 @@ targets:
|
||||
dependencies:
|
||||
- carthage: Result
|
||||
- target: StaticLibrary_ObjC_$platform
|
||||
|
||||
Framework2:
|
||||
type: framework
|
||||
platform: [iOS, tvOS, watchOS, macOS]
|
||||
sources:
|
||||
- path: Framework
|
||||
excludes:
|
||||
- "*.xcodeproj"
|
||||
|
||||
App_iOS_Tests:
|
||||
type: bundle.unit-test
|
||||
platform: iOS
|
||||
|
||||
@@ -21,6 +21,12 @@ fileprivate let framework = Target(
|
||||
settings: Settings(buildSettings: ["SETTING_2": "VALUE"])
|
||||
)
|
||||
|
||||
fileprivate let optionalFramework = Target(
|
||||
name: "MyOptionalFramework",
|
||||
type: .framework,
|
||||
platform: .iOS
|
||||
)
|
||||
|
||||
fileprivate let uiTest = Target(
|
||||
name: "MyAppUITests",
|
||||
type: .uiTestBundle,
|
||||
@@ -29,7 +35,7 @@ fileprivate let uiTest = Target(
|
||||
dependencies: [Dependency(type: .target, reference: "MyApp")]
|
||||
)
|
||||
|
||||
fileprivate let targets = [app, framework, uiTest]
|
||||
fileprivate let targets = [app, framework, optionalFramework, uiTest]
|
||||
|
||||
class ProjectGeneratorTests: XCTestCase {
|
||||
|
||||
@@ -230,10 +236,11 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
$0.it("generates targets") {
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
let nativeTargets = pbxProject.objects.nativeTargets.referenceValues
|
||||
try expect(nativeTargets.count) == 3
|
||||
try expect(nativeTargets.count) == 4
|
||||
try expect(nativeTargets.contains { $0.name == app.name }).beTrue()
|
||||
try expect(nativeTargets.contains { $0.name == framework.name }).beTrue()
|
||||
try expect(nativeTargets.contains { $0.name == uiTest.name }).beTrue()
|
||||
try expect(nativeTargets.contains { $0.name == optionalFramework.name }).beTrue()
|
||||
}
|
||||
|
||||
$0.it("generates target attributes") {
|
||||
@@ -243,7 +250,7 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
|
||||
var testTargetWithAttributes = uiTest
|
||||
testTargetWithAttributes.settings.buildSettings["CODE_SIGN_STYLE"] = "Manual"
|
||||
let project = Project(basePath: "", name: "test", targets: [appTargetWithAttributes, framework, testTargetWithAttributes])
|
||||
let project = Project(basePath: "", name: "test", targets: [appTargetWithAttributes, framework, optionalFramework, testTargetWithAttributes])
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
|
||||
guard let targetAttributes = pbxProject.objects.projects.referenceValues.first?.attributes["TargetAttributes"] as? [String: [String: Any]] else {
|
||||
@@ -804,6 +811,35 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
try expect(second.outputFiles) == []
|
||||
try expect(second.outputFilesCompilerFlags) == []
|
||||
}
|
||||
|
||||
$0.it("generates dependency build file settings") {
|
||||
let app = Target(
|
||||
name: "MyApp",
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
dependencies: [
|
||||
Dependency(type: .target, reference: "MyFramework"),
|
||||
Dependency(type: .target, reference: "MyOptionalFramework", weakLink: true)
|
||||
]
|
||||
)
|
||||
|
||||
let project = Project(basePath: "", name: "test", targets: [app, framework, optionalFramework, uiTest])
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
|
||||
guard let nativeTarget = pbxProject.objects.nativeTargets.referenceValues.first(where: { $0.name == app.name }) else {
|
||||
throw failure("PBXNativeTarget for \(app.name) not found")
|
||||
}
|
||||
let buildPhases = nativeTarget.buildPhases
|
||||
let frameworkPhases = pbxProject.objects.frameworksBuildPhases.objectReferences.filter { buildPhases.contains($0.reference) }
|
||||
|
||||
let frameworkBuildFiles = frameworkPhases[0].object.files.compactMap { pbxProject.objects.buildFiles[$0] }
|
||||
let buildFileSettings = frameworkBuildFiles.map { $0.settings }
|
||||
|
||||
try expect(frameworkBuildFiles.count) == 2
|
||||
try expect(buildFileSettings.compactMap({ $0 }).count) == 1
|
||||
try expect(buildFileSettings.compactMap({ $0?["ATTRIBUTES"] }).count) == 1
|
||||
try expect(buildFileSettings.compactMap({ $0?["ATTRIBUTES"] as? [String] }).first) == ["Weak"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -146,13 +146,13 @@ class SpecLoadingTests: XCTestCase {
|
||||
targetDictionary["dependencies"] = [
|
||||
["target": "name", "embed": false],
|
||||
["carthage": "name"],
|
||||
["framework": "path"],
|
||||
["framework": "path", "weak": true],
|
||||
]
|
||||
let target = try Target(name: "test", jsonDictionary: targetDictionary)
|
||||
try expect(target.dependencies.count) == 3
|
||||
try expect(target.dependencies[0]) == Dependency(type: .target, reference: "name", embed: false)
|
||||
try expect(target.dependencies[1]) == Dependency(type: .carthage, reference: "name")
|
||||
try expect(target.dependencies[2]) == Dependency(type: .framework, reference: "path")
|
||||
try expect(target.dependencies[2]) == Dependency(type: .framework, reference: "path", weakLink: true)
|
||||
}
|
||||
|
||||
$0.it("parses cross platform targets") {
|
||||
|
||||
Reference in New Issue
Block a user