Skip to content

Recipes

Alexander Huszagh edited this page Jul 1, 2022 · 13 revisions

This contains recipes for common logic use cases.

Table of Contents

OpenSSL

You can either use the vendored or system packages for the openssl crate. See openssl-certs for a working project.

Vendored

Use the vendored feature of the openssl crate by adding the following to your dependencies in Cargo.toml:

openssl = { version = "0.10", features = ["vendored"] }

Pre-build

To install OpenSSL in an image with apt-get available add the following to your Cross configuration:

[target.x86_64-unknown-linux-gnu]
pre-build = ["dpkg --add-architecture arm64", "apt-get update && apt-get install --assume-yes libssl-dev:arm64"]

Custom dockerfile

A sample Dockerfile for aarch64 with OpenSSL support is:

FROM ghcr.io/cross-rs/aarch64-unknown-linux-gnu:edge
RUN dpkg --add-architecture arm64
RUN apt-get update && apt-get install --assume-yes libssl-dev:arm64

Build this image and use it, as is described extensively in Custom Images.

sccache

sccache support can be done either by sccache from source or using a pre-built binary.

  1. Create a script to install sccache in the image, either from a pre-built binary or from source.
  2. Extend a Dockerfile to install sccache in the image.
  3. Passthrough the appropriate environment variables in Cross.toml when using sccache.

Install Script

First, we need a script to copy into our image as sccache.sh (make sure the script is executable).

Pre-Built Binary

#!/bin/bash

set -x
set -euo pipefail

# shellcheck disable=SC1091
. lib.sh

main() {
    local triple
    local tag
    local td
    local url="https://github.com/mozilla/sccache"
    triple="${1}"

    install_packages unzip tar

    # Download our package, then install our binary.
    td="$(mktemp -d)"
    pushd "${td}"
    tag=$(git ls-remote --tags --refs --exit-code \
        "${url}" \
        | cut -d/ -f3 \
        | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \
        | sort --version-sort \
        | tail -n1)
    curl -LSfs "${url}/releases/download/${tag}/sccache-${tag}-${triple}.tar.gz" \
        -o sccache.tar.gz
    tar -xvf sccache.tar.gz
    rm sccache.tar.gz
    cp "sccache-${tag}-${triple}/sccache" "/usr/bin/sccache"
    chmod +x "/usr/bin/sccache"

    # clean up our install
    purge_packages
    popd
    rm -rf "${td}"
    rm "${0}"
}

main "${@}"

From Source

When installing from source, we can toggle various features, however it is highly recommended to use the vendored OpenSSL.

#!/bin/bash

set -x
set -euo pipefail

# shellcheck disable=SC1091
. lib.sh

main() {
    local triple
    local tag
    local td
    local url="https://github.com/mozilla/sccache"
    triple="${1}"

    install_packages ca-certificates curl unzip

    # install rust and cargo to build sccache
    export RUSTUP_HOME=/tmp/rustup
    export CARGO_HOME=/tmp/cargo
    curl --retry 3 -sSfL https://sh.rustup.rs -o rustup-init.sh
    sh rustup-init.sh -y --no-modify-path
    rm rustup-init.sh
    export PATH="${CARGO_HOME}/bin:${PATH}"
    rustup target add "${triple}"

    # download the source code from the latest sccache release
    td="$(mktemp -d)"
    pushd "${td}"
    tag=$(git ls-remote --tags --refs --exit-code \
        "${url}" \
        | cut -d/ -f3 \
        | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \
        | sort --version-sort \
        | tail -n1)
    curl -LSfs "${url}/archive/refs/tags/${tag}.zip" \
        -o sccache.zip
    unzip sccache.zip
    mv "sccache-${tag//v/}" sccache
    rm sccache.zip

    # build from source for the desired architecture
    # you can also use additional features here
    cd sccache
    cargo build --release --target "${triple}" \
        --features=all,"openssl/vendored"
    cp "target/${triple}/release/sccache" "/usr/bin/sccache"

    # clean up our install
    rm -r "${RUSTUP_HOME}" "${CARGO_HOME}"
    purge_packages
    popd
    rm -rf "${td}"
    rm "${0}"
}

main "${@}"

Dockerfile

Next, extend our Dockerfile and build our image, saved as Dockerfile.${target}, where ${target} is replaced by our desired target (such as x86_64-unknown-linux-musl).

FROM ghcr.io/cross-rs/${target}:main
ARG DEBIAN_FRONTEND=noninteractive

COPY sccache.sh /
RUN /sccache.sh x86_64-unknown-linux-musl

ENV RUSTC_WRAPPER="/usr/bin/sccache"

Build our Docker image with:

docker build --tag ${target}:sccache \
    --file Dockerfile.${target} .

Cross.toml

Now, we need to passthrough our environment variables and ensure they're exported when running cross. In Cross.toml, define:

[target.${target}]
image = "${target}:sccache"

[build.env]
passthrough = [
    "SCCACHE_ERROR_LOG",
    "SCCACHE_LOG",
    "SCCACHE_AZURE_CONNECTION_STRING",
    "SCCACHE_AZURE_BLOB_CONTAINER",
    "SCCACHE_DIR",
]

Building with sccache

Finally, we can run cross with our sccache environment variables defined using cross:

SCCACHE_LOG=trace SCCACHE_DIR=/path/to/sccache/cache \
    cross build --target "${target}" --verbose

Using Clang and Software Collections on CentOS7

In order to use Clang on CentOS 7, you must both install the SCL repository, the LLVM toolset, and set the necessary paths to clang and LLVM. A sample Dockerfile is as follows:

FROM ghcr.io/cross-rs/x86_64-unknown-linux-gnu:main-centos

RUN yum update -y && \
    yum install centos-release-scl -y && \
    yum install llvm-toolset-7 -y

ENV LIBCLANG_PATH=/opt/rh/llvm-toolset-7/root/usr/lib64/ \
    LIBCLANG_STATIC_PATH=/opt/rh/llvm-toolset-7/root/usr/lib64/ \
    CLANG_PATH=/opt/rh/llvm-toolset-7/root/usr/bin/clang

Build this image and use it, as is described extensively in Custom Images.