How to cross-compile Coreutils or other GNU projects with clang/LLVM?

Viewed 911

I have a tough need to compile Coreutils with llvm for other arch: arm/aarch64/mips/mips32/ppc/ppc32...

Since I install all the gcc-cross tools like mips-linux-gnu, powerpc64-linux-gnu and if I have a simple C program like that test.c

#include<stdio.h>
int main(){
    printf("hello!");
    return 0;
}

I can compile it to the arch, i.e.

clang --target=mips64-linux-gnuabi64 test.c -o test-mips64
āžœ  tests file test-mips64 
test-mips64: ELF 64-bit MSB executable, MIPS, MIPS64 rel2 version 1 (SYSV), dynamically linked, interpreter /lib64/ld.so.1, BuildID[sha1]=7b33d55a0d08e6cd18d966341590dc351e346a78, for GNU/Linux 3.2.0, not stripped

I try to the same way for compile Coreutils that try to set

export CC=clang
export CXX=clang++
CFLAGS = "--target=mips64-linux-gnuabi64"
./configure --host=mips64-linux-gnuabi64

Howerver, every time got errors in configure or make...

How should I set the configure? Can I easily compile Coreuntils with llvm for other archs?

2 Answers

It's a bit tricky to get the command-line options right for cross-compiling. I got it to work with the commands below, assuming you're working on a Debian-based system (like Debian or Ubuntu). Here are the steps.

  1. Install gcc-mips64-linux-gnuabi64 and gcc-powerpc64-linux-gnu.
  2. Choose the correct arguments for CFLAGS
    • -B/usr/mips64-linux-gnuabi64/bin/ to indicate we want to use the linker ld within that directory. Do the same for powerpc.
    • --target=mips64-linux-gnuabi64 to indicate what our target for compilation is. Do the same for powerpc.
    • -I/usr/mips64-linux-gnuabi64/include to include header files. Do the same for powerpc.
  3. Use ./configure --host=mips64-linux-gnuabi to configure for mips64 and ./configure --host=powerpc64-linux-gnueabi to configure for powerpc64.

Here are the commands to compile for mips64:

make clean
CFLAGS="-B/usr/mips64-linux-gnuabi64/bin/ --target=mips64-linux-gnuabi64 -I/usr/mips64-linux-gnuabi64/include" \
    ./configure --host=mips64-linux-gnuabi
make

And the commands to compile for powerpc64:

make clean
CFLAGS="-B/usr/powerpc64-linux-gnu/bin/ --target=powerpc64-linux-gnueabi -I/usr/powerpc64-linux-gnu/include" \
    ./configure --host=powerpc64-linux-gnueabi
make

Here is the output of file ./src/ls to demonstrate that it is a powerpc64 executable:

$ file ./src/ls
./src/ls: ELF 64-bit MSB executable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), dynamically linked, interpreter /lib64/ld64.so.1, for GNU/Linux 3.2.0, BuildID[sha1]=97fe33981ca0112160f44a6fb678d6dc1b462114, not stripped

Below is a Dockerfile that can be used to reproducibly cross-compile coreutils for mips64 and powerpc64.

# Cross-compile GNU coreutils for mips64 and powerpc64 using clang.
# With help from https://medium.com/@wolfv/cross-compiling-arm-on-travis-using-clang-and-qemu-2b9702d7c6f3

FROM debian:buster

# Install compile-time dependencies.
RUN apt-get update \
    && apt-get install --yes \
        clang \
        curl \
        gcc-mips64-linux-gnuabi64 \
        gcc-powerpc64-linux-gnu \
        make \
        perl \
    && rm -rf /var/lib/apt/lists/*

# Download source code for release.
WORKDIR /tmp/coreutils
RUN curl -fsSL https://ftp.gnu.org/gnu/coreutils/coreutils-8.32.tar.xz \
    | tar xJ --strip-components 1

# Compile and install for mips64.
RUN CFLAGS="-B/usr/mips64-linux-gnuabi64/bin/ --target=mips64-linux-gnuabi64 -I/usr/mips64-linux-gnuabi64/include" \
        ./configure --host=mips64-linux-gnuabi --prefix=/opt/coreutils-mips \
    && make \
    && make install

# Compile and install for powerpc64.
RUN make clean \
    && CFLAGS="-B/usr/powerpc64-linux-gnu/bin/ --target=powerpc64-linux-gnueabi -I/usr/powerpc64-linux-gnu/include" \
        ./configure --host=powerpc64-linux-gnueabi --prefix=/opt/coreutils-powerpc64 \
    && make \
    && make install

# Keep only the compiled programs from the previous stage.
FROM debian:buster
COPY --from=0 /opt /opt

I am current working on a simple build tool in Python that maybe help you. Unfortunately, still at moment, lacks clang implementation, but works fine with GCC and MSVC. Basically the thing mix Json parameters files to generate command line building.

CppMagic

Related