mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2024-08-17 00:30:29 +03:00
Support Static Frameworks for Carthage dependencies (#688)
This commit is contained in:
parent
66333c6d79
commit
03076f40eb
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -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,
|
||||
|
@ -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") {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user