blob: b7d21594ea5db38f3c6976a8b23cf1cb2e19971d [file] [log] [blame] [view] [edit]
# Writing a "Hello World" session {#writing-a-hello-world-session}
Sessions are regular components that the `session_manager` can launch at
startup. This means that creating a session component follows all of the same
steps as creating any other component. This document discusses creating an
example session that launches at startup and prints "Hello World!" to the system
log.
## Create the directory structure {#create-the-directory-structure}
Components require a specific directory structure. The `fx` tool provides a
generator that creates this structure for you. It takes the name of the
component and the language you want to use as arguments. For example, this
component is called `hello-world-session` and is written in Rust.
Run the following command to create the directory structure for this example:
```posix-terminal
fx create component --path hello-world-session --lang rust
```
This command creates the following directory structure with a template for a
component offering a service:
```none
hello-world-session
|- meta
| |- hello-world-session.cml
|
|- src
| |- main.rs
|
|- BUILD.gn
```
## Create a component manifest {#create-a-component-manifest}
The component manifest file (`hello-world-session.cml`) declares the component
to Fuchsia. For this example, the default manifest is sufficient but take a
moment to explore the following lines of code from `hello-world-session.cml`:
1. The file starts by including other cml files if needed.
```json5
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="src/session/examples/hello-world-session/meta/hello-world-session.cml" region_tag="include_block" adjust_indentation="auto" %}
```
This `include` key lets the session component use the
`fuchsia.logger.LogSink` capability so that it can print to the system log.
1. Next is the `program` block.
```json5
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="src/session/examples/hello-world-session/meta/hello-world-session.cml" region_tag="program_block" adjust_indentation="auto" %}
```
The `program` block tells the `component_manager` where the binary for the
session component can be found. The `runner` key tells the `component_manager`
that is should run the component binary using the ELF runner.
1. Finally the component manifest describes additional capabilities that the
component can `use`, `offer`, or `expose`.
```json5
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="src/session/examples/hello-world-session/meta/hello-world-session.cml" region_tag="capabilities_block" adjust_indentation="auto" %}
```
## Writing a session in Rust {#writing-a-session-in-rust}
Now you can write the implementation for the session component. Inside the
`src/main.rs` file that was generated there is a lot of code that isn't needed
for this example.
Replace the contents of `src/main.rs` with the following code:
```rust
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="src/session/examples/hello-world-session/src/main.rs" region_tag="main" adjust_indentation="auto" %}
```
This code initializes the system log and then prints "Hello World!".
`tracing::info!` is a macro that prints to the log with a level of `info`.
There are similar macros for `error` and `warn`.
## Writing the `BUILD.gn` {#writing-the-build-gn}
The last file to modify is the `BUILD.gn`. This tells the compiler how to build
the the session component.
### Rust binary {#rust-binary}
The next section describes the actual Rust binary. It tells the compiler what
the name of the binary should be, that it includes unit tests, what dependencies
it has, and where it's source is located. For this example, the default set of
dependencies are sufficient:
```gn
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="src/session/examples/hello-world-session/BUILD.gn" region_tag="session_binary" adjust_indentation="auto" %}
```
The `fuchsia_component()` and `fuchsia_package()` templates tell Fuchsia more
about the component including what it is called, where to find the manifest,
and what dependencies the package and component have:
```gn
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="src/session/examples/hello-world-session/BUILD.gn" region_tag="component_package" adjust_indentation="auto" %}
```
## Identify the session URL {#identify-the-session-url}
`session_manager` needs to know to which session component to launch at startup,
and is configured by providing the component URL of the session.
Component URLs follow the format:
<pre><code>fuchsia-pkg://fuchsia.com/<var>package_name</var>#meta/<var>component_name.cm</var></code></pre>
Notice that the path points to a `.cm` file. `.cm` files are compiled versions
of `.cml` files that are generated when `fx build` is run. So, in this case, the
component URL is:
```none
fuchsia-pkg://fuchsia.com/hello-world-session#meta/hello-world-session.cm
```
## Building the session {#building-the-session}
To build the session `fx set` must first be used to configure the build so that
`session_manager`, your session component, and the session config are included
in the base package set. This is done using the `--with-base` flag. The session
URL must also be configured, which is done using the `--args` flag.
```posix-terminal
fx set core.x64 \
--with-base //src/session/bin/session_manager \
--with-base {{ '<var label="session path">//path/to/your/session</var>' }} \
--args=product_config.session_url = "fuchsia-pkg://fuchsia.com/<var>package_name</var>#meta/<var>component_name</var>.cm"
```
If you are using the example project from the `//src/session/examples` directory,
the `fx set` command would be:
```posix-terminal
fx set core.x64 \
--with-base //src/session/bin/session_manager \
--with-base //src/session/examples/hello-world-session \
--args=product_config.session_url = "fuchsia-pkg://fuchsia.com/hello-world-session#meta/hello-world-session.cm"
```
Once that's done and built `session_manager` should automatically start your
session on boot. You should see the "Hello" message in the system log.
```none {:.devsite-disable-click-to-copy}
$ ffx log --filter hello
[session_manager] INFO: Launching session: fuchsia-pkg://fuchsia.com/hello-world-session#meta/hello-world-session.cm
[hello_world_session] INFO: Hello World!
```