Michele mpp Marostica
Michele mpp Marostica

Reputation: 2472

dotnet build with GeneratePackageOnBuild and contentFiles

I have a project that I'm building with dotnet build -c Release /p:Platform=x86 .\Foo.csproj. The csproj file is in SDK format and has this content:

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    <AssemblyName>Foo</AssemblyName>
    <Company>Me</Company>
    <Authors>Me</Authors>
    <Version>4.12.5</Version>
    <AssemblyVersion>4.12.5.0</AssemblyVersion>
    <FileVersion>4.12.5.0</FileVersion>
    <Platforms>x86</Platforms>
    <UseWPF>true</UseWPF>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="..\Bar.csproj">
      <!-- ... -->
    </ProjectReference>
  </ItemGroup>
  <ItemGroup Label="FilesToCopy">
    <Content Include="..\dependent.dll" Pack="true" PackagePath=".\lib\net48\" PackageCopyToOutput="true" />
    <None Include="image.jpg" Pack="true" PackagePath=".\contentFiles\any\any\" PackageCopyToOutput="true" />
  </ItemGroup>
  <ItemGroup>
    <None Update="tex_cardboard.jpg">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>
  <PropertyGroup>
    <TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
  </PropertyGroup>
  <Target Name="CopyProjectReferencesToPackage" DependsOnTargets="ResolveReferences">
    <ItemGroup>
      <BuildOutputInPackage Include="@(ReferenceCopyLocalPaths-&gt;WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
    </ItemGroup>
  </Target>
</Project>

This will generate a nuget package on build with the image.jpg in a contentFiles\any\any folder.

If I understand correctly, the the .nuspec file inside of the nuget package should contain:

    <contentFiles>
      <files include="**/*" buildAction="Content" />
    </contentFiles>

But it does not.

How do I tell, in the csproj file, the image file to be included as content and not to be compiled?

Upvotes: 1

Views: 3395

Answers (1)

thatguy
thatguy

Reputation: 22089

Yes, the NuSpec file inside your package will contain the contentFiles tag unless you define a custom PackagePath for your resources in the project file. It guess that this behavior applies to .csproj files, because the default path for content files is overwritten for that file and it is no longer detected as content file applying to NuGet conventions. From the .csproj reference and MS Build targets:

This property specifies the default location of where all the content files should go if PackagePath is not specified for them. The default value is "content;contentFiles".

By default, everything gets added to the root of the content and contentFiles\any<target_framework> folder within a package and preserves the relative folder structure, unless you specify a package path [...]

Although it is explcitly stated that you can use the PackagePath on a lot of content types with different build actions, there is no mention that this results in a different NuSpec file, but in practice it does.

Apart from Content items, the and metadata can also be set on files with a build action of Compile, EmbeddedResource, ApplicationDefinition, Page, Resource, SplashScreen, DesignData, DesignDataWithDesignTimeCreateableTypes, CodeAnalysisDictionary, AndroidAsset, AndroidResource, BundleResource or None. [...]

In your csproj file, tags like None and Content determine the build action and therefore whether your image file is embedded, copied to the output folder or anything else. However, apart from the original issue, setting Pack="true" is enough to automatically include it in the contenFiles\any\<Target framework moniker> folder in your package. Setting PackageCopyToOutput="true" will copy it to the consuming project's output directory.

Upvotes: 2

Related Questions