使い方 -MPS Make フレームワークへの統合
ファセットを構築
概要
Like basically any build or make system, the MPS make executes a sequence of steps, or targets, to build an artifact. A global ordering of the necessary make steps is derived from relative priorities specified for each build targets (target A has to run before B, and B has to run before C, so the global order is A, B, C).
A complete build process may address several concerns, for example generating models into text, compiling these models, deploying them to the server, and/or generating .png files from graphviz source files. In MPS, such different build aspects are implemented with build facets. A facet is a collection of targets that address a common concern.
ファセット内のターゲットは設定パラメーターを交換できます。例: 全体的な make プロセスの早い段階で実行するように宣言されているターゲットは、設定パラメーターを収集し、第 2 のファセットに渡します。このファセット内パラメーター交換を実現するためのメカニズムは、プロパティと呼ばれます。さらに、ターゲットは、make プロセス中にクエリを使用してユーザーから情報を取得できます。
The overall make process is organized along the pipes and filters pattern. The targets act as filters, working on a stream of data being delivered to them. The data flowing among targets is called resources. There are different kinds of resources, all represented as different Java interfaces and tuples:
MResource contains MPS models created by users, those that are contained in the project's solutions and languages
GResource represents the results of the generation process, which includes the output models, that is the final state of the models after generation has completed. These are transient models, which may be inspected by using the 過渡モデルを保存 build option
TResource represents the result of text-gen
CResource represents a collection of Java classes
DResource represents a collection of delta changes to models (IDelta)
TextGenOutcomeResource represents the text files generated by textgen
Build targets specify an interface. According to the pipes and filters pattern, the interface describes the kind of data that flows into and out of a make
target. It is specified in terms of the resouce types mentioned above, as well as in terms of the kind of processing the target applies to these resources. The following four processing policies are defined:
transform がデフォルトです。このポリシーは、入力リソースタイプのインスタンスを消費し、出力リソースタイプのインスタンスを生成します。(e.g. it may
consumeMResources
and produceTResources
.)宣言する入力を消費しますが、出力は生成しません。* produce は何も消費しませんが、出力を生成します
パススルーはいかなるリソースにもアクセスせず、生産も消費もしません。
Note that the make process is more coarse grained than model generation. In other words, there is one facet that runs all the model generators. If one needs
to "interject" additional targets into the MPS generation process (as opposed to doing something before or after model generation), this requires refactoring
the generate
facets. This is beyond the scope of this discussion.
サンプルファセットの構築
As part of the mbeddr.com project to build a C base language for MPS, the actual C compiler has to be integrated into the MPS build process. More
specifically, programs written in the C base language contain a way to generate a Makefile
. This Makefile
has to be executed once it and all the
corresponding .c and .h files have been generated, i.e. at the very end of the MPS make process.
To do this, we built a make facet with two targets. The first one inspects input models and collects the absolute paths of the directories that may contain a
Makefile
after textgen. The second target then checks if there is actually a file called Makefile
in this directory and then runs make there. The two
targets exchange the directories via properties, as discussed in the overview above.
最初のターゲット: ディレクトリの収集
Facets live in the plugins
aspect of a language definition. Make sure you include the {{jetbrains.mps.make.facets} language into the plugins model,
so you can create instances of FacetDeclaration
. A facet is executed as part of the make process of a model if that model uses
the language that
declares the facet.
ファセットは runMake
と呼ばれます。 TextGen
と Generate
に依存します。これら 2 つのファセットへの依存関係は、それらのファセット内のターゲットに対するターゲットの優先順位を宣言できるように指定する必要があります。
The first target is called collectPaths
. It is specified as {{transform IMResource -> IMResource} in order to get in touch with the input models. The
facet specifies, as priorities, after configure
and before generate
. The latter is obvious, since we want to get at the models before they are
generated into text. The former priority essentially says that we want this target to run after the make process has been initialized (in other words: if
you want to do something "at the beginning", use these two priorities.)
We then declare a property pathes
which we use to store information about the modules that contain make files, and the paths to the directories in which
the generated code will reside.
Let's now look at the implementation code of the target. Here is the basic structure. We first initialize the pathes
list. We then iterate of the
input (which is a collection of resources) and do something with each input (explained below). We then use the output
statement to output the input
data, i.e. we just pass through whatever came into out target. We use the success
statement to finish this target successfully (using success
at the end is optional, since this is the default). If something goes wrong, the failure
statement can be used to terminate the target unsuccessfully.
実際の処理は、MPS データ構造に対する単純な Java プログラミングです。
We use the getGeneratorOutputPath
method to get the path to which the particular module generates its code (this can be configured by the user in the
model properties). We then get the model's dotted name and replace the dots to slashes, since this is where the generated files of a model in that module will
end up (inspect any example MPS project to see this). We then store the module's name and the model's name, separated by a slash, as a way of improving the
logging messages in our second target (via the variable locationInfo}). We add the two strings to the {{pathes
collection. This pathes
property
is queried by the second target in the facet.
2 番目のターゲット: 実行
リソースを扱う必要がないため、これは pass through
ポリシーを使用します。それが必要とするすべての入力は、上記の collectPaths
ターゲットのプロパティから取得できます。この 2 番目のターゲットは after collectPaths}, {{after textGen
と before reconcile
を実行します。それが collectPaths}, since it uses the property data populated by it. It has to run after {{textGen}, otherwise the make files aren't there yet. And it has to run before {{reconcile}, because basically everything has to run before {{reconcile
の後に走らなければならないのは明らかです
Let us now look at the implementation code. We start by grabbing all those entries from the collectPathes.pathes
property that actually contain a
Makefile
. If none is found, we return with success
.
次に、プログレスインジケータ言語を使用して、make ファイルを含むディレクトリがあるのと同じ数のワークユニットでプログレスバーを設定します。
We then iterate over all the entries in the {{modelDirectoriesWithMakefile} collection. In the loop we advance the progress indicator and then use Java
standard APIs to run the make file.
ターゲットをまとめるには、finish
ステートメントを使用してプログレスバーをクリーンアップします。
関連ページ:

共通言語パターン
この章では、MPS を学ぶ初心者がよく遭遇するであろう共通言語設計パターンについて説明します。私達は MPS ユーザーがオンラインフォーラムで確認する最も頻繁な質問としてこれらの時間を経て特定したため私達は容易な参照のために一箇所に答えをまとめることにした。MPS にはサンプルプロジェクトがバンドルされています: ここで説明するパターンの多くは、languagePatterns サンプルプロジェクトで実装されています。MPS で開き(MPS のウェルカム画面でサンプルプロジェクトを開くをクリック)...

HowTo- 追加のツールを追加する (別名再生)
追加のツールを追加する (別名再生):このドキュメントでは、MPS 用の新しいツール(Eclipse ユーザーの場合、MPS のツールは Eclipse のビューのようなもの)を作成する方法について説明します。これは、MPS に任意の追加ツールを組み込むための例として役立ちます。このテキストは、ツール開発の側面、つまり言語とメニューシステムに新しいツールを追加する方法、および現在編集されているものとビューを同期する方法を強調しています。他のすべての点で、ツールは単なる Swing UI プログラ...