对于我目前的项目,如果我们能够从源代码重新编译arm工具链(gcc, c++stdlib, nanolibc等),我们可以解决这个问题。
我可以从arm网站下载源代码的快照。我找到了一个博客,但已经过时了。他所引用的pdf在快照中已经不存在了。
浏览解压的存档文件,我似乎找不到任何如何编译的说明。
我在哪里可以找到如何从源代码编译arm-none-eabi的文档?
下载站点提供的发行说明包括从源代码构建的说明。
我在这里做了一个快速的转录,但未来的读者应该注意,它可能已经过时了。
如何从源构建工具链
您可以使用Linaro ABE(高级构建环境)从源代码构建Arm GNU工具链,并提供ABE清单文件。
下面的例子展示了如何使用Linaro ABE构建系统从源代码构建gcc-arm-aarch64-none-elf工具链。
指令ABE对git-new-workdir有依赖,需要这个工具安装在/usr/local/bin目录下:
$ wget https://raw.githubusercontent.com/git/git/master/contrib/workdir/git-new-workdir $ sudo mv git-new-workdir /usr/local/bin $ sudo chmod +x /usr/local/bin/git-new-workdir
从下面的URL克隆ABE并签出stablebranch(参见获取ABE):
$ git clone https://git.linaro.org/toolchain/abe.git
创建构建目录并更改它。目录的任何名称都可以:
$ mkdir build && cd build
配置ABE(从构建目录):
$ ../abe/configure
从https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads下载工具链清单文件到所需工具链的构建文件夹中,例如,gcc-arm-aarch64-none-elf-abe-manifest.txt:
构建工具链(从构建目录):$ wget https://developer.arm.com/-/media/Files/downloads/gnu/11.2-2022.02/manifest/gcc-arm-aarch64-none-elf-abe-manifest.txt
$ ../abe/abe.sh --manifest gcc-arm-aarch64-none-elf-abe-manifest.txt --build all
构建的工具链将被安装在build_destdir/x86_64-unknown-linux-gnu/bin/目录下。
# Usage
# sudo ./build_arm
# Setup vars
export TARGET=arm-none-eabi
export PREFIX=/opt/gnuarm
export PATH=$PATH:$PREFIX/bin
export JN='-j 8'
export GCCVER=11.2.0
export BINUVER=2.37
rm -rf build-*
rm -rf gcc-*
rm -rf binutils-*
# Get archives
wget https://ftp.gnu.org/gnu/binutils/binutils-$BINUVER.tar.gz
wget https://ftp.gnu.org/gnu/gcc/gcc-$GCCVER/gcc-$GCCVER.tar.gz
# Extract archives
tar xf binutils-$BINUVER.tar.gz
tar xf gcc-$GCCVER.tar.gz
# Build binutils
mkdir build-binutils
cd build-binutils
../binutils-$BINUVER/configure --target=$TARGET --prefix=$PREFIX
echo "MAKEINFO = :" >> Makefile
make $JN all
sudo make install
# Build GCC
mkdir ../build-gcc
cd ../build-gcc
../gcc-$GCCVER/configure --target=$TARGET --prefix=$PREFIX --without-headers --with-newlib --with-gnu-as --with-gnu-ld --enable-languages='c' --enable-frame-pointer=no
make $JN all-gcc
sudo make install-gcc
# Build libgcc.a
make $JN all-target-libgcc CFLAGS_FOR_TARGET="-g -O2"
sudo make install-target-libgcc
对于那些遇到同样问题的人,我找到了手臂工具链12.2的解决方案。它可能也适用于以前版本的工具链,我没有检查过。12.2引入c++ 20支持。
我将其装箱如下
# install dependencies for python3.8
RUN apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev wget -y
# install arm toolchain
RUN ARM_TOOLCHAIN_VERSION=12.2.Rel1
RUN curl -Lo gcc-arm-none-eabi.tar.xz "https://developer.arm.com/-/media/Files/downloads/gnu/12.2.Rel1/binrel/arm-gnu-toolchain-12.2.Rel1-x86_64-arm-none-eabi.tar.xz"
RUN mkdir -p /opt/gcc-arm-none-eabi
RUN tar xf gcc-arm-none-eabi.tar.xz --strip-components=1 -C /opt/gcc-arm-none-eabi
ENV PATH="/opt/gcc-arm-none-eabi/bin:${PATH}"
# test arm-none-gcc
RUN arm-none-eabi-gcc --version
# install python3.8
RUN wget https://www.python.org/ftp/python/3.8.12/Python-3.8.12.tgz
RUN tar -xf Python-3.8.12.tgz
WORKDIR /Python-3.8.12
RUN ./configure --enable-optimizations
RUN make -j 4
RUN make altinstall
#attempt to fix libncursesw.so.5
RUN apt install libncurses5 -y
RUN apt install libncursesw5 -y
# test arm-none-gdb
RUN arm-none-eabi-gdb --version
所以它基本上是:
- 安装一堆依赖项,
- 下载臂工具链12.2
- 从源代码编译python3.8,并将python3.8安装在任何现有的python版本旁边。
- 测试它是否可以执行arm-none-eabi-gdb
如果你想在你的主机操作系统上执行这个命令,删除dockerRUN
命令,并在这里和那里添加一些sudo:)。
如果它有任何帮助,我的完整的docker文件(其中安装了一堆更多的,像jlink支持能够编译/运行/调试vscode当附加到这个docker容器)
FROM ubuntu
ENV UDEV=on
RUN apt-get update -y
RUN apt-get upgrade -y
# Install dependencies for JLink
RUN apt install libxcb-render-util0-dev -y
RUN apt install libxrender1 libxcb-shape0 libxcb-randr0 libxcb-xfixes0 libxcb-sync1 libxcb-shm0 libxcb-icccm4 libxcb-keysyms1 libxcb-image0 libxkbcommon0 libxkbcommon-x11-0 libfontconfig1 libfreetype6 libxext6 libx11-xcb1 libsm6 libice6 libglib2.0-0 -y
# Install dependencies for JLinkServer
RUN apt install libxcursor-dev libxfixes3 libxrandr2 -y
# install jlink
RUN mkdir -p /home/Downloads
COPY JLink_Linux_V786b_x86_64.deb /home/Downloads/JLink_Linux_V786b_x86_64.deb
RUN dpkg --unpack /home/Downloads/JLink_Linux_V786b_x86_64.deb
RUN rm /var/lib/dpkg/info/jlink.postinst -f
RUN dpkg --configure jlink
RUN apt install -yf
# Install curl
RUN apt install curl bzip2 -y
# install dependencies for arm-none-eabi-gdb
#RUN apt install libncurses5 -y
# install dependencies for python3.8
RUN apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev wget -y
# install arm toolchain
RUN ARM_TOOLCHAIN_VERSION=12.2.Rel1
RUN curl -Lo gcc-arm-none-eabi.tar.xz "https://developer.arm.com/-/media/Files/downloads/gnu/12.2.Rel1/binrel/arm-gnu-toolchain-12.2.Rel1-x86_64-arm-none-eabi.tar.xz"
RUN mkdir -p /opt/gcc-arm-none-eabi
RUN tar xf gcc-arm-none-eabi.tar.xz --strip-components=1 -C /opt/gcc-arm-none-eabi
ENV PATH="/opt/gcc-arm-none-eabi/bin:${PATH}"
# test arm-none-gcc
RUN arm-none-eabi-gcc --version
# install cmake
RUN apt install cmake -y
RUN apt install udev -y
RUN /lib/systemd/systemd-udevd --daemon
# install git
RUN apt install git -y
# install ninja
RUN apt install ninja-build python3 pip -y
RUN pip install meson
# install python3.8
RUN wget https://www.python.org/ftp/python/3.8.12/Python-3.8.12.tgz
RUN tar -xf Python-3.8.12.tgz
WORKDIR /Python-3.8.12
RUN ./configure --enable-optimizations
RUN make -j 4
RUN make altinstall
#attempt to fix libncursesw.so.5
RUN apt install libncurses5 -y
RUN apt install libncursesw5 -y
# test arm-none-gdb
RUN arm-none-eabi-gdb --version
ARG USER_ID
ARG GROUP_ID
RUN addgroup --gid $GROUP_ID user && adduser --disabled-password --gecos '' --uid $USER_ID --gid $GROUP_ID user
USER user
WORKDIR /home/dev/
CMD bash
我尝试了几种不同的工具来构建工具链,最后我只是基于GCC文档https://gcc.gnu.org/wiki/InstallingGCC制作了一个脚本,以及其他一些东西。这建立了一个功能齐全的手臂工具链与gcc
,gdb
,newlib-nano
和picolibc
。它也有libssp
,由于某种原因从arm的官方版本中缺失:
#!/bin/bash
set -e
set -v
# Install prerequisites
apt-get -y install libgmp-dev
libmpfr-dev
libmpc-dev
libexpat-dev
liblzma-dev
libsource-highlight-dev
libpython3-dev
libbabeltrace-dev
libipt-dev
libncurses5-dev
libdebuginfod-dev
meson
ninja-build
texinfo
pkg-config
python3
python-is-python3
flex
diffutils
git
apt-get -y install --install-suggests gcc
# For mingw
# pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-mpc mingw-w64-x86_64-mpfr mingw-w64-x86_64-gmp mingw-w64-x86_64-meson mingw-w64-x86_64-ninja texinfo bison flex diffutils git
# Setup build directory
PREFIX=$HOME/gcc-cross-compiler/build
mkdir -p $PREFIX
cd $PREFIX/..
# Clone repositories (may be wise to checkout specific versions i.e. latest release tag)
git clone --depth=1 -b releases/gcc-13.1.0 git://gcc.gnu.org/git/gcc.git
git clone --depth=1 -b newlib-4.3.0 https://sourceware.org/git/newlib-cygwin.git
git clone --depth=1 -b gdb-13.2-release git://sourceware.org/git/binutils-gdb.git
git clone --depth=1 -b 1.8.2 https://github.com/picolibc/picolibc.git
# Build binutils
cd $PREFIX/.. && mkdir -p binutils-build && cd binutils-build
../binutils-gdb/configure
--target=arm-none-eabi
--prefix=$PREFIX
--with-pkgversion=my-custom-$(date -I)
--with-sysroot
--with-lzma
--with-expat
--with-python
--enable-ld=yes
--enable-gold=no
--enable-plugins
--enable-multilib
--enable-lto
--enable-source-highlight
--disable-werror
--disable-nls
--disable-warn-rwx-segments
make -j$(nproc)
make install
# Build gcc (state-1), this is so that our libc implementation below (newlib)
# gets compiled with the nice shiny new compiler version as well. This build
# will only build the gcc compiler itself, not all of the libraries like libgcc etc.
# because for that we need a libc implementation... which we haven't built yet.
#
# You could alternatively skip this step by installing a arm-none-eabi-gcc
# compiler from somewhere else (i.e. sudo apt install gcc-arm-none-eabi)
# and use that to compile newlib instead, which will probably work so long as
# it has been compiled with multilib support for at least rmprofile
# (because of the `--with-multilib-list=rmprofile` below)
cd $PREFIX/.. && mkdir -p gcc-stage1-build && cd gcc-stage1-build
../gcc/configure
--prefix=$PREFIX
--enable-languages=c
--target=arm-none-eabi
--with-pkgversion=stage1-my-custom-$(date -I)
--with-newlib
--with-sysroot=$PREFIX/arm-none-eabi
--with-multilib-list=rmprofile
--without-headers
--enable-lto
--enable-multiarch
--disable-libssp
--disable-nls
--disable-tls
--disable-threads
--disable-shared
make -j$(nproc) all-gcc
make install-gcc
export PATH=$PREFIX/bin:$PATH
# Build newlib using our stage1 compiler (this is essentially newlib-nano)
cd $PREFIX/.. && mkdir -p newlib-build && cd newlib-build
../newlib-cygwin/configure
--target=arm-none-eabi
--prefix=$PREFIX
--disable-newlib-supplied-syscalls
--disable-newlib-io-float
--disable-newlib-io-long-double
--disable-newlib-io-pos-args
--disable-newlib-io-c99-formats
--disable-newlib-io-long-long
--disable-newlib-multithread
--disable-newlib-retargetable-locking
--disable-newlib-wide-orient
--disable-newlib-fseek-optimization
--disable-newlib-fvwrite-in-streamio
--disable-newlib-unbuf-stream-opt
--disable-newlib-atexit-dynamic-alloc
--enable-newlib-nano-malloc
--enable-newlib-nano-formatted-io
--enable-newlib-global-atexit
--enable-lite-exit
--enable-newlib-reent-small
--enable-libssp
--enable-target-optspace
make -j$(nproc)
make install
# Build gcc (stage-2), this builds the whole gcc featureset,
# including the compiler, and all the gnu compiler libraries
cd $PREFIX/.. && mkdir -p gcc-build && cd gcc-build
../gcc/configure
--prefix=$PREFIX
--enable-languages=c,c++
--target=arm-none-eabi
--with-pkgversion=my-custom-$(date -I)
--with-newlib
--with-sysroot=$PREFIX/arm-none-eabi
--with-multilib-list=rmprofile
--without-headers
--enable-lto
--enable-target-optspace
--enable-multiarch
--disable-libssp
--disable-nls
--disable-tls
--disable-threads
--disable-shared
make -j$(nproc)
make install
# Build picolibc
cd $PREFIX/.. && mkdir -p picolibc-build && cd picolibc-build
../picolibc/scripts/do-configure arm-none-eabi
-Dsysroot-install=true
-Dfast-strcmp=false
-Dio-c99-formats=false
-Dnewlib-global-atexit=true
-Dnewlib-multithread=false
-Dnewlib-retargetable-locking=false
ninja
ninja install
此处维护:https://gist.github.com/badcf00d/2f6054441375d9c94896aaa8e878ab4f
主要的警告是nano.specs
文件不会真正工作,因为"newlib-nano"只是简单地用一些标志编译newlib使其更小。arm ABE编译器只编译newlib两次,cp
是较小的一个到*-nano.a。但是我不关心更大的newlib构建,所以我只编译newlib一次,使用较小的配置,所以lib/libc.a
是newlib-nano。我通常只是编辑nano.specs
文件,从所有内容中删除-nano
。
一旦建立,只需将其添加到您的PATH
,你应该很好去,像:
export PATH="$HOME/gcc-cross-compiler/build/bin/:$PATH"
您也可以在mingw/msys2中使用此脚本来编译Windows上的工具链(参见pacman
命令的注释)。