Support Static Frameworks for Carthage dependencies (#688)

This commit is contained in:
Kohki Miki 2019-11-08 02:03:26 +09:00 committed by Brentley Jones
parent 66333c6d79
commit 03076f40eb
11 changed files with 224 additions and 42 deletions

View File

@ -3,6 +3,7 @@
## Next Version
#### Added
- Add Carthage static framework dependencies support. [#688](https://github.com/yonaskolb/XcodeGen/pull/688) @giginet
- Added `--no-env` option to disable environment variables expansion [#704](https://github.com/yonaskolb/XcodeGen/pull/704) @rcari
#### Fixed

View File

@ -397,6 +397,9 @@ This only applies to `framework` dependencies. Implicit framework dependencies a
**Carthage Dependency**
- [ ] **findFrameworks**: **Bool** - Whether to find Carthage frameworks automatically. Defaults to `true` .
- [ ] **linkType**: **String** - Dependency link type. This value should be `dynamic` or `static`. Default value is `dynamic` .
Carthage frameworks are expected to be in `CARTHAGE_BUILD_PATH/PLATFORM/FRAMEWORK.framework` where:
- `CARTHAGE_BUILD_PATH` = `options.carthageBuildPath` or `Carthage/Build` by default
@ -408,6 +411,9 @@ Xcodegen uses `.version` files generated by Carthage in order for this framework
If any applications contain carthage dependencies within itself or any dependent targets, a carthage copy files script is automatically added to the application containing all the relevant frameworks. A `FRAMEWORK_SEARCH_PATHS` setting is also automatically added
Carthage officially supports static frameworks. In this case, frameworks are expected to be in `CARTHAGE_BUILD_PATH/PLATFORM/Static/FRAMEWORK.framework`.
You can specify `linkType` to `static` to integrate static ones.
```yaml
targets:
MyTarget:
@ -415,7 +421,8 @@ targets:
- target: MyFramework
- framework: path/to/framework.framework
- carthage: Result
findFrameworks: true
findFrameworks: false
linkType: static
- sdk: Contacts.framework
- sdk: libc++.tbd
- sdk: libz.dylib

View File

@ -32,11 +32,18 @@ public struct Dependency: Equatable {
self.implicit = implicit
self.weakLink = weakLink
}
public enum CarthageLinkType: String {
case dynamic
case `static`
public static let `default` = dynamic
}
public enum DependencyType: Equatable {
case target
case framework
case carthage(findFrameworks: Bool?)
case carthage(findFrameworks: Bool?, linkType: CarthageLinkType)
case sdk(root: String?)
case package(product: String?)
}
@ -59,7 +66,8 @@ extension Dependency: JSONObjectConvertible {
reference = framework
} else if let carthage: String = jsonDictionary.json(atKeyPath: "carthage") {
let findFrameworks: Bool? = jsonDictionary.json(atKeyPath: "findFrameworks")
type = .carthage(findFrameworks: findFrameworks)
let carthageLinkType: CarthageLinkType = (jsonDictionary.json(atKeyPath: "linkType") as String?).flatMap(CarthageLinkType.init(rawValue:)) ?? .default
type = .carthage(findFrameworks: findFrameworks, linkType: carthageLinkType)
reference = carthage
} else if let sdk: String = jsonDictionary.json(atKeyPath: "sdk") {
let sdkRoot: String? = jsonDictionary.json(atKeyPath: "root")
@ -112,11 +120,12 @@ extension Dependency: JSONEncodable {
dict["target"] = reference
case .framework:
dict["framework"] = reference
case .carthage(let findFrameworks):
case .carthage(let findFrameworks, let linkType):
dict["carthage"] = reference
if let findFrameworks = findFrameworks {
dict["findFrameworks"] = findFrameworks
}
dict["linkType"] = linkType.rawValue
case .sdk:
dict["sdk"] = reference
case .package:

View File

@ -31,8 +31,13 @@ public class CarthageDependencyResolver {
}
/// Carthage's build path for the given platform
func buildPath(for platform: Platform) -> String {
return "\(buildPath)/\(platform.carthageName)"
func buildPath(for platform: Platform, linkType: Dependency.CarthageLinkType) -> String {
switch linkType {
case .static:
return "\(buildPath)/\(platform.carthageName)/Static"
case .dynamic:
return "\(buildPath)/\(platform.carthageName)"
}
}
/// Fetches all carthage dependencies for a given target
@ -53,7 +58,7 @@ public class CarthageDependencyResolver {
let nonExistentDependencies = target.dependencies.filter { !frameworks.contains($0) }
for dependency in nonExistentDependencies {
switch dependency.type {
case .carthage(let findFrameworks):
case .carthage(let findFrameworks, _):
let findFrameworks = findFrameworks ?? project.options.findCarthageFrameworks
if findFrameworks {
relatedDependencies(for: dependency, in: target.platform)

View File

@ -601,13 +601,13 @@ public class PBXProjGenerator {
)
targetFrameworkBuildFiles.append(buildFile)
case .carthage(let findFrameworks):
case .carthage(let findFrameworks, let linkType):
let findFrameworks = findFrameworks ?? project.options.findCarthageFrameworks
let allDependencies = findFrameworks
? carthageResolver.relatedDependencies(for: dependency, in: target.platform) : [dependency]
allDependencies.forEach { dependency in
var platformPath = Path(carthageResolver.buildPath(for: target.platform))
var platformPath = Path(carthageResolver.buildPath(for: target.platform, linkType: linkType))
var frameworkPath = platformPath + dependency.reference
if frameworkPath.extension == nil {
frameworkPath = Path(frameworkPath.string + ".framework")
@ -615,7 +615,7 @@ public class PBXProjGenerator {
let fileReference = self.sourceGenerator.getFileReference(path: frameworkPath, inPath: platformPath)
self.carthageFrameworksByPlatform[target.platform.carthageName, default: []].insert(fileReference)
if dependency.link ?? (target.type != .staticLibrary) {
let buildFile = self.addObject(
PBXBuildFile(file: fileReference, settings: getDependencyFrameworkSettings(dependency: dependency))
@ -651,17 +651,22 @@ public class PBXProjGenerator {
}
for dependency in carthageDependencies {
let embed = dependency.embed ?? target.shouldEmbedCarthageDependencies
var platformPath = Path(carthageResolver.buildPath(for: target.platform))
var platformPath = Path(carthageResolver.buildPath(for: target.platform, linkType: dependency.carthageLinkType ?? .default))
var frameworkPath = platformPath + dependency.reference
if frameworkPath.extension == nil {
frameworkPath = Path(frameworkPath.string + ".framework")
}
let fileReference = sourceGenerator.getFileReference(path: frameworkPath, inPath: platformPath)
if embed {
if dependency.carthageLinkType == .static {
let embedFile = addObject(
PBXBuildFile(file: fileReference, settings: getDependencyFrameworkSettings(dependency: dependency))
)
targetFrameworkBuildFiles.append(embedFile)
} else if embed {
if directlyEmbedCarthage {
let embedFile = addObject(
PBXBuildFile(file: fileReference, settings: getEmbedSettings(dependency: dependency, codeSign: dependency.codeSign ?? true))
@ -762,7 +767,7 @@ public class PBXProjGenerator {
if !carthageFrameworksToEmbed.isEmpty {
let inputPaths = carthageFrameworksToEmbed
.map { "$(SRCROOT)/\(carthageResolver.buildPath(for: target.platform))/\($0)\($0.contains(".") ? "" : ".framework")" }
.map { "$(SRCROOT)/\(carthageResolver.buildPath(for: target.platform, linkType: .dynamic))/\($0)\($0.contains(".") ? "" : ".framework")" }
let outputPaths = carthageFrameworksToEmbed
.map { "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/\($0)\($0.contains(".") ? "" : ".framework")" }
let carthageExecutable = carthageResolver.executable
@ -925,8 +930,16 @@ public class PBXProjGenerator {
// set Carthage search paths
let configFrameworkBuildPaths: [String]
if !carthageDependencies.isEmpty {
let carthagePlatformBuildPath = "$(PROJECT_DIR)/" + carthageResolver.buildPath(for: target.platform)
configFrameworkBuildPaths = [carthagePlatformBuildPath] + frameworkBuildPaths.sorted()
var carthagePlatformBuildPaths: [String] = []
if carthageDependencies.contains(where: { $0.carthageLinkType == .static }) {
let carthagePlatformBuildPath = "$(PROJECT_DIR)/" + carthageResolver.buildPath(for: target.platform, linkType: .static)
carthagePlatformBuildPaths.append(carthagePlatformBuildPath)
}
if carthageDependencies.contains(where: { $0.carthageLinkType == .dynamic }) {
let carthagePlatformBuildPath = "$(PROJECT_DIR)/" + carthageResolver.buildPath(for: target.platform, linkType: .dynamic)
carthagePlatformBuildPaths.append(carthagePlatformBuildPath)
}
configFrameworkBuildPaths = carthagePlatformBuildPaths + frameworkBuildPaths.sorted()
} else {
configFrameworkBuildPaths = frameworkBuildPaths.sorted()
}
@ -1083,3 +1096,14 @@ extension PBXFileElement {
}
}
}
private extension Dependency {
var carthageLinkType: Dependency.CarthageLinkType? {
switch type {
case .carthage(_, let linkType):
return linkType
default:
return nil
}
}
}

View File

@ -39,8 +39,8 @@ extension Project {
dependencies: [
Dependency(type: .target, reference: "Framework_\(platform)"),
Dependency(type: .target, reference: "Framework2_\(platform)"),
Dependency(type: .carthage(findFrameworks: false), reference: "Alamofire"),
Dependency(type: .carthage(findFrameworks: false), reference: "BrightFutures"),
Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "Alamofire"),
Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "BrightFutures"),
],
scheme: scheme
)
@ -74,7 +74,7 @@ extension Project {
TargetSource(path: "Framework_\(platform)"),
],
dependencies: [
Dependency(type: .carthage(findFrameworks: false), reference: "Alamofire"),
Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "Alamofire"),
],
scheme: scheme
)
@ -90,8 +90,8 @@ extension Project {
sources: [TargetSource(path: "Framework2_\(platform)")],
dependencies: [
Dependency(type: .target, reference: "Framework_\(platform)"),
Dependency(type: .carthage(findFrameworks: false), reference: "Alamofire"),
Dependency(type: .carthage(findFrameworks: false), reference: "BrightFutures"),
Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "Alamofire"),
Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "BrightFutures"),
],
scheme: scheme
)

View File

@ -298,7 +298,7 @@ class ProjectSpecTests: XCTestCase {
buildPhase: .resources,
headerVisibility: .private,
createIntermediateGroups: true)],
dependencies: [Dependency(type: .carthage(findFrameworks: true),
dependencies: [Dependency(type: .carthage(findFrameworks: true, linkType: .dynamic),
reference: "reference",
embed: true,
codeSign: true,

View File

@ -371,6 +371,7 @@ class SpecLoadingTests: XCTestCase {
targetDictionary["dependencies"] = [
["target": "name", "embed": false],
["carthage": "name", "findFrameworks": true],
["carthage": "name", "findFrameworks": true, "linkType": "static"],
["framework": "path", "weak": true],
["sdk": "Contacts.framework"],
[
@ -379,12 +380,13 @@ class SpecLoadingTests: XCTestCase {
],
]
let target = try Target(name: "test", jsonDictionary: targetDictionary)
try expect(target.dependencies.count) == 5
try expect(target.dependencies.count) == 6
try expect(target.dependencies[0]) == Dependency(type: .target, reference: "name", embed: false)
try expect(target.dependencies[1]) == Dependency(type: .carthage(findFrameworks: true), reference: "name")
try expect(target.dependencies[2]) == Dependency(type: .framework, reference: "path", weakLink: true)
try expect(target.dependencies[3]) == Dependency(type: .sdk(root: nil), reference: "Contacts.framework")
try expect(target.dependencies[4]) == Dependency(type: .sdk(root: "DEVELOPER_DIR"), reference: "Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework")
try expect(target.dependencies[1]) == Dependency(type: .carthage(findFrameworks: true, linkType: .dynamic), reference: "name")
try expect(target.dependencies[2]) == Dependency(type: .carthage(findFrameworks: true, linkType: .static), reference: "name")
try expect(target.dependencies[3]) == Dependency(type: .framework, reference: "path", weakLink: true)
try expect(target.dependencies[4]) == Dependency(type: .sdk(root: nil), reference: "Contacts.framework")
try expect(target.dependencies[5]) == Dependency(type: .sdk(root: "DEVELOPER_DIR"), reference: "Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework")
}
$0.it("parses info plist") {

View File

@ -55,7 +55,7 @@ class CarthageDependencyResolverTests: XCTestCase {
}
try allPlatforms.forEach { platform in
try expect(expectedByPlatform[platform]) == resolver.buildPath(for: platform)
try expect(expectedByPlatform[platform]) == resolver.buildPath(for: platform, linkType: .dynamic)
}
}
}
@ -70,7 +70,7 @@ class CarthageDependencyResolverTests: XCTestCase {
let options = SpecOptions(carthageBuildPath: carthageBuildPath.string)
let resolver = CarthageDependencyResolver(project: makeTestProject(options: options))
let dependency = Dependency(type: .carthage(findFrameworks: true), reference: "CarthageTestFixture")
let dependency = Dependency(type: .carthage(findFrameworks: true, linkType: .dynamic), reference: "CarthageTestFixture")
let expectedDependencies: [Platform: [String]] = [
.macOS: ["DependencyFixtureB", "DependencyFixtureA", "CarthageTestFixture"],
.watchOS: ["DependencyFixtureA", "DependencyFixtureB", "CarthageTestFixture"],
@ -87,7 +87,7 @@ class CarthageDependencyResolverTests: XCTestCase {
$0.it("returns the main dependency when no related dependencies are found") {
let resolver = CarthageDependencyResolver(project: makeTestProject())
let dependency = Dependency(type: .carthage(findFrameworks: true), reference: "RandomDependency")
let dependency = Dependency(type: .carthage(findFrameworks: true, linkType: .dynamic), reference: "RandomDependency")
let related = resolver.relatedDependencies(for: dependency, in: .iOS)
@ -96,7 +96,7 @@ class CarthageDependencyResolverTests: XCTestCase {
$0.it("de-duplicates dependencies") {
let resolver = CarthageDependencyResolver(project: makeTestProject())
let dependency = Dependency(type: .carthage(findFrameworks: true), reference: "ReactiveSwift")
let dependency = Dependency(type: .carthage(findFrameworks: true, linkType: .dynamic), reference: "ReactiveSwift")
let related = resolver.relatedDependencies(for: dependency, in: .iOS)
@ -114,7 +114,7 @@ class CarthageDependencyResolverTests: XCTestCase {
$0.it("overrides the findFrameworks dependency global flag when specified") {
let options = SpecOptions(carthageBuildPath: carthageBuildPath.string, findCarthageFrameworks: true)
let dependency = Dependency(type: .carthage(findFrameworks: false), reference: dependencyFixtureName)
let dependency = Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: dependencyFixtureName)
let resolver = CarthageDependencyResolver(project: makeTestProject(options: options))
let target = Target(name: "1", type: .application, platform: .iOS, dependencies: [dependency])
@ -126,7 +126,7 @@ class CarthageDependencyResolverTests: XCTestCase {
$0.it("fetches all carthage dependencies for a given target, sorted alphabetically") {
let unsortedDependencyReferences = ["RxSwift", "RxCocoa", "RxBlocking", "RxTest", "RxAtomic"]
let dependencies = unsortedDependencyReferences.map {
Dependency(type: .carthage(findFrameworks: false), reference: $0)
Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: $0)
}
let nonCarthageDependencies = unsortedDependencyReferences.map { Dependency(type: .target, reference: $0) }
let target = Target(name: "1", type: .application, platform: .iOS, dependencies: dependencies + nonCarthageDependencies)

View File

@ -452,7 +452,7 @@ class ProjectGeneratorTests: XCTestCase {
Dependency(type: .framework, reference: "FrameworkZ.framework", link: true),
Dependency(type: .target, reference: iosFrameworkX.name /* , link: false */ ),
Dependency(type: .framework, reference: "FrameworkX.framework" /* , link: false */ ),
Dependency(type: .carthage(findFrameworks: false), reference: "CarthageZ"),
Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "CarthageZ"),
]
)
expectedResourceFiles[staticLibrary.name] = Set()
@ -479,10 +479,10 @@ class ProjectGeneratorTests: XCTestCase {
dependencies: [
Dependency(type: .target, reference: resourceBundle.name),
Dependency(type: .framework, reference: "FrameworkC.framework"),
Dependency(type: .carthage(findFrameworks: false), reference: "CarthageA"),
Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "CarthageA"),
// Statically linked, so don't embed into test
Dependency(type: .target, reference: staticLibrary.name),
Dependency(type: .carthage(findFrameworks: false), reference: "CarthageB", embed: false),
Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "CarthageB", embed: false),
]
)
expectedResourceFiles[iosFrameworkA.name] = Set()
@ -507,7 +507,7 @@ class ProjectGeneratorTests: XCTestCase {
Dependency(type: .framework, reference: "FrameworkD.framework"),
// Embedded into framework, so don't embed into test
Dependency(type: .framework, reference: "FrameworkE.framework", embed: true),
Dependency(type: .carthage(findFrameworks: false), reference: "CarthageC", embed: true),
Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "CarthageC", embed: true),
// Statically linked, so don't embed into test
Dependency(type: .framework, reference: "FrameworkF.framework", embed: false),
]
@ -539,7 +539,7 @@ class ProjectGeneratorTests: XCTestCase {
dependencies: [
Dependency(type: .target, reference: app.name),
Dependency(type: .target, reference: iosFrameworkB.name),
Dependency(type: .carthage(findFrameworks: false), reference: "CarthageD"),
Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "CarthageD"),
],
directlyEmbedCarthageDependencies: false
)
@ -1004,6 +1004,70 @@ class ProjectGeneratorTests: XCTestCase {
// generated plist should not be in buildsettings
try expect(targetConfig.buildSettings["INFOPLIST_FILE"] as? String) == predefinedPlistPath
}
describe("Carthage dependencies") {
$0.context("with static dependency") {
$0.it("should set dependencies") {
let app = Target(
name: "MyApp",
type: .application,
platform: .iOS,
dependencies: [
Dependency(type: .carthage(findFrameworks: true, linkType: .static), reference: "MyStaticFramework"),
]
)
let project = Project(name: "test", targets: [app])
let pbxProject = try project.generatePbxProj()
let target = pbxProject.nativeTargets.first!
let configuration = target.buildConfigurationList!.buildConfigurations.first!
try expect(configuration.buildSettings["FRAMEWORK_SEARCH_PATHS"] as? [String]) == ["$(inherited)", "$(PROJECT_DIR)/Carthage/Build/iOS/Static"]
let frameworkBuildPhase = try target.frameworksBuildPhase()
guard let files = frameworkBuildPhase?.files, let file = files.first else {
return XCTFail("frameworkBuildPhase should have files")
}
try expect(file.file?.nameOrPath) == "MyStaticFramework.framework"
try expect(target.carthageCopyFrameworkBuildPhase).beNil()
}
}
$0.context("with mixed dependencies") {
$0.it("should set dependencies") {
let app = Target(
name: "MyApp",
type: .application,
platform: .iOS,
dependencies: [
Dependency(type: .carthage(findFrameworks: true, linkType: .dynamic), reference: "MyDynamicFramework"),
Dependency(type: .carthage(findFrameworks: true, linkType: .static), reference: "MyStaticFramework"),
]
)
let project = Project(name: "test", targets: [app])
let pbxProject = try project.generatePbxProj()
let target = pbxProject.nativeTargets.first!
let configuration = target.buildConfigurationList!.buildConfigurations.first!
try expect(configuration.buildSettings["FRAMEWORK_SEARCH_PATHS"] as? [String]) == ["$(inherited)", "$(PROJECT_DIR)/Carthage/Build/iOS/Static", "$(PROJECT_DIR)/Carthage/Build/iOS"]
let frameworkBuildPhase = try target.frameworksBuildPhase()
guard let files = frameworkBuildPhase?.files else {
return XCTFail("frameworkBuildPhase should have files")
}
guard let dynamicFramework = files.first(where: { $0.file?.nameOrPath == "MyDynamicFramework.framework" }) else {
return XCTFail("Framework Build Phase should have Dynamic Framework")
}
guard let _ = files.first(where: { $0.file?.nameOrPath == "MyStaticFramework.framework" }) else {
return XCTFail("Framework Build Phase should have Static Framework")
}
guard let copyCarthagePhase = target.carthageCopyFrameworkBuildPhase else {
return XCTFail("Carthage Build Phase should be exist")
}
try expect(copyCarthagePhase.inputPaths) == [dynamicFramework.file?.fullPath(sourceRoot: Path("$(SRCROOT)"))?.string]
try expect(copyCarthagePhase.outputPaths) == ["$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/\(dynamicFramework.file!.path!)"]
}
}
}
$0.it("generate info.plist doesn't generate CFBundleExecutable for targets with type bundle") {
let plist = Plist(path: "Info.plist", attributes: [:])
@ -1080,6 +1144,76 @@ class ProjectGeneratorTests: XCTestCase {
}
}
}
describe("Carthage dependencies") {
$0.context("with static dependency") {
$0.it("should set dependencies") {
let app = Target(
name: "MyApp",
type: .application,
platform: .iOS,
dependencies: [
Dependency(type: .carthage(findFrameworks: true, linkType: .static), reference: "MyStaticFramework"),
]
)
let project = Project(name: "test", targets: [app])
let pbxProject = try project.generatePbxProj()
let target = pbxProject.nativeTargets.first!
let configuration = target.buildConfigurationList!.buildConfigurations.first!
try expect(configuration.buildSettings["FRAMEWORK_SEARCH_PATHS"] as? [String]) == ["$(inherited)", "$(PROJECT_DIR)/Carthage/Build/iOS/Static"]
let frameworkBuildPhase = try target.frameworksBuildPhase()
guard let files = frameworkBuildPhase?.files, let file = files.first else {
return XCTFail("frameworkBuildPhase should have files")
}
try expect(file.file?.nameOrPath) == "MyStaticFramework.framework"
try expect(target.carthageCopyFrameworkBuildPhase).beNil()
}
}
$0.context("with mixed dependencies") {
$0.it("should set dependencies") {
let app = Target(
name: "MyApp",
type: .application,
platform: .iOS,
dependencies: [
Dependency(type: .carthage(findFrameworks: true, linkType: .dynamic), reference: "MyDynamicFramework"),
Dependency(type: .carthage(findFrameworks: true, linkType: .static), reference: "MyStaticFramework"),
]
)
let project = Project(name: "test", targets: [app])
let pbxProject = try project.generatePbxProj()
let target = pbxProject.nativeTargets.first!
let configuration = target.buildConfigurationList!.buildConfigurations.first!
try expect(configuration.buildSettings["FRAMEWORK_SEARCH_PATHS"] as? [String]) == ["$(inherited)", "$(PROJECT_DIR)/Carthage/Build/iOS/Static", "$(PROJECT_DIR)/Carthage/Build/iOS"]
let frameworkBuildPhase = try target.frameworksBuildPhase()
guard let files = frameworkBuildPhase?.files else {
return XCTFail("frameworkBuildPhase should have files")
}
guard let dynamicFramework = files.first(where: { $0.file?.nameOrPath == "MyDynamicFramework.framework" }) else {
return XCTFail("Framework Build Phase should have Dynamic Framework")
}
guard let _ = files.first(where: { $0.file?.nameOrPath == "MyStaticFramework.framework" }) else {
return XCTFail("Framework Build Phase should have Static Framework")
}
guard let copyCarthagePhase = target.carthageCopyFrameworkBuildPhase else {
return XCTFail("Carthage Build Phase should be exist")
}
try expect(copyCarthagePhase.inputPaths) == [dynamicFramework.file?.fullPath(sourceRoot: Path("$(SRCROOT)"))?.string]
try expect(copyCarthagePhase.outputPaths) == ["$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/\(dynamicFramework.file!.path!)"]
}
}
}
}
}
}
private extension PBXTarget {
var carthageCopyFrameworkBuildPhase: PBXShellScriptBuildPhase? {
return buildPhases.first(where: { $0.name() == "Carthage" }) as? PBXShellScriptBuildPhase
}
}

View File

@ -612,9 +612,9 @@ class SourceGeneratorTests: XCTestCase {
"""
try createDirectories(directories)
let watchTarget = Target(name: "Watch", type: .watch2App, platform: .watchOS, sources: ["A"], dependencies: [Dependency(type: .carthage(findFrameworks: false), reference: "Alamofire_watch")])
let watchTarget = Target(name: "Watch", type: .watch2App, platform: .watchOS, sources: ["A"], dependencies: [Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "Alamofire_watch")])
let watchDependency = Dependency(type: .target, reference: "Watch")
let target = Target(name: "Test", type: .application, platform: .iOS, sources: ["A"], dependencies: [Dependency(type: .carthage(findFrameworks: false), reference: "Alamofire"), watchDependency])
let target = Target(name: "Test", type: .application, platform: .iOS, sources: ["A"], dependencies: [Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "Alamofire"), watchDependency])
let project = Project(basePath: directoryPath, name: "Test", targets: [target, watchTarget])
let pbxProj = try project.generatePbxProj()
@ -633,7 +633,7 @@ class SourceGeneratorTests: XCTestCase {
"""
try createDirectories(directories)
let target = Target(name: "Test", type: .application, platform: .iOS, sources: ["A", "P", "S"], dependencies: [Dependency(type: .carthage(findFrameworks: false), reference: "Alamofire")])
let target = Target(name: "Test", type: .application, platform: .iOS, sources: ["A", "P", "S"], dependencies: [Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "Alamofire")])
let project = Project(basePath: directoryPath, name: "Test", targets: [target])
let pbxProj = try project.generatePbxProj()
@ -656,7 +656,7 @@ class SourceGeneratorTests: XCTestCase {
"""
try createDirectories(directories)
let target = Target(name: "Test", type: .application, platform: .iOS, sources: ["Sources"], dependencies: [Dependency(type: .carthage(findFrameworks: false), reference: "Alamofire")])
let target = Target(name: "Test", type: .application, platform: .iOS, sources: ["Sources"], dependencies: [Dependency(type: .carthage(findFrameworks: false, linkType: .dynamic), reference: "Alamofire")])
let project = Project(basePath: directoryPath, name: "Test", targets: [target])
let pbxProj = try project.generatePbxProj()