RISC-Vのクロスコンパイラが欲しい場合、もっとも楽なのはsudo apt install gcc-13-riscv64-linux-gnuなどとすることですが、これだとRV64GC向けのバイナリが生成されるため、困ることがあります。
-march=rv64gなどとすれば、ユーザーコードはRV64Gの範囲(C拡張なし)でコンパイルできるのですが、標準ライブラリはRV64GCになっているため、結局C拡張を含むバイナリができてしまいます。
そうなっては困る用途では、https://github.com/riscv/riscv-gnu-toolchainをクローンして自分でビルドしたクロスコンパイラを使うしかなさそうです。
ところが、このリポジトリはgit submoduleの仕組みでGitHubの外のリポジトリを参照していて、これが問題を引き起こします。 例えば、以前は動作していた以下の手順が、現在では動作しなくなっています。
git clone --recursive https://github.com/riscv/riscv-gnu-toolchain # すごく時間がかかる cd riscv-gnu-toolchain git checkout 2024.04.12 -f git submodule update --init --recursive -f
上記手順は以下のようにエラーになります。 submoduleであるbinutilsはチェックアウトできますが、同じくsubmoduleであるdejagnuをチェックアウトできません。
Submodule path 'binutils': checked out 'c7f28aad0c99d1d2fec4e52ebfa3735d90ceb8e9' error: Server does not allow request for unadvertised object c298959ef991b389b64a825f70094738c6a48780 fatal: Fetched in submodule path 'dejagnu', but it did not contain c298959ef991b389b64a825f70094738c6a48780. Direct fetching of that commit failed.
どうやらhttps://git.savannah.gnu.org/git/dejagnu.gitは、コミットハッシュで直指定してフェッチすることができない設定になっているようです。
GitHubはコミットハッシュで直指定して取ってくることができますが、普通のgitリポジトリはそれができないのがデフォルトです(uploadpack.allowReachableSHA1InWantとかuploadpack.allowAnySHA1InWantの規定値はfalseです。セキュリティ上の理由とか到達可能性判定の計算コストとかの理由によります。参考:Git - git-config Documentation)。
submodule先がそういう設定のリポジトリだとこういう問題が起きうるので、submodule先は同じorganizationにクローンして管理しておくのがよさそうです。
さて、解決方法ですが、少なくとも以下の二つが使えました。
ミラーを使う
Google Open Sourceのサーバー(dejagnu - Git at Google)は、少なくともc298959ef991b389b64a825f70094738c6a48780のコミットハッシュ直指定フェッチ要求を受け入れてくれます。 なので、
git config -f .gitmodules submodule.dejagnu.url https://gnu.googlesource.com/dejagnu git submodule sync dejagnu git submodule update --init --recursive -f
のようにやればdejagnuの必要なコミットをチェックアウトできて、ビルドに進めます。
深さ指定フェッチを行う
https://git.savannah.gnu.org/git/dejagnu.gitは、refのコミットしか(直には)取得できないとはいえ、その親コミットを取得することはできます。 そこで、
git -C dejagnu fetch origin master --depth=37 git submodule update --init --recursive -f
のようにやればc298959ef991b389b64a825f70094738c6a48780までたどり着けました(今後masterが伸びたら、37個では足りなくなるかもしれません)。 これにより、submoduleをすべてチェックアウトしてビルドに進めます。
まとめ
submoduleで記録されているコミットハッシュだけからではコミットを取得できない設定のリポジトリがあるので注意しましょう。