Clone this repo:
  1. a7d967b [write-config] Add rust_api_level_cfg_flags.txt by Evan Wildenhain · 7 months ago main master
  2. 22c8e19 Switch from failure to anyhow by Dan Johnson · 1 year, 6 months ago
  3. e39b64c Suppress some exciting new warnings by Rob Tsuk · 2 years, 11 months ago
  4. 56e8b99 Otherwise there are constant warnings by Rob Tsuk · 3 years, 2 months ago
  5. 4319193 Support flatland by Rob Tsuk · 3 years, 4 months ago

fargo

fargo 0.2.0
Fargo is a prototype Fuchsia-specific wrapper around Cargo.

USAGE:
    fargo [FLAGS] [OPTIONS] <SUBCOMMAND>

FLAGS:
        --disable-cross-env    Disable the setting of CC, AR and such environmental variables
    -h, --help                 Prints help information
    -V, --version              Prints version information
    -v, --verbose              Print verbose output while performing commands

OPTIONS:
    -N, --device-name <device-name>        Name of device to target, needed if there are multiple devices visible on the
                                           network
        --manifest-path <manifest-path>    Path to Cargo.toml

SUBCOMMANDS:
    autotest             Auto build and test in Fuchsia device or emulator
    build                Build binary targeting Fuchsia device or emulator
    build-rustc          Build rustc targeting Fuchsia
    cargo                Run a cargo command for Fuchsia. Use -- to indicate that all following arguments should be
                         passed to cargo.
    check                Check binary targeting Fuchsia device or emulator
    configure            Run a configure script for the cross compilation environment
    doc                  Build a package's documentation
    enable-networking    Enable networking for a running emulator
    fmt                  Run cargo fmt using the Fuchsia toolchain
    help                 Prints this message or the help of the given subcommand(s)
    list-devices         List visible Fuchsia devices
    make-package         Make a Fuchsia package from an unstripped binary
    pkg-config           Run pkg-config for the cross compilation environment
    restart              Stop all Fuchsia emulators and start a new one
    run                  Run binary on Fuchsia device or emulator
    run-on-target        Act as as custom runner for Cargo targeting a Fuchsia device
    ssh                  Open a shell on Fuchsia device or emulator
    start                Start a Fuchsia emulator
    stop                 Stop all Fuchsia emulators
    test                 Run unit tests on Fuchsia device or emulator
    write-config         Write a .cargo/config file to allow cargo to operate correctly for Fuchsia

The fargo-test directory contains something one can use to test-drive.

Getting started

Since at the moment Fargo requires the FUCHSIA_DIR environmental variable be set to the path to a Fuchsia source tree containing a Fuchsia build, the first step is to build Fuchsia.

The Fuchsia Getting Started instruction are what you need, with the caveat that you have to pass --cargo-toml-gen to fx set.

Make sure that fx serve is running pointed at this Fuchsia build.

Once this build is complete, clone and build Fargo. For this you will need a working host Rust installation, most easily installed with rustup.

git clone https://fuchsia.googlesource.com/fargo
cd fargo
cargo install --force --path .

Fargo uses the values set by ./scripts/fx set to know what build directory to use.

Fargo uses ssh to communicate between your host computer and either the emulator or a real device to copy build results and execute them. For the emulator there is a bit of tricky set up to do.

Building for use as a prebuilt

From the directory you cloned into.

./scripts/build_cipd_prebuilt.sh

This will generate a cipd.yaml file for uploading to CIPD.

Testing if Fargo is working

Now to verify if Fargo is working correctly, try starting a fuchsia machine and executing a test.

fargo start
cd fargo/fargo-test
fargo test

Note that Fargo start now depends on an environment using fx set. If that isn‘t the way you start Fuchsia emulators, use fargo enable-networking after you’ve started the emulator.

If all is well, you should see a successful test pass just as if you had ran cargo test on any other rust project.

