2

I'm trying to cross-compile a Rust binary with Docker for raspberry-pi on ARM6 architecture. I'm specifying the environment arguments for Cargo prior to building, but it errors out on a specific library saying that the "-m64" argument was not found.

The environment arguments when the error happens are different than what I set up in the Dockerfile; why are they being reset?

FROM ubuntu:latest

RUN apt-get update && \
    apt-get install \
    --yes \
    binutils \
    build-essential \
    curl \
    git \
    wget \
    libudev-dev \
    zip

ARG RASPBERRY_PI_TOOLS_COMMIT_ID=5caa7046982f0539cf5380f94da04b31129ed521
ENV CC=arm-linux-gnueabihf-gcc
ENV TARGET=arm-unknown-linux-gnueabihf
ENV CARGO_CFG_TARGET_ARCH=arm
ENV CARGO_CFG_TARGET_ENDIAN=little
ENV CARGO_CFG_TARGET_ENV=gnu
ENV CARGO_CFG_TARGET_FAMILY=unix
ENV CARGO_CFG_TARGET_OS=linux
ENV CARGO_CFG_TARGET_POINTER_WIDTH=32
ENV CARGO_FEATURE_DEFAULT=1
ENV CARGO_FEATURE_DEV_URANDOM_FALLBACK=1
ENV CARGO_FEATURE_RSA_SIGNING=1
ENV CARGO_FEATURE_USE_HEAP=1
ENV LD=/usr/bin/arm-linux-gnueabihf-ld
ENV LD_LIBRARY_PATH=/src/parity/target/release/deps:/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib:/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib
ENV QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf/libc
RUN wget https://github.com/raspberrypi/tools/archive/$RASPBERRY_PI_TOOLS_COMMIT_ID.zip -O /root/pi-tools.zip
RUN unzip /root/pi-tools.zip -d /root
RUN mv /root/tools-$RASPBERRY_PI_TOOLS_COMMIT_ID /root/pi-tools
ENV PATH=/root/pi-tools/arm-bcm2708/arm-linux-gnueabihf/bin:$PATH
ENV PATH=/root/pi-tools/arm-bcm2708/arm-linux-gnueabihf/libexec/gcc/arm-linux-gnueabihf/4.8.3:$PATH

# Install Rust.
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --verbose
ENV PATH=/root/.cargo/bin:$PATH

# Install the arm target for Rust.
RUN rustup target add arm-unknown-linux-gnueabihf
# Configure the linker for the arm target.
ENV PKG_CONFIG_ALLOW_CROSS=1 
RUN echo '[target.arm-unknown-linux-gnueabihf]\nlinker = "arm-linux-gnueabihf-gcc"' >> /root/.cargo/config

ENV USER=root
RUN cargo new /src
WORKDIR /src
RUN git clone https://github.com/paritytech/parity && cd parity && \
    /root/.cargo/bin/rustup target add arm-unknown-linux-gnueabihf && \
    /root/.cargo/bin/cargo build --target=arm-unknown-linux-gnueabihf --release --features final

# Verify that the output file is for armv6
RUN readelf --arch-specific ./target/arm-unknown-linux-gnueabihf/debug/src

RUN file /build/parity/target/armv7-unknown-linux-gnueabihf/release/parity

EXPOSE 8080 8545 8180
ENTRYPOINT ["/build/parity/target/armv7-unknown-linux-gnueabihf/release/parity"]

The error is:

process didn't exit successfully: `/src/parity/target/release/build/backtrace-sys-3c9a41016b6512eb/build-script-build` (exit code: 101)
--- stdout
TARGET = Some("x86_64-unknown-linux-gnu")
OPT_LEVEL = Some("3")
HOST = Some("x86_64-unknown-linux-gnu")
CC_x86_64-unknown-linux-gnu = None
CC_x86_64_unknown_linux_gnu = None
HOST_CC = None
CC = Some("arm-linux-gnueabihf-gcc")
CFLAGS_x86_64-unknown-linux-gnu = None
CFLAGS_x86_64_unknown_linux_gnu = None
HOST_CFLAGS = None
CFLAGS = None
DEBUG = Some("false")
running: "arm-linux-gnueabihf-gcc" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-m64" "-I" "src/libbacktrace" "-I" "/src/parity/target/release/build/backtrace-sys-5fc2d3da7fb5f8d4/out" "-fvisibility=hidden" "-DBACKTRACE_ELF_SIZE=64" "-DBACKTRACE_SUPPORTED=1" "-DBACKTRACE_USES_MALLOC=1" "-DBACKTRACE_SUPPORTS_THREADS=0" "-DBACKTRACE_SUPPORTS_DATA=0" "-DHAVE_DL_ITERATE_PHDR=1" "-D_GNU_SOURCE=1" "-D_LARGE_FILES=1" "-Dbacktrace_full=__rbt_backtrace_full" "-Dbacktrace_dwarf_add=__rbt_backtrace_dwarf_add" "-Dbacktrace_initialize=__rbt_backtrace_initialize" "-Dbacktrace_pcinfo=__rbt_backtrace_pcinfo" "-Dbacktrace_syminfo=__rbt_backtrace_syminfo" "-Dbacktrace_get_view=__rbt_backtrace_get_view" "-Dbacktrace_release_view=__rbt_backtrace_release_view" "-Dbacktrace_alloc=__rbt_backtrace_alloc" "-Dbacktrace_free=__rbt_backtrace_free" "-Dbacktrace_vector_finish=__rbt_backtrace_vector_finish" "-Dbacktrace_vector_grow=__rbt_backtrace_vector_grow" "-Dbacktrace_vector_release=__rbt_backtrace_vector_release" "-Dbacktrace_close=__rbt_backtrace_close" "-Dbacktrace_open=__rbt_backtrace_open" "-Dbacktrace_print=__rbt_backtrace_print" "-Dbacktrace_simple=__rbt_backtrace_simple" "-Dbacktrace_qsort=__rbt_backtrace_qsort" "-Dbacktrace_create_state=__rbt_backtrace_create_state" "-Dbacktrace_uncompress_zdebug=__rbt_backtrace_uncompress_zdebug" "-o" "/src/parity/target/release/build/backtrace-sys-5fc2d3da7fb5f8d4/out/src/libbacktrace/alloc.o" "-c" "src/libbacktrace/alloc.c"
cargo:warning=arm-linux-gnueabihf-gcc: error: unrecognized command line option '-m64'
exit code: 1
--- stderr
thread 'main

