uchan note

プログラミングや電子工作の話題を書きます

タイガーブックを読む:LR(0)構文解析は先読みするのか

最新コンパイラ構成技法(原題「Modern Compiler Implementation in ML」、通称「タイガーブック」)の「3.3 LR 構文解析」の節を読んで理解したことをメモする記事です。 シリーズぽい記事タイトルですが、シリーズにする予定は今のところありません。

続きを読む

KiCad + FlatCAM で KitMill 用の基板切削データを作る

KitMill CL200(あるいは CL100/CL420)で基板切削をするための CNC プログラム(KitMill を制御するデータ)を作る手順のメモです。

f:id:uchan_nos:20210620222039j:plain
実験的に切削した基板(導体面)

記事はこちらに移動しました KiCad + FlatCAM で KitMill 用の基板切削データを作る | elchika

GCC 11のビルドとldconfig

GCC 11 をソースコードからビルドする方法と、GCC 11 に付属する標準 C++ ライブラリを利用するための ldconfig コマンドを紹介します。

GCC 11.1.0 のビルド

基本は Build GCC 11 from source on Ubuntu と同じ手順で OK です。 Ubuntu 18.04 と 20.04 でビルドできることを確認しました。

GCC はソースディレクトリでの ./configure に対応していませんので、ソースディレクトリ以外にビルド用ディレクトリを作ります。 この記事では次のようなディレクトリ構成にしていますね。

$HOME/
  gcc-releases-gcc-11.1.0/
    configure
    contrib/download_prerequisites
  build/

私は gcc-releases-gcc-11.1.0/build という感じでビルドディレクトリを作りましたが、上手くビルドできました。

ビルド設定は次の通りとしました。

../configure --prefix=/usr/local/gcc-11.1.0 --enable-languages=c,c++ --disable-multilib --program-suffix=-11.1

--prefix はインストール先ディレクトリを指定します。上記のように指定すると /usr/local/gcc-11.1.0/bin/ 以下にコンパイラgcc や g++ など)が、/usr/local/gcc-11.1.0/lib64/ 以下に C++ 標準ライブラリがインストールされることになります。

--enable-languages で必要な言語を選択します。先の記事では fortran も指定していましたが、私は使わないので。少ないほどビルドが早く終わります。

--disable-multilib を指定しない場合、次のエラーが発生しました。

collect2: error: ld returned 1 exit status

configure: error: I suspect your system does not have 32-bit development libraries (libc and headers). If you have them, rerun configure with --enable-multilib. If you do not have them, and want to build a 64-bit-only compiler, rerun configure with --disable-multilib.

GCC はデフォルトで、32 ビットおよび 64 ビット向けバイナリを生成する機能を持ちます。 しかし、32 ビット向けバイナリを生成する機能を有効にするためには、システムに 32 ビットバージョンのライブラリ(libc など)がインストールされている必要があります。 手元のマシンには 32 ビット版のライブラリ群がインストールされておらず、また、64 ビット向けのビルドだけできれば当面は困らないので、 --disable-multilib を付与することとしました。

--program-suffix=-11.1 は、ビルドされた実行ファイルのサフィックスを指定します。例えば g++-11.1 のような名前になります。

ldconfig

make と make install を実行すると /usr/local/gcc-11.1.0/bin/ 以下にコンパイラがインストールされます。 後はここにパスを通すだけでいいかな、と思うと、実はそれでは不十分というお話です。

結論としては /etc/ld.so.conf.d/ 以下に設定を置いて sudo ldconfig を実行しましょうね、ということです。

共有ライブラリ

g++-11.1 でとあるプログラムをビルドし、実行しようとしたところ、次のようなエラーが表示され、実行できませんでした。

$ ./opelac
./opelac: /lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.29' not found (required by ./opelac)

C++ 標準ライブラリの新しめの機能を使うと表示されるのだと思います。 試しに strings /lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX_ としてみると、3.4.28 までしか含まれていないことが分かりました。

実行ファイルが利用する共有ライブラリは ldd で確認できます。

$ ldd opelac
./opelac: /lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.29' not found (required by ./opelac)
        linux-vdso.so.1 (0x00007ffd51fde000)
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f0266d6c000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0266c1d000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f0266c02000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0266a10000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f0266f57000)

確かに opelac(g++-11.1 でビルドしたやつ)が libstdc++.so.6 という名前で /lib/x86_64-linux-gnu/libstdc++.so.6 を参照することが分かります。 新しいコンパイラGCC 11)でビルドした実行ファイルが、実行時にシステム標準の古いライブラリを参照してしまっているわけです。 これがエラーの原因ですね。

先ほどインストールした GCC 11 に含まれる libstdc++ を利用するようにすれば解決します。

やり方はいくつかあります。1 つは LD_LIBRARY_PATH という環境変数にライブラリファイルがあるディレクトリを設定してから opelac を実行することです。

$ LD_LIBRARY_PATH=/usr/local/gcc-11.1.0/lib64 ./opelac

共有ライブラリを一時的に差し替えてプログラムを動作させる場合にとても便利なやり方です。 ただ、毎回 LD_LIBRARY_PATH を指定しなければならず、面倒です。 恒久的に LD_LIBRARY_PATH を設定しておくには $HOME/.bashrc 等に設定を記載してください。 $HOME/.profile では LD_LIBRARY_PATH を設定できませんので注意してください。 参考 LD_LIBRARY_PATH を設定しても反映されないことがある

もう 1 つのやり方は環境変数ではなく、ld の設定ファイルを調整する方法です。 この方法はシステム全体に影響を及ぼすことができます。

$ cat /etc/ld.so.conf.d/gcc-11.1-lib64.conf
/usr/local/gcc-11.1.0/lib64
$ sudo ldconfig

こんな感じで、ライブラリの置き場所を書いたテキストファイルを配置し、ldconfig コマンドを実行するだけです。

この設定を行うと、特にシステム再起動などせず、すぐに参照先ライブラリが切り替わります。ldd で確認してみます。

$ ldd opelac
        linux-vdso.so.1 (0x00007ffffca3b000)
        libstdc++.so.6 => /usr/local/gcc-11.1.0/lib64/libstdc++.so.6 (0x00007efcbd7ce000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007efcbd67f000)
        libgcc_s.so.1 => /usr/local/gcc-11.1.0/lib64/libgcc_s.so.1 (0x00007efcbd664000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007efcbd472000)
        /lib64/ld-linux-x86-64.so.2 (0x00007efcbd9f0000)

libstdc++.so.6 の参照先が変わっていることが分かると思います。 これで、opelac コマンドがエラー無く動作するようになりました。

OS自作ゼミの紹介 - セキュリティ・キャンプ全国大会 Yトラック

このページはセキュリティ・キャンプ全国大会 2021 の集中コース「OS 自作ゼミ」の紹介ページです。 参加費無料で講義を受けることができますので、22 歳以下の方は是非応募してください。

(本記事は随時更新するかもしれません。特に 4 月中は更新頻度が高いことが予想されます。時々見に来てくださると嬉しいです。)

OS 自作ゼミ 基本情報

OS 自作ゼミの基本的な情報は以下の通りです。

  • イベント:セキュリティ・キャンプ全国大会 2021 オンライン
  • トラック:システムソフトウェア自作トラック
  • ゼミ:OS 自作ゼミ
  • 必要機材:PC、その他必要に応じて仕様書や参考書など
  • 事前学習:あり(詳しくは後述)
  • 講師:怒田さん、hikalium さん、内田
続きを読む

『ゼロからのOS自作入門』に込めた思い

2021 年 3 月 22 日に『ゼロからの OS 自作入門』を出版する予定です。 本書は OS を手作りする本で、現代のパソコンでちゃんと起動する点が特長です。

15 年前の 2006 年に出版された『30 日でできる!OS 自作入門』を読んで育った私(uchan)が その後継となるだろう本を書いたということで、執筆の裏話を記してみたいなと思います。

続きを読む

戸狩温泉スキー場で初滑り

この記事は2021年1月に戸狩温泉スキー場に行った記録です。スキーを計画している方の参考になるような記事を目指しました。 技術記事ではないのですが、uchanがスキー好きなのでご容赦ください…

続きを読む

Raspberry PiのGPIO2と3のプルアップ抵抗に注意

Raspberry Pi の GPIO2/3 に備わっているプルアップ抵抗はソフトウェアで無効化することができず、かつ抵抗値が小さいため、注意が必要だという話です。

続きを読む