Additionally, if you are using the emulator you need to enable networking, otherwise Fargo won't be able to use fx shell to invoke the test binary.

Escaping parameters

Sometimes you want to pass parameters through Fargo and cargo and on to somethinglike rustc. To make this easier Fargo will convert a “++” parameter to “--” when invoking cargo. For example, the following command:

fargo cargo rustc -- ++ --emit=llvm-ir

will get cargo to cause rustc to emil llvm ir files.

Running view-producing Rust binaries

fargo run has the options, --run-with-tiles and --run-with-sessionctl, that will use tiles_ctl or sessionctl, respectively, to launch the Rust binary. Use this option when running if your binaries want to provide a view provider service

Creating a .cargo/config

fargo write-config will create a .cargo directory with a config file that tells cargo how to compile artifacts for Fuchsia and how to run them. Creating such a config file might allow some tools to work that otherwise would not be able to compile artifacts for Fuchsia.

The config file created will be for the architecture and debug/release options that are passed to Fargo with the write-config command. If you wish to switch to a different architecture or build, re-run write-config.

The Fargo manifest file

Some build configuration needed to create a functioning Fuchsia package are not contained inside the Cargo.toml files generated as part of fx build. The Fargo manifest file Fargo.toml exists to provide those configuration.

There are four properties that one can set with this file, library_search_paths, additional_shared_libraries, additional_static_libraries and data_files as shown in the example below.

    library_search_paths = [
        "obj/src/graphics/lib/compute/common",
        "obj/src/graphics/lib/compute/common/vk",
        "obj/src/graphics/lib/compute/hotsort/platforms/vk",
        "obj/src/graphics/lib/compute/spinel",
        "obj/src/graphics/lib/compute/spinel/platforms/vk",
        "obj/src/graphics/lib/compute/spinel/platforms/vk/targets/vendors/amd/gcn3",
        "obj/src/graphics/lib/compute/spinel/platforms/vk/targets/vendors/amd/gcn3/hotsort",
        "obj/src/graphics/lib/compute/spinel/platforms/vk/targets/vendors/arm/bifrost8",
        "obj/src/graphics/lib/compute/spinel/platforms/vk/targets/vendors/arm/bifrost8/hotsort",
        "obj/src/graphics/lib/compute/spinel/platforms/vk/targets/vendors/intel/gen8",
        "obj/src/graphics/lib/compute/spinel/platforms/vk/targets/vendors/intel/gen8/hotsort",
        "obj/src/graphics/lib/compute/spinel/platforms/vk/targets/vendors/nvidia/sm50",
        "obj/src/graphics/lib/compute/spinel/platforms/vk/targets/vendors/nvidia/sm50/hotsort",
    ]

    additional_shared_libraries = [
        "libvulkan.so",
        "librust-trace-provider.so",
    ]

    additional_static_libraries = [
        "hotsort_vk",
        "hotsort_vk_hs_amd_gcn3_u64",
        "hotsort_vk_hs_arm_bifrost8_u64",
        "hotsort_vk_hs_intel_gen8_u64",
        "hotsort_vk_hs_nvidia_sm35_u64",
        "spinel_vk_spn_amd_gcn3",
        "spinel_vk_spn_arm_bifrost8",
        "spinel_vk_spn_intel_gen8",
        "spinel_vk_spn_nvidia_sm50",
    ]

    data_files = [
        { src = "src/render/shaders/copy.comp.spv", dst = "data/shaders/copy.comp.spv"},
        { src = "src/render/shaders/motioncopy-unorm.comp.spv", dst = "data/shaders/motioncopy-unorm.comp.spv"},
        { src = "src/render/shaders/motioncopy-srgb.comp.spv", dst = "data/shaders/motioncopy-srgb.comp.spv"},
        { src = "examples/static/lenna.png", dst = "data/static/lenna.png"},
        { src = "examples/static/baboon.png", dst = "data/static/baboon.png"},
    ]

library_search_paths are additional paths to pass to rustc to resolve external references at compile time. The paths should be the partial path from the Fuchsia build directory.

