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

Document the ProjectReference protocol #1892

Merged

Conversation

rainersigwald
Copy link
Member

Wrote a document explaining what ProjectReferences do behind the scenes
and how to make a green-field project that doesn't import the machinery
of Common.targets compatibile with using them.

Wrote a document explaining what ProjectReferences do behind the scenes
and how to make a green-field project that doesn't import the machinery
of Common.targets compatibile with using them.
@rainersigwald
Copy link
Member Author

@kempb, @nguerrera (this doesn't include the changes I'm making in a parallel PR but I plan to update it with that after the initial version goes in).


As with all MSBuild logic, targets can be added to do other work with `ProjectReference`s.

In particular, NuGet depends on being able to identify referenced projects' package dependencies, and calls some targets that are imported through `Microsoft.Common.targets` to do so. At the time of writing this this is in [`NuGet.targets`](https://github.com/NuGet/NuGet.Client/blob/79264a74262354c1a8f899c2c9ddcaff58afaf62/src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets).
Copy link
Contributor

@nguerrera nguerrera Mar 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Along the same lines, xaml targets add extra GetPackagingOutputs requirement

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added that, thanks--there's probably a lot of these, unfortunately.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I said Xaml, but I should have said Appx, Microsoft.AppxPackage.targets is the specific thing that adds this requirement.

These targets should exist in a project to be compatible with the common targets' `ProjectReference`. Some are called only conditionally.

These targets are all defined in `Microsoft.Common.targets` and are defined in Microsoft SDKs. You should only have to implement them yourself if you require custom behavior or are authoring a project that doesn't import the common targets.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we discuss how the targets after GetTargetFrameworkProperties need only be defined in the evaluation that includes the properties it returned? i.e. These aren't all defined in cross-targeting context, but that's OK.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added language to that effect in the targets section, think it's clear enough?

Copy link
Contributor

@nguerrera nguerrera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice.

@@ -52,6 +52,7 @@ These targets are all defined in `Microsoft.Common.targets` and are defined in M
* **New** for MSBuild 15/Visual Studio 2017. Supports the cross-targeting feature allowing a project to have multiple `TargetFrameworks`.
* **Conditions**: only when metadata `SkipGetTargetFrameworkProperties` for each reference is not true.
* Skipped for `*.vcxproj` by default.
* This target must be present in a build request that does not specify a `TargetFramework`—the “outer” build. It is not required in a fully-specified (“inner”) build.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was more concerned about the inverse: the ones below need to be in inner build, but not outer.

</ItemGroup>
```

Including `Microsoft.Common.targets` includes logic that consumes these items and transforms them into compile-time references before the compiler runs.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Importing ...


`AssignProjectConfiguration` runs when building in a solution context, and ensures that the right `Configuration` and `Platform` are assigned to each reference. For example, if a solution specifies (using the Solution Build Manager) that for a given solution configuration, a project should always be built `Release`, that is applied inside MSBuild in this target.

`PrepareProjectReferences` then runs, ensuring that each referenced project exists (creating the item `@(_MSBuildProjectReferenceExistent)`) and asking it for the closest matching `TargetFramework` to build.
Copy link
Contributor

@cdmihai cdmihai Mar 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and asking it for the closest matching TargetFramework to build.

I'd make a new paragraph out of that snippet, with more details :)


These targets are all defined in `Microsoft.Common.targets` and are defined in Microsoft SDKs. You should only have to implement them yourself if you require custom behavior or are authoring a project that doesn't import the common targets.

If implementing a project with an “outer” (determine what properties to pass to the real build) and “inner” (fully specified) build, only `GetTargetFrameworkProperties` is required in the “outer” build. The other targets listed can be “inner” build only.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to comment that linking some doc for outer and inner builds from the SDK repo would be nice, but I couldn't find any :(

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we should write one. Either next to this file or in the Sdk repo--it's kind of a core MSBuild concept now, but only really used in the Sdk, so I could see it going either way.

<!--* `BuildGenerateSources` is run
* **Conditions**: only if `'$(BuildPassReferences)' == 'true'`.
* Rare in managed projects but common in C++ scenarios (for example, using IDL to generate header code).-->
* `GetTargetFrameworkProperties` determines what properties should be passed to the main get-build-output target.
Copy link
Contributor

@cdmihai cdmihai Mar 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get-build-output target

Is that GetTargetPath? What do non-VS builds call?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's GetTargetPath in VS, default target by default otherwise, but the default target can be overridden by the consumer by setting the metadata Targets on the ProjectReference.

@rainersigwald
Copy link
Member Author

@dotnet-bot test Windows_NT Build for Desktop please

@AndyGerlicher AndyGerlicher merged commit 14e2e82 into dotnet:master Mar 23, 2017
@rainersigwald rainersigwald deleted the ProjectReference-protocol-doc branch April 11, 2017 20:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants