Repro:
Test.sln
SingleTfm.csproj: <TargetFramework>net451</TargetFramework>
MultiTfm.csproj: <TargetFrameworks>net451;netstandard1.3</TargetFrameworks>
<Project>
<Target Name="Build">
<MSBuild Projects="Test.sln" Targets="Build">
<Output TaskParameter="TargetOutputs" ItemName="CollectedBuildOutput" />
</MSBuild>
<Message Text="@(CollectedBuildOutput, '%0A')" />
</Target>
</Project>
md5-263c6b37db07aeec43c79b4b5af6a800
C:\proj\SingleTfm\bin\Debug\net451\SingleTfm.dll
C:\proj\MultiTfm\bin\Debug\net451\MultiTfm.dll
C:\proj\MultiTfm\bin\Debug\netstandard1.3\MultiTfm.dll
md5-a7b24c49ca2ffd8c82afb2bc393525b7
C:\proj\SingleTfm\bin\Debug\net451\SingleTfm.dll
Details
Microsoft (R) Build Engine version 15.3.246.41955 for .NET Core
and
Microsoft (R) Build Engine version 15.3.246.41955 for .NET Framework
Team Triage:
This doesn't seem like something we could easily change. The Build target has a single value return currently and there are potentially many assumptions made around this. Since this output is generated via the solution metaproj generation, the only way we could change this would be to change the contract of Build to return multiple values.
What is the use case for this? Is there another way to do this?
Actually, the build target has zero returned output for cross-targeting projects. Should it have returned at least one item?
What is the use case for this?
I would like to compile a particular solution configuration _and_ get a list of all assemblies produced for that solution configuration.
Is there another way to do this?
Sure. Set CustomAfterMicrosoftCommonCrossTargetingTargets to a file that contains this:
<Project>
<Target Name="Build"
DependsOnTargets="_SetBuildInnerTarget;DispatchToInnerBuilds"
Returns="@(InnerOutput)" />
</Project>
Though it seems like it should be a last-resort.
Having encountered this same issue, the triage response seems odd. In the file Microsoft.Common.CrossTargeting.targets the Build target is documented as:
````
````
Note that the output is indicated as @(InnerOutput), but the Build target lacks a Returns attribute. Please correct me if I'm wrong, but there are other Build targets that return multiple output items. The metaproject generation for solution files is an example.
It would appear, based on the documentation comment, that returning the coalesced output items is the original intent.
As an additional point, the cross targeting Build target is used to execute custom targets, by specifying the inner targets directly. Not returning the inner output in these cases really seems like a bug.
I have also encountered this issue and I agree with @williamb1024. (By the way, the Rebuild target lacks the Returns attribute too.) As for workarounds, another one is to invoke the MSBuild task building the inner cross-targeting project(s) with the DispatchToInnerBuilds target instead of Build. This workaround doesn't use the CustomAfterMicrosoftCommonCrossTargetingTargets hook (what if another package wants to set it?)
Closing as this is stale and I don't need changes here anymore. See workaround above https://github.com/Microsoft/msbuild/issues/2148#issuecomment-305033099
That workaround should, at minimum, be able to be toggled on/off as a feature of msbuild because it simply works. It makes separate distinct results come per project (one per target) and from that point one could write build scripts around that behavior... even if it violates some past assumptions.
As it stands, msbuild is just not providing any values to TargetOutputs for these projects... which violates the hell out of assumptions already. It doesn't even provide the MSBuildSourceProjectFile which it most certainly has a single value for, and which is guaranteed by the documentation to be provided.
This is not just a "oh well, it's hard to fix because we return only a single value as it stands, so we won't fix it". It's a bug. Maybe some other switch/flag is needed to gate access to new functionality so legacy can continue as it is, but this is unintuitive and contrary to documentation/expectation.
Any chance this one might be reopened?
It is not very consistent that Build returns something for 1 TFM but not for multiple TFMs (especially when the target comment/doc says it should do so).
I currently use the workaround described in https://github.com/microsoft/msbuild/issues/2148#issuecomment-305033099 but this will break on any change.
@rainersigwald can we please reopen the issue? We are adding the proposed workaround into dotnet/runtime and linking back to this issue (https://github.com/dotnet/runtime/pull/35606/files/a2c6b29240d46342244e1b2e6e669cca74261e52#r458357395).
Most helpful comment
That workaround should, at minimum, be able to be toggled on/off as a feature of msbuild because it simply works. It makes separate distinct results come per project (one per target) and from that point one could write build scripts around that behavior... even if it violates some past assumptions.
As it stands, msbuild is just not providing any values to TargetOutputs for these projects... which violates the hell out of assumptions already. It doesn't even provide the MSBuildSourceProjectFile which it most certainly has a single value for, and which is guaranteed by the documentation to be provided.
This is not just a "oh well, it's hard to fix because we return only a single value as it stands, so we won't fix it". It's a bug. Maybe some other switch/flag is needed to gate access to new functionality so legacy can continue as it is, but this is unintuitive and contrary to documentation/expectation.