web-dev-qa-db-ja.com

.NET Coreでのwin / anyランタイムの意味

私はC#.NETコアアプリケーションを構築しており、net452フレームワークを対象としています。パブリッシュするとき、ランタイムを指定できます(--runtime)。ランタイムを指定しない場合は、win7-x64を使用します(これは私のマシンが実行しているからです)。ただし、ランタイムを手動で指定することもでき、指定した文字列を受け入れるようです。ただし、 RIDカタログ は、winanyの両方が有効であることを示唆しているようです。

更新:良い答えがありませんので、質問を明確にし、賞金を追加します。 ASP.NETコアフォーラムでも質問しましたが、返事がありません。

  1. RIDをwin7-x32と指定すると、コードは64ビットWindows OSでも実行されますか?

  2. win7のRIDを指定すると、何がビルドされますか。32ビットバージョンと64ビットバージョンのどちらがビルドされますか?

  3. win7のRIDを指定した場合、プログラムはWindows 8、8.1、または10で実行されますか?

  4. any RIDは何をしますか?ポータブル展開を複数のプラットフォームで使用する方法を理解していますが、スタンドアロンの展開(anyのRIDで構築)をLinuxおよびWindowsでどのように機能させることができますか?このRIDを誤解していますか?

  5. blahのRIDを指定した場合、エラーが発生します。代わりに、私のアプリケーションはbin/Release/blahディレクトリに構築されました。単に他のランタイムにデフォルト設定されましたか?

32
Pace

RIDは、パッケージの依存関係を解決するために.NET Coreで使用されます。依存関係を解決するこのプロセスのルートはプロジェクトであり、1つ以上のRIDを明示的にタグ付けします。プロジェクトをビルドするときに、ビルドするRIDを指定します。

RIDは互換性ツリーのフォレストで定義され、ツリー内のノードはすべての子をサポートできる実行環境を表します。各RIDは、そのようなツリーのルートです。

RID互換性ツリーの例を次に示します。

