Windows上で動作するARMのクロスコンパイラの作成手順(GCC 8.2.1 arm-unknown-linux-gnueabihf)

## 概要

- arm DeveloperでWindows版が配布されていないToolchainをビルドする。
  
- ターゲットはarmv7-unknown-linux-gnueabihf(Linux用バイナリ)
  
- 作成したToolchainはRustのクロス環境で使用する。
  

## はじめに

今回の手順で必要なファイルは以下から取得してください。

https://github.com/bluexe203/crosstool-builder

本手順で作成したToolchainはこれです。
2022/09/01更新
ld.gold.exeが動作しなかった不具合を修正しました。
修正内容はbinutilsのconfigureに--enable-pluginsを追加しました。

https://stackoverflow.com/questions/46558696/build-gccgo-got-linker-error

[buildroot_gcc8.2.1_armv7_Windows.7z](https://github.com/bluexe203/crosstool-builder/releases/download/v0.10/buildroot_gcc8.2.1_armv7_Windows.7z)

本記事は以下のサイトの内容を今回の環境用(GCC 8.2.1 arm-unknown-linux-gnueabihf)に変更したものになります。この情報が無ければ今回のtoolchainの作成は不可能でした。

http://www.katsuster.net/static/2019/201904.html#20190429

記事の最初にあるgithubのリンクも記事で公開されいてるリポジトリをforkしたものになります。

## 環境の準備

ToolchainのビルドにはUbuntu20.04LTSを使用します。

## パッケージのインストール

以前に投稿した記事と同様の環境を準備します。

https://qiita.com/bluexe203/items/ddb972896ce3acc41d1d

ターミナルを起動し以下のコマンドを実行してください。

```
sudo apt update
#必須では無いが入れておくと便利
sudo apt install open-vm-tools
sudo apt install open-vm-tools-desktop
sudo apt install cifs-utils

#開発環境ビルド用
sudo apt install build-essential
sudo apt install mingw-w64
sudo apt install python
sudo apt install git
sudo apt install flex bison autogen automake autoconf libtool texinfo gawk libncurses5-dev libpython2.7-dev gcc-multilib g++-multilib dejagnu lsb zlib1g-dev
```

## ビルドスクリプトのダウンロード

~/work を作成し、そこへスクリプトをダウンロードします。

```bash
cd ~
mkdir work
cd work
# Download BuildScripts
git clone https://github.com/bluexe203/crosstool-builder.git
# Exec download.sh(download GCC, binutils, glibc, LinuxHeader, etc)
cd crosstool-builder
bash download.sh
# Check Download Files
ls tmp
# $ binutils-2.30  gcc-arm-src-snapshot-8.2-2018.08  glibc-2.28  linux-4.19
```

## ツールチェーンのビルド

ビルドにはかなり時間がかかります。

以下の順序でビルドされます。

- linux-headers
- binutils
- gcc-static
- glibc
- gcc-shared-glibc
- binutils-mingw
- gcc-shared-glibc-mingw

```bash
# cd ~/work/crosstool-builder
# Setup Build Env
source env.sh
# Build Toolchain
make -j8 install
```

buildroot/以下にツールチェーンが展開されます。

※注意：今回の手順では、bin/やarm-linux-gnueabi/以下にLinux用のバイナリとWindows用のバイナリが同じ場所に配置されます。Linux用のバイナリはWindowsでは不要ですので適宜手動で削除してください。(別の手段があればコメントを宜しくお願いします)

```bash
$ ls buildroot/
arm-linux-gnueabi  bin  include  lib  libexec  share
```

## Windows用にディレクトリをアーカイブする

作成したツールチェーンは一部のライブラリがシンボリックリンクで作成されています。

p7zip-fullをインストールし、"-l" のオプションを付けて圧縮すれば、シンボリックリンクを辿った実ファイルを格納してくれます。

```bash
sudo apt install p7zip-full
# -l convert symbolic link to Linked file
7z a -l buildroot.7z buildroot/
```

## Windows10上での作業

上記で作成したbuildroot.7zを解凍します。 (例： C:\buildroot)

PowerShellでユーザ環境変数のPathを設定します。

```powershell
 $tmpUserPath = [System.Environment]::GetEnvironmentVariable("Path", "User")
 $tmpUserPath += ";C:\buildroot\bin"
 [System.Environment]::SetEnvironmentVariable("Path", $tmpUserPath, "User")
```

一旦PowerShellを閉じて、また再度開きます。

以下のコマンドを実行してバージョンが表示されれば成功です。

```powershell
# Check Installed gcc
arm-unknown-linux-gnueabihf-gcc -v
```

これで作業は完了です。

## Tips

### Rust用のセットアップ

以下の手順のツールチェーンの部分の差し替えになります。
このRust環境で利用するために今回のツールチェーンを作成しました。

https://qiita.com/bluexe203/items/12e67ac6f2541e99b967

本ツールチェーンで作成されるgccはarm-unknown-linux-gnueabihfです。

.cargo/config

リンカーにはld.goldを使用します。
```ini
[target.armv7-unknown-linux-gnueabihf]
linker = "arm-unknown-linux-gnueabihf-gcc"
rustflags = ["-C", "link-arg=-fuse-ld=gold"]
```

### GCCのビルドツールの選定について

いずれもWindows用のexeを作成する際に問題が出たため断念しました。

- Linaro ABE
  
  - 今回利用しようとしましたが、途中でエラーが発生しビルドできませんでした。
    
  - 使用したGCC8.3用の"gcc-arm-arm-none-linux-gnueabihf-abe-manifest.txt" は
    
    gcc_filespecが無いので、自分で追記が必要です。（追加後上のエラーが発生したため断念しました。）
    
- buildroot
  
  - mingwホストのビルド方法がわからないため、利用しませんでした。
    
- crosstool-NG
  
  - 今回は試してませんが、以前使用した際にGCCとglibcのバージョンなどの組み合わせが自由でなかったため断念しました。
    
- その他のbashスクリプト
  
  - Linux用のバイナリの作成は上手くいくのですが、--with-sysrootのフラグを設定していないスクリプトが多く、Windowsに持っていった後にlibc.so等のリンカースクリプトを手で修正しないとエラーが出たり(リンク先のsoファイルが絶対パスになっていたりします)、不完全な状態だったため断念しました。(--with-sysrootを付けない場合でもビルド環境=ホスト環境の場合はきちんと動作します。)
    

--with-sysrootフラグがきちんとセットされているサンプルが今回使用したビルドスクリプトになります。

### 参考サイト

GCC を調べる - まとめリンク

http://www.katsuster.net/index.php?arg_act=cmd_show_diary&arg_date=20200602

今回の記事の内容の大半を参照させていただきました。ありがとうございました。

以下はビルド用のbashスクリプトの参考サイトです。

https://qiita.com/xecus/items/1660c826f0b8ec14a3a6

https://inaz2.hatenablog.com/entry/2015/12/01/204201

GCCのビルド手順がビルドツール任せだったものが、かなり詳細にわかるようになりました。今回のツールチェーンの生成には利用できませんでしたが勉強になりました。