Commit 42438e49 authored by David Owens II's avatar David Owens II

Moved the docs to 'anarchytools:master'.

parent 8f656e43
# atllbuild
The `atllbuild` tool uses the [`swift-llbuild`](https://github.com/apple/swift-llbuild) project to compile a swift module.
## API
```clojure
:tasks {
:build {
:tool "atllbuild"
;;Name of the module to build
:name "build"
;;Type of build. "library" and "executable" are supported.
:outputType "library"
;;walk the src directory and recursively find all swift files
:source ["src/**.swift"]
;;if true, we publish the product to the bin/ directory.
:publishProduct false
;;If true, we don't build, we only output llbuild.yaml False is the default value.
:bootstrapOnly: false
;;Path to emit llbuild.yaml
:llbuildyaml "llbuild.yaml"
;;Provide an array of compile options. NOTHING IS IMPOSSIBLE
:compileOptions []
:linkOptions [] ;;link options too!
:linkSDK true #Whether to link the platform SDK. True is the default value.
;;A product from another atllbuild task to link with.
;;You should supply a filename here, like "yaml.a".
;;Note that this is for linking dependencies built by atllbuild;
;;or other libraries, you should use UNSUPPORTED https://github.com/AnarchyTools/atbuild/issues/13
:linkWithProduct ["attools.a" "atpkg.a"]
;;The path to swiftC. By default, we guess based on your platform
swiftCPath:"/usr/local/bin/swiftc"
;; Inject platform-specific options related to
;; XCTest targets
xctestify: false
;; Inject platform-specific behavior related to
;; checking for API differences across XCTest
;; platforms
xctestStrict: false
}
}
```
## Conditional compilation
If you're packaging a project for atbuild and wish to conditionally compile your sources, you can use
```swift
#if ATBUILD
//use this code only when packaged with atbuild
#endif
```
This is useful when packaging Xcode projects that resolve their imports through bridging headers, for example.
## Implementation
The `atllbuild` tool emits an `llbuild.yaml` file. This is undocumented, but we [reverse-engineered the format from SwiftPM](https://github.com/apple/swift-package-manager). You can see an example in our [repository](/llbuild.yaml). Essentially, this file contains the compile/link commands for building the swift module.
Finally, we call `swift-build-tool -f /path/to/llbuild.yaml`.
## Boostrapping
In addition to building, we can choose to (only) emit the llbuild.yaml file, and save it for compiling later.
This is how we bootstrap atbuild, by creating an llbuild.yaml on a working machine and then using swift-build-tool on a new machine. For this reason, the `llbuild.yaml` file in this repository must be kept up to date.
\ No newline at end of file
You can import tasks in remote files.
This is useful to depend on tasks specified in another package.
```clojure
(package
:name "atbuild"
;; import all the tasks in `atpkg/build.atpkg`.
;; These will be imported as `packagename.taskname`.
;; Since you cannot declare packages with periods manually, this
;; cannot conflict with any current tasks
:import ["atpkg/build.atpkg"]
;; We can then depend on a target from the remote package in our current one
:tasks {
:mytask {
:tool "atllbuild"
:source ["src/**.swift]
:name "mytask"
:outputType "executable"
:dependencies ["atpkg.atpkg"]
}
}
)
```
You can also reference remote tasks on the command line by providing their fully-qualified name:
```bash
$ atbuild atpkg.atpkg
$ atbuild mytask
$ atbuild atbuild.mytask #equivalent to previous line
```
Packages are imported in a flat topology; if `a` imports `b` and `b` imports `c`, use `c.taskname` to refer to the task, not `b.c.taskname` or `a.b.c.taskname`.
# Implementation note
Remote packages may have paths specified in a key, like "source". *Quite possibly, these keys should be interpreted relative to the path the task was declared in, NOT the working directory.*
To support this, `Task` has a property `importedPath` that tools may want to use.
\ No newline at end of file
# nop
The nop tool has no effect. You can use this tool to create tasks that group dependencies.
\ No newline at end of file
# Overlays
You can activate settings, called "overlays", by passing them on the command line.
```bash
$ atbuild --overlay bar
```
This activates the settings for the overlay across all targets:
```clojure
(package
:name "Foo"
:overlays {
:bar {
:compileOptions ["-D" "FOO"]
}
}
)
```
You can add as many overlays as you like: `atbuild --overlay bar --overlay baz`. They are processed in order.
# Task-scoped overlays
You can also only apply an overlay to a particular task. To do this:
```clojure
(package
:name "Foo"
:tasks {
:foo {
:overlays {
:bar {
:compileOptions ["-D" "BAZ"]
}
}
}
}
)
```
Now when we build with `--overlay bar`, this will add `-D BAZ` to compile options for the `foo` task, but not for other tasks in our file.
# 'Always' overlay
We can use an overlay even when it was not specified on the CLI. This way we can share common configuration options between several tasks.
```clojure
(package
:name "Foo"
:overlays {
:optimized {
:compileOptions ["-Owholemodule"] ;;whole module optimization
}
}
:tasks {
:foo {
:overlay ["optimized"] ;;apply to this task
}
:baz {
:overlay ["optimized"] ;;apply to this task too
}
}
)
```
# Imported overlays
Overlays can be [imported](import.md). This allows libraries to export required compile flags to clients.
```clojure
(package
:name "Library"
:overlays {
:compile-linux {
:compileOptions ["-Xcc" "-fblocks"] ;; work around https://bugs.swift.org/browse/SR-397
}
}
)
```
```clojure
(package
:name "Executable"
:import ["Library.atpkg"]
:tasks {
:foo {
:overlay ["Library.compile-linux"] ;;apply to this task
}
)
```
# shell
The shell tool allows you to call a shell command.
# API
```clojure
:taskname {
:tool "shell"
;;run the following script in /bin/sh.
;;A non-zero return code indicates that build should halt.
:script "echo hello world"
}
```
# Tasks
All tasks have the following options:
```clojure
taskname: {
;;the name of a tool. Valid tools are shell, atllbuild, nop
:tool "tool"
;;What other tasks should run before this one.
:dependency []
;;see docs/overlays.md for more information about overlays
:overlay [] ;;what overlays to apply to this task
:overlays { } ;;what overlays can be applied to this task
}
```
# XCTest
atbuild is unopinionated about how you test your code; you can launch any executable as an atbuild [task](tasks.md), and use that executable to run tests.
However, if you want to use XCTest, it is tricky to configure, particularly as the implementation is quite different between platforms. To smooth this problem out, `atbuild` includes some additonal options.
```clojure
(package
:name "xctestexample"
:tasks {
;; Define a task to build our library
:build-lib {
:tool "atllbuild"
:source ["src/**.swift"]
:outputType "static-library"
:name "Foo"
;; Make sure we enable testing so that
;; we can import with @testable
:compileOptions ["-enable-testing"]
}
;; Define a task to build the tests.
;; This is sometimes called a "test target" in Xcode.
;; This is primarily an executable that links our library.
:build-tests {
:tool "atllbuild"
:source ["test/**.swift"]
:outputType "executable"
:name "footests"
:dependencies ["build-lib"]
:linkWithProduct["Foo.a"]
;; atbuild will inject platform-specific
;; compile options to make XCTest work
:xctestify true
;; XCTest on Linux is a bit stricter
;; than on OSX. Tell atbuild
;; we want stricter checks for API compliance
:xctestStrict true
}
;; A task to run our tests
:run-tests {
:dependencies ["build-tests"]
;; The xctestrun tool is a cross-platform XCTest runner
:tool "xctestrun"
;; Tell xctestrun where we built our tests
:testExecutable ".atllbuild/products/footests"
}
}
)
```
Now you can run your tests on any platform with just `atbuild run-tests`.
For more information, see a [complete example](tests/fixtures/xcs)
\ No newline at end of file
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