win10-x64
|- win10
|  `- win81
|     `- win8
|        `- win7
|           `- win
|              `- any
|                 `- base
`- win81-x64
   |- win81 (already included above)
   `- win8-x64
      |- win8 (already included above)
      `- win7-x64
         |- win7 (already included above)
         `- win-x64
            `- win (already included above)

RID互換性ツリーの完全なグラフは、ここで定義されています。

https://github.com/dotnet/corefx/blob/master/pkg/Microsoft.NETCore.Platforms/runtime.json

パッケージは、必要に応じてRIDごとに異なる実装を提供できます。ビルド時に、そのパッケージに依存している場合、ビルドプロセスはツリーのルートに最も近い実装を選択します。ツリーにパッケージによって提供されるRIDが含まれていない場合、ビルドは失敗します。

「ランタイムパッケージ」と呼ばれる特別な種類のパッケージがあります。ランタイムパッケージには、ホストオペレーティングシステムによって直接ロードおよび実行されるネイティブバイナリが含まれています。そのため、これらのパッケージは、具体的なOSバージョンの実装のみを提供します。たとえば、「win7-x64」ではなく「win7」または「win-x64」、および「ubuntu.16.04-x64」ではなく「ubuntu .16.04」、「ubuntu-x64」または「linux」。

[Update:.NET Core 2.0以降では、Linux-x64用にビルドして、単一のビルドで「すべての」x64バージョンのLinuxをターゲットにできます。 https://blogs.msdn.Microsoft.com/dotnet/2017/08/14/announcing-net-core-2-0/ を参照してください

スタンドアロンプ​​ロジェクトをバンドルすると、ランタイムパッケージが有効になります。スタンドアロンプ​​ロジェクトでは、プロジェクトの実行に必要なすべてのものをビルド出力に含める必要があります。つまり、ビルド出力には、アプリケーションのエントリポイントとしてネイティブバイナリを含める必要があります。そのネイティブバイナリは、ランタイムパッケージによって提供されます。

したがって、あなたの質問に対処するには:

  1. Win7-x32のRIDを指定すると、コードは64ビットWindows OSでも実行されますか?

はい、できますが、32ビットプロセスで実行されます。 Ubuntu dev VMからビルドおよび公開され、その後Windows 10 64ビットで実行されるアプリでこれを確認しました。アプリがwin7-x32に対して公開されている場合、IntPtr.Sizeは4であり、 win7-x64に対して公開されている場合、IntPtr.Sizeは8です。どちらの方法でも実行されます。

win7-x32ランタイムパッケージには、.NET Coreランタイムをホストし、プロジェクトをロードして実行する32ビットEXEファイルが含まれています。プロジェクトは、同じ名前のDLLファイルにバンドルされています。

  1. Win7のRIDを指定すると、何がビルドされますか。32ビットバージョンと64ビットバージョンのどちらがビルドされますか?

win7のRIDを指定すると、そのRIDまたは互換性のあるRIDでタグ付けされたネイティブバイナリビルドを見つけようとしますが、何も見つかりません。メインエントリポイントEXEの「win7」バージョンがないため、ビルドは失敗します。 32ビットまたは64ビットのいずれかを指定する必要があります(他のプラットフォームはすべて64ビットのみのようです)。

私はこの特定の詳細をテストしましたが、次のことがわかりました。

  • dotnet restoreステップは失敗しませんが、win7(またはwin10)のランタイムもインストールしません。

  • dotnet buildステップはテストアプリケーションのコンパイルに成功しますが、次のエラーを出力します。

    次のプロジェクトを実行可能にできませんでした:helloworld(.NETCoreApp、Version = v1.1)理由:パッケージグラフにcoreclrライブラリが見つかりません。 dotnet restoreを再度実行してください。

  1. Win7のRIDを指定した場合、プログラムはWindows 8、8.1、または10で実行されますか?

win7-x86またはwin7-x64のいずれかを指定すると仮定すると、はい。 win7-x86またはwin7-x64ランタイムパッケージは、それぞれ32ビットまたは64ビットEXEであるEXEエントリポイントを提供します。これらのEXEは、Windows 7以降のWindowsバージョンで実行されるネイティブバイナリです。

Windows 8、Windows 8.1、またはWindows 10専用のランタイムパッケージは現在ないことに注意してください。新しいWindowsバージョンの互換性グラフには、必要に応じてwin7-x86またはwin7-x64が含まれているため、win10-x64などの新しいRIDをターゲットにしても、特定のランタイムパッケージがビルドで使用されることになります。

  1. Any RIDは何をしますか?ポータブル展開を複数のプラットフォームで使用する方法を理解していますが、スタンドアロン展開(RIDを使用して構築)をLinuxおよびWindowsでどのように機能させることができますか?このRIDを誤解していますか?

any RIDを使用すると、他のすべてのRIDが最終的に互換ツリーにany(およびbase)を含むため、パッケージはチェーンのさらに上のRIDの実装を提供できます。ただし、ランタイムパッケージはanyの実装を提供しないため、anyを使用してスタンドアロンパッケージをビルドすることはできません。

  1. 何とかRIDを指定すると、エラーが発生するはずです。代わりに、私のアプリケーションはbin/Release/blahディレクトリに構築されました。単に他のランタイムにデフォルト設定されましたか?

プロジェクトは、"type": "platform"の依存関係でMicrosoft.NETCore.Appを使用して構成する必要があります。そのため、スタンドアロンパッケージはビルドされず、サポートライブラリの解像度はランタイムに委ねられます。この時点で、RIDは、アプリケーションのビルド構成ではなく、アプリの実行に使用している実際のランタイムによって提供されます。

プロジェクトがライブラリの場合、別のプロジェクトからプロジェクトを参照しようとすると、ライブラリが「blah」プラットフォームの実装のみを提供するため、RIDの互換性ツリーにはないため、問題が発生する可能性があります他のプロジェクトが構築されています。プロジェクトがアプリケーションの場合、blahは無視されます。

"type": "platform"project.json行を削除またはコメントアウトすることにより)スタンドアロンパッケージを生成するようにプロジェクトを再構成すると、ランタイムパッケージに依存するようになり、パッケージがないため、プロジェクトがビルドされないことがわかります。 RID blahの場合。

30

OPにリンクされている 公式ドキュメント が必要な情報をすべて提供したと思います。

まず最初に

RIDとは何ですか?

RIDはRuntime IDentifierの略です。 RIDは、アプリケーションまたは資産(つまり、アセンブリ)が実行されるターゲットオペレーティングシステムを識別するために使用されます。

RIDは実際には不透明な文字列であることに注意することが重要です。これは、それらが機能するためにそれらを使用する操作に対して正確に一致する必要があることを意味します

これは GitHub からも引用されました

RIDは、プラットフォームを識別する不透明な文字列です。 RIDは、他のRIDを「インポート」することにより、他のRIDとの関係を持ちます。このように、RIDは互換性のあるRIDの有向グラフです。

最適なRID部分的なRIDグラフを検討してください。

"any": {},

"win": {
    "#import": [ "any" ]
},
"win-x86": {
    "#import": [ "win" ]
},
"win-x64": {
    "#import": [ "win" ]
},
"win7": {
    "#import": [ "win" ]
},
"win7-x86": {
    "#import": [ "win7", "win-x86" ]
},
"win7-x64": {
    "#import": [ "win7", "win-x64" ]
}

これは、次のように有向グラフとして視覚化できます。

win7-x64    win7-x86
   |   \   /    |
   |   win7     |
   |     |      |
win-x64  |  win-x86
      \  |  /
        win
         |
        any

したがって、win7-x64を評価する場合の最適なRIDは、次のようになります。win7-x64win7win-x64winany同様に、評価する場合for win-x64win-x64winanywin7のインポートにより、win-x64win7の前に来ることに注意してください。 win-x64のインポートの前にドキュメント順に表示されます。

つまり、CoreFXリポジトリで runtime.jsonを参照しています。

このファイルを使用すると、一部のRIDに「#import」ステートメントが含まれていることに気付くでしょう。これらのステートメントは互換性ステートメントです。つまり、インポートされたRIDを含むRIDは、そのRIDのパッケージを復元するためのターゲットになります。

関連する部分のみを抽出し、

1)win7-x32のRIDを指定した場合、コードは64ビットWindows OSでも実行されますか?

"base": {
},

"any": {
    "#import": [ "base" ]
},
...
"win": {
    "#import": [ "any" ]
},
...
"win7": {
        "#import": [ "win" ]
    },
"win7-x86": {
    "#import": [ "win7", "win-x86" ]
},
"win7-x64": {
    "#import": [ "win7", "win-x64" ]
},
...

2)win7のRIDを指定すると、何がビルドされますか。32ビットバージョンと64ビットバージョンのどちらをビルドしますか?

両方のプラットフォームで実行できる共通バージョンを構築します。上記の視覚化を参照してください。

3)RIDにwin7を指定した場合、プログラムはWindows 8、8.1、または10で実行されますか?

はい。参照バージョンのインポートに基づきます。

"win8": {
    "#import": [ "win7" ]
},
"win8-x86": {
    "#import": [ "win8", "win7-x86" ]
},
"win8-x64": {
    "#import": [ "win8", "win7-x64" ]
},
"win8-arm": {
    "#import": [ "win8" ]
},

"win81": {
    "#import": [ "win8" ]
},
"win81-x86": {
    "#import": [ "win81", "win8-x86" ]
},
"win81-x64": {
    "#import": [ "win81", "win8-x64" ]
},
"win81-arm": {
    "#import": [ "win81", "win8-arm" ]
},

"win10": {
    "#import": [ "win81" ]
},
"win10-x86": {
    "#import": [ "win10", "win81-x86" ]
},
"win10-x64": {
    "#import": [ "win10", "win81-x64" ]
},

4)any RIDは何をしますか?

これは、ビルドがサポートされるプラットフォームのanyと互換性があり、任意のRIDのパッケージを復元するためのターゲットになり得ることを意味します。

5)RIDにblahを指定すると、エラーが発生することが予想されました。代わりに、私のアプリケーションはbin/Release/blah directoryで構築されました。単に他のランタイムにデフォルト設定されましたか?

引用フォームのドキュメント:

すべてのRIDは、最終的にルートany RIDにマップされます。

そして最後に、再びドキュメントから、注意してください

簡単に使用できるように見えますが、RIDを操作する際に留意しなければならない特別なことがいくつかあります。

  • これらは不透明な文字列であり、ブラックボックスとして処理する必要があります
    • プログラムでRIDを作成しないでください
  • プラットフォームに既に定義されているRIDを使用する必要があり、このドキュメントでは
  • RIDは特定である必要があるため、実際のRID値から何も仮定しないでください。このドキュメントを参照して、特定のプラットフォームに必要なRIDを判断してください。
16
Nkosi

.NET Core2.0で、次のターゲット用にビルドするのに十分です:

  • linux-x64、linux-arm
  • win-x64、win-x86
  • osx-x64

https://blogs.msdn.Microsoft.com/dotnet/2017/08/14/announcing-net-core-2-0/ を参照してください

4