Disabling the `C` extension for the `riscv64gc-unknown-linux-gnu` target

I'm currently trying to compile a simple Rust program down to riscv64, where the environment I'm working on does not have support for the c extension of risc-v. I've tried a ton of different routes, but rustc isn't seeming to want to disable the extension with -C target-feature=-c nor a custom target.

riscv64gc-unknown-linux-gnu target w/ RUSTFLAGS target feature disable
Using cross as a cross-compilation utility

CROSS_CONTAINER_OPTS="--platform linux/amd64" \
  CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C target-feature=-c,+crt-static" \
  cross build --release --target riscv64gc-unknown-linux-gnu -Z build-std

Docker builder container w/ custom target:

{
  "arch": "riscv64",
  "code-model": "medium",
  "cpu": "generic-rv64",
  "crt-objects-fallback": "false",
  "crt-static-respected": true,
  "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
  "dynamic-linking": false,
  "env": "gnu",
  "features": "+crt-static,+m,+a,+f,+d,-c",
  "linker": "rust-lld",
  "linker-flavor": "gnu-lld",
  "llvm-abiname": "lp64d",
  "llvm-target": "riscv64",
  "max-atomic-width": 64,
  "os": "linux",
  "position-independent-executables": false,
  "executables": true,
  "relocation-model": "static",
  "emit-debug-gdb-scripts": false,
  "target-family": [
    "unix"
  ],
  "target-pointer-width": "64"
}
FROM ubuntu:latest

ENV RUST_VERSION nightly
ENV SHELL=/bin/bash

RUN apt-get update && apt-get install --assume-yes --no-install-recommends \
    ca-certificates \
    build-essential \
    curl \
    g++-riscv64-linux-gnu \
    libc6-dev-riscv64-cross \
    binutils-riscv64-linux-gnu \
    llvm \
    clang \
    make \
    cmake \
    git 

RUN curl https://sh.rustup.rs -sSf | bash -s -- -y --default-toolchain ${RUST_VERSION} --component rust-src
ENV PATH="/root/.cargo/bin:${PATH}"

COPY ./riscv64g-unknown-linux-gnu.json .

ENV CC_riscv64g_unknown_linux_gnu=riscv64-linux-gnu-gcc \
    CXX_riscv64g_unknown_linux_gnu=riscv64-linux-gnu-g++ \
    CARGO_TARGET_RISCV64G_UNKNOWN_LINUX_GNU_LINKER=riscv64-linux-gnu-gcc \
    CARGO_TARGET_RISCV64G_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C target-feature=-c,+crt-static" \
    CARGO_BUILD_TARGET="/riscv64g-unknown-linux-gnu.json"

To run:

docker build -t riscv-builder -f rust-riscv-builder.dockerfile . && \
  docker run --rm -v `pwd`/.:/code -w="/code" --platform linux/amd64 riscv-builder cargo build --release -Z build-std

I've also tried adding -mno-shorten-memrefs to my linker arguments.


Each time, I'm getting a file with RVC (the c extension) still enabled:

$ file target/riscv64gc-unknown-linux-gnu/release/minimal
target/riscv64gc-unknown-linux-gnu/release/minimal: ELF 64-bit LSB executable, UCB RISC-V, RVC, double-float ABI, version 1 (SYSV), statically linked, for GNU/Linux 4.15.0, BuildID[sha1]=7452aafb7e4f3d7dbfddc44dc1019d6aab897d40, with debug_info, not stripped

or

$ file target/riscv64g-unknown-linux-gnu/release/minimal
target/riscv64g-unknown-linux-gnu/release/minimal: ELF 64-bit LSB executable, UCB RISC-V, RVC, double-float ABI, version 1 (SYSV), statically linked, BuildID[sha1]=d7e02c00e373aa1a596b1b66a49afe1c5d557100, for GNU/Linux 4.15.0, not stripped

Is there anything obvious I'm missing here? Any help would be appreciated!

1 Like