2020-06-19 18:44:56 +03:00
|
|
|
---
|
|
|
|
layout: developer-doc
|
|
|
|
title: Build Tools
|
|
|
|
category: infrastructure
|
|
|
|
tags: [infrastructure, build]
|
|
|
|
order: 1
|
|
|
|
---
|
|
|
|
|
|
|
|
# Build Tools
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-06-19 18:44:56 +03:00
|
|
|
The project is built using the Scala Build Tool which manages dependencies
|
|
|
|
between the projects as well as external dependencies and allows for incremental
|
|
|
|
compilation. The build configuration is defined in
|
|
|
|
[`build.sbt`](../../build.sbt).
|
|
|
|
|
|
|
|
<!-- MarkdownTOC levels="2,3" autolink="true" -->
|
|
|
|
|
2020-07-01 14:21:13 +03:00
|
|
|
- [Incremental Compilation](#incremental-compilation)
|
|
|
|
- [Bootstrapping](#bootstrapping)
|
|
|
|
- [Compile Hooks](#compile-hooks)
|
|
|
|
- [Helper Tasks](#helper-tasks)
|
|
|
|
- [Graal and Flatc Version Check](#graal-and-flatc-version-check)
|
2020-06-19 18:44:56 +03:00
|
|
|
- [Benchmarks](#benchmarks)
|
2020-07-01 14:21:13 +03:00
|
|
|
- [Build Information](#build-information)
|
|
|
|
- [Instruments Generation](#instruments-generation)
|
|
|
|
- [Flatbuffers Generation](#flatbuffers-generation)
|
|
|
|
- [Ensuring JARs Were Loaded](#ensuring-jars-were-loaded)
|
|
|
|
- [Debugging Command](#debugging-command)
|
2020-08-10 13:14:39 +03:00
|
|
|
- [Recompile Parser](#recompile-parser)
|
|
|
|
- [Native Image](#native-image)
|
2020-06-19 18:44:56 +03:00
|
|
|
|
|
|
|
<!-- /MarkdownTOC -->
|
|
|
|
|
2020-07-01 14:21:13 +03:00
|
|
|
## Incremental Compilation
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-06-19 18:44:56 +03:00
|
|
|
To help wit build times, we do not want to rebuild the whole project with every
|
|
|
|
change, but to only recompile the files that have been affected by the change.
|
|
|
|
This is handled by sbt which under the hood uses
|
|
|
|
[zinc](https://github.com/sbt/zinc) (the incremental compiler for Scala). zinc
|
|
|
|
analyses the compiled files and detects dependencies between them to determine
|
|
|
|
which files have to be recompiled when something has been changed.
|
|
|
|
|
2020-07-01 14:21:13 +03:00
|
|
|
## Compile Hooks
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-01 14:21:13 +03:00
|
|
|
There are some invariants that are specific to our project, so they are not
|
|
|
|
tracked by sbt, but we want to ensure that they hold to avoid cryptic errors at
|
|
|
|
compilation or runtime.
|
|
|
|
|
|
|
|
To check some state before compilation, we add our tasks as dependencies of
|
|
|
|
`Compile / compile / compileInputs` by adding the following to the settings of a
|
|
|
|
particular project.
|
|
|
|
|
|
|
|
```
|
|
|
|
Compile / compile / compileInputs := (Compile / compile / compileInputs)
|
|
|
|
.dependsOn(preCompileHookTask)
|
|
|
|
.value
|
|
|
|
```
|
|
|
|
|
|
|
|
Tasks that should be run before compilation, should be attached to the
|
|
|
|
`compileInputs` task. That is because the actual compilation process is ran in
|
|
|
|
the task `compileIncremental`. `Compile / compile` depends on
|
|
|
|
`compileIncremental` but if we add our dependency to `Compile / compile`, it is
|
|
|
|
considered as independent with `compileIncremental`, so sbt may schedule it to
|
|
|
|
run in parallel with the actual compilation process. To guarantee that our
|
2020-07-21 15:59:40 +03:00
|
|
|
pre-flight checks complete _before_ the actual compilation, we add them as a
|
|
|
|
dependency of `compileInputs` which runs _strictly before_ actual compilation.
|
2020-07-01 14:21:13 +03:00
|
|
|
|
2020-07-21 15:59:40 +03:00
|
|
|
To check some invariants _after_ compilation, we can replace the original
|
2020-07-01 14:21:13 +03:00
|
|
|
`Compile / compile` task with a custom one which does its post-compile checks
|
2022-06-13 17:09:08 +03:00
|
|
|
and returns the result of `(Compile / compile).value`.
|
2020-07-01 14:21:13 +03:00
|
|
|
|
|
|
|
## Helper Tasks
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-06-19 18:44:56 +03:00
|
|
|
There are additional tasks defined in the [`project`](../../project) directory.
|
|
|
|
They are used by [`build.sbt`](../../build.sbt) to provide some additional
|
|
|
|
functionality.
|
|
|
|
|
2020-07-01 14:21:13 +03:00
|
|
|
### Graal and Flatc Version Check
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-01 14:21:13 +03:00
|
|
|
[`EnvironmentCheck`](../../project/EnvironmentCheck.scala) defines a helper
|
|
|
|
function that can be attached to the default `Global / onLoad` state transition
|
|
|
|
to run a version check when loading the sbt project. This helper function
|
|
|
|
compares the version of JVM running sbt with GraalVM version defined in
|
|
|
|
[`build.sbt`](../../build.sbt) and the version of `flatc` installed in the
|
|
|
|
system with the Flatbuffers library version defined in
|
|
|
|
[`build.sbt`](../../build.sbt). If the versions do not match it reports an error
|
|
|
|
telling the user to change to the correct version.
|
|
|
|
|
2020-06-19 18:44:56 +03:00
|
|
|
### Benchmarks
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-06-19 18:44:56 +03:00
|
|
|
[`BenchTasks`](../../project/BenchTasks.scala) defines configuration keys for
|
|
|
|
benchmarking.
|
|
|
|
|
2020-07-01 14:21:13 +03:00
|
|
|
### Build Information
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-06-19 18:44:56 +03:00
|
|
|
[`BenchTasks`](../../project/BuildInfo.scala) records version information
|
|
|
|
including what git commit has been used for compiling the project. This
|
|
|
|
information is used by `enso --version`.
|
|
|
|
|
2020-07-01 14:21:13 +03:00
|
|
|
### Instruments Generation
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-06-19 18:44:56 +03:00
|
|
|
Truffle annotation processor generates a file that registers instruments
|
|
|
|
provided by the runtime. Unfortunately, with incremental compilation, only the
|
|
|
|
changed instruments are recompiled and the annotation processor does not detect
|
2022-06-13 17:09:08 +03:00
|
|
|
this, so un-changed instruments get overwritten.
|
|
|
|
|
|
|
|
In the past we had a pre-compile task (see
|
|
|
|
[FixInstrumentsGeneration](https://github.com/enso-org/enso/blob/8ec2a92b770dea35e47fa9287dbdd1363aabc3c0/project/FixInstrumentsGeneration.scala))
|
|
|
|
that detected changes to instruments and if only one of them was to be
|
|
|
|
recompiled, it forced recompilation of all of them, to ensure consistency. This
|
|
|
|
workaround helped to avoid later runtime issues but sometimes triggered a
|
|
|
|
cascade of recompilations, which weren't clear to the end user. Instead, to
|
|
|
|
avoid overwriting entries in META-INF files, individual services were moved to
|
|
|
|
separate subprojects and during assembly of uber jar we concatenate meta files
|
|
|
|
with the same service name.
|
2020-06-19 18:44:56 +03:00
|
|
|
|
2020-07-01 14:21:13 +03:00
|
|
|
### Flatbuffers Generation
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-06-19 18:44:56 +03:00
|
|
|
[`GenerateFlatbuffers`](../../project/GenerateFlatbuffers.scala) defines the
|
|
|
|
task that runs the Flatbuffer compiler `flatc` whenever the flatbuffer
|
|
|
|
definitions have been changed. It also makes sure that `flatc` is available on
|
|
|
|
PATH and that its version matches the version of the library. It reports any
|
|
|
|
errors.
|
|
|
|
|
2020-07-01 14:21:13 +03:00
|
|
|
### Debugging Command
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-06-19 18:44:56 +03:00
|
|
|
[`WithDebugCommand`](../../project/WithDebugCommand.scala) defines a command
|
2020-07-01 14:21:13 +03:00
|
|
|
that allows to run a task with additional JVM-level flags.
|
|
|
|
|
|
|
|
### Recompile Parser
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-07-01 14:21:13 +03:00
|
|
|
[`RecompileParser`](../../project/RecompileParser.scala) defines a task that can
|
|
|
|
be attached to the `compile` task in configurations of the `syntax` project.
|
|
|
|
This task ensures that the `syntax` project is recompiled whenever
|
2020-07-10 13:57:42 +03:00
|
|
|
`syntax-definition` changes.
|
|
|
|
|
|
|
|
## Native Image
|
2020-07-21 15:59:40 +03:00
|
|
|
|
2020-08-10 13:14:39 +03:00
|
|
|
[`NativeImage`](../../project/NativeImage.scala) task is described at
|
|
|
|
[Native Image](native-image.md).
|