Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Directory.build.targets not imported when cross-targeting #1721

Closed
tmat opened this issue Feb 17, 2017 · 18 comments
Closed

Directory.build.targets not imported when cross-targeting #1721

tmat opened this issue Feb 17, 2017 · 18 comments

Comments

@tmat
Copy link
Member

tmat commented Feb 17, 2017

Microsoft.Common.CrossTargeting.targets doesn't import these. As a result properties and tasks defined in Directory.build.props, Directory.build.targets are not available in the outer build.

Repro:

  1. Create a .NET Core Library with project:
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netcoreapp1.0;net46</TargetFrameworks>
  </PropertyGroup>
</Project>
  1. Add Directory.Build.targets next to the .csproj file:
<Project>  
  <Target Name="MyTarget">
    <Error Text="Boom!"/>
  </Target>
</Project>
  1. Run
> msbuild /t:Restore ClassLibrary.csproj
...
> msbuild /t:MyTarget ClassLibrary.csproj
Project "ClassLibrary.csproj" on node 1 (MyTarget target(s)).
ClassLibrary.csproj : error MSB4057: The target "MyTarget" does not exist in the project.
Done Building Project "ClassLibrary.csproj" (MyTarget target(s)) -- FAILED.

If the project targets a single framework like so:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp1.0</TargetFramework>
  </PropertyGroup>
</Project>

The target is invoked as expected:

Project "ClassLibrary.csproj" on node 1 (MyTarget target(s)).
Directory.Build.targets(7,5): error : Boom!
@tmat
Copy link
Member Author

tmat commented Feb 17, 2017

@srivatsn FYI

@jeffkl
Copy link
Contributor

jeffkl commented Feb 17, 2017

Nevermind I repro'd this incorrectly. You are correct, the outer build does not import Microsoft.Common.targets. @nguerrera is there a reason that Microsoft.Common.CrossTargeting.targets does not import Microsoft.Common.targets? I see it imports project extensions but since it probably should be importing directory targets like this: https://github.com/Microsoft/msbuild/blob/xplat/src/Tasks/Microsoft.Common.targets#L137

@nguerrera
Copy link
Contributor

We don't import common targets by design because there are a lot of assumptions in it that don't hold for outer build. It is not really possible to give meaningful semantics to every target in common targets in the outer context.

That said, not importing Directory.* is an oversight. We may want to introduce Directory.CrossTargeting.targets so that we can support the scenario in a non breaking way. This would be consistent with nuget model where separate files are used to augment inner and outer build.

@tmat
Copy link
Member Author

tmat commented Feb 17, 2017

Do we really need a separate file? The detection whether the current build is inner or outer is simple, if anyone needs to distinguish in the file.

@jeffkl
Copy link
Contributor

jeffkl commented Feb 17, 2017

I agree with @tmat, we should just import Directory.Build.targets. Directory.Build.props is already being imported by the outer build so I think it would be confusing that there needs to be a separate targets file. The IsCrossTargetingBuild property gives target authors enough control over what they wanted declared.

CC @AndyGerlicher

@nguerrera
Copy link
Contributor

nguerrera commented Feb 17, 2017

If we use only one file, this would be a breaking change so we need to decide that we're prepared to make it or push to get it in right now.

I'm not near a dev setup right now, but I would think that Directory.Build.props is already imported. If so, this can be used to hack a workaround: Set CustomAfterMicrosoftCommonCrossTargetingTargets to Directory.Build.targets in Directory.Build.props. However, those CustomXxx points are perilous, because they suffer from the "What if two components do this?" problem.

@jeffkl
Copy link
Contributor

jeffkl commented Feb 17, 2017

Directory.Build.props is imported at the moment which is why I think it makes sense that Directory.Build.targets should be too. Can you explain why this would be a breaking change to import the targets file? Since the functionality is new to MSBuild 15, I assume it would be safe.

@nguerrera
Copy link
Contributor

I mean it's breaking if we ship MSBuild 15 like it is now and then start importing it in MSBuild 16.

@nguerrera
Copy link
Contributor

Consider a common case: AfterTargets="Build", this would run only in inner build today, but start to run in both after change.

@jeffkl
Copy link
Contributor

jeffkl commented Feb 17, 2017

Ah I see, I misunderstood. So you're saying if we don't fix it for RTM, then we'll need a new file for future releases....

@nguerrera
Copy link
Contributor

Or maybe honor a safe opt-in from Directory.Build.props: <ImportDirectoryTargetsForCrossTargeting>true</ImportDirectoryTargetsForCrossTargeting>

Or have the courage and permission to break.

@nguerrera
Copy link
Contributor

We should at least talk about it (bar check it as potentially now-or-never) in ship room. Just fixing it will simplify things for the long haul.

@tmat
Copy link
Member Author

tmat commented Feb 17, 2017

I did more experiments and it seems like Directory.build.props is imported but Directory.build.targets isn't. Odd.

@jeffkl
Copy link
Contributor

jeffkl commented Feb 17, 2017

We're going to bar check this with management to see what they think. The change is a copy/paste from one file to another so the risk is very low but it might be too late.

@AndyGerlicher
Copy link
Contributor

FYI this will have to be in a future update. It won't be in VS2017 RTW.

@jeffkl jeffkl added the bug label Feb 17, 2017
@jeffkl jeffkl changed the title Directory.build.props, Directory.build.targets not imported when cross-targeting Directory.build.targets not imported when cross-targeting Feb 20, 2017
@JunielKatarn
Copy link
Contributor

Hi. What's the state of this issue?
Will this Directory.Build.targets be imported in some future release?

@rainersigwald rainersigwald added this to the MSBuild 15.3 milestone Apr 17, 2017
@rainersigwald
Copy link
Member

@JunielKatarn looks like the changes from #1722 are available in our latest packages (I checked Microsoft.Build.Runtime 15.2.0-preview-000103-02, but not yet pulled into the CLI or VS builds. I believe this will go out with the 15.3 update.

@JunielKatarn
Copy link
Contributor

@rainersigwald thanks!
However, I somehow made it work.
I can confirm that as of dotnet version 1.0.1, I am able to implicitly import Directory.Build.targets.

I think this use case is worth a short sample in the official docs. Is there a way to contribute to them?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants