/tmp

雑記帳.

Arch Linux に Quartus / ModelSim をインストールする

ひょんなことから FPGA を扱う機会に恵まれた. FPGA では Intel の Quartus なるソフトウェアを使って開発を行うらしい. なにはともあれインストールをしなければならない. ところがこのインストールがなかなか曲者だった. 嵌りまくったのでここにメモを残しておく.

なお, これはとりあえず動いた後に適当に思い出しながら書いているので, 正確でなかったり, 抜けていたり, 必要でない手順が含まれていたりする可能性が大いにある.

Quartus

まずは開発ツールである Quartus をインストールする. いくつか嵌りどころはあるが, 大した問題ではない. いや, 普通に考えるとそれなりに深めの嵌り所なのだが, この後に出てくる問題に比べると全く大したことではない.

まずは Intel のダウンロードページからソフトをダウンロードする. ダウンロード場所がなかなか見つからなくて迷った. これを書きながら今探しても見つけられない. 過去の私はどこからダウンロードしてきたのだろう...

ちなみにダウンロードサイトには ModelSim のインストーラもダウンロードできるが, Quartus のインストーラに全く同じものが同梱されているので必要なさそうだ.

現時点では Quartus-lite-18.0.0.614-linux.tar が最新である。これを適当にディレクトquartus にでも展開すると, 次のような構成が表れる.

.
├── components
│   ├── ModelSimSetup-18.0.0.614-linux.run
│   ├── QuartusHelpSetup-18.0.0.614-linux.run
│   ├── QuartusLiteSetup-18.0.0.614-linux.run
│   ├── arria_lite-18.0.0.614.qdz
│   ├── cyclone-18.0.0.614.qdz
│   ├── cyclone10lp-18.0.0.614.qdz
│   ├── cyclonev-18.0.0.614.qdz
│   ├── max-18.0.0.614.qdz
│   └── max10-18.0.0.614.qdz
├── readme.txt
└── setup.sh

1 directory, 11 files

さて, これのインストールだが, ZEROからのFPGA : Altera(Intel)のFPGA開発ツール「Quartus Prime」をUbuntuにインストールする を大いに参考にさせていただいた. スクリーンショット付きで分かりやすく解説されているので, ここを読めば問題なくインストールできるだろう. 参考サイトにも書かれているが, 注意点としては,

  • 最初のコンポーネント選択では ModelSim と Quartus Help を外しておく.
    • これらはインストールが完了してもなぜかプロセスが終了せず, その終了待ちをしている親のインストーラごと固まって進めなくなる.
    • これは子プロセスを kill してもうまくいかない.
      • kill しても親インストーラはウンともスンとも言わない.
      • kill した後に親インストーラの閉じるボタンを押すと, そこでやっとエラーが表示されて, その後親も固まる.
  • インストールが完了してもなぜかターミナルの制御が戻ってこないので, 完了したら Ctrl + C でプロセスを終了させる必要がある.

ちなみにインストールするディレクトリはお好みだが, ここではとりあえず /opt/intelFPGA_lite/18.0 へインストールすることにする. インストールが完了すると, /opt/intelFPGA_lite/18.0/quartus/bin/quartus を叩くことで Quartus が起動できるはずだ.

ModelSim

先の参考サイトには ModelSim のインストールが含まれていない. components/ModelSimSetup-...インストーラなので, ModelSim のインストーラを実行してインストールしておく. インストールディレクトリを Quartus をインストールしたディレクトリ (ここでは /opt/intelFPGA_lite/18.0) に揃えておくとよいだろう. まあそれは必須ではない.

さて, ModelSim を実行するコマンドは vsim である. インストール先を /opt/intelFPGA_lite/18.0 にしたならば, このコマンドは /opt/intelFPGA_lite/18.0/modelsim_ase/bin 以下にある. ではさっそく実行してみよう.

% /opt/intelFPGA_lite/18.0/modelsim_ase/bin/vsim
Error: cannot find "/opt/intelFPGA_lite/18.0/modelsim_ase/bin/../linux_rh60/vsim"

なるほどまずはエラーから. とりあえずターミナルで様子を探ってみる.

% cd /opt/intelFPGA_lite/18.0/modelsim_ase/bin
% ls -l
合計 4
drwxr-xr-x 3 ... ... 4096  8月 25 02:48 NONE
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 drill -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 dumplog64 -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 hm_entity -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 jobspy -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 mc2_util -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 mc2com -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 mc2perfanalyze -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 qhcvt -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 qhdel -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 qhdir -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 qhgencomp -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 qhlib -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 qhmake -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 qhmap -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 qhsim -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 qverilog -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 qvhcom -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 qvlcom -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 sccom -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 scgenmod -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 sdfcom -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 sm_entity -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 triage -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vcd2wlf -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vcom -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vcover -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vdbg -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vdel -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vdir -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vencrypt -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 verror -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vgencomp -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vhencrypt -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vlib -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vlog -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vmake -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vmap -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vopt -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vovl -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vrun -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 vsim -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 wlf2log -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 wlf2vcd -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 wlfman -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 wlfrecover -> ../vco
lrwxrwxrwx 1 ... ...    6  8月 25 01:18 xml2ucdb -> ../vco

