Commit 0c1ba2e6 authored by Drew's avatar Drew

Toolchain support

This allows atbuild to use a different toolchain other than the one we
use to develop atbuild (weekly snapshot).

In particular, this allows you to use "released swift" "xcode swift" or
any other kind of 2.2 Swift.

Documentation PR to follow.

Edited README to discuss atbuild options.

Resolves #58 to my satisfaction.
parent ed5be68f
Pipeline #1364 passed with stage
......@@ -71,6 +71,16 @@ How do we build a Swift project? There's a built-in tool called `atllbuild`, wh
That's all you need to get started! `atbuild` supports many more usecases than can fit in a README. For more information, browse our [documentation](http://anarchytools.org).
# Options
`atbuild` supports several command-line options:
* `--use-overlay [overlay]`, which you can read more about in our [overlays](overlays.html) documentation.
* `-f [atpkg-file]` which builds a package file other than `build.atpkg`
* `--help`, which displays a usage message
* `--clean`, which forces a clean build
* `--toolchain` which specifies a nonstandard toolchain (swift installation). By default we try to guess, but you can override our guess here. The special string `xcode` uses "xcode swift" for building. (Swift 2.2 does not contain all the tools we use, so you need to have a 3.x snapshot installed as well. However, this is a "mostly" xcode-flavored buildchain.)
# Building
We publish [binary releases](https://github.com/AnarchyTools/atbuild/releases), which are the easiest way to get started.
......@@ -99,3 +109,6 @@ To declare your project to be compatible with Anarchy Tools, simply
```markdown
[![Anarchy Tools compatible](https://img.shields.io/badge/Anarchy%20Tools-compatible-4BC51D.svg?style=flat)](http://anarchytools.org)
```
*Maintainer note: if you edit this file, edit the one in [this repo](https://github.com/AnarchyTools/anarchytools.github.io) as well.*
\ No newline at end of file
......@@ -26,8 +26,9 @@ enum Options: String {
case CustomFile = "-f"
case Help = "--help"
case Clean = "--clean"
case Toolchain = "--toolchain"
static var allOptions : [Options] { return [Overlay, CustomFile] }
static var allOptions : [Options] { return [Overlay, CustomFile, Help, Clean, Toolchain] }
}
let defaultPackageFile = "build.atpkg"
......@@ -43,10 +44,17 @@ for (i, x) in Process.arguments.enumerated() {
}
}
var packageFile = defaultPackageFile
var toolchain = DefaultToolchainPath
for (i, x) in Process.arguments.enumerated() {
if x == Options.CustomFile.rawValue {
packageFile = Process.arguments[i+1]
}
if x == Options.Toolchain.rawValue {
toolchain = Process.arguments[i+1]
if toolchain == "xcode" {
toolchain = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain"
}
}
}
let package = try! Package(filepath: packageFile, overlay: overlays, focusOnTask: focusOnTask)
......@@ -57,7 +65,7 @@ if Process.arguments.contains("--help") {
print("© 2016 Anarchy Tools Contributors.")
print("")
print("Usage:")
print("atbuild [-f packagefile] [task] [--clean]")
print("atbuild [--toolchain (/toolchain/path | xcode)] [-f packagefile] [task] [--clean]")
print("tasks:")
for (key, task) in package.tasks {
......@@ -66,10 +74,11 @@ if Process.arguments.contains("--help") {
exit(1)
}
func runTask(taskName: String, package: Package) {
guard let task = package.tasks[taskName] else { fatalError("No \(taskName) task in build configuration.") }
for task in package.prunedDependencyGraph(task) {
TaskRunner.runTask(task, package: package)
TaskRunner.runTask(task, package: package, toolchain: toolchain)
}
}
......
......@@ -19,5 +19,5 @@ import atpkg
* dependencies together.
*/
final class Nop: Tool {
func run(task: Task) {}
func run(task: Task, toolchain: String) {}
}
......@@ -14,14 +14,33 @@
import Foundation
//todo, support multiple toolchains
func findToolPath(toolName: String, toolchain: String) -> String {
//look in /usr/bin
let manager = NSFileManager.defaultManager()
let usrBin = "\(toolchain)/usr/bin/\(toolName)"
if manager.fileExists(atPath: usrBin) { return usrBin }
//look in /usr/local/bin
let usrLocalBin = "\(toolchain)/usr/local/bin/\(toolName)"
if manager.fileExists(atPath: usrLocalBin) { return usrLocalBin }
//swift-build-tool isn't available in 2.2.
//If we're looking for SBT, try in the default location
if toolName == "swift-build-tool" {
let sbtPath = "\(DefaultToolchainPath)/usr/bin/\(toolName)"
if manager.fileExists(atPath: sbtPath) { return sbtPath }
}
fatalError("Can't find a path for \(toolName)")
}
#if os(OSX)
let SDKPath = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk"
let SwiftCPath = "/Library/Developer/Toolchains/swift-latest.xctoolchain/usr/bin/swiftc"
let SwiftBuildToolpath = "/Library/Developer/Toolchains/swift-latest.xctoolchain/usr/bin/swift-build-tool"
public let DefaultToolchainPath = "/Library/Developer/Toolchains/swift-latest.xctoolchain"
let DynamicLibraryExtension = ".dylib"
#elseif os(Linux)
let SwiftCPath = "/usr/local/bin/swiftc"
let SwiftBuildToolpath = "/usr/local/bin/swift-build-tool"
public let DefaultToolchainPath = "/"
let DynamicLibraryExtension = ".so"
#endif
\ No newline at end of file
......@@ -22,7 +22,7 @@ import atpkg
* If the tool returns with an error code of non-zero, the tool will fail.
*/
final class Shell : Tool {
func run(task: Task) {
func run(task: Task, toolchain: String) {
setenv("ATBUILD_USER_PATH", userPath(), 1)
guard let script = task["script"]?.string else { fatalError("Invalid 'script' argument to shell tool.") }
do {
......
......@@ -22,10 +22,10 @@ import atpkg
final public class TaskRunner {
private init() {}
static public func runTask(task: Task, package: Package) {
static public func runTask(task: Task, package: Package, toolchain: String) {
print("Running task \(task.qualifiedName) with overlays \(task.appliedOverlays)")
let tool = toolByName(task.tool)
tool.run(task)
tool.run(task, toolchain: toolchain)
print("Completed task \(task.qualifiedName).")
}
}
\ No newline at end of file
......@@ -29,7 +29,7 @@ let tools: [String:Tool] = [
* can build new ones out of the existing ones.
*/
public protocol Tool {
func run(task: Task)
func run(task: Task, toolchain: String)
}
/**
......
......@@ -19,7 +19,7 @@ class XCTestRun : Tool {
case TestExecutable = "test-executable"
}
func run(task: Task) {
func run(task: Task, toolchain: String) {
guard let testExecutable = task[Option.TestExecutable.rawValue]?.string else {
fatalError("No \(Option.TestExecutable.rawValue) for XCTestRun task \(task.qualifiedName)")
}
......
......@@ -232,11 +232,11 @@ final class ATllbuild : Tool {
}
}
func run(task: Task) {
run(task, wmoHack: false)
func run(task: Task, toolchain: String) {
run(task, toolchain: toolchain, wmoHack: false)
}
func run(task: Task, wmoHack : Bool = false) {
func run(task: Task, toolchain: String, wmoHack : Bool = false) {
//warn if we don't understand an option
var knownOptions = Options.allOptions.map({$0.rawValue})
......@@ -416,7 +416,7 @@ final class ATllbuild : Tool {
swiftCPath = c
}
else {
swiftCPath = SwiftCPath
swiftCPath = findToolPath("swiftc",toolchain: toolchain)
}
let yaml = llbuildyaml(sources, workdir: workDirectory, modulename: name, linkSDK: sdk, compileOptions: compileOptions, linkOptions: linkOptions, outputType: outputType, linkWithProduct: linkWithProduct, swiftCPath: swiftCPath)
......@@ -432,7 +432,7 @@ final class ATllbuild : Tool {
}
//SR-566
let cmd = "\(SwiftBuildToolpath) -f \(llbuildyamlpath)"
let cmd = "\(findToolPath("swift-build-tool",toolchain: toolchain)) -f \(llbuildyamlpath)"
if system(cmd) != 0 {
fatalError(cmd)
}
......@@ -459,7 +459,7 @@ final class ATllbuild : Tool {
if task[Options.WholeModuleOptimization.rawValue]?.bool == true && !wmoHack {
print("Work around SR-881")
run(task, wmoHack: true)
run(task, toolchain: toolchain, wmoHack: true)
}
}
......
(package
:name "xcode_toolchain"
:tasks {
:default {
:tool "atllbuild"
:sources ["test.swift"]
:name "hello"
:output-type "executable"
:publish-product true
}
}
)
//this is an error on Swift 3
//but "xcode" currently ships swift 2.2
//so if we compile successfully, we used Xcode compiler.
enum E : ErrorType { }
\ No newline at end of file
......@@ -10,6 +10,15 @@ pwd
echo "****************SELF-HOSTING TEST**************"
$ATBUILD atbuild
echo "****************XCODE TOOLCHAIN TEST**************"
if [ -e "/Applications/Xcode.app" ]; then
cd $DIR/tests/fixtures/xcode_toolchain
$ATBUILD --toolchain xcode
else
echo "Xcode is not installed; skipping test"
fi
echo "****************DYNAMIC LIBRARY TEST**************"
cd $DIR/tests/fixtures/dynamic_library
$ATBUILD
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment