web-dev-qa-db-ja.com

複数のターゲット言語にコンパイルする方法

サイドノート、ちょうど Haxe について学んだ、これはこの質問にいくつかの洞察を提供するかもしれません。

私の質問の基礎は、1つの言語をいくつかの他の言語にコンパイルする場合、どのようなトレードオフ(ある場合)が必要か、またはする必要があるかです。私は特にプラグインに関して this のように考えていますが、それをクロス言語コンパイラに適用することもできます。

基本的に、コンパイラの場合、目標は、たとえばJavaScriptまたはTypeScriptでコードを記述し、それをC、Java、Swiftなどの異なるネイティブプラットフォーム/言語/環境などにコンパイルすることです。 WordPress、Magento、Shopifyなどと言います。使用している簡略化されたテンプレート言語があるか、PHPまたは他の言語を「主要」言語として選択し、その後はそうしない異なる言語にコンパイルする場合、各プラットフォームで異なる「ページ」または「テンプレート」スタイルにコンパイルできます。さらに関連しているように見えるより極端な点は、Rubyの Fog ライブラリの場合と同様です。 AWS、Google Cloud、Azureなどを抽象化して1つの上位レベルの抽象化し、これらのサービスのいずれか1つをバックエンドとしてターゲットにすることができます。Homebrewと多少似ているかもしれませんが、それについてはあまりわかりません。

私が主に疑問に思っているのは、一般的な抽象化レイヤーを作成して、これらのケースや他のケースで複数の異なるターゲットにコンパイルできるかどうかです。たとえば、Linuxはさまざまなアーキテクチャを抽象化しているので、ほとんどの場合、アーキテクチャに固有のコードを記述する必要はありません(常に?)。 Linux、Mac、Windowsなどのすべてのオペレーティングシステムを1つのものに抽象化する「高次オペレーティングシステムレイヤー」を知らないため、基盤となる実装に関係なく、それらのいずれも使用できます。 (なぜ彼らはそれをしなかったのですか?

しかし、基本的には、ソースアルゴリズムを受け取り、それをターゲット言語アルゴリズムに変換するコンパイラを作成できますか一般的な方法?たとえば、グラフィックレンダリング、httpサーバーなどです。 Mac/iOS上のメタル、ブラウザー内のWebGL、ブラウザー内のDOM、Linux上のOpenGL、Windows上のDirectXについて知っているグラフィックスレンダリングについては、おそらく(私は到達しているのですが、よくわかりません)。スプライト、ピクセル、カラーなどの概念を備えた汎用の「グラフィック」レイヤーがあり、最適化された方法でこれらの各ターゲットプラットフォームにコンパイルされることを想像できます。しかし、これはファンタジーですか?特定のプラットフォームごとにアルゴリズムを個別に記述する必要がありますか?つまり、架空の「高次グラフィックスレイヤー」で物理エンジンを作成するとします。次に、高次の物理エンジンアルゴリズムとデータ構造をいくつかの完全に異なるターゲットプラットフォーム/言語にコンパイルできますか?

どのトレードオフを行う必要がありますか?どのような制限がありますか?それも可能ですか?もしそうなら、あなたはそのようなものを実装するためにどのような措置をとる必要がありますか?

HTTPサーバーの場合、「ソケットを開く、接続をリッスンするループなど」のような単純なアルゴリズムがあるとしましょう。まあ、JavaScriptではこれを行う必要すらありません。httpServer.listen()を実行するだけです。しかし、Cでは、ソケットを開くなどのほかに、メモリを割り当てたり、いくつかのことを実行したりする必要があるかもしれません。したがって、この場合、難しいと思われます(ただし、不可能または実用的ではない?) CとJavaScriptの両方でのHTTPサーバーの汎用アルゴリズム。それはそうですか?両方のプラットフォーム(および他のプラットフォーム)で動作するHTTPサーバー用のアルゴリズムを作成する方法はありません。あるいはゲームの例でも同じですか?

極端な場合は、make game engineそして、それは各プラットフォームに最適なゲームエンジンを作ります。しかし、それよりも少し高い順序でゲームエンジンを作成するとします。各プラットフォームで最初からすべてを書き直すことなく、リモートで複数のターゲットプラットフォームにコンパイルすることは可能ですか?

基本的にこれらすべての例は、主な質問を示唆しています:プログラミングの意味で、1つのシステムから他のシステムへの変換を構築することさえ可能ですか?これがこの分野の問題をよりよく理解するのに役立つ研究論文があるかもしれない研究分野であるかどうかさえ知りません。しかし、どちらにしても、それが可能かどうか、トレードオフが何であるか、または一般に注意しなければならないことを知りたいのです。

LLVMは関連しているように見えますが、低レベルで明確なアセンブリの問題により、問題の解決がはるかに容易になっているようです。ここで説明した状況(およびその他の状況)でそれが可能かどうかはわかりません。

2
Lance Pollard

Linux、Mac、Windowsなどのすべてのオペレーティングシステムを1つのものに抽象化して、基礎となる実装に関係なくそれらを使用できる「高次オペレーティングシステムレイヤー」については知りません。

これは、Java仮想マシンやMicrosoft CLRのようなプラットフォームが行うこととまったく同じです。

なぜ彼らはそれをしなかったのですか?

彼らがそうしたと私は言うでしょう。ただし、このようなプラットフォームは、ソフトウェア開発のすべてではありません。これらは、ほとんどのプログラムが必要とし、ほとんどのオペレーティングシステムが提供するサービスの抽象化を示しています。ただし、抽象化では常に違いや詳細がわかりません。それが抽象化である理由です。これらの詳細は、効率やセキュリティのために重要な場合があります。

たとえば、 確かにJavaで非常に機能的で高速なWebサーバーを記述できます それは多くの目的のために十分です。ただし、単に「十分」であるだけでなく、現在存在する任意のプラットフォームで最速のWebサーバーであるWebサーバーが必要になる場合があります。各プラットフォームのネットワークスタックの詳細を確認する必要があります。1つのOSが、他のプラットフォームではすぐに利用できない、または効率的に実装されていないネットワークスタック/スケジューラのパラメーターを公開する場合があります。

しかし、それよりも少し高い順序でゲームエンジンを作成するとします。各プラットフォームで最初からすべてを書き直すことなく、リモートで複数のターゲットプラットフォームにコンパイルすることは可能ですか?

通常、最初からすべてを書き直す必要はありません。より一般的には、条件付きコンパイルのための何らかの機能があります。つまり、2つのプラットフォームで基本機能が大幅に異なる場合は、次のようにします。

 #ifdef OS1
 void drawSquare() {
    plainOldDrawSquare()
 }
 #elseif OS2
 void drawSquare() {
   fiddleWithLowLevelGraphicsConfiguration();
   superfastPlatformSpecificDrawSquare()
 }
 #endif

#で始まる行は、特定のプラットフォーム用にビルドするソースコードのバージョンをコンパイラに指示するコンパイラへのディレクティブです。

8

私は少なくともこのようにして開発された "生きている" ソフトウェア製品 を1つ知っています:一般的な高水準言語(この中にcase "AlgoPascal" )は、他のいくつかの異なる高レベル言語(C++、C#、Delphi、CPython)にコンパイルされます。過去のVBAバージョンも)。そう、これは間違いなく可能です

もちろん、このような科学数学ライブラリの場合、オペレーティングシステム固有のライブラリやAPIはほとんど必要ありません。そして、それはここで行わなければならないトレードオフです:すべてのターゲット環境の最小の共通分母しかサポートできません-または、サポートされているすべてのオペレーティングシステムプラットフォーム(.NETおよび=)で共通に見えるターゲットランタイムインフラストラクチャを作成する必要がありますJavaアプローチ:ほとんどのオペレーティングシステムの仕様を抽象化する膨大な共通ライブラリセットを提供します)。

あなたの質問とは直接関係のないALGLIBに付記を追加しましょう。私にとって、ベンダーは、「実際の」AlgoPascalソースコードを公開せずに、この方法でライブラリをオープンソースする方法を見つけたようです。公開されたソースコードはおそらくGPLが "変更を加えるための作業の好ましい形式" と呼んでいるものではないため、法的な影響については不明です。おそらく、これはOpensource.SEの質問に値するでしょう。それ自身。

4
Doc Brown

Charles Grantがすでに指摘しているように、仮想マシンでこれをある程度統合することは可能です。ただし、 リークの多い抽象化の法則 には問題があります。あなたが抽象化したものはどこかで漏れるでしょう。抽象データを処理しているだけであれば問題ありません。すべてのVMシステムは、文字列、整数、配列などの概念をマップできるため、プラットフォーム固有のコードがいくつかあります。

システムの境界に到達すると困難が始まります。ファイルシステムの方法をどこまで抽象化できますか?たとえば、プロセスによって現在開かれているファイルを削除する場合はどうでしょうか。 Linuxでは問題ありませんが、Windowsでは大きな問題です。すべてのウィジェットライブラリを備えたGUIはどうですか?入力デバイスはどうですか?マウスを使用している場合は右クリックする機能を必要とするインターフェイスは正常に機能しますが、タッチスクリーンでは実際には機能しません。

したがって、オペレーティングシステムの抽象化はすべて、対象とするプラットフォームの共通の機能セットに制限する必要があります。このため、Javaのような言語を使用してこの問題を解決すると約束した場合でも、遅かれ早かれOS固有のコードで問題が発生します。

1
Manziel