特定のプラットフォーム用のライブラリを構築する必要があるCEFsharpに依存するライブラリを作成しました。そのため、AnyCPUサポートはありません。
これをNuGetにパックします。私が理解している限り、これらのファイルをビルドフォルダーに入れ、参照する正しいdllを選択する.targets
ファイルを用意する必要があります。だから私は次のようなNuGetパッケージになりました:
lib
monodroid
MyLib.dll
xamarin.ios10
MyLib.dll
net45
MyLib.dll (x86)
build
net45
x86
MyLib.dll (x86)
x64
MyLib.dll (x64)
MyLib.targets
.targets
ファイル内に次のコードを挿入しました:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.Microsoft.com/developer/msbuild/2003">
<Target Name="PlatformCheck" BeforeTargets="InjectReference"
Condition="(('$(Platform)' != 'x86') AND ('$(Platform)' != 'x64'))">
<Error Text="$(MSBuildThisFileName) does not work correctly on '$(Platform)' platform. You need to specify platform (x86 or x64)." />
</Target>
<Target Name="InjectReference" BeforeTargets="ResolveAssemblyReferences">
<ItemGroup Condition="'$(Platform)' == 'x86' or '$(Platform)' == 'x64'">
<Reference Include="MyLib">
<HintPath>$(MSBuildThisFileDirectory)$(Platform)\MyLib.dll</HintPath>
</Reference>
</ItemGroup>
</Target>
</Project>
ここまでは順調ですね。今問題に。このNuGetを新しいWPFプロジェクトに追加すると、次のように.csproj
ファイルにライブラリへの参照が表示されます。
<Reference Include="MyLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d64412599724c860, processorArchitecture=x86">
<HintPath>..\packages\MyLib.0.0.1\lib\net45\MyLib.dll</HintPath>
<Private>True</Private>
</Reference>
.targets
ファイルに関する言及はありません。これはまだNuGet 3でそれを行う方法ですか?私は何か間違ったことをしましたか?現在、これはx86 libへの参照のため、x64を実行しているときに実行時に失敗します。
あまりにも長い間これをいじった後、私はそれを理解しました。
どうやらbuild.propおよびbuild.targetファイルは、NuGetパッケージとまったく同じ名前を持つ必要があります。そうでない場合、csprojファイルに追加されません。
編集:
私は 小さなgithubリポジトリ を作成しました。これを独自のプロジェクトで使用する方法を示しています。
3つのプロジェクトを含むソリューションを示しています。1つはiOS用、もう1つはAndroid用で、Net45はx86とx64の両方を対象としています。
.propsファイルに注意してください。パスは、解凍されたNuGetのフォルダー構造を指しています。したがって、これらのパスは、nuspecファイルに入力したものにマップされます。
したがって、リポジトリと同様に、次のようなnuspecを定義します。
_<?xml version="1.0"?>
<package>
<metadata>
<id>My.Awesome.Library</id>
<version>1.0.0</version>
<title>My Awesome Library</title>
<description>Herpa Derpa</description>
</metadata>
<files>
<file src="My.Awesome.Library.Droid\bin\Release\My.Awesome.Library.*"
target="lib\monodroid70" />
<file src="My.Awesome.Library.iOS\bin\Release\My.Awesome.Library.*"
target="lib\xamarin.ios10" />
<file src="My.Awesome.Library.Net45\bin\x64\Release\My.Awesome.Library.*"
target="build\x64" />
<file src="My.Awesome.Library.Net45\bin\x86\Release\My.Awesome.Library.*"
target="build\x86" />
<file src="My.Awesome.Library.Net45\bin\x86\Release\My.Awesome.Library.*"
target="lib\net45" />
<file src="My.Awesome.Library.props" target="build\net45" />
</files>
</package>
_
X86ファイルを_build\x86
_に入れ、x64ファイルを_build\x64
_に入れました。この場合、これらのファイルの場合、フォルダービルドの名前は基本的に何でもかまいません。ここで重要なのは、以下のpropsファイルがそれぞれのプラットフォームのこれらのフォルダーをポイントしていることです。
X86 libを_lib\net45
_に入れても問題ないかどうかはわかりません。それを試すことができます。小道具ファイルはとにかくあなたのために正しいものを選ぶはずです。
_<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.Microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Reference Include="My.Awesome.Library" Condition="'$(Platform)' == 'x86'">
<HintPath>$(MSBuildThisFileDirectory)..\x86\My.Awesome.Library.dll</HintPath>
</Reference>
<Reference Include="My.Awesome.Library" Condition="'$(Platform)' == 'x64'">
<HintPath>$(MSBuildThisFileDirectory)..\x64\My.Awesome.Library.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
_
この場合、$(MSBuildThisFileDirectory)
は_build\net45\
_フォルダになります。パスがDLLを正しく指していることを確認してください。ここでは、_build\net45
_フォルダーが重要です。これは、NuGetがターゲットとpropsファイルを自動的にインポートする方法です。
また、_My.Awesome.Library
_という名前は、ほぼ一貫しています。ここで重要なのは、propsファイルの名前がNuGetパッケージIDと一致することです。そうでなければ、NuGetはそれをインポートしないようです。
上記の解決策から私が同意しないことがいくつかあります。 nugetフォルダーにファイルを追加してデフォルトのファイル構造を使用する場合、nuspecファイルに<Files>
情報を含める必要はありません。しかし、ソリューションフォルダーからnugetファイルを実行する場合は、それが必要です。
より良いnuspecコンテンツ:
<?xml version="1.0"?>
<package>
<metadata>
<id>YourProjectName</id>
<version>1.0.0</version>
<authors>John Doe</authors>
<title>Your Project Name</title>
<description>Herpa Derpa</description>
</metadata>
</package>
私はまた、彼が.dllをbuild
フォルダーに持っていることに同意しません。これらはlib
フォルダーに移動し、build
フォルダーには.targets
および.props
ファイル。 nugetのドキュメント here はこれについて言及しています。
また、lib
フォルダーは、参照内にある.dll用です。第2に、build
フォルダに追加された.dllは、SQliteがinterop
dllに対して行う方法と同様に、場合によっては必要になる可能性がある補足dllです。したがって、この場合、それらを保持するためのより良い場所はlibフォルダー内です。
より良いフォルダー構造:
- nuget
-- project.nuspec
-- build
---- YourProjectName.props
---- YourProjectName.targets
-- lib
--- <x64>
---- YourProjectName.dll
--- <x86>
---- YourProjectName.dll
.propsファイルの内容:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.Microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Reference Include="YourProjectName" Condition="'$(Platform)' == 'x86'">
<HintPath>$(MSBuildThisFileDirectory)x86\YourProjectName.dll</HintPath>
</Reference>
<Reference Include="YourProjectName" Condition="'$(Platform)' == 'x64'">
<HintPath>$(MSBuildThisFileDirectory)x64\YourProjectName.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
.targetsファイルの内容:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.Microsoft.com/developer/msbuild/2003">
<Target Name="PlatformCheck" BeforeTargets="InjectReference"
Condition="(('$(Platform)' != 'x86') AND ('$(Platform)' != 'x64'))">
<Error Text="$(MSBuildThisFileName) does not work correctly on '$(Platform)' platform. You need to specify platform (x86 or x64)." />
</Target>
<Target Name="InjectReference" BeforeTargets="ResolveAssemblyReferences">
<ItemGroup Condition="('$(Platform)' == 'x86' or '$(Platform)' == 'x64') and '$(TargetFrameworkVersion)'=='v4.6'">
<Reference Include=" YourProjectName ">
<HintPath>$(MSBuildThisFileDirectory)..\..\lib\net46\$(Platform)\ YourProjectName.dll</HintPath>
</Reference>
</ItemGroup>
</Target>
</Project>
Nuget Package Manager APPでnuspecファイルを開き、追加したすべてのファイルが選択されていることを確認することで、上記が機能したことを確認できます。これらをプロジェクトに追加すると、参照先のプロジェクトで選択されたアーキテクチャに従ってDLLがロードされます。また、「Any CPU」が選択されている場合はターゲットファイルでエラーが発生し、ユーザーに通知されます。 x86とx64のどちらかを選択する必要があります
編集:
明確にされなかった点の1つは、.targetおよび.propsの名前がnugetパッケージファイル名と同じである必要があることです(バージョンも意味します)。 これがないと、ビジュアルスタジオを再び開くときに二重参照が表示されます。