Goal
In the guide on building components we saw several examples of defining components for executables and then packaging them. In this document we review ways of making data files available to components in the same package.
Hermetic data files with resource()
At runtime, components are able to read the contents of their own package by
accessing the path /pkg/
in their namespace. The resource()
template may be
used to add contents to the package that may be accessed this way.
import("//build/dist/resource.gni")
# List of greetings
resource("greetings") {
sources = [ "greetings.txt" ]
outputs = [ "data/{{source_file_part}}" ]
}
For information about {{source_file_part}}
and similar syntax see GN placeholders.
See resource.gni for more usage instructions on the resource()
template, and related templates resource_group()
and resource_tree()
.
More examples using resource()
, resource_group()
, and resource_tree()
can
be found in additional packaged resources.
Including resources with a component
Add a dependency on the resource target from a component in order to ensure that the resource(s) are included in the same package.
import("//build/components.gni")
# Sends a random greeting to a client
executable("greeter") {
sources = [ "greeter.cc" ]
deps = [ ... ]
}
fuchsia_component("greeting_server") {
deps = [
":greeter",
":greetings",
]
manifest = "meta/greeting_server.cml"
}
In the example above, at runtime the component will be able to read the file
in its namespace at the path /pkg/data/greetings.txt
. This will work regardless
of what package(s) (defined with fuchsia_package()
) this component is
included in.
Packaging conventions
Small data files (less than 4kb) should be packaged under
meta/
, though this is not required. Packaging small files undermeta/
allows the packaging system to archive them in a singlemeta.far
file, which is a more efficient way to store small files.Otherwise, data files are usually packaged under
data/
by convention, though again this is not a technical requirement.
Using different resources in different packages
Sometimes it's desirable to package the same component with different data files.
import("//build/dist/resource.gni")
import("//build/components.gni")
# Sends a random greeting to a client
executable("greeter") {
sources = [ "greeter.cc" ]
deps = [ ... ]
}
fuchsia_component("greeting_server") {
deps = [ ":greeter" ]
manifest = "meta/greeting_server.cml"
}
# List of production greetings.
# Contains only the finest greetings and the best regards.
resource("greetings") {
sources = [ "greetings.txt" ]
outputs = [ "data/greetings.txt" ]
}
fuchsia_package("greeting") {
deps = [
":greeting_server",
":greetings",
]
}
# Greetings for testing.
# Contains exactly one greeting so that tests are reproducible.
resource("test_greeting") {
testonly = true
sources = [ "test_greeting.txt" ]
outputs = [ "data/greetings.txt" ]
}
# Connects to the greeting server.
# Ensures that the expected greeting is sent back.
fuchsia_test_component("greeting_test_client") {
...
}
fuchsia_test_package("greeting_integration_test") {
test_components = [ ":greeting_test_client" ]
deps = [
":greeting_server",
":test_greeting",
]
}
In the example above, the same greeting_server
component is added to two
packages, one for production and another for testing. In both cases the
component will find a file under /pkg/data/greetings.txt
. However the
contents of this file will vary between the production version and the testing
version, depending on the package association.