183 lines
6.1 KiB
Markdown
183 lines
6.1 KiB
Markdown
|
|
---
|
||
|
|
title: Build System
|
||
|
|
description: Project detection, cross-compilation, code signing, and .core/build.yaml configuration.
|
||
|
|
---
|
||
|
|
|
||
|
|
# Build System
|
||
|
|
|
||
|
|
The `build/` package provides automatic project type detection, cross-compilation for multiple OS/architecture targets, artefact archiving with checksums, and code signing. Configuration lives in `.core/build.yaml` at the project root.
|
||
|
|
|
||
|
|
## How it works
|
||
|
|
|
||
|
|
1. **Detect** — Probes the project directory for marker files to determine the project type.
|
||
|
|
2. **Build** — Runs the appropriate builder plugin for each configured target (OS/arch pair).
|
||
|
|
3. **Archive** — Packages build outputs into compressed archives with SHA-256 checksums.
|
||
|
|
4. **Sign** — Optionally signs binaries before archiving (macOS codesign, GPG, or Windows signtool).
|
||
|
|
|
||
|
|
Run with:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
core build # Build for configured targets
|
||
|
|
core build --ci # All targets, JSON output for CI pipelines
|
||
|
|
```
|
||
|
|
|
||
|
|
## Project detection
|
||
|
|
|
||
|
|
`discovery.go` probes marker files in priority order. The first match wins:
|
||
|
|
|
||
|
|
| Marker file | Detected type | Builder |
|
||
|
|
|-------------|--------------|---------|
|
||
|
|
| `wails.json` | `wails` | Wails v3 desktop app |
|
||
|
|
| `go.mod` | `go` | Standard Go binary |
|
||
|
|
| `package.json` | `node` | Node.js (stub) |
|
||
|
|
| `composer.json` | `php` | PHP (stub) |
|
||
|
|
| `CMakeLists.txt` | `cpp` | CMake C++ |
|
||
|
|
| `Dockerfile` | `docker` | Docker buildx |
|
||
|
|
| `*.yml` (LinuxKit pattern) | `linuxkit` | LinuxKit VM image |
|
||
|
|
| `Taskfile.yml` | `taskfile` | Task CLI delegation |
|
||
|
|
|
||
|
|
## Builder interface
|
||
|
|
|
||
|
|
Each builder implements three methods:
|
||
|
|
|
||
|
|
```go
|
||
|
|
type Builder interface {
|
||
|
|
Name() string
|
||
|
|
Detect(fs io.Medium, dir string) (bool, error)
|
||
|
|
Build(ctx context.Context, cfg *Config, targets []Target) ([]Artifact, error)
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
- `Detect` checks whether the builder should handle a given directory.
|
||
|
|
- `Build` produces `[]Artifact`, where each artefact has a file `Path`, `OS`, `Arch`, and a SHA-256 `Checksum`.
|
||
|
|
|
||
|
|
## Builders
|
||
|
|
|
||
|
|
### Go builder (`go.go`)
|
||
|
|
|
||
|
|
Runs `go build` with ldflags injection and cross-compilation via `GOOS`/`GOARCH` environment variables. Reads the entry point from `build.yaml`'s `project.main` field.
|
||
|
|
|
||
|
|
### Wails builder (`wails.go`)
|
||
|
|
|
||
|
|
Builds Wails v3 desktop applications with platform-specific packaging. Uses `wails.json` for application metadata.
|
||
|
|
|
||
|
|
### Docker builder (`docker.go`)
|
||
|
|
|
||
|
|
Runs `docker buildx build` with optional multi-platform support and registry push.
|
||
|
|
|
||
|
|
### C++ builder (`cpp.go`)
|
||
|
|
|
||
|
|
Runs CMake configure and build in a temporary directory. Requires `CMakeLists.txt`.
|
||
|
|
|
||
|
|
### LinuxKit builder (`linuxkit.go`)
|
||
|
|
|
||
|
|
Produces multi-format VM images from LinuxKit YAML configurations. Output formats: ISO, qcow2, raw, VMDK.
|
||
|
|
|
||
|
|
### Taskfile builder (`taskfile.go`)
|
||
|
|
|
||
|
|
Delegates to the `task` CLI, mapping build targets to Taskfile tasks. Used for projects that have not yet migrated to native builders.
|
||
|
|
|
||
|
|
### Node and PHP stubs
|
||
|
|
|
||
|
|
Stub builders for Node.js and PHP projects. Node runs `npm run build`; PHP wraps Docker builds. Both are minimal and intended for extension.
|
||
|
|
|
||
|
|
## Artefacts and checksums
|
||
|
|
|
||
|
|
Each builder produces `[]Artifact`:
|
||
|
|
|
||
|
|
```go
|
||
|
|
type Artifact struct {
|
||
|
|
Path string // File path of the built artefact
|
||
|
|
OS string // Target operating system
|
||
|
|
Arch string // Target architecture
|
||
|
|
Checksum string // SHA-256 hash
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Checksums are computed automatically and written to `dist/*.sha256` files.
|
||
|
|
|
||
|
|
## Archive formats
|
||
|
|
|
||
|
|
`archive.go` packages build outputs into compressed archives. Supported formats:
|
||
|
|
|
||
|
|
- `tar.gz` — default for Linux/macOS
|
||
|
|
- `tar.xz` — smaller archives (uses Borg's xz compression)
|
||
|
|
- `zip` — default for Windows
|
||
|
|
|
||
|
|
## Code signing
|
||
|
|
|
||
|
|
The `signing/` sub-package implements a `Signer` interface with three backends:
|
||
|
|
|
||
|
|
| Signer | Platform | Tool | Key source |
|
||
|
|
|--------|----------|------|-----------|
|
||
|
|
| macOS | darwin | `codesign` | Keychain identity |
|
||
|
|
| GPG | any | `gpg --detach-sign` | GPG key ID |
|
||
|
|
| Windows | windows | `signtool` | Certificate store |
|
||
|
|
|
||
|
|
Each signer checks `Available()` at runtime to verify the signing tool exists. Signing runs after compilation, before archiving.
|
||
|
|
|
||
|
|
## .core/build.yaml reference
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
version: 1
|
||
|
|
|
||
|
|
project:
|
||
|
|
name: my-app # Project name (used in archive filenames)
|
||
|
|
description: My application
|
||
|
|
main: ./cmd/my-app # Go entry point (go/wails only)
|
||
|
|
binary: my-app # Output binary name
|
||
|
|
|
||
|
|
build:
|
||
|
|
cgo: false # Enable CGO (default: false)
|
||
|
|
flags:
|
||
|
|
- -trimpath # Go build flags
|
||
|
|
ldflags:
|
||
|
|
- -s # Strip debug info
|
||
|
|
- -w # Strip DWARF
|
||
|
|
|
||
|
|
targets: # Cross-compilation targets
|
||
|
|
- os: linux
|
||
|
|
arch: amd64
|
||
|
|
- os: linux
|
||
|
|
arch: arm64
|
||
|
|
- os: darwin
|
||
|
|
arch: arm64
|
||
|
|
- os: windows
|
||
|
|
arch: amd64
|
||
|
|
```
|
||
|
|
|
||
|
|
### Field reference
|
||
|
|
|
||
|
|
| Field | Type | Description |
|
||
|
|
|-------|------|-------------|
|
||
|
|
| `version` | `int` | Config schema version (always `1`) |
|
||
|
|
| `project.name` | `string` | Project name, used in archive filenames |
|
||
|
|
| `project.description` | `string` | Human-readable description |
|
||
|
|
| `project.main` | `string` | Go entry point path (e.g. `./cmd/myapp`) |
|
||
|
|
| `project.binary` | `string` | Output binary filename |
|
||
|
|
| `build.cgo` | `bool` | Whether to enable CGO (default `false`) |
|
||
|
|
| `build.flags` | `[]string` | Go build flags (e.g. `-trimpath`) |
|
||
|
|
| `build.ldflags` | `[]string` | Linker flags (e.g. `-s -w`) |
|
||
|
|
| `targets` | `[]Target` | List of OS/arch pairs to compile for |
|
||
|
|
| `targets[].os` | `string` | Target OS (`linux`, `darwin`, `windows`) |
|
||
|
|
| `targets[].arch` | `string` | Target architecture (`amd64`, `arm64`) |
|
||
|
|
|
||
|
|
### Generated configuration
|
||
|
|
|
||
|
|
Running `core setup repo` in a git repository auto-generates `.core/build.yaml` based on detected project type:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
core setup repo # Generates .core/build.yaml, release.yaml, test.yaml
|
||
|
|
core setup repo --dry-run # Preview without writing files
|
||
|
|
```
|
||
|
|
|
||
|
|
## Adding a new builder
|
||
|
|
|
||
|
|
1. Create `build/builders/mylang.go`.
|
||
|
|
2. Implement the `Builder` interface:
|
||
|
|
- `Name()` returns a human-readable name.
|
||
|
|
- `Detect(fs, dir)` checks for a marker file (e.g. `myconfig.toml`).
|
||
|
|
- `Build(ctx, cfg, targets)` produces artefacts.
|
||
|
|
3. Register the builder in `build/buildcmd/`.
|
||
|
|
4. Write tests verifying `Detect` (marker present/absent) and `Build` (at minimum with a mock `io.Medium`).
|