さらに、この記事には、Ubuntu 12.04環境でlibxmlを移植するために必要な手順の完全なシーケンスが含まれています。 必要な環境設定とemscriptenを含めます。
Emscriptenをインストールして構成する
Emscriptenは、JavaScriptのLLVMバイトコードからのコンパイラです。 C / C ++コードは、 clangコンパイラを使用してLLVMバイトコードにコンパイルできます。 他の言語にもLLVMバイトコードコンパイラがあります。 バイトコードに基づいたEmscriptenは、最新のブラウザーなどのJavaScriptインタープリターで実行できる適切なJavaScriptコードを生成します。 emscriptenを使用して、Mozillaのスタッフは最近Doomの移植に成功しました。
Emscriptenは以下を提供します。emconfigure-環境をセットアップし、その後./configureを起動するためのユーティリティ。 emmake-環境を構成してからmakeを実行するユーティリティ。 emcc -JavaScriptのLLVMコンパイラ。
それでは、emscriptenを操作するための環境をセットアップしましょう( マニュアルを参照)。
clang + llvmをインストール(> = 3.0):
wget llvm.org/releases/3.0/clang+llvm-3.0-i386-linux-Ubuntu-11_10.tar.gz
tar xfv clang + llvm-3.0-i386-linux-Ubuntu-11_10.tar.gz
node.jsをインストールします(> = 0.5.5):
sudo apt-get install nodejs
emscriptenの現在のバージョンをアンロードします。
git clone git://github.com/kripken/emscripten.git
cd emscripten
clangの正常性の確認:
../clang+llvm-3.0-i386-linux-Ubuntu-11_10/bin/clang tests / hello_world.cpp
./a.out
>>こんにちは、世界!
node.jsの正常性の確認:
ノードテスト/ hello_world.js
>>こんにちは、世界!
emccを初めて実行して、構成ファイル「 〜/ .emscripten 」を作成します。
./emcc
構成ファイルで、clang + llvmディレクトリーとemscriptenインストールディレクトリーを指定する必要があります。
EMSCRIPTEN_ROOT = os.path.expanduser( ' 〜/ path / emscripten ')#これはemscriptenを使用するプロジェクトが見つけるのに役立ちます
LLVM_ROOT = os.path.expanduser( ' 〜/パス/ clang + llvm-3.0-i386-linux-Ubuntu-11_10 / bin ')
emccを再度実行して、正しく構成されていることを確認する必要があります。 この場合、「 emcc:no input files 」というメッセージが表示されます 。
./emcc
>> emcc:入力ファイルなし
emccを使用してhello_wolrd.cppをコンパイルすることにより、すべてが正しく機能することを確認できます。
./emcc tests / hello_world.cpp
ノードa.out.js
>>こんにちは、世界
パート1:C / C ++ソースのコンパイル
移植を開始する前に、プロジェクトのソースコードがC / C ++コンパイラによってエラーなしでコンパイルされていることを確認する必要があります。
リポジトリからlibxmlをアンロードしてコンパイルします。
git clone git://git.gnome.org/libxml2
cd libxml2
git checkout v2.7.8
CC =〜/パス/ clang + llvm-3.0-i386-linux-Ubuntu-11_10 / bin / clang ./autogen.sh --without-debug --without-ftp --without-http --without-python-正規表現なし-スレッドなし-モジュールなし
作る
Libxmlには、xmlスキーマを検証するためのxmllintコンソールユーティリティが含まれています。 コンパイルされたコードの正しい動作を検証するために使用できます。 このようなチェックを実行する必要があります。これには、元のバージョンと移植されたバージョンが等しく正しく動作することを確認することも含まれます。 xmllintでのテストは次のようになります。
$。/ xmllint --noout --schema test.xsd test.xml
>> test.xml検証
すべてが正常に機能する場合、test.xmlファイルにいくつかの変更を加えると、xmllintがエラーメッセージを表示します。
パート2:構成
次のコマンドでemscriptenを使用して、プロジェクトをコンパイル用に構成できます。
〜/ path / emscripten / emconfigure ./autogen.sh --without-debug --without-ftp --without-http --without-python --without-regexps --without-threads --without-modules
emconfigureは、。/ configureがgccまたはclangの代わりにemccコンパイラーを使用するように環境変数を設定します。 ./configureが正しく機能するように環境を設定します(構成テスト(ネイティブコードをコンパイルする)を含む)。
デフォルトの構成結果(フラグなし)には、この段階での多くの不必要な機能(HTTPおよびFTPサポートなど)が含まれます。 xml-schemesを検証するだけなので、プロジェクトを構成して、不要な機能を排除する必要があります。 一般に、移植する際に不要な機能を除外することをお勧めします。 これにより、コードのサイズが小さくなり、ネットワーク環境にとって重要になります。 さらに、一部のヘッダーファイルでは、手動編集が必要な場合があります(glibcではなく、newlibを使用するファイル)。
パート3:プロジェクトをビルドする
アセンブリは次のコマンドによって実行されます。
〜/パス/ emscripten / emmake make
emmakeはemconfigureと似ています:環境変数も設定します。 emmakeのおかげで、ビルド中にネイティブコードの代わりにLLVMバイトコードが生成されます。 これは、各オブジェクトファイルとそれに続くレイアウトのJavaScriptコードの生成を回避するために行われます。 代わりに、LLVMバイトコードビルダーが使用されます。
アセンブリの結果、多くの異なるファイルが構築されます。 しかし、それらを実現することはできません。 前述のように、これはLLVMバイトコード(BCを使用して表示できます)であるため、次のステップが必要です。
パート4:JavaScriptへの変換
xmllintはxmllint.oおよびlibxml2.aに依存しています。 LLVMリンカーは動的リンク(遅延バインディング)をサポートせず、emccはそれを無視します。 そのため、リンクするlibxml2.a静的ライブラリを手動で指定する必要があります。
libz (圧縮用のオープンライブラリ)への依存は、それほど明白ではありません。 libz.aなしでビルドすると、gzopen関数を呼び出そうとすると、実行中にエラーが発生します。 したがって、libz.aをビルドする必要があります。
cd〜/パス
wget zlib.net/zlib-1.2.7.tar.gz
tar xfv zlib-1.2.7.tar.gz
cd zlib-1.2.7
〜/ path / emscripten / emconfigure ./configure --static
〜/パス/ emscripten / emmake make
これで、JavaScriptコードをコンパイルできます。
cd〜/パス/ libxml2
〜/ path / emscripten / emcc -O2 xmllint.o .libs / libxml2.a ../zlib-1.2.7/libz.a -o xmllint.test.js --embed-file test.xml --embed-file test.xsd
どこで:
- emcc-gccまたはclangの代替(上記を参照);
- -O2は最適化フラグです。 LLVMおよび追加の最適化は、クロージャーコンパイラ(詳細モード)を含むJavaScriptレベルで実行されます。
- コンパイルするファイル
- -oは、結果のxmllint.test.jsファイルです。 接尾辞「js」は、生成されたコードの形式(この場合はJavaScript)をemccで示します。
- --embed-file-指定されたファイルの内容を生成されたコードに含め、これらのファイルが標準stdio呼び出し(fopen、freadなど)からアクセスできるように仮想ファイルシステムを構成するようにemccに指示します。 これは、コンパイルされたコードからファイルにアクセスする最も簡単な方法です。
パート5:JavaScriptのテスト
Node.js、SpiderMonkey、またはV8が提供するJavaScriptコンソールを使用して、このコードを実行できます。
ノードxmllint.test.js --noout --schema test.xsd test.xml
>> test.xml検証
結果はネイティブコードとまったく同じになります。 同様に、xmlスキーマにエラーを導入した場合、xmllintはそれらを検出する必要があります。
重要 :ネイティブビルドとJavaScriptビルドに使用されるすべての引数は正確に同一でなければなりません。
パート6:リファクタリングと再利用
現時点では、検証用の2つのファイルがスクリプトにハードコーディングされています。 スキームに従ってXMLファイルを検証するには、一般化された関数が必要です。 実際には簡単ですが、作業が追加されるClosure Compilerを使用してコードが最適化されることを考慮する必要があります。
最初に行うことは、--pre-jsオプションを指定してemccを呼び出すことです。 生成されたコードの前にJavaScriptコードを追加します(それぞれpost-js、後)。 重要なことは、最適化が実行される前であっても--pre-jsがコードを追加することです。 そして、これは正しい最適化に必要なコードが生成されたコードとともに最適化されることを意味します。 一方、Closure Compilerは、必要な関数を未使用として破棄できます。
--pre-jsオプションを使用して含めるスクリプトは次のとおりです。
モジュール['preRun'] = function(){ FS.createDataFile( 「/」、 「test.xml」、 モジュール['intArrayFromString'](モジュール['xml'])、 本当 true); FS.createDataFile( 「/」、 「test.xsd」、 モジュール['intArrayFromString'](モジュール['schema'])、 本当 true); }; モジュール['arguments'] = ['--noout'、 '-schema'、 'test.xsd'、 'test.xml']; モジュール['return'] = ''; モジュール['print'] = function(text){ モジュール['return'] + = text + '\ n'; };
次のスクリプトを検討してください。
- モジュール-emscriptenを使用して生成されたコードが他のJavaScriptコードとやり取りするオブジェクト。
- Module.nameの代わりにModule ['name']など、モジュールにアクセスするには文字列名を使用することが重要です。 この場合、クロージャーは名前を変更しません。
- 最初に行うことは、生成されたコードの直前に実行されるModule.preRunを変更することです(ただし、環境をセットアップした後)。 preRun関数では、ファイルシステムAPI( Emscripten FileSystem API )を使用して2つのファイルが作成されます 。 簡単にするために、以前のテストと同じファイル名が使用されています(test.xmlおよびtest.xsd)。 これらのファイルの内容は、モジュール['xml']およびモジュール['xsd']に設定されます。 これらの変数には、XMLおよびXMLスキーマが含まれている必要があります。 文字列は、intArrayFromStringを使用して配列に変換されます。
- Module.argumentsをインストールします-consoleコマンドの引数リストに相当します。 引数は、テストで以前に使用したものでなければなりません。 唯一の違いは、test.xmlファイルとtest.xsdファイルにユーザーデータが含まれることです。
- Module.printは、コードがstdioから操作を呼び出そうとしたときに呼び出されます。 後で読み取ることができるように、すべての出力をバッファーに保存します。
したがって、入力ファイルtest.xmlおよびtest.xsdにユーザーが入力した情報が含まれ、検証結果がバッファーに保存されるようになりました。
ただし、それだけではありません。 コードをコンパイルします。
〜/パス/ emscripten / emcc -O2 xmllint.o .libs / libxml2.a ../zlib-1.2.7/libz.a -o xmllint.raw.js --pre-js pre.js
コンパイルコマンドは以前のように見えますが、ファイルを含める必要がなくなりました。 代わりに、-pre-jsフラグを使用してpre.jsを含めます。
コンパイル後、xmllint.raw.jsには最適化および縮小されたコードが含まれます。 使いやすくするために、JavaScript関数でラップします。
関数validateXML(xml、スキーマ){ var Module = { xml:xml、 スキーマ:スキーマ }; {{{GENERATED_CODE}}} return Module.return; }
GENERATED_CODEは、コンパイル結果(xmllint.raw.js)に置き換える必要があります。 validateXML関数は、適切な引数をxmlおよびスキーマフィールドに割り当てます。 したがって、test.xmlおよびtest.xsdファイルにユーザーデータが含まれていることを確認します。 生成されたコードが実行された後、関数は検証結果を返します。
以上です! xml.jsは、通常のJavaScriptコードから使用できます。 必要なのは、jsファイルをインクルードし、xmlとスキーマでvalidateXML関数を呼び出すだけです。