diff --git a/dir.props b/dir.props index d2aadc3f413..61079e03748 100644 --- a/dir.props +++ b/dir.props @@ -43,7 +43,7 @@ 0.2.0 1.6.35 1.4.2 - 4.5.0-preview1-4518 + 4.5.0-preview1-4527 diff --git a/documentation/ProjectReference-Protocol.md b/documentation/ProjectReference-Protocol.md index c85a219ae31..7734a0f261c 100644 --- a/documentation/ProjectReference-Protocol.md +++ b/documentation/ProjectReference-Protocol.md @@ -1,4 +1,4 @@ -# The `ProjectReference` Protocol +# The `ProjectReference` Protocol The MSBuild engine doesn't have a notion of a “project reference”—it only provides the [`MSBuild` task](https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-task) to allow cross-project communication. @@ -31,7 +31,9 @@ There are empty hooks in the default targets for `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 determining the parameters it needs to produce a compatible build by calling its `GetTargetFrameworkProperties` target. +`PrepareProjectReferences` then runs, ensuring that each referenced project exists (creating the item `@(_MSBuildProjectReferenceExistent)`). + +`_ComputeProjectReferenceTargetFrameworkMatches` calls `GetTargetFrameworks` in existent ProjectReferences and determines the parameters needed to produce a compatible build by calling the `AssignReferenceProperties` task for each reference that multitargets. `ResolveProjectReferences` does the bulk of the work, building the referenced projects and collecting their outputs. @@ -47,16 +49,25 @@ These targets are all defined in `Microsoft.Common.targets` and are defined in M 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. -* `GetTargetFrameworkProperties` determines what properties should be passed to the “main” target. - * **New** for MSBuild 15/Visual Studio 2017. Supports the cross-targeting feature allowing a project to have multiple `TargetFrameworks`. +* `GetTargetFrameworks` tells referencing projects what options are available to the build. + * It returns an item with metadata `TargetFrameworks` indicating what TargetFrameworks are available in the project, as well as boolean metadata `HasSingleTargetFramework` and `IsRidAgnostic`. + * **New** in MSBuild 15.5. +* `GetTargetFrameworkProperties` determines what properties should be passed to the “main” target for a given `ReferringTargetFramework`. + * **Deprecated** in MSBuild 15.5. + * 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. -* `GetTargetPath` should the path of the project's output, but _not_ build that output. + * This should return either + * a string of the form `TargetFramework=$(NearestTargetFramework);ProjectHasSingleTargetFramework=$(_HasSingleTargetFramework);ProjectIsRidAgnostic=$(_IsRidAgnostic)`, where the value of `NearestTargetFramework` will be used to formulate `TargetFramework` for the following calls and the other two properties are booleans, or + * an item with metadata `DesiredTargetFrameworkProperties` (key-value pairs of the form `TargetFramework=net46`), `HasSingleTargetFramework` (boolean), and `IsRidAgnostic` (boolean). +* `GetTargetPath` should return the path of the project's output, but _not_ build that output. * **Conditions**: this is used for builds inside Visual Studio, but not on the command line. * It's also used when the property `BuildProjectReferences` is `false`, manually indicating that all `ProjectReferences` are up to date and shouldn't be (re)built. + * This should return a single item that is the primary output of the project, with metadata describing that output. See [`TargetPathWithTargetPlatformMoniker`](https://github.com/Microsoft/msbuild/blob/080ef976a428f6ff7bf53ca5dd4ee637b3fe949c/src/Tasks/Microsoft.Common.CurrentVersion.targets#L1834-L1842) for the default metadata. * **Default** targets should do the full build and return an assembly to be referenced. * **Conditions**: this is _not_ called when building inside Visual Studio. Instead, Visual Studio builds each project in isolation but in order, so the path returned from `GetTargetPath` can be assumed to exist at consumption time. * If the `ProjectReference` defines the `Targets` metadata, it is used. If not, no target is passed, and the default target of the reference (usually `Build`) is built. + * The return value of this target should be identical to that of `GetTargetPath`. * `GetNativeManifest` should return a manifest suitable for passing to the `ResolveNativeReferences` target. * `GetCopyToOutputDirectoryItems` should return the outputs of a project that should be copied to the output of a referencing project. * `Clean` should delete all outputs of the project. @@ -68,4 +79,4 @@ As with all MSBuild logic, targets can be added to do other work with `ProjectRe 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). -`Microsoft.AppxPackage.targets` adds a dependency on the target `GetPackagingOutputs`. \ No newline at end of file +`Microsoft.AppxPackage.targets` adds a dependency on the target `GetPackagingOutputs`. diff --git a/src/.nuget/project.json b/src/.nuget/project.json index c3e05402a74..f3a4c6fde07 100644 --- a/src/.nuget/project.json +++ b/src/.nuget/project.json @@ -6,7 +6,7 @@ "Microsoft.Net.Compilers": "2.3.1", "MicroBuild.Core": "0.2.0", "Microsoft.DotNet.BuildTools.GenAPI": "1.0.0-beta2-00731-01", - "NuGet.Build.Tasks": "4.5.0-preview1-4518" + "NuGet.Build.Tasks": "4.5.0-preview1-4527" }, "frameworks": { "net46": {} diff --git a/src/Tasks/Microsoft.Common.CrossTargeting.targets b/src/Tasks/Microsoft.Common.CrossTargeting.targets index 61eb29ff956..6d392a199f9 100644 --- a/src/Tasks/Microsoft.Common.CrossTargeting.targets +++ b/src/Tasks/Microsoft.Common.CrossTargeting.targets @@ -20,6 +20,21 @@ Copyright (C) Microsoft Corporation. All rights reserved. + + + <_ThisProjectBuildMetadata Include="$(MSBuildProjectFullPath)"> + $(TargetFrameworks) + $(TargetFramework) + true + false + + false + true + + + + <_TargetFramework Include="$(TargetFrameworks)" /> diff --git a/src/Tasks/Microsoft.Common.CurrentVersion.targets b/src/Tasks/Microsoft.Common.CurrentVersion.targets index 6451832246c..7334199e64c 100644 --- a/src/Tasks/Microsoft.Common.CurrentVersion.targets +++ b/src/Tasks/Microsoft.Common.CurrentVersion.targets @@ -1516,17 +1516,26 @@ Copyright (C) Microsoft Corporation. All rights reserved. ==================================================================================== _GetProjectReferenceTargetFrameworkProperties - Builds the GetTargetFrameworkProperties target of all existent project references, - passing $(TargetFrameworkMoniker) as $(ReferringTargetFramework) and sets the - SetTargetFramework metadata of the project reference to the value that is returned. - - This allows a cross-targeting project to select how it should be configured to - build against the most appropriate target for the referring target framework. + Builds the GetTargetFrameworks target of all existent project references to get a list + of all supported TargetFrameworks of the referenced projects. Calls the + GetReferenceNearestTargetFrameworkTask to determine the closest match for each project. + This allows a cross-targeting project to select how it should be configured to build + against the most appropriate target for the referring target framework. ====================================================================================== --> - + + + + $(NugetTargetMoniker) + $(TargetFrameworkMoniker) + + - - $(NugetTargetMoniker) - $(TargetFrameworkMoniker) - - - - + Condition="'%(_MSBuildProjectReferenceExistent.SkipGetTargetFrameworkProperties)' != 'true'" + SkipNonexistentTargets="true"> + + + + + + - <_MSBuildProjectReferenceExistent Condition="'%(_MSBuildProjectReferenceExistent.Identity)' == '%(Identity)' and '$(_ProjectReferenceTargetFrameworkProperties)' != ''"> - $(_ProjectReferenceTargetFrameworkProperties) + + + + + TargetFramework=%(AnnotatedProjects.NearestTargetFramework) + - %(_MSBuildProjectReferenceExistent.UndefineProperties);TargetFramework;ProjectHasSingleTargetFramework - - %(_MSBuildProjectReferenceExistent.UndefineProperties);ProjectHasSingleTargetFramework - + + + %(AnnotatedProjects.UndefineProperties);TargetFramework + + + + + %(AnnotatedProjects.UndefineProperties);RuntimeIdentifier + + + + <_MSBuildProjectReferenceExistent Remove="@(_MSBuildProjectReferenceExistent)" Condition="'%(_MSBuildProjectReferenceExistent.SkipGetTargetFrameworkProperties)' != 'true'" /> + <_MSBuildProjectReferenceExistent Include="@(AnnotatedProjects)" /> + + - <_MSBuildProjectReferenceExistent Condition="'%(_MSBuildProjectReferenceExistent.Identity)' == '%(Identity)' and '$(_ProjectReferenceTargetFrameworkProperties)' != ''"> - %(_MSBuildProjectReferenceExistent.UndefineProperties);RuntimeIdentifier;ProjectIsRidAgnostic - - %(_MSBuildProjectReferenceExistent.UndefineProperties);ProjectIsRidAgnostic - + <_ThisProjectBuildMetadata Include="$(MSBuildProjectFullPath)"> + $(TargetFrameworks) + $(TargetFramework) + true + false + + false + true + - - - <_ProjectReferenceTargetFrameworkProperties /> - diff --git a/targets/bootstrapDependencies/Core/15.0/Microsoft.Common.targets/ImportAfter/Microsoft.NuGet.ImportAfter.targets b/targets/bootstrapDependencies/Core/15.0/Microsoft.Common.targets/ImportAfter/Microsoft.NuGet.ImportAfter.targets new file mode 100644 index 00000000000..433922aacf3 --- /dev/null +++ b/targets/bootstrapDependencies/Core/15.0/Microsoft.Common.targets/ImportAfter/Microsoft.NuGet.ImportAfter.targets @@ -0,0 +1,18 @@ + + + + + $(MSBuildExtensionsPath)\NuGet.targets + + +