Build file reference
Every tag and attribute a build.markup.code takes, each with an example. Where a mistake is common, its row shows what
the build says about it, word for word. Build files walks through a build file from the start.
The file
A project's build file is build.markup.code, at the project's top. It holds an optional import, then exactly one tag:
the build.
import platform.build
# A program called robot, and the one library it uses.
(IsolateAssemblyBuild
name={"robot"}
group={"com.me"}
version={"0.1.0"}
description={"Drives two motors from a gamepad."}
(+dependencies let pi : RepositoryDependency coordinate={"com.grandtheorem:raspberry-pi:0.1.0"} /)
/IsolateAssemblyBuild)
import platform.buildis the only import, and it's optional: the build's tags are found without it.#starts a comment that runs to the end of the line. Written right before a tag,#(comments out the whole tag, however many lines it spans.- A tag is
(Type …), holding its attributes and then any tags inside it. It closes with/), with its type's name, as in/IsolateAssemblyBuild), or, for a tag added to a slot, with the slot's name, as in/dependencies). - An attribute is
name={"value"}: a string in quotes, inside braces. Inside the quotes,\"is a quote and\\a backslash. - Every problem shows at once, each where it's written. Text that isn't markup at all stops the reading at the first place it appears.
| You write | The build says |
|---|---|
// a comment | `/` is not markup: a markup file holds its imports, then its one top-level tag |
import platform.io | `import platform.io` is not V0's: a build file imports platform.build alone |
name="robot" | `name=` takes its value in braces: name={"…"} |
name={robot} | `name={robot}` needs evaluating: V0 reads an attribute written as a string literal, name={"…"} |
name={"robot"} twice | `name` is written twice |
"tab\t" | `\t` is not an escape a build file reads: write \" or \\ |
(IsolateAssemblyBuild … /LibraryAssemblyBuild) | `(IsolateAssemblyBuild` is closed by `/LibraryAssemblyBuild)`: close it with /) or /IsolateAssemblyBuild) |
| a tag with no closer | `(IsolateAssemblyBuild` is never closed: close it with /) or /IsolateAssemblyBuild) |
| an empty file | a markup file holds one top-level tag, and none is written |
| two builds in one file | a markup file has exactly one top-level tag, and this is a second |
The build: IsolateAssemblyBuild and LibraryAssemblyBuild
The file's one tag says what the project makes.
IsolateAssemblyBuildbuilds a program, which runs as an isolate:out/<name>-<version>.nylon.LibraryAssemblyBuildbuilds a library, for other projects to use:out/<name>-<version>.nylib.
(LibraryAssemblyBuild
name={"sensors"}
group={"com.me"}
version={"1.2.0-rc.1"}
/LibraryAssemblyBuild)
| Attribute | What it holds | |
|---|---|---|
name | required | The project's name, such as robot. |
group | required | Who it's from, such as com.me. |
version | required | A version in three numbers, major.minor.patch, such as 0.1.0. |
description | optional | A sentence about the project, in any words. |
Together, group, name and version are the project's coordinate, com.me:robot:0.1.0, which is how a library is
found and named.
- A
nameorgroupis ASCII letters, digits,.,_and-. It starts with a letter or a digit, never holds.., and is at most 100 characters. - A
version's numbers have no leading zeros. A pre-release follows a-, as in1.2.0-rc.1. A version takes no+build metadata.
| You write | The build says |
|---|---|
no name | IsolateAssemblyBuild has no `name`: write name={"…"} |
name={"my bots"} | `my bots` is not a name a coordinate can carry: write ASCII letters, digits, `.`, `_` and `-` |
name={"-robot"} | `-robot` is not a name a coordinate can carry: start it with a letter or digit |
name={"a..b"} | `a..b` is not a name a coordinate can carry: write it with no `..` |
version={"1.0"} | `1.0` is not a semantic version: write major.minor.patch, as 0.1.0 |
version={"0.1.00"} | `0.1.00` isn't a version: a version's numbers have no leading zeros, write 0.1.0 |
version={"1.0.0+b"} | `1.0.0+b` has build metadata, which a version doesn't take: write 1.0.0 |
level={"debug"} | `level` is not V0's: the level is the action's, and Run builds for debugging |
author={"me"} | `author` is not an attribute of IsolateAssemblyBuild that V0 reads: it reads `name`, `group`, `version`, `description` |
(Build …) | `Build` is the base of every build and is never the root: write IsolateAssemblyBuild or LibraryAssemblyBuild |
Inside the build: +modules and +dependencies
A tag inside the build is added to one of its two slots, written before its type: (+modules …) or
(+dependencies …). Nothing else goes inside a build, and nothing goes inside a module or a dependency.
| You write | The build says |
|---|---|
(GitDependency …) | `(GitDependency)` is added to one of the root's slots: (+modules let main : IsolateAssemblyModule /) or (+dependencies : GitDependency … /) |
(+deps : GitDependency …) | `+deps` is not a slot of IsolateAssemblyBuild: V0 reads +modules and +dependencies |
Modules
A module is a folder of code that builds together. Without a +modules tag a build has one, main, at src/main, so
most build files write none. A module's code is in <path>/code/ and its resource files are in <path>/resource/. One
module doesn't see another's code.
(IsolateAssemblyBuild
name={"robot"}
group={"com.me"}
version={"0.1.0"}
(+modules let main : IsolateAssemblyModule /)
(+modules let tools : IsolateAssemblyModule path={"src/tools"} /)
/IsolateAssemblyBuild)
letnames the module. Its name is required, and a build's modules each have their own.pathis optional: the module's folder, from the project's top, inside the project. It'ssrc/<name>when it isn't written.- A program's modules are
IsolateAssemblyModule, and a library's areLibraryAssemblyModule.
A module takes nothing else.
| You write | The build says |
|---|---|
(+modules : IsolateAssemblyModule /) | a module is named by its tag: (+modules let main : IsolateAssemblyModule /) |
LibraryAssemblyModule in a program | `LibraryAssemblyModule` is not a module of IsolateAssemblyBuild, whose modules are IsolateAssemblyModule |
description={"…"} on a module | `description` is not an attribute of IsolateAssemblyModule that V0 reads: it reads `path` |
path={"../elsewhere"} on a module | `../elsewhere` leaves the project: a module's path is a folder inside it, as src/tools |
two modules named main | a module named `main` is written twice |
Dependencies
A dependency is a library the build links. Name only the libraries your code uses: a library brings the ones it needs
itself. let gives a dependency a name, which is optional; when it's written, each dependency's is its own.
Tools | Nylon | Add Nylon Library… writes a dependency for you. Libraries says how a build finds each one.
RepositoryDependency
A published library, by its coordinate. It's fetched once and kept, since a published version never changes.
(+dependencies let pi : RepositoryDependency coordinate={"com.grandtheorem:raspberry-pi:0.1.0"} /)
| Attribute | What it holds | |
|---|---|---|
coordinate | required | group:name:version |
GitDependency
A library in a Git repository, built from its own build file there. It's fetched and built on Reload.
(+dependencies let motors : GitDependency url={"https://github.com/me/motors.git"} tag={"v0.3.0"} /)
| Attribute | What it holds | |
|---|---|---|
url | required | https://… or git@host:path |
branch | optional | A branch, which moves: Reload fetches its newest commit |
tag | optional | A tag, which stays put |
commit | optional | A commit, which stays put |
path | optional | The folder in the repository that holds the library's build file, inside the repository. Its top when it isn't written |
Name at most one of branch, tag and commit. With none, the build uses the repository's default branch.
ProjectDependency
Another project on your computer, built every time this one is.
(+dependencies let sensors : ProjectDependency path={"../sensors"} /)
| Attribute | What it holds | |
|---|---|---|
path | required | The folder holding the library's build file, relative to this build file's folder, or absolute |
FileDependency
A library that's already built, read as it is.
(+dependencies let sensors : FileDependency path={"libs/sensors-0.1.0.nylib"} /)
| Attribute | What it holds | |
|---|---|---|
path | required | A .nylib file, relative to this build file's folder, or absolute |
Common mistakes
| You write | The build says |
|---|---|
coordinate={"com.grandtheorem:raspberry-pi"} | `com.grandtheorem:raspberry-pi` is not a coordinate: write group:artifact:version, as com.grandtheorem:raspberry-pi:0.1.0 |
a GitDependency with no url | GitDependency has no `url`: write url={"…"} |
url={"/Users/me/repo"} | `/Users/me/repo` is not a url V0 fetches: write https://… or git@host:path, and name a repository on this machine with a ProjectDependency |
path={"../x"} on a GitDependency | `../x` leaves the repository: a GitDependency's path is a folder inside it, or empty for its root |
both branch and tag | `tag` is a second way to name the commit: a GitDependency names it by at most one of branch, tag and commit |
tag={""} | `tag` is empty |
MavenDependency | `MavenDependency` is not a dependency V0 reads: GitDependency, ProjectDependency, FileDependency or RepositoryDependency |
two dependencies named pi | a dependency named `pi` is written twice |