なんと, すべて ../vco とやらへのシンボリックリンクである. vco は, 実行されたときの自分自身の名前を見て動作を変えるタイプのファイルである. こういう動作は busybox や extractbb (本物は dvipdfmx) でも見られ, 面白い. それはともかくとして, ../vco は実はシェルスクリプトなのでエディタで開ける. すると, 204-210 行目にこういうコードがあるはずだ.

        case $utype in
          2.4.[7-9]*)       vco="linux" ;;
          2.4.[1-9][0-9]*)  vco="linux" ;;
          2.[5-9]*)         vco="linux" ;;
          2.[1-9][0-9]*)    vco="linux" ;;
          3.[0-9]*)           vco="linux" ;;
          *)                vco="linux_rh60" ;;

これは Linux カーネルバージョンにより何か分岐しているコードのようなのだが, 問題は Linux 4.x 系の分岐が含まれていないこと. 現時点でうちの Arch Linux は 4.18.4 なのでここで分岐に失敗している. linux_rh60 というのはエラーメッセージにも含まれていたし, 怪しい.

ということで, 3.[0-9]*) の後ろに一行追加する.

        case $utype in
          2.4.[7-9]*)       vco="linux" ;;
          2.4.[1-9][0-9]*)  vco="linux" ;;
          2.[5-9]*)         vco="linux" ;;
          2.[1-9][0-9]*)    vco="linux" ;;
          3.[0-9]*)           vco="linux" ;;
          4.[0-9]*)           vco="linux" ;;
          *)                vco="linux_rh60" ;;

編集したらファイルを保存する. このファイル, なぜか書き込み権限がないので注意. Vim で開いたら読み込み専用になった. 別に所有者は自分自身なのでなんとでもなるが.

これで動け, と思うのだが...

% ./vsim
/opt/intelFPGA_lite/18.0/modelsim_ase/bin/../linux/vish: error while loading shared libraries: libXft.so.2: cannot open shared object file: No such file or directory

なるほどね. ちなみにこのメッセージは一旦できた環境から一部をわざと壊して再現しているので, エラーメッセージ内のライブラリ名などは違うかもしれない.

で, 新しく vish という人物が登場してきた. どうもさっきのファイル vcovish を呼び出すらしい. エラーメッセージは見慣れた依存関係エラーであるから, vish に足りていないライブラリをまずは探す.

% cd ../linux
% ldd vish
    linux-gate.so.1 (0xf7f3e000)
    libpthread.so.0 => /usr/lib32/libpthread.so.0 (0xf7ef6000)
    libdl.so.2 => /usr/lib32/libdl.so.2 (0xf7ef0000)
    libm.so.6 => /usr/lib32/libm.so.6 (0xf7e23000)
    libX11.so.6 => /usr/lib32/libX11.so.6 (0xf7cd6000)
    libXext.so.6 => /usr/lib32/libXext.so.6 (0xf7cc1000)
    libXft.so.2 => not found
    libXrender.so.1 => /usr/lib32/libXrender.so.1 (0xf7cb5000)
    libfontconfig.so.1 => not found
    librt.so.1 => /usr/lib32/librt.so.1 (0xf7caa000)
    libncurses.so.5 => /usr/lib32/libncurses.so.5 (0xf7c47000)
    libc.so.6 => /usr/lib32/libc.so.6 (0xf7a6a000)
    /lib/ld-linux.so.2 => /usr/lib/ld-linux.so.2 (0xf7f40000)
    libxcb.so.1 => /usr/lib32/libxcb.so.1 (0xf7a3e000)
    libXau.so.6 => /usr/lib32/libXau.so.6 (0xf7a39000)
    libXdmcp.so.6 => /usr/lib32/libXdmcp.so.6 (0xf7a32000)

これは後で再現しているだけなので, 実際はもう少しいろいろ足りないライブラリがあった. not found となるライブラリがなくなるように, 全てのライブラリをインストールする必要がある. ここで私は「あれ? freetype が入ってないわけなくない?」と思ったのだが, 騙されるなかれ, じつはこの vish は 32-Bit バイナリなのである.

% file vish
vish: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.4, BuildID[sha1]=77d8354d389082fe6128a20bc3f4db5ded41a81b, stripped

あーはいはい. つまり必要なのは lib32-* 系のライブラリである. 必要なパッケージの名前はほとんどライブラリの名前と同じなので, 探すのはそう難しくない. pacman -Ss を使って検索し, pacman -S を使ってガンガン入れていく. なお, lib32-* 系のライブラリはレポジトリ [multilib] に入っているのだが, このレポジトリはデフォルトで無効になっている. 有効にしていない人は /etc/pacman.conf の [multilib] の部分をアンコメントして有効にする必要がある.

さあ, 全ての依存を解決したぞ. これでいけるだろう.

% ../bin/vsim
Error in startup script: 
Initialization problem, exiting.

Initialization problem, exiting.

Initialization problem, exiting.

    while executing
"Transcript::action_log "PROPREAD \"$key\" \"$value\"""
    (procedure "VsimProperties::Init" line 59)
    invoked from within
