2013年10月15日火曜日

OS X Mountain Lion で i686-elf 向け GCC をビルドする

Xcode の Command Line Tools でインストールされる gcc コマンドは llvm-gcc なので、本当の GNU C Compiler ではありません。 Mac でクロスコンパイル用の GCC をビルドするためには、本物の gcc コマンドが必要です。
Mountain Lionユーザのためのクロスコンパイラビルド - Handwriting を読んでこの事実を知りました(それまで5回ぐらいクロスコンパイル用 GCC をビルドしようとして失敗していました)。

以下、ビルド手順メモ

ネイティブ用 GCC ビルド

クロスコンパイル用 GCC をビルドするための GCC をビルドします。A bare-metal x86-cross-compiler on Mountain Lion | The Intobooks や、そこからリンクされている Compiling gcc-4.7.1 on Mac OSX Lion が参考になりました。これらの記事の手順は僕の Mountain Lion でも使えました。

各種ソースコードのダウンロードと展開

$ cd ~
$ mkdir gcc-4.8.1
$ cd gcc-4.8.1
$ curl -O http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-4.8.1/gcc-4.8.1.tar.gz
$ curl -O http://ftp.tsukuba.wide.ad.jp/software/gmp/gmp-5.1.3.tar.gz
$ curl -O http://ftp.tsukuba.wide.ad.jp/software/mpfr/mpfr-3.1.2.tar.gz
$ curl -O http://ftp.tsukuba.wide.ad.jp/software/mpc/mpc-1.0.1.tar.gz
$ tar zxvf gcc-4.8.1.tar.gz
$ tar xzvf gmp-5.1.3.tar.gz 
$ tar xzvf mpfr-3.1.2.tar.gz
$ tar xzvf mpc-1.0.1.tar.gz

ビルドとインストール

ビルドするまえに環境変数 PATH の値をなるべくシンプルに調整するとミスがありません。PATHを調整し終えたらいざビルド。

GMP
$ mkdir gmp-build
$ cd gmp-build
$ ../gmp-5.1.3/configure --prefix=/Users/uchan/gcc-4.8.1/ --enable-cxx
$ make -j4
$ make install
$ cd ..

MPFR
$ mkdir mpfr-build
$ cd mpfr-build
$ ../mpfr-3.1.2/configure --prefix=/Users/uchan/gcc-4.8.1 --with-gmp=/Users/uchan/gcc-4.8.1
$ make -j4
$ make install
$ cd ..

MPC
$ mkdir mpc-build
$ cd mpc-build
$ ../mpc-1.0.1/configure --prefix=/Users/uchan/gcc-4.8.1 --with-gmp=/Users/uchan/gcc-4.8.1 --with-mpfr=/Users/uchan/gcc-4.8.1
$ make -j4
$ make install
$ cd ..

GCC
$ mkdir gcc-build
$ cd gcc-build
$ ../gcc-4.8.1/configure --prefix=/Users/uchan/gcc-4.8.1 --enable-checking=release --with-gmp=/Users/uchan/gcc-4.8.1 --with-mpfr=/Users/uchan/gcc-4.8.1 --with-mpc=/Users/uchan/gcc-4.8.1 --enable-languages=c,c++
$ make -j4
$ make install
$ cd ..

