Rollup merge of #100927 - andrewpollack:fuchsia-docs-rustup, r=tmandry
Adding new Fuchsia rustup docs... reworking walkthrough Docs improvements: * Adding new `rustup` target add for Fuchsia targets * Reworking walkthrough to show directory building as it happens * Reworking walkthrough to use `hello_fuchsia_pkg/` directory cc. `@djkoloski`
This commit is contained in:
commit
3de558dd2d
1 changed files with 438 additions and 109 deletions
|
@ -5,14 +5,10 @@
|
||||||
[Fuchsia] is a modern open source operating system that's simple, secure,
|
[Fuchsia] is a modern open source operating system that's simple, secure,
|
||||||
updatable, and performant.
|
updatable, and performant.
|
||||||
|
|
||||||
[Fuchsia]: https://fuchsia.dev/
|
|
||||||
|
|
||||||
## Target maintainers
|
## Target maintainers
|
||||||
|
|
||||||
The [Fuchsia team]:
|
The [Fuchsia team]:
|
||||||
|
|
||||||
[Fuchsia team]: https://team-api.infra.rust-lang.org/v1/teams/fuchsia.json
|
|
||||||
|
|
||||||
- Tyler Mandry ([@tmandry](https://github.com/tmandry))
|
- Tyler Mandry ([@tmandry](https://github.com/tmandry))
|
||||||
- Dan Johnson ([@computerdruid](https://github.com/computerdruid))
|
- Dan Johnson ([@computerdruid](https://github.com/computerdruid))
|
||||||
- David Koloski ([@djkoloski](https://github.com/djkoloski))
|
- David Koloski ([@djkoloski](https://github.com/djkoloski))
|
||||||
|
@ -24,27 +20,162 @@ the members reported by the API. The API should be considered to be
|
||||||
authoritative if this occurs. Instead of pinging individual members, use
|
authoritative if this occurs. Instead of pinging individual members, use
|
||||||
`@rustbot ping fuchsia` to contact the team on GitHub.
|
`@rustbot ping fuchsia` to contact the team on GitHub.
|
||||||
|
|
||||||
|
## Table of contents
|
||||||
|
|
||||||
|
1. [Requirements](#requirements)
|
||||||
|
1. [Walkthrough structure](#walkthrough-structure)
|
||||||
|
1. [Compiling a Rust binary targeting Fuchsia](#compiling-a-rust-binary-targeting-fuchsia)
|
||||||
|
1. [Targeting Fuchsia with rustup and cargo](#targeting-fuchsia-with-rustup-and-cargo)
|
||||||
|
1. [Targeting Fuchsia with a compiler built from source](#targeting-fuchsia-with-a-compiler-built-from-source)
|
||||||
|
1. [Creating a Fuchsia package](#creating-a-fuchsia-package)
|
||||||
|
1. [Creating a Fuchsia component](#creating-a-fuchsia-component)
|
||||||
|
1. [Building a Fuchsia package](#building-a-fuchsia-package)
|
||||||
|
1. [Publishing a Fuchsia package](#publishing-a-fuchsia-package)
|
||||||
|
1. [Creating a Fuchsia package repository](#creating-a-fuchsia-package-repository)
|
||||||
|
1. [Publishing Fuchsia package to repository](#publishing-fuchsia-package-to-repository)
|
||||||
|
1. [Running a Fuchsia component on an emulator](#running-a-fuchsia-component-on-an-emulator)
|
||||||
|
1. [Starting the Fuchsia emulator](#starting-the-fuchsia-emulator)
|
||||||
|
1. [Watching emulator logs](#watching-emulator-logs)
|
||||||
|
1. [Serving a Fuchsia package](#serving-a-fuchsia-package)
|
||||||
|
1. [Running a Fuchsia component](#running-a-fuchsia-component)
|
||||||
|
1. [`.gitignore` extensions](#gitignore-extensions)
|
||||||
|
1. [Testing](#testing)
|
||||||
|
1. [Running unit tests](#running-unit-tests)
|
||||||
|
1. [Running the compiler test suite](#running-the-compiler-test-suite)
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
This target is cross-compiled from a host environment. Development may be done
|
This target is cross-compiled from a host environment. You will need a recent
|
||||||
from the [source tree] or using the Fuchsia SDK.
|
copy of the [Fuchsia SDK], which provides the tools, libraries, and binaries
|
||||||
|
required to build and link programs for Fuchsia.
|
||||||
|
|
||||||
[source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build
|
Development may also be done from the [source tree].
|
||||||
|
|
||||||
Fuchsia targets support std and follow the `sysv64` calling convention on
|
Fuchsia targets support `std` and follow the `sysv64` calling convention on
|
||||||
x86_64. Fuchsia binaries use the ELF file format.
|
x86_64. Fuchsia binaries use the ELF file format.
|
||||||
|
|
||||||
## Building the target
|
## Walkthrough structure
|
||||||
|
|
||||||
|
This walkthrough will cover:
|
||||||
|
|
||||||
|
1. Compiling a Rust binary targeting Fuchsia.
|
||||||
|
1. Building a Fuchsia package.
|
||||||
|
1. Publishing and running a Fuchsia package to a Fuchsia emulator.
|
||||||
|
|
||||||
|
For the purposes of this walkthrough, we will only target `x86_64-fuchsia`.
|
||||||
|
|
||||||
|
## Compiling a Rust binary targeting Fuchsia
|
||||||
|
|
||||||
|
Today, there are two main ways to build a Rust binary targeting Fuchsia
|
||||||
|
using the Fuchsia SDK:
|
||||||
|
1. Allow [rustup] to handle the installation of Fuchsia targets for you.
|
||||||
|
1. Build a toolchain locally that can target Fuchsia.
|
||||||
|
|
||||||
|
### Targeting Fuchsia with rustup and cargo
|
||||||
|
|
||||||
|
The easiest way to build a Rust binary targeting Fuchsia is by allowing [rustup]
|
||||||
|
to handle the installation of Fuchsia targets for you. This can be done by issuing
|
||||||
|
the following commands:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
rustup target add x86_64-fuchsia
|
||||||
|
rustup target add aarch_64-fuchsia
|
||||||
|
```
|
||||||
|
|
||||||
|
After installing our Fuchsia targets, we can now compile a Rust binary that targets
|
||||||
|
Fuchsia.
|
||||||
|
|
||||||
|
To create our Rust project, we can issue a standard `cargo` command as follows:
|
||||||
|
|
||||||
|
**From base working directory**
|
||||||
|
```sh
|
||||||
|
cargo new hello_fuchsia
|
||||||
|
```
|
||||||
|
|
||||||
|
The rest of this walkthrough will take place from `hello_fuchsia`, so we can
|
||||||
|
change into that directory now:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd hello_fuchsia
|
||||||
|
```
|
||||||
|
|
||||||
|
*Note: From this point onwards, all commands will be issued from the `hello_fuchsia/`
|
||||||
|
directory, and all `hello_fuchsia/` prefixes will be removed from references for sake of brevity.*
|
||||||
|
|
||||||
|
We can edit our `src/main.rs` to include a test as follows:
|
||||||
|
|
||||||
|
**`src/main.rs`**
|
||||||
|
```rust
|
||||||
|
fn main() {
|
||||||
|
println!("Hello Fuchsia!");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
assert_eq!(2 + 2, 4);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In addition to the standard workspace created, we will want to create a
|
||||||
|
`.cargo/config.toml` file to link necessary libraries
|
||||||
|
during compilation:
|
||||||
|
|
||||||
|
**`.cargo/config.toml`**
|
||||||
|
```txt
|
||||||
|
[target.x86_64-fuchsia]
|
||||||
|
|
||||||
|
rustflags = [
|
||||||
|
"-Lnative", "<SDK_PATH>/arch/x64/sysroot/lib",
|
||||||
|
"-Lnative", "<SDK_PATH>/arch/x64/lib"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
*Note: Make sure to fill out `<SDK_PATH>` with the path to the downloaded [Fuchsia SDK].*
|
||||||
|
|
||||||
|
In total, our new project will look like:
|
||||||
|
|
||||||
|
**Current directory structure**
|
||||||
|
```txt
|
||||||
|
hello_fuchsia/
|
||||||
|
┣━ src/
|
||||||
|
┃ ┗━ main.rs
|
||||||
|
┣━ Cargo.toml
|
||||||
|
┗━ .cargo/
|
||||||
|
┗━ config.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, we can build our rust binary as:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo build --target x86_64-fuchsia
|
||||||
|
```
|
||||||
|
|
||||||
|
Now we have a Rust binary at `target/x86_64-fuchsia/debug/hello_fuchsia`,
|
||||||
|
targeting our desired Fuchsia target.
|
||||||
|
|
||||||
|
**Current directory structure**
|
||||||
|
```txt
|
||||||
|
hello_fuchsia/
|
||||||
|
┣━ src/
|
||||||
|
┃ ┗━ main.rs
|
||||||
|
┣━ target/
|
||||||
|
┃ ┗━ x86_64-fuchsia/
|
||||||
|
┃ ┗━ debug/
|
||||||
|
┃ ┗━ hello_fuchsia
|
||||||
|
┣━ Cargo.toml
|
||||||
|
┗━ .cargo/
|
||||||
|
┗━ config.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Targeting Fuchsia with a compiler built from source
|
||||||
|
|
||||||
|
An alternative to the first workflow is to target Fuchsia by using
|
||||||
|
`rustc` built from source.
|
||||||
|
|
||||||
Before building Rust for Fuchsia, you'll need a clang toolchain that supports
|
Before building Rust for Fuchsia, you'll need a clang toolchain that supports
|
||||||
Fuchsia as well. A recent version (14+) of clang should be sufficient to compile
|
Fuchsia as well. A recent version (14+) of clang should be sufficient to compile
|
||||||
Rust for Fuchsia.
|
Rust for Fuchsia.
|
||||||
|
|
||||||
You'll also need a recent copy of the [Fuchsia SDK], which provides the tools
|
|
||||||
and binaries required to build and link programs for Fuchsia.
|
|
||||||
|
|
||||||
[Fuchsia SDK]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core
|
|
||||||
|
|
||||||
x86-64 and AArch64 Fuchsia targets can be enabled using the following
|
x86-64 and AArch64 Fuchsia targets can be enabled using the following
|
||||||
configuration.
|
configuration.
|
||||||
|
|
||||||
|
@ -75,15 +206,21 @@ export CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/
|
||||||
These can be run together in a shell environment by executing
|
These can be run together in a shell environment by executing
|
||||||
`(source config-env.sh && ./x.py install)`.
|
`(source config-env.sh && ./x.py install)`.
|
||||||
|
|
||||||
## Building Rust programs
|
Once `rustc` is installed, we can create a new working directory to work from,
|
||||||
|
`hello_fuchsia` along with `hello_fuchsia/src`:
|
||||||
|
|
||||||
After compiling Rust binaries, you'll need to build a component, package it, and
|
```sh
|
||||||
serve it to a Fuchsia device or emulator. All of this can be done using the
|
mkdir hello_fuchsia
|
||||||
Fuchsia SDK.
|
cd hello_fuchsia
|
||||||
|
mkdir src
|
||||||
|
```
|
||||||
|
|
||||||
As an example, we'll compile and run this simple program on a Fuchsia emulator:
|
*Note: From this point onwards, all commands will be issued from the `hello_fuchsia/`
|
||||||
|
directory, and all `hello_fuchsia/` prefixes will be removed from references for sake of brevity.*
|
||||||
|
|
||||||
**`hello_fuchsia.rs`**
|
There, we can create a new file named `src/hello_fuchsia.rs`:
|
||||||
|
|
||||||
|
**`src/hello_fuchsia.rs`**
|
||||||
```rust
|
```rust
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello Fuchsia!");
|
println!("Hello Fuchsia!");
|
||||||
|
@ -95,62 +232,14 @@ fn it_works() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Create a new file named `hello_fuchsia.rs` and fill out its contents with that
|
**Current directory structure**
|
||||||
code.
|
|
||||||
|
|
||||||
### Create a package
|
|
||||||
|
|
||||||
On Fuchsia, a package is the unit of distribution for software. We'll need to
|
|
||||||
create a new package directory where we will place files like our finished
|
|
||||||
binary and any data it may need. The working directory will have this layout:
|
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
hello_fuchsia.rs
|
hello_fuchsia/
|
||||||
hello_fuchsia.cml
|
┗━ src/
|
||||||
package
|
┗━ hello_fuchsia.rs
|
||||||
┣━ bin
|
|
||||||
┃ ┗━ hello_fuchsia
|
|
||||||
┣━ meta
|
|
||||||
┃ ┣━ package
|
|
||||||
┃ ┗━ hello_fuchsia.cm
|
|
||||||
┗━ hello_fuchsia.manifest
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Make the `package`, `package/bin`, and `package/meta` directories and create the
|
Using your freshly installed `rustc`, you can compile a binary for Fuchsia using
|
||||||
following files inside:
|
|
||||||
|
|
||||||
**`package/meta/package`**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "hello_fuchsia",
|
|
||||||
"version": "0"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The `package` file describes our package's name and version number. Every
|
|
||||||
package must contain one.
|
|
||||||
|
|
||||||
**`package/hello_fuchsia.manifest`**
|
|
||||||
```txt
|
|
||||||
bin/hello_fuchsia=package/bin/hello_fuchsia
|
|
||||||
lib/ld.so.1=<SDK_PATH>/arch/x64/sysroot/dist/lib/ld.so.1
|
|
||||||
lib/libfdio.so=<SDK_PATH>/arch/x64/dist/libfdio.so
|
|
||||||
meta/package=package/meta/package
|
|
||||||
meta/hello_fuchsia.cm=package/meta/hello_fuchsia.cm
|
|
||||||
```
|
|
||||||
|
|
||||||
*Note: Relative manifest paths are resolved starting from the working directory
|
|
||||||
of `pm`. Make sure to fill out `<SDK_PATH>` with the path to the downloaded
|
|
||||||
SDK.*
|
|
||||||
|
|
||||||
The `.manifest` file will be used to describe the contents of the package by
|
|
||||||
relating their location when installed to their location on the file system. You
|
|
||||||
can use this to make a package pull files from other places, but for this
|
|
||||||
example we'll just be placing everything in the `package` directory.
|
|
||||||
|
|
||||||
### Compiling a binary
|
|
||||||
|
|
||||||
Using your freshly compiled `rustc`, you can compile a binary for Fuchsia using
|
|
||||||
the following options:
|
the following options:
|
||||||
|
|
||||||
* `--target x86_64-fuchsia`/`--target aarch64-fuchsia`: Targets the Fuchsia
|
* `--target x86_64-fuchsia`/`--target aarch64-fuchsia`: Targets the Fuchsia
|
||||||
|
@ -167,19 +256,108 @@ Putting it all together:
|
||||||
TARGET_ARCH="<x86_64-fuchsia|aarch64-fuchsia>"
|
TARGET_ARCH="<x86_64-fuchsia|aarch64-fuchsia>"
|
||||||
ARCH="<x64|aarch64>"
|
ARCH="<x64|aarch64>"
|
||||||
|
|
||||||
rustc --target ${TARGET_ARCH} -Lnative=${SDK_PATH}/arch/${ARCH}/lib -Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib -o package/bin/hello_fuchsia hello_fuchsia.rs
|
rustc \
|
||||||
|
--target ${TARGET_ARCH} \
|
||||||
|
-Lnative=${SDK_PATH}/arch/${ARCH}/lib \
|
||||||
|
-Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib \
|
||||||
|
--out-dir bin src/hello_fuchsia.rs
|
||||||
```
|
```
|
||||||
|
|
||||||
### Bulding a component
|
**Current directory structure**
|
||||||
|
```txt
|
||||||
|
hello_fuchsia/
|
||||||
|
┣━ src/
|
||||||
|
┃ ┗━ hello_fuchsia.rs
|
||||||
|
┗━ bin/
|
||||||
|
┗━ hello_fuchsia
|
||||||
|
```
|
||||||
|
|
||||||
On Fuchsia, components require a component manifest written in Fuchia's markup
|
## Creating a Fuchsia package
|
||||||
|
|
||||||
|
Before moving on, double check your directory structure:
|
||||||
|
|
||||||
|
**Current directory structure**
|
||||||
|
```txt
|
||||||
|
hello_fuchsia/
|
||||||
|
┣━ src/ (if using rustc)
|
||||||
|
┃ ┗━ hello_fuchsia.rs ...
|
||||||
|
┣━ bin/ ...
|
||||||
|
┃ ┗━ hello_fuchsia ...
|
||||||
|
┣━ src/ (if using cargo)
|
||||||
|
┃ ┗━ main.rs ...
|
||||||
|
┗━ target/ ...
|
||||||
|
┗━ x86_64-fuchsia/ ...
|
||||||
|
┗━ debug/ ...
|
||||||
|
┗━ hello_fuchsia ...
|
||||||
|
```
|
||||||
|
|
||||||
|
With our Rust binary built, we can move to creating a Fuchsia package.
|
||||||
|
On Fuchsia, a package is the unit of distribution for software. We'll need to
|
||||||
|
create a new package directory where we will place files like our finished
|
||||||
|
binary and any data it may need.
|
||||||
|
|
||||||
|
To start, make the `pkg`, and `pkg/meta` directories:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir pkg
|
||||||
|
mkdir pkg/meta
|
||||||
|
```
|
||||||
|
|
||||||
|
**Current directory structure**
|
||||||
|
```txt
|
||||||
|
hello_fuchsia/
|
||||||
|
┗━ pkg/
|
||||||
|
┗━ meta/
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, create the following files inside:
|
||||||
|
|
||||||
|
**`pkg/meta/package`**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "hello_fuchsia",
|
||||||
|
"version": "0"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `package` file describes our package's name and version number. Every
|
||||||
|
package must contain one.
|
||||||
|
|
||||||
|
**`pkg/hello_fuchsia.manifest`**
|
||||||
|
```txt
|
||||||
|
bin/hello_fuchsia=target/x86_64-fuchsia/debug/hello_fuchsia # If using cargo...
|
||||||
|
bin/hello_fuchsia=bin/hello_fuchsia # If using rustc...
|
||||||
|
lib/ld.so.1=<SDK_PATH>/arch/x64/sysroot/dist/lib/ld.so.1
|
||||||
|
lib/libfdio.so=<SDK_PATH>/arch/x64/dist/libfdio.so
|
||||||
|
meta/package=pkg/meta/package
|
||||||
|
meta/hello_fuchsia.cm=pkg/meta/hello_fuchsia.cm
|
||||||
|
```
|
||||||
|
|
||||||
|
*Note: Relative manifest paths are resolved starting from the working directory
|
||||||
|
of `pm`. Make sure to fill out `<SDK_PATH>` with the path to the downloaded
|
||||||
|
SDK.*
|
||||||
|
|
||||||
|
The `.manifest` file will be used to describe the contents of the package by
|
||||||
|
relating their location when installed to their location on the file system. The
|
||||||
|
`bin/hello_fuchsia=` entry will be different depending on how your Rust binary
|
||||||
|
was built, so choose accordingly.
|
||||||
|
|
||||||
|
**Current directory structure**
|
||||||
|
```txt
|
||||||
|
hello_fuchsia/
|
||||||
|
┗━ pkg/
|
||||||
|
┣━ meta/
|
||||||
|
┃ ┗━ package
|
||||||
|
┗━ hello_fuchsia.manifest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Creating a Fuchsia component
|
||||||
|
|
||||||
|
On Fuchsia, components require a component manifest written in Fuchsia's markup
|
||||||
language called CML. The Fuchsia devsite contains an [overview of CML] and a
|
language called CML. The Fuchsia devsite contains an [overview of CML] and a
|
||||||
[reference for the file format]. Here's a basic one that can run our single binary:
|
[reference for the file format]. Here's a basic one that can run our single binary:
|
||||||
|
|
||||||
[overview of CML]: https://fuchsia.dev/fuchsia-src/concepts/components/v2/component_manifests
|
**`pkg/hello_fuchsia.cml`**
|
||||||
[reference for the file format]: https://fuchsia.dev/reference/cml
|
|
||||||
|
|
||||||
**`hello_fuchsia.cml`**
|
|
||||||
```txt
|
```txt
|
||||||
{
|
{
|
||||||
include: [ "syslog/client.shard.cml" ],
|
include: [ "syslog/client.shard.cml" ],
|
||||||
|
@ -190,43 +368,152 @@ language called CML. The Fuchsia devsite contains an [overview of CML] and a
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```txt
|
||||||
|
hello_fuchsia/
|
||||||
|
┗━ pkg/
|
||||||
|
┣━ meta/
|
||||||
|
┃ ┗━ package
|
||||||
|
┣━ hello_fuchsia.manifest
|
||||||
|
┗━ hello_fuchsia.cml
|
||||||
|
```
|
||||||
|
|
||||||
Now we can compile that CML into a component manifest:
|
Now we can compile that CML into a component manifest:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
${SDK_PATH}/tools/${ARCH}/cmc compile hello_fuchsia.cml --includepath ${SDK_PATH}/pkg -o package/meta/hello_fuchsia.cm
|
${SDK_PATH}/tools/${ARCH}/cmc compile \
|
||||||
|
pkg/hello_fuchsia.cml \
|
||||||
|
--includepath ${SDK_PATH}/pkg \
|
||||||
|
-o pkg/meta/hello_fuchsia.cm
|
||||||
```
|
```
|
||||||
|
|
||||||
`--includepath` tells the compiler where to look for `include`s from our CML.
|
**Current directory structure**
|
||||||
In our case, we're only using `syslog/client.shard.cml`.
|
```txt
|
||||||
|
hello_fuchsia/
|
||||||
|
┗━ pkg/
|
||||||
|
┣━ meta/
|
||||||
|
┃ ┣━ package
|
||||||
|
┃ ┗━ hello_fuchsia.cm
|
||||||
|
┣━ hello_fuchsia.manifest
|
||||||
|
┗━ hello_fuchsia.cml
|
||||||
|
```
|
||||||
|
|
||||||
### Building and publishing a package
|
*Note: `--includepath` tells the compiler where to look for `include`s from our CML.
|
||||||
|
In our case, we're only using `syslog/client.shard.cml`.*
|
||||||
|
|
||||||
Next, we'll build our package as defined by our manifest:
|
### Building a Fuchsia package
|
||||||
|
|
||||||
|
Next, we'll build a package manifest as defined by our manifest:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
${SDK_PATH}/tools/${ARCH}/pm -o hello_fuchsia -m package/hello_fuchsia.manifest build -output-package-manifest hello_fuchsia_manifest
|
${SDK_PATH}/tools/${ARCH}/pm \
|
||||||
|
-o hello_fuchsia_manifest \
|
||||||
|
-m pkg/hello_fuchsia.manifest \
|
||||||
|
build \
|
||||||
|
-output-package-manifest hello_fuchsia_package_manifest
|
||||||
```
|
```
|
||||||
|
|
||||||
This will produce `hello_fuchsia_manifest` which is a package manifest we can
|
This will produce `pkg/hello_fuchsia_manifest/` which is a package manifest we can
|
||||||
publish directly to a repository. We can set up that repository with:
|
publish directly to a repository.
|
||||||
|
|
||||||
|
**Current directory structure**
|
||||||
|
```txt
|
||||||
|
hello_fuchsia/
|
||||||
|
┗━ pkg/
|
||||||
|
┣━ meta/
|
||||||
|
┃ ┣━ package
|
||||||
|
┃ ┗━ hello_fuchsia.cm
|
||||||
|
┣━ hello_fuchsia_manifest/
|
||||||
|
┃ ┗━ ...
|
||||||
|
┣━ hello_fuchsia.manifest
|
||||||
|
┣━ hello_fuchsia.cml
|
||||||
|
┗━ hello_fuchsia_package_manifest
|
||||||
|
```
|
||||||
|
|
||||||
|
We are now ready to publish the package.
|
||||||
|
|
||||||
|
## Publishing a Fuchsia package
|
||||||
|
|
||||||
|
With our package and component manifests setup,
|
||||||
|
we can now publish our package. The first step will
|
||||||
|
be to create a Fuchsia package repository to publish
|
||||||
|
to.
|
||||||
|
|
||||||
|
### Creating a Fuchsia package repository
|
||||||
|
|
||||||
|
We can set up our repository with:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
${SDK_PATH}/tools/${ARCH}/pm newrepo -repo repo
|
${SDK_PATH}/tools/${ARCH}/pm newrepo \
|
||||||
|
-repo pkg/repo
|
||||||
```
|
```
|
||||||
|
|
||||||
And then publish our new package to that repository with:
|
**Current directory structure**
|
||||||
|
```txt
|
||||||
|
hello_fuchsia/
|
||||||
|
┗━ pkg/
|
||||||
|
┣━ meta/
|
||||||
|
┃ ┣━ package
|
||||||
|
┃ ┗━ hello_fuchsia.cm
|
||||||
|
┣━ hello_fuchsia_manifest/
|
||||||
|
┃ ┗━ ...
|
||||||
|
┣━ repo/
|
||||||
|
┃ ┗━ ...
|
||||||
|
┣━ hello_fuchsia.manifest
|
||||||
|
┣━ hello_fuchsia.cml
|
||||||
|
┗━ hello_fuchsia_package_manifest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Publishing Fuchsia package to repository
|
||||||
|
|
||||||
|
We can publish our new package to that repository with:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
${SDK_PATH}/tools/${ARCH}/pm publish -repo repo -lp -f <(echo "hello_fuchsia_manifest")
|
${SDK_PATH}/tools/${ARCH}/pm publish \
|
||||||
|
-repo repo \
|
||||||
|
-lp -f <(echo "hello_fuchsia_package_manifest")
|
||||||
```
|
```
|
||||||
|
|
||||||
Then we can add it to `ffx`'s package server as `hello-fuchsia` using:
|
Then we can add the repository to `ffx`'s package server as `hello-fuchsia` using:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm repo -r hello-fuchsia
|
${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm \
|
||||||
|
repo \
|
||||||
|
-r hello-fuchsia
|
||||||
```
|
```
|
||||||
|
|
||||||
### Starting the emulator
|
## Running a Fuchsia component on an emulator
|
||||||
|
|
||||||
|
At this point, we are ready to run our Fuchsia
|
||||||
|
component. For reference, our final directory
|
||||||
|
structure will look like:
|
||||||
|
|
||||||
|
**Final directory structure**
|
||||||
|
```txt
|
||||||
|
hello_fuchsia/
|
||||||
|
┣━ src/ (if using rustc)
|
||||||
|
┃ ┗━ hello_fuchsia.rs ...
|
||||||
|
┣━ bin/ ...
|
||||||
|
┃ ┗━ hello_fuchsia ...
|
||||||
|
┣━ src/ (if using cargo)
|
||||||
|
┃ ┗━ main.rs ...
|
||||||
|
┣━ target/ ...
|
||||||
|
┃ ┗━ x86_64-fuchsia/ ...
|
||||||
|
┃ ┗━ debug/ ...
|
||||||
|
┃ ┗━ hello_fuchsia ...
|
||||||
|
┗━ pkg/
|
||||||
|
┣━ meta/
|
||||||
|
┃ ┣━ package
|
||||||
|
┃ ┗━ hello_fuchsia.cm
|
||||||
|
┣━ hello_fuchsia_manifest/
|
||||||
|
┃ ┗━ ...
|
||||||
|
┣━ repo/
|
||||||
|
┃ ┗━ ...
|
||||||
|
┣━ hello_fuchsia.manifest
|
||||||
|
┣━ hello_fuchsia.cml
|
||||||
|
┗━ hello_fuchsia_package_manifest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Starting the Fuchsia emulator
|
||||||
|
|
||||||
Start a Fuchsia emulator in a new terminal using:
|
Start a Fuchsia emulator in a new terminal using:
|
||||||
|
|
||||||
|
@ -235,50 +522,83 @@ ${SDK_PATH}/tools/${ARCH}/ffx product-bundle get workstation_eng.qemu-${ARCH}
|
||||||
${SDK_PATH}/tools/${ARCH}/ffx emu start workstation_eng.qemu-${ARCH} --headless
|
${SDK_PATH}/tools/${ARCH}/ffx emu start workstation_eng.qemu-${ARCH} --headless
|
||||||
```
|
```
|
||||||
|
|
||||||
Once the emulator is running, start a package repository server to serve our
|
### Watching emulator logs
|
||||||
|
|
||||||
|
Once the emulator is running, open a separate terminal to watch the emulator logs:
|
||||||
|
|
||||||
|
**In separate terminal**
|
||||||
|
```sh
|
||||||
|
${SDK_PATH}/tools/${ARCH}/ffx log \
|
||||||
|
--since now
|
||||||
|
```
|
||||||
|
|
||||||
|
### Serving a Fuchsia package
|
||||||
|
|
||||||
|
Now, start a package repository server to serve our
|
||||||
package to the emulator:
|
package to the emulator:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
${SDK_PATH}/tools/${ARCH}/ffx repository server start
|
${SDK_PATH}/tools/${ARCH}/ffx repository server start
|
||||||
```
|
```
|
||||||
|
|
||||||
Once the repository server is up and running, register our repository:
|
Once the repository server is up and running, register it with the target Fuchsia system running in the emulator:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
${SDK_PATH}/tools/${ARCH}/ffx target repository register --repository hello-fuchsia
|
${SDK_PATH}/tools/${ARCH}/ffx target repository register \
|
||||||
|
--repository hello-fuchsia
|
||||||
```
|
```
|
||||||
|
|
||||||
And watch the logs from the emulator in a separate terminal:
|
### Running a Fuchsia component
|
||||||
|
|
||||||
```sh
|
|
||||||
${SDK_PATH}/tools/${ARCH}/ffx log --since now
|
|
||||||
```
|
|
||||||
|
|
||||||
Finally, run the component:
|
Finally, run the component:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
${SDK_PATH}/tools/${ARCH}/ffx component run fuchsia-pkg://hello-fuchsia/hello_fuchsia#meta/hello_fuchsia.cm
|
${SDK_PATH}/tools/${ARCH}/ffx component run \
|
||||||
|
fuchsia-pkg://hello-fuchsia/hello_fuchsia_manifest#meta/hello_fuchsia.cm
|
||||||
```
|
```
|
||||||
|
|
||||||
On reruns of the component, the `--recreate` argument may also need to be
|
On reruns of the component, the `--recreate` argument may also need to be
|
||||||
passed.
|
passed.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
${SDK_PATH}/tools/${ARCH}/ffx component run --recreate fuchsia-pkg://hello-fuchsia/hello_fuchsia#meta/hello_fuchsia.cm
|
${SDK_PATH}/tools/${ARCH}/ffx component run \
|
||||||
|
--recreate \
|
||||||
|
fuchsia-pkg://hello-fuchsia/hello_fuchsia_manifest#meta/hello_fuchsia.cm
|
||||||
|
```
|
||||||
|
|
||||||
|
## `.gitignore` extensions
|
||||||
|
|
||||||
|
Optionally, we can create/extend our `.gitignore` file to ignore files and
|
||||||
|
directories that are not helpful to track:
|
||||||
|
|
||||||
|
```txt
|
||||||
|
pkg/repo
|
||||||
|
pkg/meta/hello_fuchsia.cm
|
||||||
|
pkg/hello_fuchsia_manifest
|
||||||
|
pkg/hello_fuchsia_package_manifest
|
||||||
```
|
```
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
### Running unit tests
|
### Running unit tests
|
||||||
|
|
||||||
Tests can be run in the same way as a regular binary, simply by passing `--test`
|
Tests can be run in the same way as a regular binary.
|
||||||
to the `rustc` invocation and then repackaging and rerunning. The test harness
|
|
||||||
will run the applicable unit tests.
|
* If using `cargo`, you can simply pass `test --no-run`
|
||||||
|
to the `cargo` invocation and then repackage and rerun the Fuchsia package. From our previous example,
|
||||||
|
this would look like `cargo test --target x86_64-fuchsia --no-run`, and moving the executable
|
||||||
|
binary path found from the line `Executable unittests src/main.rs (target/x86_64-fuchsia/debug/deps/hello_fuchsia-<HASH>)`
|
||||||
|
into `pkg/hello_fuchsia.manifest`.
|
||||||
|
|
||||||
|
* If using the compiled `rustc`, you can simply pass `--test`
|
||||||
|
to the `rustc` invocation and then repackage and rerun the Fuchsia package.
|
||||||
|
|
||||||
|
The test harness will run the applicable unit tests.
|
||||||
|
|
||||||
Often when testing, you may want to pass additional command line arguments to
|
Often when testing, you may want to pass additional command line arguments to
|
||||||
your binary. Additional arguments can be set in the component manifest:
|
your binary. Additional arguments can be set in the component manifest:
|
||||||
|
|
||||||
**`hello_fuchsia.cml`**
|
**`pkg/hello_fuchsia.cml`**
|
||||||
```txt
|
```txt
|
||||||
{
|
{
|
||||||
include: [ "syslog/client.shard.cml" ],
|
include: [ "syslog/client.shard.cml" ],
|
||||||
|
@ -293,11 +613,20 @@ your binary. Additional arguments can be set in the component manifest:
|
||||||
This will pass the argument `it_works` to the binary, filtering the tests to
|
This will pass the argument `it_works` to the binary, filtering the tests to
|
||||||
only those tests that match the pattern. There are many more configuration
|
only those tests that match the pattern. There are many more configuration
|
||||||
options available in CML including environment variables. More documentation is
|
options available in CML including environment variables. More documentation is
|
||||||
available on the [Fuchsia devsite](https://fuchsia.dev/reference/cml).
|
available on the [Fuchsia devsite].
|
||||||
|
|
||||||
### Running the compiler test suite
|
### Running the compiler test suite
|
||||||
|
|
||||||
Running the Rust test suite on Fuchsia is [not currently supported], but work is
|
Running the Rust test suite on Fuchsia is [not currently supported], but work is
|
||||||
underway to enable it.
|
underway to enable it.
|
||||||
|
|
||||||
|
[Fuchsia team]: https://team-api.infra.rust-lang.org/v1/teams/fuchsia.json
|
||||||
|
[Fuchsia]: https://fuchsia.dev/
|
||||||
|
[source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build
|
||||||
|
[rustup]: https://rustup.rs/
|
||||||
|
[cargo]: https://doc.rust-lang.org/cargo/
|
||||||
|
[Fuchsia SDK]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core
|
||||||
|
[overview of CML]: https://fuchsia.dev/fuchsia-src/concepts/components/v2/component_manifests
|
||||||
|
[reference for the file format]: https://fuchsia.dev/reference/cml
|
||||||
|
[Fuchsia devsite]: https://fuchsia.dev/reference/cml
|
||||||
[not currently supported]: https://fxbug.dev/105393
|
[not currently supported]: https://fxbug.dev/105393
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue