gyp

## はじめに
[gyp](https://code.google.com/p/gyp/) の日本語情報です。

## gyp とは？
gyp はマルチプラットフォーム対応のメタビルドシステムです。CMake、scons、waf などを使い倒した Google の人たちがそれらを運用する上での問題を回避するために開発されているようです。基本的にはネイティブコードをビルドするためのシステムのようです。

### gyp で何ができるの？
gyp はあくまでメタビルドシステムで、ビルドそのものは既存のビルドシステムを利用します。gyp は対応しているビルド設定ファイル (Makefile など) を生成するだけです。

主な対応は以下のとおりです。

 1. ninja
 2. make
 3. Xcode
 4. Visual Studio
 5. Eclipse

Google では主に ninja を使っているようです。

### なぜ gyp を使うの？
私も Windows/Mac OS X/Linux/Android/iOS それぞれに対応するネイティブコードを書いています。はじめのうちは、Windows は Visual Studio、Mac OS X/iOS は Xcode、Linux は Makefile、Android は NDK 用 Makefile をそれぞれ個別に用意していましたが、すぐに面倒になりました。

次に、これらに対応したビルド設定ファイルを自動生成するためのビルドツールを探してみるとすぐにいくつか出てきました。半年ほど cmake と scons を並行運用していましたが、その中で気に入らない点が出てきました。

 - ビルドはできるが Visual Studio、Xcode などのプロジェクトファイルが生成できない
    - scons、waf などはこれ
 - Visual Studio、Xcode のプロジェクトファイルが生成できるが中身がイマイチ
    - cmake では、include ディレクトリがなぜか絶対パスだったりした
 - プロジェクト間の設定の共有がイマイチ
    - Android NDK の export の概念に相当するものがあったりなかったり
 - Android NDK に対応していなかった
    - 当時は cmake、scons、waf どれも対応してませんでした

この辺をすべてうまく対応してくれたのが gyp です。

### どんな製品で使われているの？
gyp は Google Chrome をはじめとした Google 製クライアントプログラムを中心に利用実績があります。ちなみに、gyp は Google Chrome などを他環境でビルドするための作られたもので、以前は scons でビルドされていました。Google 日本語入力のベースである mozc や node.js(以前は waf でビルドされていました)、その中で動いている JavaScript エンジンの v8(以前は scons でビルドされていました)、libuv なんかも gyp でビルドされるようになっています。

### どんな環境で使えるの？
gyp は Python で実装されていて、Python 2.7 で動作します。古い Cent OS など Python 2.4 が既定の環境では Python 2.7 を用意する必要があります。

私は gyp を Windows、Mac OS X、Ubuntu で利用していますが、今のところ大きな不満はありません。

### どうやって使うの？
gyp はただの Python スクリプト群です。New BSD ライセンスなので、自分のプロジェクトに組み込んでしまうのが楽だと思います。私は node.js を参考に以下のようにして運用しています。

 - $PROJECT_ROOT/tools/gyp
    - gyp 一式を配置する
 - $PROJECT_ROOT/build/common.gypi
    - 各プロジェクトの共通設定を書く
        - Visual Studio のプロジェクト設定、Xcode のプロジェクト設定など
 - $PROJECT_ROOT/configure.py
    - gyp を呼び出してプロジェクトファイルを生成するスクリプトを書く
 - $PROJECT_ROOT/README.md
    - ビルド手順を書く



## 変更履歴
gyp は活発に修正が行われています。最新版を取り込むと、稀に自分のプロジェクトのビルドができなくなったりします。そのため、変更履歴をチェックしてから取り込むようにするといいでしょう。変更履歴は英語で記載されていますが、適当に日本語訳したものをここに記載しておきます。

### [r1885](https://code.google.com/p/gyp/source/detail?r=1885)
Android 向けの修正。rule_trigger ターゲットを削除した。

rule_trigger ターゲットは意味のある目的を提供しない。rule にあるすべての出力ファイルは extra_outputs に追加されていて、これは final target によってすでに依存されている。複数アーキテクチャのビルドをしようとすると、同じ rule trigger taget 名が双方のアーキテクチャで生成されるので、問題が発生する。よって削除した。

### [r1884](https://code.google.com/p/gyp/source/detail?r=1884)
OS X でのすべてのジェネレータにおける ARCHS フィルタリングを改良した。

※訳注：SDKROOT に macosx、iphoneos、iphonesimulator のいずれかを指定すると、指定に応じて適切なアーキテクチャが選択されるようになったようである。

### [r1883](https://code.google.com/p/gyp/source/detail?r=1883)
ターゲットタイプ None を ninja でビルドするときの振る舞いを修正した。

GYP はターゲットタイプが None だと有効な ninja ルールを生成しない。これらのターゲットは依存関係を構築するために利用されることがある。

※訳注：ヘッダファイルだけを持っているターゲットなど。

この問題を再現する最小の gyp ファイルは以下のとおり。

    {
      'targets': [
        {
          'target_name': 'dummy',
          'type': 'none',
          'sources': [
            'test.h',
          ],
        },
      ],
    }

これで dummy.ninja というファイルが生成されるが、dummy という名前のルールはない。msvs-ninja ビルドを使うと、MSVS はターゲットがないと文句を言ってきてプロジェクトのコンパイルは失敗する。

### [r1882](https://code.google.com/p/gyp/source/detail?r=1882)
Xcode 5.1 以降で 64 ビットアーキテクチャをデフォルトで有効にした。

Xcode 5.1 のリリースノートによると「Standard Architectures」ビルド設定は現在 64 ビットアーキテクチャも含むようになっている。「Standard Architectures Including 64-Bit」はまだ非推奨になっていない。

### [r1881](https://code.google.com/p/gyp/source/detail?r=1881)
iOS でビルドするときの ARCHS の選択を修正した。

iOS でビルドするときは gyp ファイルでどんなアーキテクチャセットを指定するかをよく考えること。x86_64 は Xcode 4.0 以降でしか指定できない。

※訳注：ARCHS を指定しないと、$(ARCHS_STANDARD) を指定したことになる。

### [r1880](https://code.google.com/p/gyp/source/detail?r=1880)
ninja 向けの修正。individual_generated_bindings のサイズを削減した。

### [r1879](https://code.google.com/p/gyp/source/detail?r=1879)
ninja 向けの修正。rule inputs をひとつのノードに入れるようにした。

rule が n 個のソースファイルにマッチしそれが M 個の入力を保つ場合、すべてのビルドエッジのために繰り返される inputs は生成された ninja ファイルに n * m 回現れる。

この修正を加えると、gyp は代わりにひとつのスタンプノードを書くようになる。これによって生成される ninja ファイルは振る舞いに変化を与えずにスリムになる。

chromium では生成された individual_generated_bindings.ninja のファイルサイズが 4.5 MB から 401kb に削減される。これにより空ビルドが速くなる。

### [r1878](https://code.google.com/p/gyp/source/detail?r=1878)
msvs-ninja で、選択された C/C++ ファイルをビルドできるようにした。

このコミットで「msvs_external_builder_clcompile_cmd」プロパティが新しく追加される。これはユーザが選択された C/C++ ファイルをビルド試行するときに指定する。

msvs-ninja では、msvs_external_builder_clcompile_cmd が gyp-win-tool の ExecClCompile コマンドに新しくマッピングされる。ninja のターゲットの一覧に選択されたファイルの一覧が展開され、ninja が起動される。

### [r1877](https://code.google.com/p/gyp/source/detail?r=1877)
ninja 向けの修正。rule の inputs で RULE_INPUT_* 変数を受け付けなくした。

https://code.google.com/p/gyp/wiki/GypLanguageSpecification#Rules では、inputs においてこれらが利用できないとあるし、chromium r257511 では実際に利用されていない。

### [r1876](https://code.google.com/p/gyp/source/detail?r=1876)
msvs_emulation で、使われていないメソッドを削除した。

### [r1875](https://code.google.com/p/gyp/source/detail?r=1875)
perforce などのソースコントロールシステムで、チェックアウトされたファイルは既定では読み取り専用になる (git や subversion なんかではそんなことはない)。

こういうシステム上では、win-tool を使って再帰コピーが失敗する。例えば、gyp に「copies」があるとソースツリーから出力ディレクトリに何かしらがコピーされるが、それは初期の属性を伴ってコピーされるため、次からは上書きできずに失敗してしまう、というわけだ。
### [r1874](https://code.google.com/p/gyp/source/detail?r=1874)
Mac での ninja ビルド向けの修正。[r1871](https://code.google.com/p/gyp/source/detail?r=1871) によるリンクの退行を修正した。

このバグは同じ rsp ファイルを使う i386 と x86_64 バイナリによって発生する。複数アーキテクチャでビルドするときは rsp ファイル名にアーキテクチャ名を追加することで対応した。

※ ld64 (64 ビット向けの ld) は、32 bit リンクのための rsp ファイルを使って 64 ビット版でリンクするとき、正しいアーキテクチャを持たない *.o ファイルについて警告を出力し、それをスキップするのだが、プロセス終了コードは 0 になる。

これをテストするには、各アーキテクチャの最終的なファットバイナリからシンボル一覧を取得し、すべてが存在しているかを確認する。この確認は、このパッチなしでは結構期待どおりに失敗してくれる。