hikalium.com

Mac OSX におけるはりぼてOSの開発環境を(再)整備した話

  • この記事は、自作OS Advent Calendar 2016の一部として作成されました。

  • はりぼてOSをマルチプラットフォームで開発できるよう、開発環境を整備した話が書かれています。
    • タイトルに反して、Linuxでの開発についても書かれています!

背景

みなさんは「はりぼてOS」をご存知ですか?

はりぼてOSは、川合秀実氏著の「30日でできる!OS自作入門」という本の中でつくりあげられるOSです。 名前の通り、非常に「はりぼて」な完成度となっておりますが、それでもブートローダーを含めフルスクラッチで開発されており、またKさん(川合秀実氏のこと)らしく、フロッピーディスク1枚に余裕で収まるサイズを実現しており、OS自作の基礎を学ぶには最適です。

…なんてことは、自作OSアドベントカレンダーをご覧になっている皆様にとっては常識でしょう(笑)。まさにこの本は、自作OS界における「聖書」と言っても過言ではありません(本の厚さ的にも)。

Macでも開発したいよ!(ついでにLinuxも)

まず、この本が前提としている開発環境は、なんとWindowsなのです。まあ確かに入門者向けなのでWindows用となっているのはわからなくもないですが、開発環境がWindowsに制限されているなんて、OS自作らしくないですよね。

ということで、他のOSで開発するにはどうすればいいだろうか、と思って調べてみると、サポートページにはあっけなくLinuxとMac向けの開発環境セットへのリンクが書かれていました。

「なあんだ、hikaliumがやるまでもないじゃん。解散!」 と思ったあなた方。解散するのはまだ早いですよ!

既存パッケージの問題点

すでにパッケージは存在していましたが、それらは完璧ではありませんでした。

はりぼてOSソースに含まれるMakefileの修正が必要

これは面倒です!だって、コンパイルするOSごとに、Makefileの書き換えが必要になるんですよね?いったいいくつMakefileがあると思っているのですか!?

それに、改造したはりぼてOSをGitHubで公開した際などに、コンパイルしたい人の開発環境にあわせてMakefileを書き換えなければいけないなんて…ちょっと面倒ですよね。

make runmake installができない

make runではqemuを使用します。しかし、Windows版以外の開発環境にはqemuが含まれていないため、「手動で頑張ってね!」という一言が書かれています。これは悲しいです。全環境でmake runとしたら起動してほしいです。

make installについても同様です。というか、今時フロッピードライブなんてPCについてないですよね!どうしたものでしょうか…。

生成されるバイナリが完全に同一だと保証できない

既存の開発パッケージは、先人たちが各自の知識を振り絞って作成したものでした。そのため、コンパイラのコンパイル時に当てるパッチなどは各自異なっており、共通のソースに基づいたものではありませんでした。

今回、諸事情により「バイナリレベルで完全に一致するharibote.sysを生成したい」という目標があったので、これを達成するために、開発パッケージをソースコードからまとめ直す必要がありました。

まずはtolsrcを手に入れる

ということで、私は開発環境をソースコードからコンパイルする必要性に駆られ、まずtolsrc(tolsetのソース)を手に入れることにしました。 このtolsrcは、本に付属しているCDにも入っているのですが、今回はすでにMacでコンパイルできると書かれていた、Akkieさんによるソースパッケージを利用させていただきました。

コンパイルエラー続出!

しかし、なんとAkkieさんが作成したtolsrcをmakeしても、コンパイルエラーが出てしまい、gocc1(本家tolsetにおけるcc1)等のコンパイルに失敗してしまいました。 これは、配布されているtolsrcのソース(というか主にgccのソース)があまりにも古く、最新のC言語の規格に一致しない部分や、ビット幅依存の部分が存在したためです。

そのエラーは、主に以下の4点が原因となっていました。

  • main関数の宣言が仕様と異なる
    • 本来はint main(int argc, char *argv[])と定義すべき
    • いくつかのソースではint main(int argc, UCHAR *argv[])となっていた
  • 三項演算子を代入式の左辺に使用している部分があった
    • この記法はC++ではValid
    • しかしCではInvalid
  • __builtin_stdarg_startがリンクできない
    • 昔のgccでは、va_startに相当するビルトイン関数が__builtin_stdarg_startだった
    • しかし現在では__builtin_va_startである。
    • 先人たちも同じ罠にはまっていた
    • http://sf.osask.jp/w/536.html
  • 一部のプログラムは32bit向けにコンパイルされることが前提となっていた
    • 主にgo0023s関係
    • この問題はやっかいで、コンパイルは通るのに、実行するとSegmentation Faultで落ちるという辛いバグを引き起こした。
    • コンパイルオプションに-m32をつけることで解決。
    • 一部のファイル生成規則がハードコーディングされていたせいで、-m32が反映されない問題に数十分費やしてしまった。

開発環境ごとのコマンドの差異を吸収するコマンドをつくる

さて、ここまででほとんどの実行バイナリは用意できました。 しかし、もう一つ大きな問題が残っています。それは、開発環境ごとのコマンドの違いです。

  • ファイルの複製
    • Windows: copy
    • Mac / Linux: cp
  • ファイルの結合
    • Windows: copy /b file1+file2 dstFile
      (2016-12-07追記)記事の公開後に川合さんから「Windowsのコピーコマンドで結合という意味になるのは、+でつないでいるからであって/bというオプションのおかげではないですよ!」とのご指摘を受けましたので、修正しました。ご指摘ありがとうございます!
      ちなみに、`/b`は「バイナリモードで(改行コードを変換せず)処理してね」ということのようです。
    • Mac / Linux: cat
  • ファイルの削除
    • Windows: del
    • Mac / Linux: rm

これらをどうやって共通にするか。 その解決策として私が選んだのは、「専用のプログラムをつくる」ということでした。 その名も、haritolです。

  • haritol concat
  • haritol remove

引数によって、動作を変えます。 さらに、Windowsでは、一般のプログラムに渡す引数ではワイルドカードが機能しないという問題がありました。これは、Makefile内臓のワイルドカード機能を用いて解決しました。

これで全環境で同じソースをコンパイルできるようになった!

もちろん、Makefileの書き換えは必要でしたが、それでも一度書き換えてしまえば、すべての開発環境で同様にコンパイルすることが可能なはりぼてOSソースコードを用意することができました。

この成果は、以下のgithubで公開しています。

「書き換え済みharib27f」と、各環境にあわせた「z_tools」をダウンロードして、z_toolsはz_toolsに名前を変更すれば、あとはharib27f/に移動し、make runするだけです!簡単でしょ?

謝辞

この成果は、tolsetの移植にかかわった偉大なる先人方、特にAkkie氏、わこう氏、hideyosi氏の成果に基づいています。 また、uchan氏には、go_0023sのコンパイルエラーが発生した際に助けていただきました。

そしてなにより、「30日でできる!OS自作入門」の著者であり、私が現在サイボウズ・ラボユースでお世話になっているKさん(川合秀実氏)には、感謝してもしきれません。というかこのネタ自体が、Kさんからお願いされたお仕事に基づいています。

最後に、はりぼてOSと自作OS界で活動されているすべての皆様に、感謝申し上げます。


Last modified of this contents: 2016-12-07T11:56:37+00:00

/note/20161202.md

広告を非表示にする