title = "Building Spin Application Code" template = "main" date = "2023-11-04T00:00:01Z" enable_shortcodes = true [extra] url = "https://github.com/spinframework/spin-docs/blob/main/content/v4/build.md"
- Setting Up for
spin build - Running
spin build - Running the Application After Build
- Overriding the Working Directory
- Building With Profiles
- Next Steps
A Spin application is made up of one or more components. Components are binary Wasm modules; building refers to the process of converting your source code into those modules.
Even languages that don't require a compile step when used 'natively' may still require a build step to adapt them to work as Wasm modules.
Because most compilers don't target Wasm by default, building Wasm modules often requires special command options, which you may not have at your fingertips. What's more, when developing a multi-component application, you may need to issue such commands for several components on each iteration. Doing this manually can be tedious and error-prone.
To make the build process easier, the spin build command allows you to build all the components in one command.
You don't have to use
spin buildto manage your builds. If you prefer to use a Makefile or other build system, you can!spin buildis just there to provide an 'out of the box' solution.
To use spin build, each component that you want to build must specify the command used to build it in spin.toml, as part of its component.(name).build table:
[component.hello]
# This is the section you need for `spin build`
[component.hello.build]
command = "npm run build"If you generated the component from a Spin Framework project-supplied template, the build section should be set up correctly for you. You don't need to change or add anything.
Different components may be built from different languages, and so each component can have its own build command. In addition, some components may be precompiled into Wasm modules, and don't need a build command at all. If a component doesn't have a build command,
spin buildjust skips it.
{{ tabs "sdk-type" }}
{{ startTab "Rust"}}
For Rust applications, you must have the wasm32-wasip2 target installed:
$ rustup target add wasm32-wasip2The build command typically runs cargo build with the wasm32-wasip2 target and the --release option:
[component.hello.build]
command = "cargo build --target wasm32-wasip2 --release"{{ blockEnd }}
{{ startTab "TypeScript" }}
For JavaScript and TypeScript applications, you must have Node.js.
It's normally convenient to put the detailed build instructions in package.json. The build script looks like:
{
"scripts": {
"build": "node build.mjs && mkdirp dist && j2w -i build/bundle.js --initLocation http://hello.localhost -o dist/hello.wasm"
}
}The build command can then call the NPM script:
[component.hello.build]
command = "npm run build"{{ blockEnd }}
{{ startTab "Python" }}
Ensure that you have Python 3.10 or later installed on your system. You can check your Python version by running:
python3 --versionIf you do not have Python 3.10 or later, you can install it by following the instructions here.
For Python applications, you must have componentize-py installed:
$ pip3 install componentize-pyThe build command then calls componentize-py on your application file:
[component.hello.build]
command = "componentize-py -w spin-http componentize app -o app.wasm"{{ blockEnd }}
{{ startTab "Go" }}
The build command calls go tool to run the componentize-go tool with appropriate options:
[component.hello.build]
command = "go tool componentize-go build"{{ blockEnd }}
{{ blockEnd }}
The output of the build command must match the component's
sourcepath. If you change thebuildorsourceattributes, make sure to keep them in sync.
Once the build commands are set up, running spin build will execute, sequentially, each build command:
$ spin build
Building component hello with `cargo build --target wasm32-wasip2 --release`
Updating crates.io index
Updating git repository `https://github.com/spinframework/spin`
//--snip--
Compiling hello v0.1.0 (hello)
Finished release [optimized] target(s) in 39.05s
Finished building all Spin componentsIf your build doesn't work, and your source code looks okay, you can run
spin doctorto check for problems with your Spin configuration and tools.
You can pass the --up option to spin build to start the application as soon as the build process completes successfully.
This is equivalent to running spin up immediately after spin build. It accepts all the same flags and options that up does. See Running Applications for details.
By default, the command to build a component is executed in the directory containing the spin.toml file. If a component's entire build source is under a subdirectory, it is often more convenient to build in that subdirectory rather than try to pass the path to the build command. You can do this by setting the workdir option in the component.(id).build table.
For example, consider this Rust component located in subdirectory deep:
.
├── deep
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
└── spin.tomlTo have the Rust build command run in directory deep, we can set the component's workdir:
[component.deep.build]
# `command` is the normal build command for this language
command = "cargo build --target wasm32-wasip2 --release"
# This tells Spin to run it in the directory of the build file (in this case Cargo.toml)
workdir = "deep"
workdirmust be a relative path, and it is relative to the directory containingspin.toml. Specifying an absolute path leads to an error.
A component can define build profiles, which override certain component settings to allow for different usages. For example, a component might define a debug profile, which compiles the binary with debugging information. A profile can also override environment variables and dependencies.
To define a profile, create a profile.<name> entry in the component TOML. For example:
[component.example]
source = "./out/release/example.wasm"
[component.example.build]
command = "make release"
[component.example.profile.debug]
source = "./out/debug/example.wasm"
environment = { TRACE_LEVEL = "full" }
[component.example.profile.debug.build]
command = "make debug"To use a build profile, pass the --profile <name> flag to the Spin command you're running. For example, spin build --profile debug or spin up --profile debug.
When you have build profiles in play, you run the risk of accidentally running
spin buildwith a profile and then runningspin uporspin registry pushwithout a profile, not realising that you are running or pushing the default profile rather than the one you just built! Spin will warn you if you do this. But a safer technique is to provide--buildas part of theuporregistrypush command, e.g.spin up --profile debug --build,spin registry push --profile publish --build. This guarantees that the right profile has been freshly built. You can set theSPIN_ALWAYS_BUILDenvironment variable to tell Spin to always use the--buildoption.
If a component doesn't define a profile (or doesn't override a particular field in its profile), Spin will fall back to the 'base' value. You only need to override the specific components and fields where the profile differs from the base. For example:
[component.example1]
source = "./out/example1.wasm" # source will be the same with or without `--profile debug`
[component.example1.build]
command = "make release1"
[component.example1.profile.debug.build]
command = "make debug1"
[component.example2] # everything will be the same with our without `--profile debug`
source = "./out/example2.wasm"
[component.example2.build]
command = "make example2"