additional_shared_libraries are the names of shared libraries that should be included in the Fuchsia package that is created by Fargo to run Rust executables on Fuchsia. These are expected to be found in the shared libraries folder in the Fuchsia build directory

additional_static_libraries are the names of static libraries that should be included in the link line when building with Fargo. The extract-linkage command can be used to parse the link output of fx build -v for search paths and library names. On Mac, copying the rustc line producing the binary and executing pbpaste | fargo extract-linkage is one way to use extract-linkage.

data_files are partial paths to additional data files to be included in the Fuchsia package that is created by Fargo to run Rust executables on Fuchsia. These paths should be the partial path from the root of the crate being compiled.

In the example above, Fargo.toml is used to resolve the static libraries used by Spinel, to include two shared libraries needed by some of the samples for Carnelian and to include two compiled shaders also needed by a particular sample.

Currently there is no way to limit these configuration to one example or binary.

Getting help

For problems getting the Fuchsia build to complete, the getting started page on fuchsia.dev is the best place to start looking for help.

For Fargo itself, the best place for help is the rust-fuchsia Google group.

Using different versions of cargo and rustc

By default Fargo will use the copies of cargo and rustc provided in $FUCHSIA_DIR/buildtools. To change this behavior, set the environmental variables FARGO_CARGO and FARGO_RUSTC before running Fargo.

If you need to be using a different version of nightly for some reason, you'll need the x86_64-fuchsia target. If you installed rust with rustup you can install the target with:

rustup default nightly
rustup target add x86_64-fuchsia

Environmental variables set by Fargo

CARGO_TARGET_[X86_64|AARCH64]_UNKNOWN_FUCHSIA_RUNNER - set to the Fargo binary to run remotely on simulator or device.

CARGO_TARGET_[X86_64|AARCH64]_UNKNOWN_FUCHSIA_RUSTFLAGS - set to provide linker flags

CARGO_TARGET_[X86_64|AARCH64]_UNKNOWN_FUCHSIA_LINKER - set to specify the linker

RUSTC - set to cause cargo to use the copy of rustc in buildtools

RUSTDOC - set to cause cargo to use the copy of rustdoc in buildtools

FUCHSIA_SHARED_ROOT - set to the directory containing shared libraries for the current selected architecture. Useful for build scripts.

ZIRCON_BUILD_ROOT - set to the zircon build directory for the current architecture. Useful for build scripts.

Using crates that link with native libraries

Some crates are wrappers around libraries written in other languages. An example of one such crate is cairo-rs. Cargo has to know what libraries need to be linked to a binary using such a crate and where to find those libraries.

Cargo uses build.rs files to locate such libraries. This provides a challenge for Fargo, as it is unlikely that such build.rs files would know how to cross compile their libraries for Fuchsia.

Luckily, many of the crates of interest which have native dependencies use pkg-config as one of the ways to find native dependencies. Fargo provides functions to set up and use a Fuchsia-specific pkg-config directory.

fargo pkg-config is a wrapper around pkg-config that sets the environment so that only packages found in the Fuchsia-specific pkg-config directory are visible. This is useful to test if a particular package is already installed.

fargo configure is a wrapper around a package's automake configure script. It takes care of setting up environmental variables such that many automake based packages will properly cross-compile.

See scripts/build_cairo_support.sh for an example of how to use these functions to build native support.

Fargo sets the following environmental variables before invoking configure:

CC, CXX, RANLIB, LD, AR, CFLAGS, CXXFLAGS, CPPFLAGS
LDFLAGS, PKG_CONFIG_PATH, PKG_CONFIG_LIBDIR,
PKG_CONFIG_ALL_STATIC

The --disable-cross-env option will prevent these environmental variables from being set when invoking cargo. This is useful when the components being built by C or C++ are intended for the host, not the target.

Fargo roadmap

The goal is to transition Fargo to using something like an SDK instead.