Open joelverhagen opened 7 years ago
Please check spec on wiki for planned behavior
Spec: https://github.com/NuGet/Home/wiki/Adding-nuget-pack-as-a-msbuild-target
This doesn't work:
<TreatAsPackageReference>false</TreatAsPackageReference>
The output .nuspec still has projectB as a package reference and only one file: projectA.dll under lib.
This is a non-trivial feature that hasn't been implemented for RC yet.
Supporting this will require potentially walking the entire project closure to determine all projects that need to be merged into the package, or reading the assets file and matching the project closure with both the project reference flags and the pack flags found in the project (since it can be set either way).
This is also impacted by build outputs not flowing transitively to parent projects yet.
Plan of action:
PackageSpec
to the lock/assets file.<TreatAsPackageReference>
is true.PackTask
away from looking at child projects. Look at restore's assets file instead.This has repercussions on:
<Reference>
. How is this collapsed?<PackageReference>
... what about <Reference>
?@rohit21agrawal, I partially got through consuming the assets file from in the pack task: https://github.com/joelverhagen/NuGet.Client/tree/jver/3891
This also has some progress on getting the output DLLs of child projects (using @(ReferenceCopyLocalPaths)
MSBuild items).
This branch is pretty rough so let me know if I can clarify.
As per @rrelyea : https://github.com/NuGet/Home/issues/3893#issuecomment-265843267
"We don't plan to enable this in dotnet pack / msbuild /t:pack in 4.0 timeframe. We'll listen to customer feedback and consider in the future."
moving to future as this is post-rtm work.
building a nupkg from multiple projects seems like a major feature to be missing :/
@gulbanana thanks for the feedback. this is something that is not planned for the 4.0 RTM release, but this is something we will definitely address in a future release.
@kzu 's nugetizer 3000 does this?
Hi guys,
Just out of curiosity - are there any plans to proceed on this one? Currently, I need to use the dirty workaround that is MSBuild internals specifics:
<ItemGroup>
<_PackageFiles Include="$(OutputPath)\ReferencedProjectDll.dll">
<BuildAction>None</BuildAction>
<PackagePath>lib\net45\</PackagePath>
</_PackageFiles>
</ItemGroup>
Indeed @zvirja you could try install-package NuGet.Build.Packaging
, which should be compatible with "sdk pack" and give you that behavior automatically.
@kzu Thanks for the advice. I tried it for a couple of times, but cannot make it work. After I install this package to .NET Core project, it seems that SDK "Pack" is invoked rather than one from the package. As result it fails because you assign the NuspecFile
property to non-existing file.
Package version I tried - 0.1.324
.
Is there something that I'm missing? Is that suppose to work with .NET Core SDK projects?
Thanks!
P.S. BTW, was unable to find a bug tracker to ask this question there - is it present somewhere?
@zvirja you need to be on VS 15.3 at least
@kzu Do you mean that MSBuild that is shipped with VS 2017.2 isn't compatible? Currently I run build from the command line, so it's unclear how VS version is involved..
Sent from my Samsung SM-T719 using FastHub
+1 on also having a project with a reference project built in the same solution to include in a single NuGet package.
@zvirja in pre-15.3, the only way to override the built-in SDK 'Pack' target is to build with an explicitly garbage argument like https://github.com/xamarin/Xamarin.VSSDK/blob/master/build.proj#L8
Under MSBuild 15.3 (which == VS 15.3, since one doesn't ship without the other anymore), installing the nugetizer nuget package itself will perform the overriding as necessary.
+1. Can't stress enough how much this is needed for my project.
+1
+1
+1
+1 @zvirja do you have the workaround somewhere I can have a look at?
@UncleFirefox ATM no, as I no longer need this feature. However, you can use smth like:
<ItemGroup>
<Content Include="$(OutputPath)\ReferencedLib.dll">
<Pack>true</Pack>
<PackagePath>lib\$(TargetFramework)</PackagePath>
</Content>
</ItemGroup>
If you target multiple frameworks, I'd look to smth like below (stolen from here):
<PropertyGroup>
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);IncludeReferencedProjectInPackage</TargetsForTfmSpecificContentInPackage>
</PropertyGroup>
<Target Name="IncludeReferencedProjectInPackage" Condition="'$(IncludeBuildOutput)' != 'false'">
<ItemGroup>
<TfmSpecificPackageFile Include="$(OutputPath)\ReferencedLib.dll" PackagePath="lib/$(TargetFramework)" />
</ItemGroup>
</Target>
Hope that helps 😉
Setting the PackagePath
can even be omitted when using $(TargetsForTfmSpecificBuildOutput)
:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard1.6</TargetFrameworks>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);IncludeP2POutput</TargetsForTfmSpecificBuildOutput>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\testprivatelib\testprivatelib.csproj" PrivateAssets="All" />
</ItemGroup>
<Target Name="IncludeP2POutput">
<ItemGroup>
<BuildOutputInPackage Include="$(OutputPath)\testprivatelib.dll" />
</ItemGroup>
</Target>
</Project>
@dasMulli 's approach is the recommended one when it comes to adding files that need to go into lib folder.
Also wishing there was a way for project references to be auto-included in nuget packages...
I'm having the exact same issue with <PackageReference>
. I need PrivateAssets="all"
but I also need the referenced DLLs to end up packaged along with the build output. I guess the same approach is the best approach for this?
What would be really cool though is to not have PrivateAssets="all"
because that way the test project doesn't need to duplicate the package references, but still suppress the nuspec dependency and include it as \lib
build output.
Just mentioning this feature is much wanted.
Nugetizer already does this ;) On Wed, Jan 10, 2018 at 4:22 PM Paul den Dulk notifications@github.com wrote:
Just mentioning this feature is much wanted.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/NuGet/Home/issues/3891#issuecomment-356708485, or mute the thread https://github.com/notifications/unsubscribe-auth/AAKW6yfO1vqGTkwTiwTdmjNXimwLB2nLks5tJQ4CgaJpZM4Kr815 .
--
-- /kzu from mobile
Ran into another conversion where I could really use the capability to include the build output from a NuGet package rather than depending on it via nuspec.
Looks like the TargetsForTfmSpecificBuildOutput
workaround above no longer works in newer SDKs.
Here's the current workaround for including copy-local references from NuGet packages:
<!-- https://github.com/NuGet/Home/issues/3891 -->
<Target Name="SomeUniqueName" BeforeTargets="_GetBuildOutputFilesWithTfm">
<ItemGroup>
<BuildOutputInPackage
Include="@(ReferenceCopyLocalPaths)"
Condition="'%(ReferenceCopyLocalPaths.NuGetPackageId)' == 'SomeNuGetPackageId'" />
</ItemGroup>
</Target>
Would be good to get some of these arms races officially supported. 😜
@jnm2 what were you trying to pack there? "self-contained" tools, msbuild tasks etc? Posted a sample of how to include a publish output in an arbitrary location in a package at https://github.com/dotnet/sdk/issues/1846#issuecomment-356726385
btw, which version did the TargetsForTfmSpecificBuildOutput
fail with? using an underscore-prefixed target is a bad practice (but then, that's why it's a workaround 🙃)
Thanks @kzu, Nugetizer solved my problem. It took some trial and error though.
I would think my scenario is quite common. I have an existing solution, quite big, and start to convert the projects with the least dependencies to the new csproj format. This breaks the existing nuget publishing.
@dasMulli NUnit pulls NUnit.System.Linq as a NuGet package but prefers to bundle lib\net20\NUnit.System.Linq.dll
rather than leaving it as a dependency. I forget offhand what the other times were that I needed this. I think Roslyn analyzers.
I tried to find TargetsForTfmSpecificBuildOutput
using the MSBuild structured log viewer with /t:Pack and didn't find it. Maybe I made a mistake? I'll try again if that is preferable to the underscore version.
Any update on this yet?
Adding my voice to this. We're running in to the same issue. Just feels dirty and wrong without it auto-including project references.
if the project reference are more than 2 levels , it is really mess that need to know what dll need to be included and add it to each level .csproj manually . really hope it have a solution soon.
If you do dotnet publish on a project, it will include all the reference dlls in the publish folder. You can then package these into a nuget package manually somehow.
But it's not ideal.
Also adding my +1. This is blocking a fairly simple project for me. I just need a .nuget
package containing everything required to run the project.
Nuget team, this is a must-have, please
One workaround that would work with dotnet.exe pack or msbuild /t:pack
if you are packing a project with project references and want to include references as DLLs instead of dependencies in output nuspec is shown by the below example:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net47</TargetFrameworks>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary2\ClassLibrary2.csproj" PrivateAssets="all" />
<ProjectReference Include="..\ClassLibrary3\ClassLibrary3.csproj" Condition="'$(TargetFramework)' == 'net47'" PrivateAssets="all" />
</ItemGroup>
<Target Name="CopyProjectReferencesToPackage" DependsOnTargets="ResolveProjectReferences">
<ItemGroup>
<BuildOutputInPackage Include="@(_ResolvedProjectReferencePaths)" />
</ItemGroup>
</Target>
</Project>
Documentation for these extension points in the pack target can be found here: https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#advanced-extension-points-to-create-customized-package
<BuildOutputInPackage Include="@(_ResolvedProjectReferencePaths)" />
From my understanding it is considered "bad form" to take a dependency on a property/item/target that starts with an underscore _
. Everything in MSBuild is "public" and "global", and the convention of naming things starting with _
is to make consumers aware that this property/item/target can change in the future, and shouldn't be depended on.
So while this workaround may work now, I don't see that as a long term solution to this problem. And for people to aware when using this workaround that it might not work long term.
Updated workaround:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net47</TargetFrameworks>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary2\ClassLibrary2.csproj" PrivateAssets="all" />
<ProjectReference Include="..\ClassLibrary3\ClassLibrary3.csproj" Condition="'$(TargetFramework)' == 'net47'" PrivateAssets="all" />
</ItemGroup>
<Target Name="CopyProjectReferencesToPackage" DependsOnTargets="BuildOnlySettings;ResolveReferences">
<ItemGroup>
<BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference')->WithMetadataValue('PrivateAssets', 'All'))" />
</ItemGroup>
</Target>
</Project>
Documentation for these extension points in the pack target can be found here: https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#advanced-extension-points-to-create-customized-package
CC: @eerhardt
Is there a good way for the NuGet package to import the dependencies that the Project had?
Say Project A
depends on Project B
, but Project B
depends on NuGet Package 1
and Nuget Package 2
.
How can I make Project A
list the dependences of Project B
as its own dependencies?
This workaround is great at getting the DLL into the NuGet package, but I assume things will fail if they depend on something that doesn't exist?
@Tadimsky, @kzu's https://github.com/NuGet/NuGet.Build.Packaging nugetizer project is probably what you are looking for.
@Tadimsky right now there is no good way to do it, but that will be kept in mind when this feature is implemented. For now, your only option is to list it as a dependency in your top level project/
This seems like a very-much needed feature. Why would someone want a separate NuGet for each project dependency?
Surprised (and disappointed) that this is sitll open ... can we do anything to help?
Open since 2016 ... how is this not yet fixed and released? Please hurry up folks ...
Steps
dotnet new --type lib
two .csproj class libraries: projectA and projectB.<TargetFramework>
to<TargetFrameworks>
if you don't have https://github.com/NuGet/Home/issues/3865.ProjectReference
to projectB.<Type>project</Type>
to the<ProjectReference>
.dotnet pack
projectAExpected
projectB.dll should be in the .nupkg along with projectA.dll
Actual
projectB is still a package reference, not a DLL included in the package.
Environment
Tried latest dev's pack target.
dotnet --info
UPDATE: Please see workaround posted as comment to see how to add ProjectReferences as DLLs in the package dynamically.