コンソールとフィルタが大好きなプログラマ(==自分)の為のObjective-C入門以前

iPhoneiPadが今の所人気があることもあり、そのアプリケーション実装言語であるObjective-Cを触ってみようかと思うプログラマはまだそれなりにいるだろうし*1、特に注目していなかったけど今更ながら業務都合で……という事情の人もいるだろう。というか後者は私のことだ。

プログラミング経験者でもMacでの開発経験(の前にMacを使ったこと)が無い場合、概ね次の点が障壁となると思う。

  1. 開発用のMacの入手
  2. Mac全般の使い方
  3. Xcodeでの開発の方法
  4. Objective-Cの言語本体にまつわる部分の知識
  5. 使用するライブラリ/フレームワークの知識

実は意外と複数の分野にまたがっている。まあ今までC言語ファームウェアやライブラリを書いてきた人をいきなりMFCを使ったWindowsアプリ開発に放り込むようなもので、アレもコレも不慣れなことばかりでストレスがたまってしまう。

私の場合、開発用のMacは入手済みだ。Macの使い方は――まだ若干戸惑うこともあるけどWindows仕様のホイールマウスで何とかなっている。しかしXcodeがどうにも使い慣れないというか、ちょっとした勉強程度でもXcodeを使うなんて大仰というか。もともとIDEの類が苦手なことも影響しているのだろう。

そこで考えてみたのだが、Mac OSでは端末エミュレータ上でbashで作業できるので、コンソール生活しながらコンソールアプリでObjective-Cを勉強した方がまだ効率的というか、不慣れなXcodeに振り回されない分だけObjective-C本体や各種フレームワークの学習に集中できるのではないだろうか? 幸いにもLinux等のコンソールにはそれなりに慣れているのだから。

何しろ手元のMacのキーボードは `A' の左にCtrlキーがある訳で、どう考えてもUnixerやLinuxerを狙い撃ち(ry

コンソールでどこまでできそうか?

手元のMacはOSのバージョンが10.6.8で、Xcode 3.2.4が入っている。今回の計画に関係しそうなツールはこんな感じ。

これなら十分にコンソール生活できる気がする。emacsvimの設定はUbuntu上で使用している.emacsや.vim + .vimrcをコピペしただけで済んだ。

ちょっとしたツールを作ってビルドする分にはLinuxFreeBSD上で作業するような感じで進めることができるし、システムプログラミングする場合の勝手も似ている。

Objective-CC言語をマクロ的に拡張した感じなので、UnixC言語システムプログラミングする延長でObjective-C的な機能を使うことができるはずだ。

Xcodeを使わずにObjective-Cのコードをビルドする方法

Xcodeは内部でgccを使ってビルドを行っている。このことはデバッガコンソールの中身がどうみてもgdbな所からうかがえるし、何よりAppleのドキュメントにもそれらしきことが書いてあったりする。

Appleコンパイラは、GNU Compiler Collectionのコンパイラをベースにしています。Objective-Cの構文はGNU C/C++の構文のスーパーセットで、Objective-CコンパイラはC、C++、およびObjective-Cソースコードに対応しています。

日本語ドキュメント - Apple Developer

ということはコンソールからgccを叩いてもObjective-Cのソースをコンパイルできるはずだ。

例えばこんなソースがあるとする。

#include <stdlib.h>
#import <Foundation/Foundation.h>

int main(void) {
  // print hello, and exit
  NSLog(@"hello, world");
  return EXIT_SUCCESS;
}

このファイルがhello.mという名前だった場合、例えばこんな感じでビルドできる。

gcc -Wall -std=gnu99 -pedantic -framework Foundation -o hello hello.m

`-framework' はApple独自拡張のgccのリンカオプションで、使用しているフレームワークを指定する。Objective-Cで書いていても特にフレームワークを使用していなければこのオプションは不要だが*2、まあ便利なライブラリを使うことが大半なので事実上の必須項目だろう。

`-std=gnu99' のナゾ

ビルドオプション中の `-std=gnu99' は、許容するC/C++の機能を指定している。この場合は「C99規格の機能 + GNU拡張」が使用可能となる。gccのinfoによると、このオプションはObjective-Cのソースにも効果があるらしい。

ここで、先ほどのソースをオプションを変更してビルドしてみると、少々面白いことになる。

$ gcc -Wall -std=c89 -pedantic -framework Foundation -o hello hello.m
hello.m: In function 'main':
hello.m:5: error: expected expression before '/' token

6行目でエラーが発生してビルドできない。実は「//」をコメントとして使用しているのが原因だ。

この例ではオプション `-std=gnu99' を `-std=c89' に変更している。`-std=c89' はC89規格の機能のみ使用可能とするオプションだ。C89では「//」はコメントではない為、プリプロセス時に取り除かれることなくコンパイルが行われ、そこで「//」を通常のコードとして解析しようと試みて失敗している。

Appleのドキュメント上は「//」は行末コメントとなっているのだが、コンパイラとしてはこの辺りのオプションで実現しているようだ。

ちなみに `-std=' で指定できる内容は幾つかあるのだが、なぜ `gnu99' を指定したかというと、Xcodeが生成するプロジェクトのデフォルト値だからだ。この値は任意に変更できるようだが、特にこだわりがないならXcodeに合わせておいたほうが良いだろう。

*1:え、時代はHTML + CSS + JavaScriptだって? またまた、そんなどこぞのオライリー本みたいな(ry

*2:実際、C言語hello worldと同等のコードを書いてビルドしてみたら、-frameworkでフレームワークを全く指定しなくてもビルドできた。