SDK definition¶
Filename convention¶
When crafting and publishing a regular SDK,
the name of the SDK definition file must be sdkcraft.yaml or .sdkcraft.yaml.
When an SDK is built from the definition file,
the resulting package contains the SDK metadata in sdk.yaml.
The difference is that the sdkcraft.yaml file
is used at build time by SDKcraft,
while the sdk.yaml file
is used at runtime by Workshop.
Accordingly,
in-project SDKs are defined using sdk.yaml or meta/sdk.yaml
and stored in .workshop/<NAME>/.
Because these SDKs are defined in-place rather than built,
they don’t support SDKcraft build-time features,
like build-base, platforms or parts.
When sketching a local SDK,
the SDK definition file is also named sdk.yaml
and stored under $XDG_DATA_HOME/workshop/.
Workshop ignores other files in this directory,
but hooks can be defined inline.
Like in-project SDKs,
the sketch SDK doesn’t support SDKcraft build-time features.
Structure¶
The definition in the file must be written in
YAML
and include these top-level fields:
name, version, and platforms.
Other fields are optional.
Key |
Value |
Description |
|---|---|---|
|
string |
SDK’s name, used to reference it in the workshop definition. |
|
string |
SDK’s base image that provides the underlying OS capabilities. It can be SDKs with a |
|
string |
Base OS used to build the SDK. Required by SDKcraft if a |
|
string |
SDK’s arbitrary version; semantic versioning is recommended. Note Use quotes to avoid potential data type mismatches:
without them, |
|
string |
A short one-line summary of up to 79 characters. |
|
string |
A longer, more detailed description of the SDK, up to one hundred words. |
|
string |
Name of the software license under which the SDK is distributed. Note Make sure it matches the individual components of the SDK. |
|
object |
A collection of named platforms, describing where the SDK can be built and installed. See SDK platform for a detailed discussion. |
|
object |
See SDK parts for a detailed discussion. |
|
object |
See SDK plugs and slots for a detailed discussion. |
|
object |
See SDK plugs and slots for a detailed discussion. |
JSON Schema¶
The following
JSON Schema
formalizes the sdkcraft.yaml format:
SDKcraft definition schema
{
"$defs": {
"CameraPlug": {
"additionalProperties": false,
"description": "SDKcraft project camera plug definition.",
"properties": {
"interface": {
"const": "camera",
"title": "Interface",
"type": "string"
}
},
"required": [
"interface"
],
"title": "CameraPlug",
"type": "object"
},
"DesktopPlug": {
"additionalProperties": false,
"description": "SDKcraft project desktop plug definition.",
"properties": {
"interface": {
"const": "desktop",
"title": "Interface",
"type": "string"
}
},
"required": [
"interface"
],
"title": "DesktopPlug",
"type": "object"
},
"GPUPlug": {
"additionalProperties": false,
"description": "SDKcraft project GPU plug definition.",
"properties": {
"interface": {
"const": "gpu",
"title": "Interface",
"type": "string"
}
},
"required": [
"interface"
],
"title": "GPUPlug",
"type": "object"
},
"MountPlug": {
"additionalProperties": false,
"description": "SDKcraft project mount plug definition.",
"properties": {
"interface": {
"const": "mount",
"title": "Interface",
"type": "string"
},
"workshop-target": {
"title": "Workshop-Target",
"type": "string"
},
"uid": {
"exclusiveMaximum": 4294967295,
"minimum": 0,
"title": "Uid",
"type": "integer"
},
"gid": {
"exclusiveMaximum": 4294967295,
"minimum": 0,
"title": "Gid",
"type": "integer"
},
"mode": {
"maximum": 511,
"minimum": 0,
"title": "Mode",
"type": "integer"
},
"read-only": {
"default": false,
"title": "Read-Only",
"type": "boolean"
}
},
"required": [
"interface",
"workshop-target"
],
"title": "MountPlug",
"type": "object"
},
"MountSlot": {
"additionalProperties": false,
"description": "SDKcraft project mount slot definition.",
"properties": {
"interface": {
"const": "mount",
"title": "Interface",
"type": "string"
},
"workshop-source": {
"title": "Workshop-Source",
"type": "string"
}
},
"required": [
"interface",
"workshop-source"
],
"title": "MountSlot",
"type": "object"
},
"Platform": {
"additionalProperties": false,
"description": "A single platform entry in the platforms dictionary.\n\nThis model defines how a single value under the ``platforms`` key works for a project.",
"properties": {
"build-on": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array",
"uniqueItems": true
},
{
"type": "string"
}
],
"examples": [
"amd64",
[
"arm64",
"riscv64"
]
],
"minLength": 1,
"title": "Build-On"
},
"build-for": {
"anyOf": [
{
"items": {
"type": "string"
},
"maxItems": 1,
"minItems": 1,
"type": "array"
},
{
"type": "string"
}
],
"examples": [
"amd64",
[
"riscv64"
]
],
"title": "Build-For"
}
},
"required": [
"build-on",
"build-for"
],
"title": "Platform",
"type": "object"
},
"SSHPlug": {
"additionalProperties": false,
"description": "SDKcraft project SSH plug definition.",
"properties": {
"interface": {
"const": "ssh",
"title": "Interface",
"type": "string"
}
},
"required": [
"interface"
],
"title": "SSHPlug",
"type": "object"
},
"TunnelPlug": {
"additionalProperties": false,
"description": "SDKcraft project tunnel plug definition.",
"properties": {
"interface": {
"const": "tunnel",
"title": "Interface",
"type": "string"
},
"endpoint": {
"default": "",
"title": "Endpoint",
"type": "string"
}
},
"required": [
"interface"
],
"title": "TunnelPlug",
"type": "object"
},
"TunnelSlot": {
"additionalProperties": false,
"description": "SDKcraft project tunnel plug definition.",
"properties": {
"interface": {
"const": "tunnel",
"title": "Interface",
"type": "string"
},
"endpoint": {
"default": "",
"title": "Endpoint",
"type": "string"
}
},
"required": [
"interface"
],
"title": "TunnelSlot",
"type": "object"
}
},
"additionalProperties": false,
"description": "SDKcraft project definition.",
"properties": {
"name": {
"description": "The name of the project. This is used when uploading, publishing, or installing.\n\nThe project name must consist only of lower-case ASCII letters (``a``-``z``), numerals\n(``0``-``9``), and hyphens (``-``). It must contain at least one letter, not start or\nend with a hyphen, and not contain two consecutive hyphens. The maximum length is 40\ncharacters.\n",
"examples": [
"ubuntu",
"jupyterlab-desktop",
"lxd",
"digikam",
"kafka",
"mysql-router-k8s"
],
"maxLength": 40,
"minLength": 1,
"pattern": "(?!^(system|try-.*|project-.*|sketch)$)^([a-z0-9][a-z0-9-]?)*[a-z]+([a-z0-9-]?[a-z0-9])*$",
"title": "Project Name",
"type": "string"
},
"title": {
"anyOf": [
{
"description": "A human-readable title.",
"examples": [
"Ubuntu Linux",
"Jupyter Lab Desktop",
"LXD",
"DigiKam",
"Apache Kafka",
"MySQL Router K8s charm"
],
"maxLength": 40,
"minLength": 2,
"title": "Title",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Title"
},
"version": {
"anyOf": [
{
"description": "The version of the project, enclosed in quotation marks.",
"examples": [
"\"0.1\"",
"\"1.0.0\"",
"\"v1.0.0\"",
"\"24.04\""
],
"maxLength": 32,
"title": "version string",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Version"
},
"summary": {
"anyOf": [
{
"description": "A short description of the project.",
"examples": [
"Linux for Human Beings",
"The cross-platform desktop application for JupyterLab",
"Container and VM manager",
"Photo Management Program",
"Charm for routing MySQL databases in Kubernetes",
"An open-source event streaming platform for high-performance data pipelines"
],
"maxLength": 78,
"title": "Summary",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Summary"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The full description of the project.",
"title": "Description"
},
"base": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Base"
},
"build-base": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Build-Base"
},
"platforms": {
"additionalProperties": {
"$ref": "#/$defs/Platform"
},
"description": "Determines which architectures the project builds and runs on.",
"examples": [
"{amd64: {build-on: [amd64], build-for: [amd64]}, arm64: {build-on: [amd64, arm64], build-for: [arm64]}}"
],
"patternProperties": {
"(amd64|arm64|armhf|i386|ppc64el|riscv64|s390x)": {
"anyOf": [
{
"type": "null"
},
{
"properties": {
"build-on": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"type": "string"
},
"type": "array"
}
],
"title": "Build-On"
},
"build-for": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"type": "string"
},
"type": "array"
}
],
"title": "Build-For"
}
},
"required": [
"build-on"
],
"type": "object"
}
]
}
},
"title": "Platforms",
"type": "object"
},
"contact": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"type": "string"
},
"type": "array",
"uniqueItems": true
},
{
"type": "null"
}
],
"default": null,
"description": "The author's contact links and email addresses.",
"examples": [
"[contact@example.com, https://example.com/contact]"
],
"title": "Contact"
},
"issues": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"type": "string"
},
"type": "array",
"uniqueItems": true
},
{
"type": "null"
}
],
"default": null,
"description": "The links and email addresses for submitting issues, bugs, and feature requests.",
"examples": [
"[issues@example.com, https://example.com/issues]"
],
"title": "Issues"
},
"source-code": {
"anyOf": [
{
"format": "uri",
"minLength": 1,
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The links to the source code of the project.",
"examples": [
"[https://github.com/canonical/craft-application]"
],
"title": "Source-Code"
},
"license": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The project's license as an SPDX expression",
"examples": [
"GPL-3.0+",
"Apache-2.0"
],
"title": "License"
},
"adopt-info": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Selects a part to inherit metadata from.",
"examples": [
"foo-part"
],
"title": "Adopt-Info"
},
"parts": {
"additionalProperties": {
"additionalProperties": true,
"type": "object"
},
"default": {
"default-part": {
"plugin": "nil"
}
},
"title": "Parts",
"type": "object"
},
"package-repositories": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "The package repositories to use for build and stage packages.",
"examples": [
"[{type: apt, components: [main], suites: [xenial], key-id: 78E1918602959B9C59103100F1831DDAFC42E99D, url: http://ppa.launchpad.net/snappy-dev/snapcraft-daily/ubuntu}]"
],
"title": "Package-Repositories"
},
"plugs": {
"default": {},
"patternProperties": {
"^[a-z](-?[a-z0-9])*$": {
"discriminator": {
"mapping": {
"camera": "#/$defs/CameraPlug",
"desktop": "#/$defs/DesktopPlug",
"gpu": "#/$defs/GPUPlug",
"mount": "#/$defs/MountPlug",
"ssh": "#/$defs/SSHPlug",
"tunnel": "#/$defs/TunnelPlug"
},
"propertyName": "interface"
},
"oneOf": [
{
"$ref": "#/$defs/CameraPlug"
},
{
"$ref": "#/$defs/DesktopPlug"
},
{
"$ref": "#/$defs/GPUPlug"
},
{
"$ref": "#/$defs/MountPlug"
},
{
"$ref": "#/$defs/SSHPlug"
},
{
"$ref": "#/$defs/TunnelPlug"
}
]
}
},
"propertyNames": {
"description": "The name of the plug. This is used when connecting and disconnecting.\n\nThe plug name must consist only of lower-case ASCII letters (``a-z``), numerals\n(``0-9``), and hyphens (``-``). It must start with a letter, not end with a\nhyphen, and not contain two consecutive hyphens.\n",
"examples": [
"desktop",
"gpu",
"ssh-agent"
]
},
"title": "Plugs",
"type": "object"
},
"slots": {
"default": {},
"patternProperties": {
"^[a-z](-?[a-z0-9])*$": {
"discriminator": {
"mapping": {
"mount": "#/$defs/MountSlot",
"tunnel": "#/$defs/TunnelSlot"
},
"propertyName": "interface"
},
"oneOf": [
{
"$ref": "#/$defs/MountSlot"
},
{
"$ref": "#/$defs/TunnelSlot"
}
]
}
},
"propertyNames": {
"description": "The name of the slot. This is used when connecting and disconnecting.\n\nThe slot name must consist only of lower-case ASCII letters (``a-z``), numerals\n(``0-9``), and hyphens (``-``). It must start with a letter, not end with a\nhyphen, and not contain two consecutive hyphens.\n",
"examples": [
"dashboard",
"gdb",
"toolchain"
]
},
"title": "Slots",
"type": "object"
}
},
"required": [
"name",
"platforms"
],
"title": "Project",
"type": "object"
}
This one formalizes the sdk.yaml format:
SDK definition schema
{
"$defs": {
"CameraPlug": {
"additionalProperties": false,
"description": "SDKcraft project camera plug definition.",
"properties": {
"interface": {
"const": "camera",
"title": "Interface",
"type": "string"
}
},
"required": [
"interface"
],
"title": "CameraPlug",
"type": "object"
},
"DesktopPlug": {
"additionalProperties": false,
"description": "SDKcraft project desktop plug definition.",
"properties": {
"interface": {
"const": "desktop",
"title": "Interface",
"type": "string"
}
},
"required": [
"interface"
],
"title": "DesktopPlug",
"type": "object"
},
"GPUPlug": {
"additionalProperties": false,
"description": "SDKcraft project GPU plug definition.",
"properties": {
"interface": {
"const": "gpu",
"title": "Interface",
"type": "string"
}
},
"required": [
"interface"
],
"title": "GPUPlug",
"type": "object"
},
"MountPlug": {
"additionalProperties": false,
"description": "SDKcraft project mount plug definition.",
"properties": {
"interface": {
"const": "mount",
"title": "Interface",
"type": "string"
},
"workshop-target": {
"title": "Workshop-Target",
"type": "string"
},
"uid": {
"exclusiveMaximum": 4294967295,
"minimum": 0,
"title": "Uid",
"type": "integer"
},
"gid": {
"exclusiveMaximum": 4294967295,
"minimum": 0,
"title": "Gid",
"type": "integer"
},
"mode": {
"maximum": 511,
"minimum": 0,
"title": "Mode",
"type": "integer"
},
"read-only": {
"default": false,
"title": "Read-Only",
"type": "boolean"
}
},
"required": [
"interface",
"workshop-target"
],
"title": "MountPlug",
"type": "object"
},
"MountSlot": {
"additionalProperties": false,
"description": "SDKcraft project mount slot definition.",
"properties": {
"interface": {
"const": "mount",
"title": "Interface",
"type": "string"
},
"workshop-source": {
"title": "Workshop-Source",
"type": "string"
}
},
"required": [
"interface",
"workshop-source"
],
"title": "MountSlot",
"type": "object"
},
"SSHPlug": {
"additionalProperties": false,
"description": "SDKcraft project SSH plug definition.",
"properties": {
"interface": {
"const": "ssh",
"title": "Interface",
"type": "string"
}
},
"required": [
"interface"
],
"title": "SSHPlug",
"type": "object"
},
"TunnelPlug": {
"additionalProperties": false,
"description": "SDKcraft project tunnel plug definition.",
"properties": {
"interface": {
"const": "tunnel",
"title": "Interface",
"type": "string"
},
"endpoint": {
"default": "",
"title": "Endpoint",
"type": "string"
}
},
"required": [
"interface"
],
"title": "TunnelPlug",
"type": "object"
},
"TunnelSlot": {
"additionalProperties": false,
"description": "SDKcraft project tunnel plug definition.",
"properties": {
"interface": {
"const": "tunnel",
"title": "Interface",
"type": "string"
},
"endpoint": {
"default": "",
"title": "Endpoint",
"type": "string"
}
},
"required": [
"interface"
],
"title": "TunnelSlot",
"type": "object"
}
},
"additionalProperties": true,
"description": "Structure to hold output metadata.",
"properties": {
"name": {
"description": "The name of the project. This is used when uploading, publishing, or installing.\n\nThe project name must consist only of lower-case ASCII letters (``a``-``z``), numerals\n(``0``-``9``), and hyphens (``-``). It must contain at least one letter, not start or\nend with a hyphen, and not contain two consecutive hyphens. The maximum length is 40\ncharacters.\n",
"examples": [
"ubuntu",
"jupyterlab-desktop",
"lxd",
"digikam",
"kafka",
"mysql-router-k8s"
],
"maxLength": 40,
"minLength": 1,
"pattern": "(?!^(system|try-.*|project-.*|sketch)$)^([a-z0-9][a-z0-9-]?)*[a-z]+([a-z0-9-]?[a-z0-9])*$",
"title": "Project Name",
"type": "string"
},
"title": {
"anyOf": [
{
"description": "A human-readable title.",
"examples": [
"Ubuntu Linux",
"Jupyter Lab Desktop",
"LXD",
"DigiKam",
"Apache Kafka",
"MySQL Router K8s charm"
],
"maxLength": 40,
"minLength": 2,
"title": "Title",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Title"
},
"version": {
"anyOf": [
{
"description": "The version of the project, enclosed in quotation marks.",
"examples": [
"\"0.1\"",
"\"1.0.0\"",
"\"v1.0.0\"",
"\"24.04\""
],
"maxLength": 32,
"title": "version string",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Version"
},
"summary": {
"anyOf": [
{
"description": "A short description of the project.",
"examples": [
"Linux for Human Beings",
"The cross-platform desktop application for JupyterLab",
"Container and VM manager",
"Photo Management Program",
"Charm for routing MySQL databases in Kubernetes",
"An open-source event streaming platform for high-performance data pipelines"
],
"maxLength": 78,
"title": "Summary",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Summary"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Description"
},
"base": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Base"
},
"architecture": {
"title": "Architecture",
"type": "string"
},
"contact": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"type": "string"
},
"type": "array",
"uniqueItems": true
},
{
"type": "null"
}
],
"default": null,
"title": "Contact"
},
"issues": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"type": "string"
},
"type": "array",
"uniqueItems": true
},
{
"type": "null"
}
],
"default": null,
"title": "Issues"
},
"source-code": {
"anyOf": [
{
"format": "uri",
"minLength": 1,
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Source-Code"
},
"license": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "License"
},
"plugs": {
"default": {},
"patternProperties": {
"^[a-z](-?[a-z0-9])*$": {
"discriminator": {
"mapping": {
"camera": "#/$defs/CameraPlug",
"desktop": "#/$defs/DesktopPlug",
"gpu": "#/$defs/GPUPlug",
"mount": "#/$defs/MountPlug",
"ssh": "#/$defs/SSHPlug",
"tunnel": "#/$defs/TunnelPlug"
},
"propertyName": "interface"
},
"oneOf": [
{
"$ref": "#/$defs/CameraPlug"
},
{
"$ref": "#/$defs/DesktopPlug"
},
{
"$ref": "#/$defs/GPUPlug"
},
{
"$ref": "#/$defs/MountPlug"
},
{
"$ref": "#/$defs/SSHPlug"
},
{
"$ref": "#/$defs/TunnelPlug"
}
]
}
},
"propertyNames": {
"description": "The name of the plug. This is used when connecting and disconnecting.\n\nThe plug name must consist only of lower-case ASCII letters (``a-z``), numerals\n(``0-9``), and hyphens (``-``). It must start with a letter, not end with a\nhyphen, and not contain two consecutive hyphens.\n",
"examples": [
"desktop",
"gpu",
"ssh-agent"
]
},
"title": "Plugs",
"type": "object"
},
"slots": {
"default": {},
"patternProperties": {
"^[a-z](-?[a-z0-9])*$": {
"discriminator": {
"mapping": {
"mount": "#/$defs/MountSlot",
"tunnel": "#/$defs/TunnelSlot"
},
"propertyName": "interface"
},
"oneOf": [
{
"$ref": "#/$defs/MountSlot"
},
{
"$ref": "#/$defs/TunnelSlot"
}
]
}
},
"propertyNames": {
"description": "The name of the slot. This is used when connecting and disconnecting.\n\nThe slot name must consist only of lower-case ASCII letters (``a-z``), numerals\n(``0-9``), and hyphens (``-``). It must start with a letter, not end with a\nhyphen, and not contain two consecutive hyphens.\n",
"examples": [
"dashboard",
"gdb",
"toolchain"
]
},
"title": "Slots",
"type": "object"
},
"sdkcraft-started-at": {
"title": "Sdkcraft-Started-At",
"type": "string"
}
},
"required": [
"name",
"architecture",
"sdkcraft-started-at"
],
"title": "Metadata",
"type": "object"
}
Examples¶
This is a real-world example of an SDK definition file for a Go development environment. It involves a nontrivial layout of build and target architectures, and also uses the parts mechanism:
name: go
build-base: ubuntu@24.04
title: Go SDK
summary: The Go programming language
description: |
Go is an open source programming language that enables the production of simple, efficient and reliable software at scale.
version: "1.25.1"
license: LGPL-2.1
platforms:
amd64:
build-on: [amd64]
build-for: [amd64]
arm64:
build-on: [amd64]
build-for: [arm64]
riscv64:
build-on: [amd64]
build-for: [riscv64]
plugs:
mod-cache:
interface: mount
workshop-target: /home/workshop/go/pkg/mod
parts:
go:
plugin: dump
source: https://go.dev/dl/go$CRAFT_PROJECT_VERSION.linux-$CRAFT_ARCH_BUILD_FOR.tar.gz
source-type: tar
This YAML file defines an SDK that supports multiple bases:
name: multibase
version: '0.1'
summary: Multibase SDK
description: |
This is my multibase SDK description.
license: GPL-3.0
platforms:
noble:
build-on: ['ubuntu@24.04:amd64', 'ubuntu@24.04:arm64']
build-for: 'ubuntu@24.04:all'
jammy:
build-on: ['ubuntu@22.04:amd64', 'ubuntu@22.04:arm64']
build-for: 'ubuntu@22.04:all'
This is a more elaborate example of an SDK that uses several plugs:
name: ros2
title: The ROS 2 SDK
base: ubuntu@24.04
version: "0.1"
summary: The strictly necessary ROS 2 development environment for your project.
description: |
The ROS 2 SDK creates a minimum viable development environment
for your ROS 2 project.
It sets up a bare-bones ROS 2 workspace
before installing all of the dependencies
for the ROS 2 project mounted by workshop.
A developer can thus connect to the workshop
to immediately build the project.
license: LGPL-2.1
platforms:
amd64:
arm64:
plugs:
ros-cache:
interface: mount
workshop-target: /home/workshop/.ros
colcon-artifacts:
interface: mount
workshop-target: /home/workshop/colcon
gpu:
interface: gpu
See also¶
Reference:
Tutorial: