mirror of
https://github.com/yonaskolb/XcodeGen.git
synced 2024-12-11 07:16:40 +03:00
Support external target dependencies via subprojects (#701)
* Allow external target dependencies via subprojects * Update CHANGELOG * Update ProjectSpec * Fix test * Use existing fixture for test * Sort subprojects by name * Throw subproject generation error instead of crashing * Cleanup target dependency generation * Update test fixture project * Combine extentions in Linkage * Update XcodeProj to 7.7.0 * Update CHANGELOG.md * Update ProjectSpec.md Co-authored-by: Yonas Kolb <yonaskolb@users.noreply.github.com>
This commit is contained in:
parent
6b7b7e6134
commit
6bfd620549
@ -2,6 +2,9 @@
|
||||
|
||||
## Next Version
|
||||
|
||||
#### Added
|
||||
- Support External Target References via subprojects. [#701](https://github.com/yonaskolb/XcodeGen/pull/701) @evandcoleman
|
||||
|
||||
#### Fixed
|
||||
- Fixed compilation as library by locking down XcodeProj version [#767](https://github.com/yonaskolb/XcodeGen/pull/767) @yonaskolb
|
||||
|
||||
|
@ -382,7 +382,7 @@ targets:
|
||||
|
||||
A dependency can be one of a 6 types:
|
||||
|
||||
- `target: name` - links to another target
|
||||
- `target: name` - links to another target. If you are using project references you can specify a target within another project by using `ProjectName/TargetName` for the name
|
||||
- `framework: path` - links to a framework
|
||||
- `carthage: name` - helper for linking to a Carthage framework
|
||||
- `sdk: name` - links to a dependency with the SDK. This can either be a relative path within the sdk root or a single filename that references a framework (.framework) or lib (.tbd)
|
||||
@ -423,10 +423,14 @@ Carthage officially supports static frameworks. In this case, frameworks are exp
|
||||
You can specify `linkType` to `static` to integrate static ones.
|
||||
|
||||
```yaml
|
||||
projectReferences:
|
||||
FooLib:
|
||||
path: path/to/FooLib.xcodeproj
|
||||
targets:
|
||||
MyTarget:
|
||||
dependencies:
|
||||
- target: MyFramework
|
||||
- target: FooLib/FooTarget
|
||||
- framework: path/to/framework.framework
|
||||
- carthage: Result
|
||||
findFrameworks: false
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Foundation
|
||||
import XcodeProj
|
||||
|
||||
public enum Linkage {
|
||||
case dynamic
|
||||
@ -6,10 +7,10 @@ public enum Linkage {
|
||||
case none
|
||||
}
|
||||
|
||||
extension Target {
|
||||
extension PBXProductType {
|
||||
|
||||
public var defaultLinkage: Linkage {
|
||||
switch type {
|
||||
switch self {
|
||||
case .none,
|
||||
.appExtension,
|
||||
.application,
|
||||
|
@ -147,8 +147,17 @@ extension Project {
|
||||
for dependency in target.dependencies {
|
||||
switch dependency.type {
|
||||
case .target:
|
||||
if getProjectTarget(dependency.reference) == nil {
|
||||
errors.append(.invalidTargetDependency(target: target.name, dependency: dependency.reference))
|
||||
let dependencyTargetReference = try TargetReference(dependency.reference)
|
||||
|
||||
switch dependencyTargetReference.location {
|
||||
case .local:
|
||||
if getProjectTarget(dependency.reference) == nil {
|
||||
errors.append(.invalidTargetDependency(target: target.name, dependency: dependency.reference))
|
||||
}
|
||||
case .project(let dependencyProjectName):
|
||||
if getProjectReference(dependencyProjectName) == nil {
|
||||
errors.append(.invalidTargetDependency(target: target.name, dependency: dependency.reference))
|
||||
}
|
||||
}
|
||||
case .sdk:
|
||||
let path = Path(dependency.reference)
|
||||
|
@ -26,6 +26,8 @@ public class PBXProjGenerator {
|
||||
|
||||
var generated = false
|
||||
|
||||
private var projects: [ProjectReference: PBXProj] = [:]
|
||||
|
||||
public init(project: Project, projectDirectory: Path? = nil) {
|
||||
self.project = project
|
||||
carthageResolver = CarthageDependencyResolver(project: project)
|
||||
@ -168,9 +170,6 @@ public class PBXProjGenerator {
|
||||
addObject(packageReference)
|
||||
}
|
||||
|
||||
try project.targets.forEach(generateTarget)
|
||||
try project.aggregateTargets.forEach(generateAggregateTarget)
|
||||
|
||||
let productGroup = addObject(
|
||||
PBXGroup(
|
||||
children: targetFileReferences.valueArray,
|
||||
@ -180,6 +179,49 @@ public class PBXProjGenerator {
|
||||
)
|
||||
derivedGroups.append(productGroup)
|
||||
|
||||
let sortedProjectReferences = project.projectReferences.sorted { $0.name < $1.name }
|
||||
let subprojectFileReferences: [PBXFileReference] = sortedProjectReferences.map { projectReference in
|
||||
let projectPath = Path(projectReference.path)
|
||||
|
||||
return addObject(
|
||||
PBXFileReference(
|
||||
sourceTree: .group,
|
||||
name: projectReference.name,
|
||||
lastKnownFileType: Xcode.fileType(path: projectPath),
|
||||
path: projectPath.normalize().string
|
||||
)
|
||||
)
|
||||
}
|
||||
if subprojectFileReferences.count > 0 {
|
||||
let subprojectsGroups = addObject(
|
||||
PBXGroup(
|
||||
children: subprojectFileReferences,
|
||||
sourceTree: .group,
|
||||
name: "Projects"
|
||||
)
|
||||
)
|
||||
derivedGroups.append(subprojectsGroups)
|
||||
|
||||
let subprojects: [[String: PBXFileElement]] = subprojectFileReferences.map { projectReference in
|
||||
let group = addObject(
|
||||
PBXGroup(
|
||||
children: [],
|
||||
sourceTree: .group,
|
||||
name: "Products"
|
||||
)
|
||||
)
|
||||
return [
|
||||
"ProductGroup": group,
|
||||
"ProjectRef": projectReference
|
||||
]
|
||||
}
|
||||
|
||||
pbxProject.projects = subprojects
|
||||
}
|
||||
|
||||
try project.targets.forEach(generateTarget)
|
||||
try project.aggregateTargets.forEach(generateAggregateTarget)
|
||||
|
||||
if !carthageFrameworksByPlatform.isEmpty {
|
||||
var platforms: [PBXGroup] = []
|
||||
for (platform, files) in carthageFrameworksByPlatform {
|
||||
@ -316,6 +358,90 @@ public class PBXProjGenerator {
|
||||
return targetDependency
|
||||
}
|
||||
|
||||
func generateExternalTargetDependency(from: String, to target: String, in project: String, platform: Platform) throws -> (PBXTargetDependency, Target, PBXReferenceProxy) {
|
||||
guard let projectReference = self.project.getProjectReference(project) else {
|
||||
fatalError("project not found")
|
||||
}
|
||||
|
||||
let pbxProj = try getPBXProj(from: projectReference)
|
||||
|
||||
guard let targetObject = pbxProj.targets(named: target).first else {
|
||||
fatalError("target not found")
|
||||
}
|
||||
|
||||
let projectFileReferenceIndex = self.pbxProj.rootObject!
|
||||
.projects
|
||||
.map { $0["ProjectRef"] as? PBXFileReference }
|
||||
.firstIndex { $0?.path == Path(projectReference.path).normalize().string }
|
||||
|
||||
guard let index = projectFileReferenceIndex,
|
||||
let projectFileReference = self.pbxProj.rootObject?.projects[index]["ProjectRef"] as? PBXFileReference,
|
||||
let productsGroup = self.pbxProj.rootObject?.projects[index]["ProductGroup"] as? PBXGroup else {
|
||||
fatalError("Missing subproject file reference")
|
||||
}
|
||||
|
||||
let targetProxy = addObject(
|
||||
PBXContainerItemProxy(
|
||||
containerPortal: .fileReference(projectFileReference),
|
||||
remoteGlobalID: .object(targetObject),
|
||||
proxyType: .nativeTarget,
|
||||
remoteInfo: target
|
||||
)
|
||||
)
|
||||
|
||||
let productProxy = addObject(
|
||||
PBXContainerItemProxy(
|
||||
containerPortal: .fileReference(projectFileReference),
|
||||
remoteGlobalID: .object(targetObject.product!),
|
||||
proxyType: .reference,
|
||||
remoteInfo: target
|
||||
)
|
||||
)
|
||||
|
||||
let productReferenceProxy = addObject(
|
||||
PBXReferenceProxy(
|
||||
fileType: Xcode.fileType(path: Path(targetObject.productNameWithExtension()!)),
|
||||
path: targetObject.productNameWithExtension(),
|
||||
remote: productProxy,
|
||||
sourceTree: .buildProductsDir
|
||||
)
|
||||
)
|
||||
|
||||
productsGroup.children.append(productReferenceProxy)
|
||||
|
||||
let targetDependency = addObject(
|
||||
PBXTargetDependency(
|
||||
target: targetObject,
|
||||
targetProxy: targetProxy
|
||||
)
|
||||
)
|
||||
|
||||
guard let productType = targetObject.productType,
|
||||
let buildConfigurations = targetObject.buildConfigurationList?.buildConfigurations,
|
||||
let defaultConfigurationName = targetObject.buildConfigurationList?.defaultConfigurationName,
|
||||
let defaultConfiguration = buildConfigurations.first(where: { $0.name == defaultConfigurationName }) ?? buildConfigurations.first else {
|
||||
|
||||
fatalError("Missing target info")
|
||||
}
|
||||
|
||||
let buildSettings = defaultConfiguration.buildSettings
|
||||
let settings = Settings(buildSettings: buildSettings, configSettings: [:], groups: [])
|
||||
let deploymentTargetString = buildSettings[platform.deploymentTargetSetting] as? String
|
||||
let deploymentTarget = deploymentTargetString == nil ? nil : try Version(deploymentTargetString!)
|
||||
let requiresObjCLinking = (buildSettings["OTHER_LDFLAGS"] as? String)?.contains("-ObjC") ?? (productType == .staticLibrary)
|
||||
let dependencyTarget = Target(
|
||||
name: targetObject.name,
|
||||
type: productType,
|
||||
platform: platform,
|
||||
productName: targetObject.productName,
|
||||
deploymentTarget: deploymentTarget,
|
||||
settings: settings,
|
||||
requiresObjCLinking: requiresObjCLinking
|
||||
)
|
||||
|
||||
return (targetDependency, dependencyTarget, productReferenceProxy)
|
||||
}
|
||||
|
||||
func generateBuildScript(targetName: String, buildScript: BuildScript) throws -> PBXShellScriptBuildPhase {
|
||||
|
||||
let shellScript: String
|
||||
@ -439,6 +565,15 @@ public class PBXProjGenerator {
|
||||
childGroups.forEach(sortGroups)
|
||||
}
|
||||
|
||||
func getPBXProj(from reference: ProjectReference) throws -> PBXProj {
|
||||
if let cachedProject = projects[reference] {
|
||||
return cachedProject
|
||||
}
|
||||
let pbxproj = try XcodeProj(pathString: (project.basePath + Path(reference.path).normalize()).string).pbxproj
|
||||
projects[reference] = pbxproj
|
||||
return pbxproj
|
||||
}
|
||||
|
||||
func generateTarget(_ target: Target) throws {
|
||||
let carthageDependencies = carthageResolver.dependencies(for: target)
|
||||
|
||||
@ -487,60 +622,72 @@ public class PBXProjGenerator {
|
||||
return !linkingAttributes.isEmpty ? ["ATTRIBUTES": linkingAttributes] : nil
|
||||
}
|
||||
|
||||
func processTargetDependency(_ dependency: Dependency, dependencyTarget: Target, embedFileReference: PBXFileElement) {
|
||||
let dependencyLinkage = dependencyTarget.type.defaultLinkage
|
||||
let link = dependency.link ??
|
||||
((dependencyLinkage == .dynamic && target.type != .staticLibrary) ||
|
||||
(dependencyLinkage == .static && target.type.isExecutable))
|
||||
|
||||
if link {
|
||||
let dependencyFile = embedFileReference
|
||||
let buildFile = addObject(
|
||||
PBXBuildFile(file: dependencyFile, settings: getDependencyFrameworkSettings(dependency: dependency))
|
||||
)
|
||||
targetFrameworkBuildFiles.append(buildFile)
|
||||
|
||||
if !anyDependencyRequiresObjCLinking
|
||||
&& dependencyTarget.requiresObjCLinking ?? (dependencyTarget.type == .staticLibrary) {
|
||||
anyDependencyRequiresObjCLinking = true
|
||||
}
|
||||
}
|
||||
|
||||
let embed = dependency.embed ?? (!dependencyTarget.type.isLibrary && (
|
||||
target.type.isApp
|
||||
|| (target.type.isTest && (dependencyTarget.type.isFramework || dependencyTarget.type == .bundle))
|
||||
))
|
||||
if embed {
|
||||
let embedFile = addObject(
|
||||
PBXBuildFile(
|
||||
file: embedFileReference,
|
||||
settings: getEmbedSettings(dependency: dependency, codeSign: dependency.codeSign ?? !dependencyTarget.type.isExecutable)
|
||||
)
|
||||
)
|
||||
|
||||
if dependencyTarget.type.isExtension {
|
||||
// embed app extension
|
||||
extensions.append(embedFile)
|
||||
} else if dependencyTarget.type.isFramework {
|
||||
copyFrameworksReferences.append(embedFile)
|
||||
} else if dependencyTarget.type.isApp && dependencyTarget.platform == .watchOS {
|
||||
copyWatchReferences.append(embedFile)
|
||||
} else if dependencyTarget.type == .xpcService {
|
||||
copyFilesBuildPhasesFiles[.xpcServices, default: []].append(embedFile)
|
||||
} else {
|
||||
copyResourcesReferences.append(embedFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for dependency in targetDependencies {
|
||||
|
||||
let embed = dependency.embed ?? target.shouldEmbedDependencies
|
||||
|
||||
switch dependency.type {
|
||||
case .target:
|
||||
let dependencyTargetName = dependency.reference
|
||||
let targetDependency = generateTargetDependency(from: target.name, to: dependencyTargetName)
|
||||
dependencies.append(targetDependency)
|
||||
let dependencyTargetReference = try TargetReference(dependency.reference)
|
||||
|
||||
guard let dependencyTarget = project.getTarget(dependencyTargetName) else { continue }
|
||||
|
||||
let dependecyLinkage = dependencyTarget.defaultLinkage
|
||||
let link = dependency.link ??
|
||||
((dependecyLinkage == .dynamic && target.type != .staticLibrary) ||
|
||||
(dependecyLinkage == .static && target.type.isExecutable))
|
||||
|
||||
if link {
|
||||
let dependencyFile = targetFileReferences[dependencyTarget.name]!
|
||||
let buildFile = addObject(
|
||||
PBXBuildFile(file: dependencyFile, settings: getDependencyFrameworkSettings(dependency: dependency))
|
||||
)
|
||||
targetFrameworkBuildFiles.append(buildFile)
|
||||
|
||||
if !anyDependencyRequiresObjCLinking
|
||||
&& dependencyTarget.requiresObjCLinking ?? (dependencyTarget.type == .staticLibrary) {
|
||||
anyDependencyRequiresObjCLinking = true
|
||||
}
|
||||
}
|
||||
|
||||
let embed = dependency.embed ?? (!dependencyTarget.type.isLibrary && (
|
||||
target.type.isApp
|
||||
|| (target.type.isTest && (dependencyTarget.type.isFramework || dependencyTarget.type == .bundle))
|
||||
))
|
||||
if embed {
|
||||
let embedFile = addObject(
|
||||
PBXBuildFile(
|
||||
file: targetFileReferences[dependencyTarget.name]!,
|
||||
settings: getEmbedSettings(dependency: dependency, codeSign: dependency.codeSign ?? !dependencyTarget.type.isExecutable)
|
||||
)
|
||||
)
|
||||
|
||||
if dependencyTarget.type.isExtension {
|
||||
// embed app extension
|
||||
extensions.append(embedFile)
|
||||
} else if dependencyTarget.type.isFramework {
|
||||
copyFrameworksReferences.append(embedFile)
|
||||
} else if dependencyTarget.type.isApp && dependencyTarget.platform == .watchOS {
|
||||
copyWatchReferences.append(embedFile)
|
||||
} else if dependencyTarget.type == .xpcService {
|
||||
copyFilesBuildPhasesFiles[.xpcServices, default: []].append(embedFile)
|
||||
} else {
|
||||
copyResourcesReferences.append(embedFile)
|
||||
}
|
||||
switch dependencyTargetReference.location {
|
||||
case .local:
|
||||
let dependencyTargetName = dependency.reference
|
||||
let targetDependency = generateTargetDependency(from: target.name, to: dependencyTargetName)
|
||||
dependencies.append(targetDependency)
|
||||
guard let dependencyTarget = project.getTarget(dependencyTargetName) else { continue }
|
||||
processTargetDependency(dependency, dependencyTarget: dependencyTarget, embedFileReference: targetFileReferences[dependencyTarget.name]!)
|
||||
case .project(let dependencyProjectName):
|
||||
let dependencyTargetName = dependencyTargetReference.name
|
||||
let (targetDependency, dependencyTarget, dependencyProductProxy) = try generateExternalTargetDependency(from: target.name, to: dependencyTargetName, in: dependencyProjectName, platform: target.platform)
|
||||
dependencies.append(targetDependency)
|
||||
processTargetDependency(dependency, dependencyTarget: dependencyTarget, embedFileReference: dependencyProductProxy)
|
||||
}
|
||||
|
||||
case .framework:
|
||||
@ -1086,15 +1233,24 @@ public class PBXProjGenerator {
|
||||
dependencies[dependency.reference] = dependency
|
||||
}
|
||||
case .target:
|
||||
if isTopLevel || dependency.embed == nil {
|
||||
if let dependencyTarget = project.getTarget(dependency.reference) {
|
||||
dependencies[dependency.reference] = dependency
|
||||
if !dependencyTarget.shouldEmbedDependencies {
|
||||
// traverse target's dependencies if it doesn't embed them itself
|
||||
queue.append(dependencyTarget)
|
||||
let dependencyTargetReference = try! TargetReference(dependency.reference)
|
||||
|
||||
switch dependencyTargetReference.location {
|
||||
case .local:
|
||||
if isTopLevel || dependency.embed == nil {
|
||||
if let dependencyTarget = project.getTarget(dependency.reference) {
|
||||
dependencies[dependency.reference] = dependency
|
||||
if !dependencyTarget.shouldEmbedDependencies {
|
||||
// traverse target's dependencies if it doesn't embed them itself
|
||||
queue.append(dependencyTarget)
|
||||
}
|
||||
} else if project.getAggregateTarget(dependency.reference) != nil {
|
||||
// Aggregate targets should be included
|
||||
dependencies[dependency.reference] = dependency
|
||||
}
|
||||
} else if project.getAggregateTarget(dependency.reference) != nil {
|
||||
// Aggregate targets should be included
|
||||
}
|
||||
case .project:
|
||||
if isTopLevel || dependency.embed == nil {
|
||||
dependencies[dependency.reference] = dependency
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
/* Begin PBXFileReference section */
|
||||
6023D61BF2C57E6AE09CE7A3 /* BundleX.bundle */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "wrapper.plug-in"; path = BundleX.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
60D6679FB526839EAFEA2EEE /* config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = config.xcconfig; sourceTree = "<group>"; };
|
||||
D6340FC7DEBC81E0127BAFD6 /* ExternalTarget.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ExternalTarget.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
@ -33,6 +34,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6023D61BF2C57E6AE09CE7A3 /* BundleX.bundle */,
|
||||
D6340FC7DEBC81E0127BAFD6 /* ExternalTarget.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@ -55,6 +57,21 @@
|
||||
productReference = 6023D61BF2C57E6AE09CE7A3 /* BundleX.bundle */;
|
||||
productType = "com.apple.product-type.bundle";
|
||||
};
|
||||
E76A5F5E363E470416D3B487 /* ExternalTarget */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = B5049D72EC10A5C87F29B6B1 /* Build configuration list for PBXNativeTarget "ExternalTarget" */;
|
||||
buildPhases = (
|
||||
F08051CAC5E72EEEB8FB447B /* Sources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = ExternalTarget;
|
||||
productName = ExternalTarget;
|
||||
productReference = D6340FC7DEBC81E0127BAFD6 /* ExternalTarget.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
@ -78,6 +95,7 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
63A2D4898D974A06E85B07F8 /* BundleX */,
|
||||
E76A5F5E363E470416D3B487 /* ExternalTarget */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@ -90,6 +108,13 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F08051CAC5E72EEEB8FB447B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
@ -248,6 +273,27 @@
|
||||
};
|
||||
name = "Staging Release";
|
||||
};
|
||||
1B1B4A623B8E9937627EF22C /* Test Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = "Test Debug";
|
||||
};
|
||||
270E1D32776D2D196D435FDA /* Staging Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@ -308,6 +354,69 @@
|
||||
};
|
||||
name = "Staging Debug";
|
||||
};
|
||||
30E2E954A636A240B1CE5C15 /* Staging Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = "Staging Release";
|
||||
};
|
||||
3B4B85DEBC49A5BEF2196886 /* Staging Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = "Staging Debug";
|
||||
};
|
||||
42D8986753AED7AA1F3DB83D /* Production Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = "Production Debug";
|
||||
};
|
||||
49FA7F235A6CA1F941192151 /* Staging Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@ -415,6 +524,48 @@
|
||||
};
|
||||
name = "Test Debug";
|
||||
};
|
||||
6081D1A42688EBF6CF4B2579 /* Production Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = "Production Release";
|
||||
};
|
||||
7919FDD28F9A535EA26FB151 /* Test Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = "Test Release";
|
||||
};
|
||||
9BD6CAD5463121A1C3FED138 /* Production Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@ -529,6 +680,19 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = "Production Debug";
|
||||
};
|
||||
B5049D72EC10A5C87F29B6B1 /* Build configuration list for PBXNativeTarget "ExternalTarget" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
42D8986753AED7AA1F3DB83D /* Production Debug */,
|
||||
6081D1A42688EBF6CF4B2579 /* Production Release */,
|
||||
3B4B85DEBC49A5BEF2196886 /* Staging Debug */,
|
||||
30E2E954A636A240B1CE5C15 /* Staging Release */,
|
||||
1B1B4A623B8E9937627EF22C /* Test Debug */,
|
||||
7919FDD28F9A535EA26FB151 /* Test Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = "";
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 1B166EB49192B73A9DD8E108 /* Project object */;
|
||||
|
@ -6,3 +6,6 @@ targets:
|
||||
BundleX:
|
||||
type: bundle
|
||||
platform: iOS
|
||||
ExternalTarget:
|
||||
type: framework
|
||||
platform: iOS
|
||||
|
@ -110,6 +110,7 @@
|
||||
BFCCC56337A5D9D513C1C791 /* module.modulemap in CopyFiles */ = {isa = PBXBuildFile; fileRef = F2950763C4C568CC85021D18 /* module.modulemap */; };
|
||||
C3672B561F456794151C047C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4C3FE6B986506724DAB5D0F /* ViewController.swift */; };
|
||||
C400EBD25886ACB5CD9035EB /* module.modulemap in CopyFiles */ = {isa = PBXBuildFile; fileRef = F2950763C4C568CC85021D18 /* module.modulemap */; };
|
||||
C7B9C14C4AE497A9A9556603 /* ExternalTarget.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3DCDCD083AABD1D30EA34576 /* ExternalTarget.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
C836F09B677937EFF69B1FCE /* NotificationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C934C1F7A68CCD0AB6B38478 /* NotificationController.swift */; };
|
||||
C88598A49087A212990F4E8B /* ResourceFolder in Resources */ = {isa = PBXBuildFile; fileRef = 6B1603BA83AA0C7B94E45168 /* ResourceFolder */; };
|
||||
CCA17097382757012B58C17C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1BC32A813B80A53962A1F365 /* Assets.xcassets */; };
|
||||
@ -123,6 +124,7 @@
|
||||
E4D0F435405DABCB51C5B684 /* TestFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E43116070AFEF5D8C3A5A957 /* TestFramework.framework */; };
|
||||
E5DD0AD6F7AE1DD4AF98B83E /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 65C8D6D1DDC1512D396C07B7 /* Localizable.stringsdict */; };
|
||||
E8A135F768448632F8D77C8F /* StandaloneAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3571E41E19A5AB8AAAB04109 /* StandaloneAssets.xcassets */; };
|
||||
EB29B16FF4DE8A7F3EDD0A0F /* ExternalTarget.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DCDCD083AABD1D30EA34576 /* ExternalTarget.framework */; };
|
||||
F07FC32458F3193917261C15 /* BundleX.bundle in Copy Bundles to Resources directory */ = {isa = PBXBuildFile; fileRef = 45C12576F5AA694DD0CE2132 /* BundleX.bundle */; };
|
||||
F5D71267BB5A326BDD69D532 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E55F45EACB0F382722D61C8D /* Assets.xcassets */; };
|
||||
F6537CE373C94809E6653758 /* Headers in Headers */ = {isa = PBXBuildFile; fileRef = 2E1E747C7BC434ADB80CC269 /* Headers */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@ -202,6 +204,13 @@
|
||||
remoteGlobalIDString = E7815F2F0D9CDECF9185AAF3;
|
||||
remoteInfo = "XPC Service";
|
||||
};
|
||||
8F4740ACBFA31AAF289F64AC /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = F192E783CCA898FBAA5C34EA /* AnotherProject */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = D6340FC7DEBC81E0127BAFD6;
|
||||
remoteInfo = ExternalTarget;
|
||||
};
|
||||
9636E133F9CACD17C56B7915 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0FBAE303E3CFC2ABAC876A77 /* Project object */;
|
||||
@ -272,6 +281,13 @@
|
||||
remoteGlobalIDString = AE3F93DB94E7208F2F1D9A78;
|
||||
remoteInfo = Framework_iOS;
|
||||
};
|
||||
FF75DC967D1097BC31DCF5E6 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = F192E783CCA898FBAA5C34EA /* AnotherProject */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = E76A5F5E363E470416D3B487;
|
||||
remoteInfo = ExternalTarget;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@ -435,6 +451,7 @@
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
C7B9C14C4AE497A9A9556603 /* ExternalTarget.framework in Embed Frameworks */,
|
||||
63D8E7F00276736EDA62D227 /* Framework2.framework in Embed Frameworks */,
|
||||
B2D43A31C184E34EF9CB743C /* Framework.framework in Embed Frameworks */,
|
||||
);
|
||||
@ -548,6 +565,7 @@
|
||||
EE1343F2238429D4DA9D830B /* File1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = File1.swift; path = Group/File1.swift; sourceTree = "<group>"; };
|
||||
EF92E90B6F1D583382BD85BE /* StaticLibrary_ObjC.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = StaticLibrary_ObjC.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F0D48A913C087D049C8EDDD7 /* App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = App.entitlements; sourceTree = "<group>"; };
|
||||
F192E783CCA898FBAA5C34EA /* AnotherProject */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AnotherProject; path = AnotherProject/AnotherProject.xcodeproj; sourceTree = "<group>"; };
|
||||
F2950763C4C568CC85021D18 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = "<group>"; };
|
||||
F2FA55A558627ED576A4AFD6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||
FA86D418796C1A6864414460 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
|
||||
@ -562,6 +580,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
EB29B16FF4DE8A7F3EDD0A0F /* ExternalTarget.framework in Frameworks */,
|
||||
4CB673A7C0C11E04F8544BDB /* Contacts.framework in Frameworks */,
|
||||
262891CCD5F74316610437FA /* Framework2.framework in Frameworks */,
|
||||
2FAE950E8FF2E7C0F7FF1FE9 /* Framework.framework in Frameworks */,
|
||||
@ -728,6 +747,7 @@
|
||||
79DC4A1E4D2E0D3A215179BC /* Bundles */,
|
||||
FC1515684236259C50A7747F /* Frameworks */,
|
||||
AC523591AC7BE9275003D2DB /* Products */,
|
||||
D7929BCBA599BD85A3B8A039 /* Projects */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
@ -850,6 +870,14 @@
|
||||
path = StandaloneFiles;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9DCF6BEAF3BA2AD29290E9B3 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3DCDCD083AABD1D30EA34576 /* ExternalTarget.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9EDF27BB8A57733E6639D36D /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -949,6 +977,14 @@
|
||||
path = tvOS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D7929BCBA599BD85A3B8A039 /* Projects */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F192E783CCA898FBAA5C34EA /* AnotherProject */,
|
||||
);
|
||||
name = Projects;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DBF93518FC96D95A54552713 /* iOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1154,6 +1190,7 @@
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
7C4CC3918BD0DA1E04A5E2B0 /* PBXTargetDependency */,
|
||||
0D33D01C71E8002A07F02122 /* PBXTargetDependency */,
|
||||
A94F38390A74E215EC107BB5 /* PBXTargetDependency */,
|
||||
E84285243DE0BB361A708079 /* PBXTargetDependency */,
|
||||
@ -1609,6 +1646,12 @@
|
||||
);
|
||||
mainGroup = 293D0FF827366B513839236A;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 9DCF6BEAF3BA2AD29290E9B3 /* Products */;
|
||||
ProjectRef = F192E783CCA898FBAA5C34EA /* AnotherProject */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
0867B0DACEF28C11442DE8F7 /* App_iOS */,
|
||||
@ -1644,6 +1687,16 @@
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
3DCDCD083AABD1D30EA34576 /* ExternalTarget.framework */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.framework;
|
||||
path = ExternalTarget.framework;
|
||||
remoteRef = 8F4740ACBFA31AAF289F64AC /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
1C008C34DA06FEE7841B0AC3 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
@ -2167,6 +2220,11 @@
|
||||
target = 0636AAF06498C336E1CEEDE4 /* TestFramework */;
|
||||
targetProxy = C42BA4EA0239AF536F0F0993 /* PBXContainerItemProxy */;
|
||||
};
|
||||
7C4CC3918BD0DA1E04A5E2B0 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = E76A5F5E363E470416D3B487;
|
||||
targetProxy = FF75DC967D1097BC31DCF5E6 /* PBXContainerItemProxy */;
|
||||
};
|
||||
7EFC0278E67CD35F8981993C /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 578C80E461E675508CED5DC3 /* StaticLibrary_ObjC_macOS */;
|
||||
|
@ -15,6 +15,9 @@ fileGroups:
|
||||
- Configs
|
||||
- FileGroup
|
||||
- SomeFile
|
||||
projectReferences:
|
||||
AnotherProject:
|
||||
path: ./AnotherProject/AnotherProject.xcodeproj
|
||||
configFiles:
|
||||
Test Debug: Configs/config.xcconfig
|
||||
targets:
|
||||
@ -106,6 +109,7 @@ targets:
|
||||
- target: iMessageApp
|
||||
- sdk: Contacts.framework
|
||||
- bundle: BundleX.bundle
|
||||
- target: AnotherProject/ExternalTarget
|
||||
scheme:
|
||||
testTargets:
|
||||
- App_iOS_Tests
|
||||
|
@ -217,7 +217,7 @@ class ProjectSpecTests: XCTestCase {
|
||||
try expectValidationError(project, .invalidSchemeConfig(scheme: "scheme1", config: "releaseInvalid"))
|
||||
}
|
||||
|
||||
$0.it("fails with invalid project reference") {
|
||||
$0.it("fails with invalid project reference in scheme") {
|
||||
var project = baseProject
|
||||
project.schemes = [Scheme(
|
||||
name: "scheme1",
|
||||
@ -233,6 +233,36 @@ class ProjectSpecTests: XCTestCase {
|
||||
try expectValidationError(project, .invalidProjectReferencePath(reference))
|
||||
}
|
||||
|
||||
$0.it("fails with invalid project reference in dependency") {
|
||||
var project = baseProject
|
||||
project.targets = [
|
||||
Target(
|
||||
name: "target1",
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
dependencies: [Dependency(type: .target, reference: "invalidProjectRef/target2")]
|
||||
),
|
||||
]
|
||||
try expectValidationError(project, .invalidTargetDependency(target: "target1", dependency: "invalidProjectRef/target2"))
|
||||
}
|
||||
|
||||
$0.it("allows project reference in target dependency") {
|
||||
var project = baseProject
|
||||
let externalProjectPath = fixturePath + "TestProject/AnotherProject/AnotherProject.xcodeproj"
|
||||
project.projectReferences = [
|
||||
ProjectReference(name: "validProjectRef", path: externalProjectPath.string)
|
||||
]
|
||||
project.targets = [
|
||||
Target(
|
||||
name: "target1",
|
||||
type: .application,
|
||||
platform: .iOS,
|
||||
dependencies: [Dependency(type: .target, reference: "validProjectRef/ExternalTarget")]
|
||||
),
|
||||
]
|
||||
try project.validate()
|
||||
}
|
||||
|
||||
$0.it("allows missing optional file") {
|
||||
var project = baseProject
|
||||
project.targets = [Target(
|
||||
|
@ -376,6 +376,7 @@ class SpecLoadingTests: XCTestCase {
|
||||
var targetDictionary = validTarget
|
||||
targetDictionary["dependencies"] = [
|
||||
["target": "name", "embed": false],
|
||||
["target": "project/name", "embed": false],
|
||||
["carthage": "name", "findFrameworks": true],
|
||||
["carthage": "name", "findFrameworks": true, "linkType": "static"],
|
||||
["framework": "path", "weak": true],
|
||||
@ -386,13 +387,14 @@ class SpecLoadingTests: XCTestCase {
|
||||
],
|
||||
]
|
||||
let target = try Target(name: "test", jsonDictionary: targetDictionary)
|
||||
try expect(target.dependencies.count) == 6
|
||||
try expect(target.dependencies.count) == 7
|
||||
try expect(target.dependencies[0]) == Dependency(type: .target, reference: "name", embed: false)
|
||||
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")
|
||||
try expect(target.dependencies[1]) == Dependency(type: .target, reference: "project/name", embed: false)
|
||||
try expect(target.dependencies[2]) == Dependency(type: .carthage(findFrameworks: true, linkType: .dynamic), reference: "name")
|
||||
try expect(target.dependencies[3]) == Dependency(type: .carthage(findFrameworks: true, linkType: .static), reference: "name")
|
||||
try expect(target.dependencies[4]) == Dependency(type: .framework, reference: "path", weakLink: true)
|
||||
try expect(target.dependencies[5]) == Dependency(type: .sdk(root: nil), reference: "Contacts.framework")
|
||||
try expect(target.dependencies[6]) == Dependency(type: .sdk(root: "DEVELOPER_DIR"), reference: "Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework")
|
||||
}
|
||||
|
||||
$0.it("parses info plist") {
|
||||
|
@ -312,6 +312,51 @@ class ProjectGeneratorTests: XCTestCase {
|
||||
try expect(dependencies).contains { $0.target == frameworkTarget }
|
||||
}
|
||||
|
||||
$0.it("generates dependency from external project file") {
|
||||
let subproject: PBXProj
|
||||
prepareXcodeProj: do {
|
||||
let project = try! Project(path: fixturePath + "TestProject/AnotherProject/project.yml")
|
||||
let generator = ProjectGenerator(project: project)
|
||||
let writer = FileWriter(project: project)
|
||||
let xcodeProject = try! generator.generateXcodeProject()
|
||||
try! writer.writeXcodeProject(xcodeProject)
|
||||
try! writer.writePlists()
|
||||
subproject = xcodeProject.pbxproj
|
||||
}
|
||||
let externalProjectPath = fixturePath + "TestProject/AnotherProject/AnotherProject.xcodeproj"
|
||||
let projectReference = ProjectReference(name: "AnotherProject", path: externalProjectPath.string)
|
||||
var target = app
|
||||
target.dependencies = [
|
||||
Dependency(type: .target, reference: "AnotherProject/ExternalTarget")
|
||||
]
|
||||
let project = Project(
|
||||
name: "test",
|
||||
targets: [target],
|
||||
schemes: [],
|
||||
projectReferences: [projectReference]
|
||||
)
|
||||
let pbxProject = try project.generatePbxProj()
|
||||
|
||||
let projectReferences = pbxProject.rootObject?.projects ?? []
|
||||
try expect(projectReferences.count) == 1
|
||||
try expect((projectReferences.first?["ProjectRef"])?.name) == "AnotherProject"
|
||||
|
||||
let dependencies = pbxProject.targetDependencies
|
||||
let targetUuid = subproject.targets(named: "ExternalTarget").first?.uuid
|
||||
try expect(dependencies.count) == 1
|
||||
try expect(dependencies).contains { dependency in
|
||||
guard let id = dependency.targetProxy?.remoteGlobalID else { return false }
|
||||
|
||||
switch id {
|
||||
case .object(let object):
|
||||
return object.uuid == targetUuid
|
||||
case .string(let value):
|
||||
return value == targetUuid
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$0.it("generates targets with correct transitive embeds") {
|
||||
// App # Embeds it's frameworks, so shouldn't embed in tests
|
||||
// dependencies:
|
||||
|
Loading…
Reference in New Issue
Block a user