Chrome Native Client Tutorial C++ Getting Started編 (Part 2)

前のエントリでは、Native Client SDKに含まれるgetting_started、つまりチュートリアルについての説明ドキュメントを和訳して掲載しました。このエントリでは、そのチュートリアルの続きです。ここでは、SDKに付いてくるMakefileをより簡単に書くためのマクロの紹介や、共通的に使われるであろう関数を集めたJavaScriptコードの説明について言及しています。Native Clientモジュールの開発には欠かせないものですので、ぜひ読んでみてください。

原文: C++ Tutorial: Getting Started (Part 2)


C++ Tutorial: Getting Started (Part 2)

概要

このチュートリアルは、Native Client SDKビルドシステムと共通JavaScriptファイルを使って Part 1を最終的なPNaClウェブアプリケーションに変換するための方法を紹介します。また、あなたのWebアプリケーションを Chrome Appsで必要になる Content Security Policy(CSP)互換にするためのいくつかのテクニックをデモンストレーションします。

Native Client SDKビルドシステムの利用は、全てのSDK Toolchainを使ったビルドや、DebugとRelease設定の切り替えを簡単にします。また、次のセクションで見せるように、あなたのプロジェクトのMakefileを単純にします。最後に、あなたのアプリケーションを実行およびデバッグするためのいくつかの便利なコマンドを追加します。

この例の最終的なコードは、ダウンロードしたNative Client SDKの中のpeper_$(VERSION)/getting_started_part2ディレクトリで見つけることができます。

Native Client SDKビルドシステムの利用

このセクションは、SDKビルドシステムの使い方を説明します。それをするために、私たちはMakefile内を変更するでしょう。Part 1とPart 2でMakefileはとても異なるので、1から始める方が簡単です。ここには、新しいMakefileの内容があります。以下のセクションでは、より詳細な説明をします。

Makefileの単純化

Part 1のMakefileは、単に一つのToolchain(PNaCl)と一つの設定(Release)をサポートするだけです。また、一つのソースファイルのみのサポートです。それは相対的にシンプルですが、もし私たちが複数のToolchain、設定、ソースファイル、またはビルド手順のサポートを追加したい場合は、増加的に複雑さが増してしまうでしょう。SDKビルドシステムは、Makefileの重大な複雑性の増加なしにそれらを可能にするため、変数やマクロ群を使います。

ここに、3つのToolchain(PNaCl, Newlib NaCl, Glibc NaCl)と2つの設定(Debug, Release)をサポートする新しいMakefileがあります。

VALID_TOOLCHAINS := pnacl newlib glibc
NACL_SDK_ROOT ?= $(abspath $(CURDIR)/../..)
include $(NACL_SDK_ROOT)/tools/common.mk
TARGET = part2
LIBS = ppapi_cpp ppapi
CFLAGS = -Wall
SOURCES = hello_tutorial.cc
# Build rules generated by macros from common.mk:
$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
# The PNaCl workflow uses both an unstripped and finalized/stripped binary.
# On NaCl, only produce a stripped binary for Release configs (not Debug).
ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
$(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS)))
endif
$(eval $(call NMF_RULE,$(TARGET),))

有効なToolchainの選択とcommon.mkの導入

Makefileは、このプロジェクトにとって有効なToolchainの特定から始まります。Native Client SDKビルドシステムは、例やライブラリのために複数のToolchainのプロジェクトをサポートすることがあるかもしれませんが、一般的には、プロジェクトを開始する際に一つのToolchainを選択し、それを変更することはないでしょう。より詳細な情報は、 Toolchains section of the Native Client overviewをご覧ください。

この例では、pnacl, newlib, そしてglibc Toolchainをサポートします。

VALID_TOOLCHAINS := pnacl newlib glibc

次に、利便性のために、NACL_SDK_ROOTの場所を指定します。この例はpepper_$(VERSION)/getting_started/part2の中にあるため、SDKのルートは2つディレクトリを上がった場所になります。

NACL_SDK_ROOT ?= $(abspath $(CURDIR)/../..)

あなた自身のプロジェクトでは、インストールされたSDKの絶対パスをここで使うことができます。また、NACL_SDK_ROOT環境変数をセットすることで、この初期値を上書き可能です。より詳細な情報は、 Step 5 of Part 1 if this tutorialをご覧ください。

次に、tools/common.mkファイルをインクルードします。このファイルは、プロジェクトをビルドしリンクするための新しいビルドルールを含む、Native Client SDKビルドシステムのための機能を提供します。私たちは以下のようにしてそれを利用します。

include $(NACL_SDK_ROOT)/tools/common.mk

あなたのプロジェクトの設定

tools/common.mkのインクルードの後、名前やソースファイル、ライブラリを指定することで、プロジェクトを設定します:

TARGET = part2
LIBS = ppapi_cpp ppapi
CFLAGS = -Wall
SOURCES = hello_tutorial.cc

これらの変数名は、必須ではなく、SDKビルドシステムによって使われません。それらは、以下で説明されるルールにおいてのみ利用されます。規約によって、全てのSDK Makefileは以下の変数を使用します:

TARGET

ビルドするプロジェクトの名前です。この値は生成されるライブラリや実行形式の名前を決定します。上記の例では、対象をpart2と呼んでいるので、PNaCl向けにpart2.pexeと呼ばれる実行形式が生成されるでしょう。NaCl Toolchain向けには、実行形式のファイル名はアーキテクチャのサフィックスが与えられます。例えば、ARM実行形式はpart2_arm.nexeとなります。

LIBS

この実行形式が必要とするリンクする対象のライブラリのリストです。ライブラリの検索パスは、現在のToolchainやアーキテクチャ向けのディレクトリ内のみを見るように既にセットアップされています。この例では、ppapi_cppおよびppapiに対してリンクします。ppapi_cppは、 Pepper C++ interfaceを使うために必要となります。

CFLAGS

コンパイラに渡される拡張フラグのリストです。この例では、全ての警告をONにするために、-Wallを渡しています。

LDFLAGS

リンカに渡される追加フラグの一覧です。この例は特別なリンカフラグを何も必要としていないので、この値は省略されています。

SOURCES

コンパイルするCまたはC++ソースの一覧です。空白で区切られます。もし長いソースのリストの場合は、一行ごとに一つファイルを書いて、行を継続するためにバックスラッシュを使うと読みやすくなるでしょう。ここに例があります:

SOURCES = foo.cc \
          bar.cc \
          baz.cc \
          quux.cc

ビルドマクロ

多くのプロジェクトのために、以下のビルドマクロを変更する必要はないでしょう。それらは、上記で定義された値を使っています。

$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
$(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS)))
endif
$(eval $(call NMF_RULE,$(TARGET),))

最初の行は、CFLAGSフラグを使って、SOURCES内の各ソースをコンパイルするためのルールを定義します:

$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))

次の6行は、一つ以上の実行形式内でオブジェクトファイルをリンクするためのルールを定義しています。TOOLCHAINがpnaclの時は、上記の例ではpart2.pexeという名前で一つだけ実行形式が生成されます。NaCl Toolchainを使ってる時は、各アーキテクチャ向けに3つの実行形式が生成されます。上記の例では、part2_arm.nexe, part2_x86_32.nexe, そしてpart2_x86_64.nexeとなります。

CONFIGがReleaseの際は、各実行形式はデバッグ情報を削除するためにstrip(訳注: シンボル情報の削除)され、ファイルサイズが減少された状態になります。そうではない場合は、TOOLCHAINがpnaclの際は、ワークフローはデバッグのためにstripされないバイナリを作成し、その後ファイナライズされ、公開のためにstripする、という流れになります。

ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
$(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS)))
endif

最後に、NMFルールは、前の手順において生成された各実行形式を参照するNaClマニフェストファイル(.nmf)を生成します:

$(eval $(call NMF_RULE,$(TARGET),))

Chrome Appsで機能するindex.htmlの作成

このセクションでは、Part 1のHTMLやJavaScriptをCSP互換にさせるために必要になる変更を説明します。もしあなたが Chrome Appをビルドしたい場合に必要になりますが、オープンなウェブ上でPNaClを使いたい場合は必要ではありません。

CSPルール

Chrome Apps CSPは、以下のような行為を制限します:

  • あなたのChrome Appページ内では、インラインスクリプトを使うことができません。その制限は、

このエントリーをはてなブックマークに追加

関連記事

2023年のRemap

Remapにファームウェアビルド機能を追加しました

Google I/O 2023でのウェブ関連のトピック

2022年を振り返って

現在のRemapと今後のRemapについて