以上でクロスコンパイル用 GCC をビルドするためのネイティブ GCC が出来上がりました!(ややこしい(^^;

さて、やっとクロスコンパイル用 GCC のビルドです。まず PATH の調整など。先ほどビルドした GCC のパスと、クロスコンパイル用 GCC のパスも忘れず通します。GCC, GMP, MPFR, MPC のソースは先ほど展開したものを再利用します。
$ export PATH=$HOME/i686-elf-gcc-4.8.1/bin:$HOME/gcc-4.8.1/bin:$PATH
$ cd ~
$ mkdir i686-elf-gcc-4.8.1
$ cd i686-elf-gcc-4.8.1
$ mkdir src
$ cd src
$ ln -s ~/gcc-4.8.1/src/gcc-4.8.1 ./
$ ln -s ~/gcc-4.8.1/src/gmp-5.1.3 ./
$ ln -s ~/gcc-4.8.1/src/mpfr-3.1.2 ./
$ ln -s ~/gcc-4.8.1/src/mpc-1.0.1 ./

binutils
$ curl -O http://ftp.tsukuba.wide.ad.jp/software/binutils/releases/binutils-2.23.2.tar.bz2
$ tar xjvf binutils-2.23.2.tar.bz2
$ mkdir binutils-build
$ cd binutils-build
$ ../binutils-2.23.2/configure --prefix=/Users/uchan/i686-elf-gcc-4.8.1 --target=i686-elf
$ make -j4
$ make install
$ cd ..

GCC
$ mkdir gcc-build
$ cd gcc-build
$ ../gcc-4.8.1/configure --prefix=/Users/uchan/i686-elf-gcc-4.8.1 --target=i686-elf --enable-languages=c,c++ --without-headers
$ make -j4 all-gcc
$ make install-gcc

必要な configure オプションについては 開発環境(自作OS) - こうじのがく まとめ(自作OS、ホームページ作成) を参考にしました。
  • --without-headers : 自作 OS 開発には標準ヘッダファイルや標準ライブラリは要りませんので、これを指定しておきましょう。
make に all-gcc を指定するのが重要です。これを指定しないと make の途中でエラーが発生するかもしれません。(実際、 libstdc++ のビルドに失敗している様でした)

以上でクロスコンパイル用 GCC のインストールは完了です。やったね!

2013年10月11日金曜日

【自作OS】 Bookmarks

自作OSを作る上で参考になりそうなサイトを見つけたら追記していきます。主に個人用メモ。

起動処理,MBR

HDDの話 : CHS・LBAアドレスの話
MBR(Master Boot Recode)の構造 : MBRの何処に何が書いてあるか
Partition types : パーティションタイプのリスト

ATA in x86 RealMode (BIOS) : リアルモードでの BIOS の色々なお話。フロッピーの BPB に書かれている "Sectors per Track" や "Number of Heads" の値は「ほとんど常に間違っている」という記述に笑ってしまった(笑)
INT 13 Drive Type : BIOSは起動直後に DL レジスタにドライブ番号を格納してくれるというお話(でもこの番号は信頼性がない場合があり、MSのIPLは番号決め打ちしているという情報をいただいた)

Windows NT ブート処理とハード ディスクの制限 : MS公式サイト。Windows NT の IPL のディスク読み取り処理は BIOS int 0x13 にのみ依存することなどが書いてある

NASM

The Netwide Assembler: NASM : nasm の -f オプションに応じてビット数がデフォルトで設定されており、通常は明示的な BITS ディレクティブは必要ない。

ELF

Executable and Linkable Format - Wikipedia
ELF

リンカ ld

GNU リンカ LD の使い方
NASK環境からの解脱

building binutils

[Qemu-devel] [PATCH] configure: disable clang -Wstring-plus-int warning

メモリマップ

(AT)memorymap - OS-Wiki
Memory Map (x86) - OSDev Wiki

C++対応

C++ - OSDev Wiki

【自作OS】USBメモリからブートする

昨日あるチャットで自作OSの話題になったとき、最近のパソコンにはフロッピーが無い、USBメモリから起動できたらいいよね、という話が出ました。

気になったのでやってみました。


ブートセクタ - Wikipedia によれば、どんな起動デバイスでも BIOS は先頭 512 バイトを 0x7c00 番地に配置して実行してくれるらしい。

Hello World を表示する 512 バイトのバイナリを用意して、それを USB メモリの MBR に書き込んでしまえばいいはず。ちょうど良いことに「30日でできる! OS自作入門」の2日目3節で Hello World を表示するだけの 512 バイトのバイナリを作っていますので、これを利用することにしました。

MBR への書き込みには 【取り扱い注意】USB(メモリ)ブート関連ツール で紹介されている BOOTICE というツールを使いました。BOOTICE の画面で ProcessMBR → Restore MBR を選択し、上記の 512 バイトバイナリを選択すれば書き込めます。楽ちんだね!

壊れてもいい USB メモリを使ってくださいね!

で MBR への書き込みが完了した USB メモリをパソコンに刺して起動させれば、ほら! Hello World が出ました!

2013年9月6日金曜日

【Java】cannot be resolved to a type エラーと CLASSPATH の順序

Java の クラスパス の設定でちょっと躓いたので記録。

javac や java コマンドの実行時にクラスパスを指定するには2通りのやり方がある。 -classpath オプションを使う方法と CLASSPATH 環境変数を使う方法だ。今回検証したのは環境変数による設定のみである。

発生した問題を説明する。依存ライブラリの jar ファイルを全て CLASSPATH に含めて java コマンドを実行しても、コンパイルした bin ディレクトリ外では以下の様なエラーが発生した。

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
 Options cannot be resolved to a type
 Options cannot be resolved to a type
 CommandLineParser cannot be resolved to a type
 PosixParser cannot be resolved to a type
 CommandLine cannot be resolved to a type
 Option cannot be resolved to a type
 ParseException cannot be resolved to a type

 at com.github.uchan_nos.c_helper.Launcher.main(Launcher.java:32)

コンパイル時はエラーがなく、さらに bin ディレクトリで java コマンドを実行すれば正常に実行されるのに、 java コマンドを実行するときのカレントディレクトリが異なるとダメになる。

この時のクラスパスの設定は次。
export CLASSPATH=`python ~/gitrepos/c-helper/tools/classpath.py /Applications/eclipse/plugins`:~/java/lib/commons-cli-1.2/commons-cli-1.2.jar:~/gitrepos/c-helper/bin

`と`で囲まれた python コマンドは、依存している jar ファイルの名前をコロン区切りにするためのもの。その後ろに追加で依存する commons-cli-1.2.jar ファイルを指定した。

このようなときは、クラスパスの順序を変えれば解決するかもしれない。今回の場合は以下のように修正したら解決した。
export CLASSPATH=~/java/lib/commons-cli-1.2/commons-cli-1.2.jar:~/gitrepos/c-helper/bin:`python ~/gitrepos/c-helper/tools/classpath.py /Applications/eclipse/plugins`

私自身クラスパスの仕組みをはっきりと把握できていないため、今回の対処法が全ての場合で有効かは分からないが、今回の場合はこれが特効薬だった。

2013年8月16日金曜日

OS X Mountain Lion + Python 3 + Beautiful Soup 4

OS X Mountain Lion 上で動く Python 3 に Beautiful Soup 4 をインストールしようとしたら嵌ったのでメモ。

Python 3.3.2 (HomeBrew でインストールしたもの)
Beautiful Soup 4.3.0

上手く行ったインストール方法


$ sudo pip3 install beautifulsoup4
$ cd /usr/local/lib/python3.3/site-packages/
$ sudo 2to3-3.3 -w bs4

問題

pip3 でインストールするだけだと Beautiful Soup をインポートするときに SyntaxError 例外が発生する。

uchan@uchan-mba:site-packages$ python3
Python 3.3.2 (default, Jul 11 2013, 15:15:27) 
[GCC 4.2.1 Compatible Apple LLVM 4.2 (clang-425.0.28)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from bs4 import BeautifulSoup4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "./bs4/__init__.py", line 392
    print soup.prettify()
             ^
SyntaxError: invalid syntax

2to3-3.3 コマンドを手動で実行することで、ライブラリのソースコードを Python 3.3 向けに修正することができる。(インストーラが自動実行しないのはライブラリのバグかもしれない)

2013年7月29日月曜日

Qt Creator で Qt Quick アプリケーションを作ると QML ファイルが読み込めない

OS X Mountain Lion + Qt 5.1.0 + Qt Creator 2.8.0 という環境で開発しています。

Qt Creator で ファイル > ファイル/プロジェクトの新規作成 > Qt Quick 2 Application (Built-in Types) からプロジェクトを作ると main.qml, main.cpp, qtquick2applicationviewer.cpp が含まれたプロジェクトが生成されます。各ファイルに関する説明は QtQuick での C++ × QML バインディングについてまとめてみた を読むといいです。僕もこれを参考に勉強しています。

しかし、初期状態で作成したプロジェクトを実行しようとしても main.qml ファイルの読込エラーが発生してしまいます。原因を調査したところ、どうやらビルド成果物のパスに日本語が含まれると QML ファイルのコピーに失敗してしまうようです。

プロジェクトを作るときのウィザードで日本語を含むパスを指定する(画像参照)と QML ファイルのコピーに失敗しますので、設定を変えて(「デスクトップ」を「Desktop」にでも変更しましょう)再度プロジェクトを生成すると上手く行きます。エラーに悩まされている人は参考にしてください。

成果物へのパスに日本語が含まれている 
「デスクトップ」を「Desktop」に変えた
プロジェクトを再度作成したら英語になった!

ちなみに、元々コピー対象ではないリソースなどをバンドル(hoge.appのこと)に含めるには How to add resource files to an OS X application bundle という方法があるようです。この方法を使っても main.qml が見つからないエラーを解決できます。ただ、この方法は上手くやらないとプロジェクトファイルが OS X 専用になってしまうと思います。なるべく先述の設定変更で対処するのがいいでしょう。

2013年7月23日火曜日

Qt 5.1 + QML + qmlscene

QML でプログラミングを始めよう を参考に QML の勉強を始めました。
ボタンの表示からテキストエディタの作成、C++との連携など一連の内容が書いてあって参考になりそうな感じです。

Qt 5から QML ファイルのプレビュー方法が変わったらしく、ちょっとはまったのでメモしておきます。

上記サイトでは QMLViewer を用いてプレビューを行なっていますが、どうやら Qt 5 からは qmlscene コマンドを使うようです。BeagleBoard 向け Qt 5

公式の First Steps with QML | QtDoc 5.1 を見たら qmlscene を使うんだよとちゃんと書いてありました。お恥ずかしい (^^;

ということで、以下の様な QML ファイルを作って qmlscene しましょう。

-- win.qml --
import QtQuick 2.0

Rectangle {
  id: simplebutton
  color: "gray"
  width: 150
  height: 75

  Text {
    id: buttonlabel
    anchors.centerIn: parent
    text: "hello!!"
  }
}

$ qmlscene win.qml