如何从 Ubuntu 为 Raspberry Pi 和 OpenWrt 交叉编译 C?

问题描述 投票:0回答:2
  • 我正在使用 RaspberryPi;我在这个 RaspberryPi 上安装了 OpenWrt。
  • 我需要在OpenWrt上执行一个C程序。
    • 我有 Ubuntu 上的源代码。
    • 我知道我需要交叉编译代码。

我的问题如下:

要运行我的 C 程序,我需要交叉编译 OpenWrt 的代码吗?还是需要交叉编译 RaspberryPi 的代码?

更具体地说,我找到了一些关于为 RaspberryPi 交叉编译 C 的教程...但它不依赖于操作系统(在本例中是OpenWrt)?

我应该遵循OpenWrt的交叉编译还是RaspberryPi的简单交叉编译?

c raspberry-pi cross-compiling openwrt
2个回答
0
投票

去下载 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

解压后有一个

gcc
编译器

假设您有一个包含以下内容的

main.c

#include <stdio.h>

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

    return 0;
}

真正的 gcc 编译位于

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

使用 GCC 编译你的

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

编译

~/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

检查可执行文件

~/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

0
投票

在这种情况下,供应商(即OpenWRT)并不是很重要;主要有三件事很重要:您的目标 CPU 架构(例如,MIPS); 其操作系统(例如,Linux);和 其 libc(例如,muslglibc)。

鉴于 OpenWRT 只是带有 musl 而不是 glibc 的 Linux,您可以使用 OpenWRT 提供的工具链(如其他答案所示) GCC 周围的 musl 包装器(https://musl.cc/)。 然而,还有第三种更直接的方法:与 LLVM 交叉编译。

LLVM 从一开始就被设计为一个交叉编译器;您无需为每个架构/操作系统/libc 组合手动下载和更新单独的编译器二进制文件(如 GCC 的情况),您可以下载 LLVM/Clang 一次,每次只需指定一个“目标三元组”(示例安装)对于 Debian/Ubuntu):

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

现在,对于每个目标,您只需安装编译时内置标头和运行时(LLVM 的

compiler-rt
libgcc
),然后指定目标三元组。

(注意:libgcc 与 glibc 和 GCC 不同;您可以在此处了解更多信息。)

例如,您的案例具有运行 OpenWRT (
aarch64
) 和
linux
libc 的 64 位 Arm (
musl
) 机器,需要以下运行时库和三元组:

1.

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

2.

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

作为另一个例子,具有软浮点数 (
mips
) 的 32 位
sf
机器将如下所示:

apt install libgcc1-mips-cross

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

(注意:截至撰写本文时,LLVM 在软浮点 MIPS 目标方面存在一个小错误;我在这里记录了该错误及其解决方法。)
© www.soinside.com 2019 - 2024. All rights reserved.