Z.OOL.ネット信託統治領 はてな諸島

こちらは "Z.OOL.ネット信託統治領 はてな諸島" です。

Linuxbrew において ARM 系アーキテクチャで brew install が異常終了する問題を回避する

この投稿は、技術的事項についての速報的で簡易な短信についての投稿です。
どうか宜しくお願い致します。


[BGM]: New Order - True Faith (1987) (Official Music Video)

本稿について

本稿は、技術的事項についての速報的で簡易な短信についての Z.OOL.ネット信託統治領 Qrunch 諸島からのクロス投稿です。

本稿は、以下の Qrunch 諸島の投稿から御覧になれます。どうか御了承下さい。

z80oolong.qrunch.io

追記 (2018/10/25)

この度、本稿を大幅に加筆及び修正した上で、 ”Qiita 半島” に投稿しました。今後は、本稿の追記及び訂正等は、以下の Qiita 半島の投稿において行いますので、どうか御了承下さい。

qiita.com

概要

Rasberry pi 及び Debian noroot 環境等の ARM 系アーキテクチャにおいて、 Linuxbrew を用いて各種パッケージをビルドする場合に、 brew install コマンドを起動すると、以下のようなエラーメッセージを出力して brew install コマンドが異常終了する場合があります。

  *** Error in `gcc-4.9': double free or corruption (top): 0x000b6a30 ***

この問題は、 brew install コマンドを実行する際に、 gcc コンパイラの起動時に、 Linuxbrew の内部で、各種環境変数が格納されている Ruby 定数 ENV を拡張することにより、 gcc コンパイラに渡す最適化オプションの一つとして -march=nativegcc コマンドに渡しており、この時に、 gcc コマンドがオプション -march=native に基づいて ARM 系アーキテクチャの識別を行おうとした際に、現行の gcc コンパイラのバージョンにおいて適切に -march=native のオプションを処理出来ない事が brew install コマンドが異常終了する原因であると考えられます。

そこで、ディレクト$HOMEBREW_PREFIX/bin (ここに、 $HOMEBREW_PREFIX は Linuxbrew の導入先となるディレクトリ。以下同様。) 以下に、 gcc コマンドに渡すオプションのうち、 -march=native 及び -mcpu=native を除去するための gcc コマンドのラッパースクリプトを導入することにより、 ARM アーキテクチャ上で動作する Linuxbrew において、brew install コマンドが異常終了する問題を回避することが可能となりました。

本稿では、 ARM 系アーキテクチャ上の Linuxbrew において、 brew install が異常終了する問題の原因の概略と、この問題を回避するための gcc コンパイラのラッパースクリプトの導入する手法について述べます。

問題の原因について

まず、 Linuxbrew において、 gcc コンパイラは、まず最初に Linuxbrew の内部の各種ライブラリにて、 Linuxbrew における gcc のビルド環境が設定され、次に、ラッパースクリプト $HOMEBREW_PREFIX/Library/Homebrew/shim/linux/gcc-* を介して gcc コンパイラが起動されます。

この時、 Linuxbrew における gcc のビルド環境が設定される過程において、 gcc コンパイラに、各種 CPU のアーキテクチャの最適化のためのオプションである -march=native が渡されます。

しかし、 ARM アーキテクチャ上で動作する gcc コンパイラに、オプション -march=native が渡されると、現行の ARM アーキテクチャ上の gcc コンパイラでは、適切な CPU のアーキテクチャの検出が行われないために、 gcc コンパイラが異常終了を起こします。

以上に述べた原因により、ARM 系アーキテクチャ上の Linuxbrew を用いて brew install コマンドを起動すると、 gcc コンパイラの不具合により、 brew install コマンドが異常終了すると考えられます。

ラッパースクリプトの導入

以上の問題を回避するために、 Linuxbrew において、 gcc コンパイラを実行する際に、オプション -march=native 及び -mcpu=native を除去するための gcc コンパイラのラッパースクリプトを以下の通りに作成しました。

上記の gcc ラッパースクリプト ccLinuxbrew に導入するには、以下の brew install コマンドを実行します。

  $ brew install https://raw.githubusercontent.com/z80oolong/gcc-arm-wrap/master/gcc-arm-wrap.rb

また、以下のように git clone コマンドによってこの git リポジトリを取得した後に、以下の通りに brew install コマンドを実行しても、 gcc ラッパースクリプトを導入出来ます。

  $ git clone https://github.com/z80oolong/gcc-arm-wrap.git
  $ cd gcc-arm-wrap
  $ brew install ./gcc-arm-wrap.rb

上記コマンドの実行後は、 gcc ラッパースクリプト cc の導入の他、 gcc, g++, gcc-4.9, g++-4.9 等のコマンドも cc へのシンボリックリンクとして生成されます。

以上の gcc ラッパースクリプトの導入により、 ARM アーキテクチャ上の Linuxbrew において、 brew install コマンドに基づいた各種パッケージの導入に関する問題が回避されました。

謝辞

ARM アーキテクチャにおける Linuxbrew の異常終了の問題の概要及びその回避については、 Mokutsumo 氏によるブログ "自己実現武呂具" の記事の "printipiのコンパイルで *** Error in 'g++': double free or corruption (top): 0x01099c18 ***" を参考にしました。 Mokutsumo 氏には心より感謝致します。

また、 Linuxbrew 本体のリポジトリの開発を行っている Shaun Jackman 氏を始めとする Linuxbrew の開発コミュニティの各氏に心より感謝致します。

そして最後に、 Linuxbrew の全ての事に関わる全ての皆様に心より感謝致します。