LearningC
LearningC

Reputation: 98

How do I cross-compile C for Raspberry Pi and OpenWrt from Ubuntu?

My question is the following:

To run my C program, do I need to cross-compile the code for OpenWrt - or do I need to cross-compile the code for RaspberryPi?

To be more specific, I've found some tutorials about cross-compiling C for RaspberryPi... but does it not depend on the OS (OpenWrt in this case)?

Should I follow the cross-compilation for OpenWrt or the simple cross-compilation for RaspberryPi?

Upvotes: 1

Views: 1264

Answers (2)

Thraetaona
Thraetaona

Reputation: 31

The vendor (i.e., OpenWRT) in this case is not very important; mainly three things matter: your target CPU architecture (e.g., MIPS); its O/S (e.g., Linux); and its libc (e.g., musl, glibc).

Given that OpenWRT is just Linux with musl instead of glibc, you could use both OpenWRT-provided toolchains (as the other answer indicates) or musl wrappers around GCC (https://musl.cc/). However, there is also a third and more straightforward way: cross-compiling with LLVM.

LLVM was designed to be a cross-compiler from the beginning; instead of having to manually download and update separate compiler binaries for every architecture/OS/libc combination (as is the case with GCC), you can download LLVM/Clang once and merely specify a "target triplet" each time (sample installation for Debian/Ubuntu):

apt install llvm clang
apt install lld
apt install llvm-binutils

Now, for each target, you will only have to install compile-time built-in headers and runtime (either LLVM's compiler-rt or libgcc) followed by specifying the target triplet.

(Note: libgcc is different from glibc and GCC; you can learn more about it here.)

For instance, your case with a 64-bit arm (aarch64) machine running OpenWRT (linux) and musl libc would require the following runtime library and triplet:

1.

apt install libclang-rt-dev:arm64 OR apt install libgcc1-arm64-cross

2.

clang main.c --target=aarch64-linux-musl -fuse-ld=lld -o program

As another example, a 32-bit mips machine with soft floats (sf) would be as follows:

apt install libgcc1-mips-cross

clang main.c --target=mips-linux-muslsf -fuse-ld=lld -o program

(Note: As of the time of writing, LLVM has a small bug with soft-float MIPS targets; I documented said bug and its workaround here.)

Upvotes: 0

Justin Yu
Justin Yu

Reputation: 61

Go and download the toolchain for Pi4 https://downloads.openwrt.org/releases/22.03.0/targets/bcm27xx/bcm2711/openwrt-toolchain-22.03.0-bcm27xx-bcm2711_gcc-11.2.0_musl.Linux-x86_64.tar.xz

Unzip and there is a gcc compiler

Assume that you have a main.c with the following content

#include <stdio.h>

int main()
{
    printf("Hello World");

    return 0;
}

The real gcc compile is sitting at openwrt-toolchain-22.03.0-bcm27xx-bcm2711_gcc-11.2.0_musl.Linux-x86_64/toolchain-aarch64_cortex-a72_gcc-11.2.0_musl/bin/aarch64-openwrt-linux-musl-gcc-11.2.0

Use the GCC to compile your main.c

./openwrt-toolchain-22.03.0-bcm27xx-bcm2711_gcc-11.2.0_musl.Linux-x86_64/toolchain-aarch64_cortex-a72_gcc-11.2.0_musl/bin/aarch64-openwrt-linux-musl-gcc-11.2.0 main.c

Compile

~/test$ ./openwrt-toolchain-22.03.0-bcm27xx-bcm2711_gcc-11.2.0_musl.Linux-x86_64/toolchain-aarch64_cortex-a72_gcc-11.2.0_musl/bin/aarch64-openwrt-linux-musl-gcc-11.2.0 main.c
aarch64-openwrt-linux-musl-gcc-11.2.0: warning: environment variable 'STAGING_DIR' not defined
aarch64-openwrt-linux-musl-gcc-11.2.0: warning: environment variable 'STAGING_DIR' not defined
aarch64-openwrt-linux-musl-gcc-11.2.0: warning: environment variable 'STAGING_DIR' not defined
~/test$ ls
a.out
main.c
openwrt-toolchain-22.03.0-bcm27xx-bcm2711_gcc-11.2.0_musl.Linux-x86_64
openwrt-toolchain-22.03.0-bcm27xx-bcm2711_gcc-11.2.0_musl.Linux-x86_64.tar.xz

Check the executable

~/test$ file a.out
a.out: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-aarch64.so.1, with debug_info, not stripped

Upvotes: 0

Related Questions