"VsimProperties::Init $MTIKeypath"
    (procedure "PropertiesInit" line 18)
    invoked from within
"PropertiesInit"
    invoked from within
"ncFyP12 -+"
    (file "/mtitcl/vsim/vsim" line 1)
** Fatal: Read failure in vlm process (0,0)

うーん.

前半部分のエラー内容は異なるかもしれない (というか事実違った気がする) が, とりあえず大切なのは一番最後の Fatal: Read failure in vlm process (0,0) である. さっぱり分からないのでググると割と簡単に情報が得られる. それによると libfreetype2 のバージョンが高いとエラーを起こすらしい. 起こさないようにするにはだいたい libfreetype2 2.4.7 くらいをもってこればよいそうな. ちなみに今の Arch Linux には freetype 2.9.1 が入っている. 高い.

まあそうだよね. Linux カーネルの分岐に 3.x までしか含まれていないくらい古い時点で, 何かしら依存ライブラリでこけると思っていた. freetype 2.4.7 なんて古すぎて AUR にもないのでソースからコンパイルする必要がある.

まず必要なのは freetype-2.4.7.tar.gz . また, 最新の fontconfig はこんな古い freetype とは仕事できないので, 当時の fontconfig を持ってくる必要がある. どれくらいの fontconfig が必要なのか分からないが, とりあえず fontconfig 2.5.0 を選んだ (根拠はそれほどない) . これもソースからコンパイルする必要があり, fontconfig-2.5.0.tar.gz が必要になる.

まずは適当に検索して freetype-2.4.7.tar.gz を入手する. これを展開して由緒正しい ./configure && make && sudo make install の流れをすればよいのだが, ここでは 32-Bit のバイナリを生成する必要があることに注意する. autotools - Build 32bit on 64 bit Linux using an automake configure script? - Stack Overflow によれば, それには configure に対して --build=i686-pc-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32" なるオプションをつければよいらしい.

こんな古い freetype の, しかも 32-Bit 版を /usr/local 以下にインストールするのは気が引けるが, そうしないと次の fontconfig のビルドが失敗する. 全てが終われば削除しても問題なさそうなので, 一時的にでも sudo make install しておく.

続いて fontconfig をビルドする. これのビルドは freetype と同様なので省略する. アーカイブを展開して, 例のオプションをつけて ./configure し, make && sudo make install すればよい.

ふー疲れた. そうして, ようやく vsim が起動できるようになったはずだ. 一度試してみるとよい.

おまけ

これでいい人はこれでよいのだが, このままでは /usr/local 以下にこの古い 32-Bit なバイナリ達が残ることになる. 特に, /usr/local/bin/usr/bin より優先度が高いので fc-* 系のコマンドが /usr/local/bin にある古いものになってしまう. これは嬉しくないので, なんとかここから移動したい.

ModelSim が欲しいのは libfontconfig.so.1libfreetype.so.6 の二つ. これらを別の場所へコピーして退避する.

退避先だが, ModelSim のインストール先ディレクトリに lib32 という名前のディレクトリを作った. この lib32 ディレクトリに /usr/local/lib から libfontconfig.so.1libfreetype.so.6 をコピーしてくる (私は不安だったので libfontconfig.so*libfreetype.so* を, cp -R コマンドで SymLink ごとコピーしてきた). コピーしてしまえば元のあいつらはもうアンインストールしてしまう. freetype をビルドしたディレクトリに入り, sudo make uninstall すると freetype がアンインストールされる. 同様に fontconfig をビルドしたディレクトリに入り sudo make uninstall すると fontconfig がアンインストールされる.

lib32 がライブラリ検索パスに含まれていないため, このままではまた ModelSim がエラーを出す. 先の lib32 ディレクトリを LD_LIBRARY_PATH に追加することで使えるようになる. おあつらえ向きに vco などという全コマンドが経由するシェルスクリプトがあるので, こいつを編集して達成しよう.

vco の末尾には次のような, 見るからにコマンドを実行してそうな行がある.

if [ -z "$*" ] ; then
  exec "$arg0"
else
  exec "$arg0" "$@"
fi

ここを次のように書き換えてしまえばよい.

if [ -z "$*" ] ; then
  exec env LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$dir/lib32" "$arg0"
else
  exec env LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$dir/lib32" "$arg0" "$@"
fi

これで, システムをクリーンに保ったまま vsim が起動できるようになる. 弊害として vsim 起動時に Fontconfig error: Cannot load default config file なるエラーが出るが, まあいいだろう. vsim コマンドを打ってしばらく待つと, 古めかしい出でたちのウィンドウが現れる. めでたい. あーーー, 疲れた.

おわりに

起動できることは確認したが, それ以上の動作確認はしていない. またどこかでエラーが出るかもしれない. 怪しいとしたら freetype/fontconfig だろうが, こいつらは所詮フォントをレンダリングするだけなのでそれほど致命的なエラーは起こさないと信じる. とは言うものの, 今はまさにそのフォントレンダラがなぜか致命的な原因だったわけだが...

この手の問題はやって解決できないことはほとんどないが, かなり疲れる.