I've set my ENV TARGET=arm-unknown-linux-gnueabihf in the Dockerfile, but when the error happens and it complains about not understanding what -m64 is, it's compiling for a TARGET = Some("x86_64-unknown-linux-gnu"), which is not the target I specified.

How do I make compilation use the original target I specified in the Dockerfile?

This is the dockerhub build

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Yazanator
  • 127
  • 8

2 Answers2

3

TARGET isn't used by Cargo. Cargo can be configured by environment variables as follows:

Cargo can also be configured through environment variables in addition to the TOML syntax above. For each configuration key above of the form foo.bar the environment variable CARGO_FOO_BAR can also be used to define the value. For example the build.jobs key can also be defined by CARGO_BUILD_JOBS.

Source

You are confused by an environment variable that Cargo set for your build script:

Cargo sets several environment variables when build scripts are run. Because these variables are not yet set when the build script is compiled, the above example using env! won't work and instead you'll need to retrieve the values when the build script is run:

TARGET - the target triple that is being compiled for. Native code should be compiled for this triple. Some more information about target triples can be found in clang’s own documentation.

Source

To fix your docker script do:

ENV CARGO_BUILD_TARGET=arm-unknown-linux-gnueabihf

See:

Community
  • 1
  • 1
Stargateur
  • 24,473
  • 8
  • 65
  • 91
  • Thanks, will try this now! – Yazanator Jan 04 '19 at 14:22
  • Looks like still showing the same error after adding it to my Dockerfile. I'll try to compile it manually sans Dockerfile in case Docker is doing something weird. – Yazanator Jan 04 '19 at 14:52
  • Didn't work for me in the Dockerfile, but did so without Docker. I believe something in Running it from Docker causes this bug, will try to find a fix. – Yazanator Jan 04 '19 at 22:42
  • @Yazanator sorry I don't use docker so I can't help much about this, if this answer doesn't answer you don't accept it. – Stargateur Jan 05 '19 at 00:34
  • gotcha, I posted a solution I found a few hours back. Thanks for your help! – Yazanator Jan 05 '19 at 18:20
0

I should've been compiling to armhv7 which is compatible with the Raspberry Pi 3 Model B.

This is a Dockerfile that compiles the parity binary for armhv7:

FROM debian:latest

RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    ca-certificates \
    cmake \
    curl \
    git \
    pkg-config \
    gcc-arm-linux-gnueabihf \
    g++-arm-linux-gnueabihf \
    libc6-dev-armhf-cross \
    && rm -rf \
    /var/lib/apt/lists/*

RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \
        /etc/apt/sources.list.d/deb-src.list \
    && dpkg --add-architecture armhf \
    && apt-get update \
    && apt-get install -y \
        libssl-dev:armhf \
        libc6-dev:armhf \
    && rm -rf \
      /var/lib/apt/lists/*

ENV USER=root
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --verbose
ENV PATH=/root/.cargo/bin:$PATH

ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \
    CC_armv7_unknown_linux_gnueabihf="/usr/bin/arm-linux-gnueabihf-gcc" \
    CXX_armv7_unknown_linux_gnueabihf="/usr/bin/arm-linux-gnueabihf-g++" \
    CROSS_COMPILE="1" \
    OPENSSL_INCLUDE_DIR="/usr/include/arm-linux-gnueabihf" \
    OPENSSL_LIB_DIR="/usr/lib/arm-linux-gnueabihf"

RUN /root/.cargo/bin/rustup target add armv7-unknown-linux-gnueabihf

RUN dpkg --add-architecture armhf && \
    apt-get update && \
    apt-get install -y libudev-dev:armhf

RUN git clone https://github.com/paritytech/parity-ethereum.git && cd parity-ethereum && \
    cargo build --target=armv7-unknown-linux-gnueabihf --release


CMD ./parity-ethereum/target/armv7-unknown-linux-gnueabihf/release/parity

EXPOSE 8080 8545 8180
ENTRYPOINT ["/build/parity/target/armv7-unknown-linux-gnueabihf/release/parity"]
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Yazanator
  • 127
  • 8
  • It doesnt work and giving an error... error[E0658]: use of unstable library feature 'duration_as_u128' (see issue #50202) --> ethcore/src/engines/clique/mod.rs:342:75 – Hsn Apr 30 '19 at 15:10
  • any solution for that? – Hsn Apr 30 '19 at 15:44