<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <VersionPrefix>0.1.4-preview</VersionPrefix> <TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks> <TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks> <EnableDefaultCompileItems>false</EnableDefaultCompileItems> <BaseOutputPath>../bin/</BaseOutputPath> <PackageOutputPath>$(BaseOutputPath)nupkgs</PackageOutputPath> <!-- IsTool true causes the build output to be placed in the package's tools folder. This allows projects to reference the tasks package without including the tasks dll in their output. --> <!-- TODO: This has no effect currently, because we are using a custom .nuspec with the tools path hardcoded. Uncomment this once we are able to remove the custom .nuspec workaround. --> <!-- <IsTool>true</IsTool> --> <!-- We want to package the tasks package together with its package dependencies, the linker, and the linker's dependencies, in order to prevent projects that consume the tasks package from pulling in the linker. To do this, we need to include project references and package references in the package, and prevent any of these references from being marked as dependencies in the tasks package. To include the linker in the package, we want to package the tasks project together with its project references. This is not supported by the pack targets (https://github.com/dotnet/cli/issues/1290, https://github.com/dotnet/cli/issues/3959), so we work around this by explicitly setting the package path to include the build output. Using the publish directory will also cause dependencies from package references to be packaged. To prevent the linker from being marked as a package dependency, we can't use PrivateAssets="All", because this removes it from the publish output as well, due to an issue in the SDK (https://github.com/dotnet/sdk/issues/952). To work around this, we use a custom .nuspec that doesn't declare any dependencies. This also prevents package references from being marked as dependencies. --> <!-- TODO: Remove the custom .nuspec once the P2P PrivateAssets issue is fixed. --> <NuspecFileName>ILLink.Tasks.nuspec</NuspecFileName> <NuspecFile>$(BaseOutputPath)$(NuspecFileName)</NuspecFile> <NuspecProperties>id=$(AssemblyName);authors=$(AssemblyName);description=linker tasks;</NuspecProperties> </PropertyGroup> <!-- TODO: Remove this workaround once we're able to avoid using a custom .nuspec. We may still need a similar workaround to dynamically include the publish output in the package contents. We can't specify the output path to package in the static nuspec properties, because the project's output path gets set at a later point. To work around this, we add the output path to the nuspec properties dynamically as part of the pack target. We use the same workaround to set the version in the .nuspec file. We can't insert this into the pack target by modifying PackDependsOn, since GenerateNuspec is always prepended to PackDependsOn, which would cause the nuspec file to be generated before our extra properties are added. Instead, we use GenerateNuspecDependsOn. We could probably also use BeforeTargets="GenerateNuspec". --> <PropertyGroup> <GenerateNuspecDependsOn>SetDynamicNuspecProperties;BinPlacePackageDeps;$(GenerateNuspecDependsOn)</GenerateNuspecDependsOn> </PropertyGroup> <Target Name="SetDynamicNuspecProperties" DependsOnTargets="LayoutPackage"> <PropertyGroup> <NuspecProperties>$(NuspecProperties)version=$(Version);</NuspecProperties> </PropertyGroup> </Target> <!-- This target is necessary because the .nuspec includes the full path of the selected dlls in the package layout. We want the assets to be included in the package without the bin prefix, so we place the .nuspec and the included targets alongside the publish directories in the bin directory. --> <Target Name="BinPlacePackageDeps"> <Copy SourceFiles="$(NuspecFileName)" DestinationFolder="$(BaseOutputPath)" /> <Copy SourceFiles="ILLink.Tasks.targets" DestinationFolder="$(BaseOutputPath)" /> <Copy SourceFiles="ILLink.CrossGen.targets" DestinationFolder="$(BaseOutputPath)" /> </Target> <Target Name="LayoutPackage"> <ItemGroup> <TFMsToPublish Include="$(TargetFrameworks)" /> <ProjectsToPublish Include="$(MSBuildProjectFile)"> <AdditionalProperties>TargetFramework=%(TFMsToPublish.Identity);PublishDir=$(BaseOutputPath)%(TFMsToPublish.Identity)</AdditionalProperties> </ProjectsToPublish> </ItemGroup> <MSBuild Projects="@(ProjectsToPublish)" Targets="Publish" /> </Target> <ItemGroup> <Compile Include="LinkTask.cs" /> <Compile Include="CompareSizes.cs" /> <Compile Include="ComputeManagedAssemblies.cs" /> <Compile Include="ComputeReadyToRunAssemblies.cs" /> <Compile Include="GetRuntimeLibraries.cs" /> <Compile Include="CreateRootDescriptorFile.cs" /> <Compile Include="CreateRuntimeRootDescriptorFile.cs" /> <Compile Include="FilterByMetadata.cs" /> <Compile Include="Utils.cs" /> <Compile Include="Microsoft.NET.Build.Tasks/LockFileCache.cs" /> <Compile Include="Microsoft.NET.Build.Tasks/BuildErrorException.cs" /> <Compile Include="FindNativeDeps.cs" /> <Compile Include="ComputeRemovedAssemblies.cs" /> <Compile Include="CheckEmbeddedRootDescriptor.cs" /> <Compile Include="SetAssemblyActions.cs" /> </ItemGroup> <!-- TODO: Uncomment this once we can avoid hard-coding this in a custom .nuspec. --> <!-- Targets under the build directory of the package automatically get included in the consumer's build. --> <!-- <ItemGroup> <Content Include="ILLink.Tasks.targets"> <PackagePath>build</PackagePath> </Content> </ItemGroup> --> <!-- TODO: Use this to set the package contents once we can avoid using a custom .nuspec. --> <!-- We can't glob everything in the output path for two reasons: 1. Content gets expanded before "Build" is called during "Pack". We could work around this by creating our own target to call build and then pack, but it would be nice to avoid changing the build/package pipeline. 2. We'll try to include the tasks dll twice. This only causes a warning during pack, but should be avoided. <Content Include="$(OutputPath)*.dll;$(OutputPath)*.json"> <PackagePath>tools</PackagePath> </Content> There may also be a better ItemGroup to use than Content. Content semantics mean to output with the build, which isn't our goal. Instead, we want to include these dependencies in the package without necessarily including them in the build. --> <!-- <ItemGroup> <Content Include="$(OutputPath)illink.dll;$(OutputPath)Mono.Cecil.dll"> <PackagePath>tools</PackagePath> </Content> </ItemGroup> --> <ItemGroup> <!-- TODO: Once https://github.com/dotnet/sdk/issues/952 is fixed, use PrivateAssets="All" to prevent this project reference from being marked as a dependency of the tasks package (while still including it in the publish output). --> <ProjectReference Include="../../../linker/Mono.Linker.csproj"> <!-- SetConfiguration isn't required when the configuration is already set in the solution. Setting it here allows packing the tasks csproj on its own. This lets us avoid some of the strange behavior that shows up when trying to build from a .sln file. There is a nuget bug that prevents this from working properly during restore (https://github.com/NuGet/Home/issues/4873). For the moment, the linker has a workaround for this issue. However, this still won't work properly because the build target doesn't propagate this information properly either - this is probably another bug. Building from the .csproj would cause cecil to be built twice, once through the linker with the netstandard configuration and once directly from the tasks project in the default configuration info (because some target gets its reference information from the lock file, which doesn't have configuration info). --> <SetConfiguration>Configuration=illink_$(Configuration)</SetConfiguration> </ProjectReference> <ProjectReference Include="../../../cecil/Mono.Cecil.csproj" /> <ProjectReference Include="../ILLink.CustomSteps/ILLink.CustomSteps.csproj"> <SetConfiguration>Configuration=illink_$(Configuration)</SetConfiguration> </ProjectReference> </ItemGroup> <!-- Workaround for the SetConfiguration issue described above. --> <Target Name="SetCecilConfiguration" AfterTargets="AssignProjectConfiguration"> <ItemGroup> <ProjectReferenceWithConfiguration Condition=" '%(Filename)%(Extension)' == 'Mono.Cecil.csproj' Or '%(Filename)%(Extension)' == 'Mono.Cecil.Pdb.csproj' "> <SetConfiguration Condition=" '$(TargetFramework)' == 'net46' ">Configuration=net_4_0_$(Configuration)</SetConfiguration> <SetConfiguration Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">Configuration=netstandard_$(Configuration)</SetConfiguration> </ProjectReferenceWithConfiguration> </ItemGroup> </Target> <ItemGroup> <!-- TODO: Once we can avoid using a custom .nuspec, we should be able to set PrivateAssets="All" on these packages to prevent them from becoming package dependencies, and use an msbuild itemgroup to include their assets in the package instead of passing the publish path to the .nuspec. --> <!-- We use private assets for the Microsoft.Build packages to prevent them from being published with the tasks dll, because these are already a part of the SDK. --> <PackageReference Include="Microsoft.Build.Framework" Version="15.1.1012" PrivateAssets="All" /> <PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.1.1012" PrivateAssets="All" /> <PackageReference Include="NuGet.ProjectModel" Version="4.3.0-preview1-2500" /> <PackageReference Include="System.Reflection.Metadata" Version="1.3.0" PrivateAssets="All" /> </ItemGroup> </Project>