Skip to main content

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.

build.markup.code
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.build is 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 writeThe 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 filea markup file holds one top-level tag, and none is written
two builds in one filea 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.

  • IsolateAssemblyBuild builds a program, which runs as an isolate: out/<name>-<version>.nylon.
  • LibraryAssemblyBuild builds a library, for other projects to use: out/<name>-<version>.nylib.
build.markup.code
(LibraryAssemblyBuild
name={"sensors"}
group={"com.me"}
version={"1.2.0-rc.1"}
/LibraryAssemblyBuild)
AttributeWhat it holds
namerequiredThe project's name, such as robot.
grouprequiredWho it's from, such as com.me.
versionrequiredA version in three numbers, major.minor.patch, such as 0.1.0.
descriptionoptionalA 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 name or group is 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 in 1.2.0-rc.1. A version takes no + build metadata.
You writeThe build says
no nameIsolateAssemblyBuild 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 writeThe 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.

build.markup.code
(IsolateAssemblyBuild
name={"robot"}
group={"com.me"}
version={"0.1.0"}

(+modules let main : IsolateAssemblyModule /)
(+modules let tools : IsolateAssemblyModule path={"src/tools"} /)
/IsolateAssemblyBuild)
  • let names the module. Its name is required, and a build's modules each have their own.
  • path is optional: the module's folder, from the project's top, inside the project. It's src/<name> when it isn't written.
  • A program's modules are IsolateAssemblyModule, and a library's are LibraryAssemblyModule.

A module takes nothing else.

You writeThe 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 maina 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.

build.markup.code
(+dependencies let pi : RepositoryDependency coordinate={"com.grandtheorem:raspberry-pi:0.1.0"} /)
AttributeWhat it holds
coordinaterequiredgroup:name:version

GitDependency​

A library in a Git repository, built from its own build file there. It's fetched and built on Reload.

build.markup.code
(+dependencies let motors : GitDependency url={"https://github.com/me/motors.git"} tag={"v0.3.0"} /)
AttributeWhat it holds
urlrequiredhttps://… or git@host:path
branchoptionalA branch, which moves: Reload fetches its newest commit
tagoptionalA tag, which stays put
commitoptionalA commit, which stays put
pathoptionalThe 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.

build.markup.code
(+dependencies let sensors : ProjectDependency path={"../sensors"} /)
AttributeWhat it holds
pathrequiredThe 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.

build.markup.code
(+dependencies let sensors : FileDependency path={"libs/sensors-0.1.0.nylib"} /)
AttributeWhat it holds
pathrequiredA .nylib file, relative to this build file's folder, or absolute

Common mistakes​

You writeThe 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 urlGitDependency 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 pia dependency named `pi` is written twice