Skip to content

Xcode Project Generation #174

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 10, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ xcuserdata
*~
*.xcscmblueprint
/default.profraw
*.xcodeproj
9 changes: 6 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ let package = Package(
/** Base types for the package-engine */
name: "PackageType",
dependencies: ["PackageDescription", "Utility"]), //FIXME dependency on PackageDescription sucks
Target( //FIXME Carpet is too general, we only need `Path`
Target( //FIXME Utility is too general, we only need `Path`
name: "ManifestParser",
dependencies: ["PackageDescription", "PackageType"]),
Target(
Expand All @@ -35,7 +35,7 @@ let package = Package(
Target(
/** Fetches Packages and their dependencies */
name: "Get",
dependencies: ["ManifestParser"]),
dependencies: ["PackageDescription", "PackageType"]),
Target(
/** Builds Modules and Products */
name: "Build",
Expand All @@ -44,9 +44,12 @@ let package = Package(
/** Common components of both executables */
name: "Multitool",
dependencies: ["PackageType"]),
Target(
name: "Xcodeproj",
dependencies: ["PackageType"]),
Target(
name: "swift-build",
dependencies: ["Get", "Transmute", "Build", "Multitool"]),
dependencies: ["ManifestParser", "Get", "Transmute", "Build", "Multitool", "Xcodeproj"]),
Target(
name: "swift-test",
dependencies: ["Multitool"]),
Expand Down
16 changes: 8 additions & 8 deletions Sources/Build/describe().swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

import func POSIX.getenv
import func POSIX.mkdir
import PackageType
import Utility
import func POSIX.fopen
import func libc.fclose
import PackageType
import Utility

/**
- Returns: path to generated YAML for consumption by the llbuild based swift-build-tool
Expand Down Expand Up @@ -41,7 +41,7 @@ public func describe(prefix: String, _ conf: Configuration, _ modules: [Module],
}

var mkdirs = Set<String>()
let swiftcArgs = Xcc + Xswiftc
let swiftcArgs = Xcc + Xswiftc + verbosity.ccArgs

for case let module as SwiftModule in modules {

Expand All @@ -53,7 +53,7 @@ public func describe(prefix: String, _ conf: Configuration, _ modules: [Module],
args.append("-enable-testing")

#if os(OSX)
if let platformPath = Resources.path.platformPath {
if let platformPath = Toolchain.platformPath {
let path = Path.join(platformPath, "Developer/Library/Frameworks")
args += ["-F", path]
} else {
Expand All @@ -65,7 +65,7 @@ public func describe(prefix: String, _ conf: Configuration, _ modules: [Module],
let swiftc = SwiftcTool(
inputs: node.inputs,
outputs: node.outputs,
executable: Resources.path.swiftc,
executable: Toolchain.swiftc,
moduleName: module.c99name,
moduleOutputPath: node.moduleOutputPath,
importPaths: prefix,
Expand Down Expand Up @@ -96,7 +96,7 @@ public func describe(prefix: String, _ conf: Configuration, _ modules: [Module],
description: "Compiling \(module.name)",
inputs: inputs,
outputs: [productPath, module.targetName],
args: [Resources.path.swiftc, "-o", productPath] + args + module.sources.paths + otherArgs)
args: [Toolchain.swiftc, "-o", productPath] + args + module.sources.paths + otherArgs)

let command = Command(name: module.targetName, tool: shell)
append(command, buildable: module)
Expand All @@ -121,7 +121,7 @@ public func describe(prefix: String, _ conf: Configuration, _ modules: [Module],
objects = product.buildables.flatMap{ return IncrementalNode(module: $0, prefix: prefix).objectPaths }
}

var args = [Resources.path.swiftc] + swiftcArgs
var args = [Toolchain.swiftc] + swiftcArgs

switch product.type {
case .Library(.Static):
Expand All @@ -130,7 +130,7 @@ public func describe(prefix: String, _ conf: Configuration, _ modules: [Module],
#if os(OSX)
args += ["-Xlinker", "-bundle"]

if let platformPath = Resources.path.platformPath {
if let platformPath = Toolchain.platformPath {
let path = Path.join(platformPath, "Developer/Library/Frameworks")
args += ["-F", path]
} else {
Expand Down
12 changes: 6 additions & 6 deletions Sources/Build/misc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import Utility
func platformArgs() -> [String] {
var args = [String]()

#if os(OSX)
args += ["-target", "x86_64-apple-macosx10.10"]
#if os(OSX)
args += ["-target", "x86_64-apple-macosx10.10"]

if let sysroot = Resources.path.sysroot {
args += ["-sdk", sysroot]
}
#endif
if let sysroot = Toolchain.sysroot {
args += ["-sdk", sysroot]
}
#endif

return args
}
Expand Down
5 changes: 2 additions & 3 deletions Sources/Get/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@
*/

import struct PackageDescription.Version
import ManifestParser
import PackageType
import Utility

extension Package {
// FIXME we *always* have a manifest, don't reparse it

static func make(repo repo: Git.Repo) throws -> Package? {
static func make(repo repo: Git.Repo, manifestParser: (path: String, url: String) throws -> Manifest) throws -> Package? {
guard let origin = repo.origin else { throw Error.NoOrigin(repo.path) }
let manifest = try Manifest(path: repo.path, baseURL: origin)
let manifest = try manifestParser(path: repo.path, url: origin)
let pkg = Package(manifest: manifest, url: origin)
guard Version(pkg.versionString) != nil else { return nil }
return pkg
Expand Down
14 changes: 8 additions & 6 deletions Sources/Get/PackagesDirectory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import struct PackageDescription.Version
import func POSIX.mkdir
import func POSIX.rename
import ManifestParser
import PackageType
import Utility

Expand All @@ -20,9 +19,11 @@ import Utility
*/
class PackagesDirectory {
let prefix: String
let manifestParser: (path: String, url: String) throws -> Manifest

init(prefix: String) {
init(prefix: String, manifestParser: (path: String, url: String) throws -> Manifest) {
self.prefix = prefix
self.manifestParser = manifestParser
}
}

Expand All @@ -33,7 +34,7 @@ extension PackagesDirectory: Fetcher {
for prefix in walk(self.prefix, recursively: false) {
guard let repo = Git.Repo(path: prefix) else { continue } //TODO warn user
guard repo.origin == url else { continue }
return try Package.make(repo: repo)
return try Package.make(repo: repo, manifestParser: manifestParser)
}
return nil
}
Expand All @@ -42,13 +43,13 @@ extension PackagesDirectory: Fetcher {
let dstdir = Path.join(prefix, Package.nameForURL(url))
if let repo = Git.Repo(path: dstdir) where repo.origin == url {
//TODO need to canonicalize the URL need URL struct
return try RawClone(path: dstdir)
return try RawClone(path: dstdir, manifestParser: manifestParser)
}

// fetch as well, clone does not fetch all tags, only tags on the master branch
try Git.clone(url, to: dstdir).fetch()

return try RawClone(path: dstdir)
return try RawClone(path: dstdir, manifestParser: manifestParser)
}

func finalize(fetchable: Fetchable) throws -> Package {
Expand All @@ -57,7 +58,8 @@ extension PackagesDirectory: Fetcher {
let prefix = Path.join(self.prefix, clone.finalName)
try mkdir(prefix.parentDirectory)
try rename(old: clone.path, new: prefix)
return try Package.make(repo: Git.Repo(path: prefix)!)!
//TODO don't reparse the manifest!
return try Package.make(repo: Git.Repo(path: prefix)!, manifestParser: manifestParser)!
case let pkg as Package:
return pkg
default:
Expand Down
7 changes: 4 additions & 3 deletions Sources/Get/RawClone.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
*/

import struct PackageDescription.Version
import ManifestParser
import PackageType
import Utility
import libc
Expand All @@ -23,21 +22,23 @@ import libc
*/
class RawClone: Fetchable {
let path: String
let manifestParser: (path: String, url: String) throws -> Manifest

// lazy because the tip of the default branch does not have to be a valid package
//FIXME we should error gracefully if a selected version does not however
var manifest: Manifest! {
if let manifest = _manifest {
return manifest
} else {
_manifest = try? Manifest(path: path, baseURL: repo.origin!)
_manifest = try? manifestParser(path: path, url: repo.origin!)
return _manifest
}
}
private var _manifest: Manifest?

init(path: String) throws {
init(path: String, manifestParser: (path: String, url: String) throws -> Manifest) throws {
self.path = path
self.manifestParser = manifestParser
if !repo.hasVersion {
throw Error.Unversioned(path)
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/Get/get().swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import Utility
- Throws: Error.InvalidDependencyGraph
- Returns: The modules that this manifest requires building
*/
public func get(manifest: Manifest) throws -> [Package] {
public func get(manifest: Manifest, manifestParser: (path: String, url: String) throws -> Manifest) throws -> [Package] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think (path: String, url: String) throws -> Manifest can be typealiased as its being repeated a few times

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typealias ManifestParser = (path: String, url: String) throws -> Manifest

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer not to typealias closures. It just means you have to hunt out the definition rather than have the information in front of you.

There is no potential badness that can happen from not typealiasing it that I can see, if I accidentally type the wrong signature the compiler will point it out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with Max. I've used typealias for function types in production app, didn't like it. I think it's worse also because autocompletion just five you ManifestParser instead of (path: String, url: String) throws -> Manifest

let dir = Path.join(manifest.path.parentDirectory, "Packages")
let box = PackagesDirectory(prefix: dir)
let box = PackagesDirectory(prefix: dir, manifestParser: manifestParser)

//TODO don't lose the dependency information during the Fetcher process!

Expand Down
13 changes: 0 additions & 13 deletions Sources/ManifestParser/Error.swift

This file was deleted.

17 changes: 8 additions & 9 deletions Sources/ManifestParser/Manifest+parse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import struct PackageType.Manifest
import func POSIX.realpath
import PackageDescription
import PackageType
import Utility
import func POSIX.fopen
import func libc.fileno
import func libc.unlink
import func libc.fclose

extension Manifest {
public init(path pathComponents: String..., baseURL: String) throws {
public init(path pathComponents: String..., baseURL: String, swiftc: String, libdir: String) throws {

guard baseURL.chuzzle() != nil else { fatalError() } //TODO

Expand All @@ -36,32 +36,31 @@ extension Manifest {
path = joinedPath
}

guard path.isFile else { throw Error.NoManifest(path) }
guard path.isFile else { throw PackageType.Package.Error.NoManifest(path) }

if let toml = try parse(path) {
if let toml = try parse(path: path, swiftc: swiftc, libdir: libdir) {
let toml = try TOMLItem.parse(toml)
let package = PackageDescription.Package.fromTOML(toml, baseURL: baseURL)
let products = PackageDescription.Product.fromTOML(toml)

self.init(path: path, package: package, products: products)
} else {
// As a special case, we accept an empty file as an unnamed package.
self.init(path: path, package: Package(), products: [Product]())
self.init(path: path, package: PackageDescription.Package(), products: [])
}
}
}

private func parse(manifestPath: String) throws -> String? {
private func parse(path manifestPath: String, swiftc: String, libdir: String) throws -> String? {

// For now, we load the manifest by having Swift interpret it directly.
// Eventually, we should have two loading processes, one that loads only
// the the declarative package specification using the Swift compiler
// directly and validates it.

let libdir = Resources.runtimeLibPath

var cmd = [Resources.path.swiftc]
var cmd = [swiftc]
cmd += ["--driver-mode=swift"]
cmd += verbosity.ccArgs
cmd += ["-I", libdir]
cmd += ["-L", libdir, "-lPackageDescription"]
#if os(OSX)
Expand Down
15 changes: 14 additions & 1 deletion Sources/Multitool/build().swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,23 @@
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import func POSIX.getenv
import Utility

public func build(YAMLPath YAMLPath: String, target: String) throws {
var args = [Resources.path.swift_build_tool, "-f", YAMLPath, target]
var args = [swift_build_tool(), "-f", YAMLPath, target]
if verbosity != .Concise { args.append("-v") }
try system(args)
}

private func swift_build_tool() -> String {
if let tool = getenv("SWIFT_BUILD_TOOL") { //FIXME remove and if people complain, make it a flag
return tool
} else if let path = try? Path.join(exepath, "..", "swift-build-tool").abspath() where path.isFile {
return path
} else {
return "swift-build-tool"
}
}

private let exepath: String = try! Process.arguments.first!.abspath()
6 changes: 4 additions & 2 deletions Sources/POSIX/system.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,16 @@ public func system() {}

/// Convenience wrapper for posix_spawn.
func posix_spawnp(path: String, args: [String], environment: [String: String] = [:], fileActions: posix_spawn_file_actions_t? = nil) throws -> pid_t {
var environment = environment
let argv = args.map{ $0.withCString(strdup) }
defer { for arg in argv { free(arg) } }

var environment = environment
for key in ["PATH", "SDKROOT", "TOOLCHAINS", "HOME", "SWIFT_EXEC",
// FIXME these
"SPM_INSTALL_PATH", "SWIFT_BUILD_TOOL"] {
environment[key] = POSIX.getenv(key)
if environment[key] == nil {
environment[key] = POSIX.getenv(key)
}
}

let env = environment.map{ "\($0.0)=\($0.1)".withCString(strdup) }
Expand Down
10 changes: 10 additions & 0 deletions Sources/Transmute/transmute().swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ public func transmute(packages: [Package], rootdir: String) throws -> ([Module],
// depend upon 'Utility', and hope that no users define
// test modules named 'Functional'.
testModule.dependencies = modules.filter{ $0.name == "Utility" }
} else if testModule.basename == "Transmute" {
// FIXME: Turns out TransmuteTests violate encapsulation :(
testModule.dependencies = modules.filter{
switch $0.name {
case "Get", "Transmute", "ManifestParser":
return true
default:
return false
}
}
} else {
// Normally, test modules are only dependent upon modules with
// the same basename. For example, a test module in
Expand Down
Loading