Skip to content

Commit d9afc2b

Browse files
committed
Simplify Roslyn multi-targeting
- Fix the text flow warping in the MSBuild Console logging. - Use checked version properties instead of hard-coded checks. - Update the structure of the projects list in the Solution file. - Refactor Roslyn multi-targeting to use multiple projects in the same project directory without using Shared projects. This refactoring is made in preparation for the solution to use the NuGet's CPVM (Central Package Versions Management) feature. This also slightly improves IDE load time and Build performance.
1 parent d86dca8 commit d9afc2b

File tree

33 files changed

+344
-670
lines changed

33 files changed

+344
-670
lines changed

CommunityToolkit.sln

Lines changed: 95 additions & 376 deletions
Large diffs are not rendered by default.

Directory.Build.rsp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-NoLogo
2+
-MaxCPUCount
3+
-NodeReuse:True
4+
-Verbosity:Normal
5+
-ConsoleLoggerParameters:ForceNoAlign

eng/Toolkit.Common.props

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,15 @@
4848
<ContinuousIntegrationBuild>$(TF_BUILD)</ContinuousIntegrationBuild>
4949
</PropertyGroup>
5050

51+
<!-- Identify projects targeting multiple Roslyn versions and add defaults -->
52+
<PropertyGroup Condition="$(MSBuildProjectName.Contains('.Roslyn'))">
53+
<IsCompilerTargeting>True</IsCompilerTargeting>
54+
<TargetCompilerIdentifier>Roslyn</TargetCompilerIdentifier>
55+
<!-- TODO: Update the supported Compiler versions here as new ones get released -->
56+
<SupportedCompilerVersions>4.0;4.1;4.2;4.3;4.4;4.5</SupportedCompilerVersions>
57+
</PropertyGroup>
58+
59+
<!-- Use custom build logic for projects targeting multiple version of the Roslyn Compiler -->
60+
<Import Project="Toolkit.CompilerTargeting.props" Condition="'$(IsCompilerTargeting)' == 'true'" />
61+
5162
</Project>

eng/Toolkit.Common.targets

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,20 @@
1717
<None Include="$(RepositoryDirectory)ThirdPartyNotices.txt" Pack="true" PackagePath="\" Visible="False" />
1818
</ItemGroup>
1919

20+
<!--
21+
Add additional Pre-Processor symbols to $(DefineConstants) and $(FinalDefineConstants) in VB.
22+
This overrides the same target in the .NET SDK. Since, that version has issues in DesignTime.
23+
-->
24+
<Target Name="AddImplicitDefineConstants"
25+
Condition="'$(DisableImplicitDefineConstants)' != 'true'"
26+
DependsOnTargets="GenerateTargetPlatformDefineConstants;GenerateNETCompatibleDefineConstants;GeneratePlatformCompatibleDefineConstants"
27+
BeforeTargets="CompileDesignTime;CoreCompile">
28+
29+
<!-- Add the Custom defines before entering compilation process. Make sure it also works in Design Time -->
30+
<PropertyGroup Condition="@(_ImplicitDefineConstant->Count()) > 0">
31+
<DefineConstants Condition="'$(Language)' != 'VB'">$(DefineConstants);@(_ImplicitDefineConstant)</DefineConstants>
32+
<FinalDefineConstants Condition="'$(Language)' == 'VB'">$(FinalDefineConstants),@(_ImplicitDefineConstant->'%(Identity)=-1', ',')</FinalDefineConstants>
33+
</PropertyGroup>
34+
</Target>
35+
2036
</Project>

eng/Toolkit.CompilerTargeting.props

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<Project>
2+
3+
<!--
4+
This file contains logic that supports targeting multiple Compiler (i.e. Roslyn) versions.
5+
So, Define Identifiers and supported Versions before entering this file like so...
6+
7+
<PropertyGroup Condition="$(MSBuildProjectName.Contains('.Roslyn'))>
8+
<IsCompilerTargeting>True</IsCompilerTargeting>
9+
<TargetCompilerIdentifier>Roslyn</TargetCompilerIdentifier>
10+
<SupportedCompilerVersions>4.1;4.2;4.3;4.4;4.5</SupportedCompilerVersion>
11+
</PropertyGroup>
12+
13+
Then, this file can be conditionally imported using the $(IsCompilerTargeting) property only for
14+
projects that actually needs compiler targeting. In this case, the $(MSBuildProjectName) property
15+
contains compiler targeting information.
16+
17+
Hence, using that to set the former property allows to keep the the following import and
18+
the above default properties in a common place rather than duplicating them in each and
19+
every required project file. This keeps the project files simple.
20+
21+
<Import Project="Toolkit.CompilerTargeting.props" Condition="'$(IsCompilerTargeting)' == 'true'" />
22+
-->
23+
24+
<PropertyGroup>
25+
<!-- Make a lower-case version of the identifier to use it as a folder name. e.g., roslyn4.0 -->
26+
<_ShortCompilerIdentifier>$(TargetCompilerIdentifier.ToLowerInvariant())</_ShortCompilerIdentifier>
27+
28+
<!-- Extract Version 40 from Roslyn40 in the Project Name: e.g., 'CommunityToolkit.Mvvm.Roslyn40.UnitTests' -->
29+
<_CompilerNameInProjectNameIndex>$(MSBuildProjectName.IndexOf($(TargetCompilerIdentifier)))</_CompilerNameInProjectNameIndex>
30+
<_ShortCompilerVersion Condition="$(_CompilerNameInProjectNameIndex) != -1">$(MSBuildProjectName.Substring($([MSBuild]::Add($(_CompilerNameInProjectNameIndex), $(TargetCompilerIdentifier.Length))), 2))</_ShortCompilerVersion>
31+
32+
<!-- Convert to a valid Version string by adding a missing period ('.') -->
33+
<TargetCompilerVersion Condition="$(_ShortCompilerVersion.Length) == 2">$(_ShortCompilerVersion[0]).$(_ShortCompilerVersion[1])</TargetCompilerVersion>
34+
35+
<!-- Default to v4.0 for Roslyn compiler since, only from that version onwards supports Source Generators -->
36+
<TargetCompilerVersion Condition="'$(TargetCompilerVersion)' == ''">4.0</TargetCompilerVersion>
37+
38+
<!-- This can be used as folder names and also in paths. e.g., roslyn4.0 -->
39+
<TargetCompiler Condition="'$(TargetCompiler)' == ''">$(_ShortCompilerIdentifier)$(TargetCompilerVersion)</TargetCompiler>
40+
</PropertyGroup>
41+
42+
<!-- Since we're are separating the assets, we can use the project name without the "Roslyn40" identifier for other default properties -->
43+
<PropertyGroup>
44+
<ProjectName Condition="'$(ProjectName)' == ''">$(MSBuildProjectName.Replace('.$(TargetCompilerIdentifier)$(_ShortCompilerVersion)', ''))</ProjectName>
45+
<AssemblyName Condition="'$(AssemblyName)' == '' AND '$(ProjectName)' != ''">$(ProjectName)</AssemblyName>
46+
<RootNamespace Condition="'$(RootNamespace)' == '' AND '$(ProjectName)' != ''">$(ProjectName)</RootNamespace>
47+
</PropertyGroup>
48+
49+
<PropertyGroup>
50+
<!-- Currently 'project.assets.json' and 'project.nuget.cache' doesn't have unique file-names based on project name like other restore assets do -->
51+
<MSBuildProjectExtensionsPath Condition="'$(TargetCompiler)' != ''">$([System.IO.Path]::Combine('obj', '$(TargetCompiler)'))</MSBuildProjectExtensionsPath>
52+
</PropertyGroup>
53+
54+
<!-- We also override output paths to separate compiler version specific assets but only after .NET SDK appends 'TargetFramework' -->
55+
<PropertyGroup>
56+
<CustomBeforeMicrosoftCommonTargets>$(MSBuildThisFileDirectory)Toolkit.CompilerTargeting.targets</CustomBeforeMicrosoftCommonTargets>
57+
</PropertyGroup>
58+
59+
</Project>

eng/Toolkit.CompilerTargeting.targets

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<Project>
2+
3+
<PropertyGroup>
4+
<VSTestResultsDirectory>$([System.IO.Path]::Combine('$(BaseOutputPath)', 'TestResults'))</VSTestResultsDirectory>
5+
</PropertyGroup>
6+
7+
<!-- Append the Compiler moniker (i.e., roslyn4.0) to 'TargetFramework' in the output paths -->
8+
<Choose>
9+
<When Condition="'$(TargetCompilerVersion)' != ''">
10+
<PropertyGroup>
11+
<OutputPath>$(OutputPath.Replace('$(TargetFramework)', '$(TargetFramework)-$(TargetCompiler)'))</OutputPath>
12+
<IntermediateOutputPath>$(IntermediateOutputPath.Replace('$(TargetFramework)', '$(TargetFramework)-$(TargetCompiler)'))</IntermediateOutputPath>
13+
<DocumentationFile>$(DocumentationFile.Replace('$(TargetFramework)', '$(TargetFramework)-$(TargetCompiler)'))</DocumentationFile>
14+
<VSTestResultsDirectory>$([System.IO.Path]::Combine('$(VSTestResultsDirectory)', '$(TargetCompiler)'))</VSTestResultsDirectory>
15+
<PublishDir>$(PublishDir.Replace('$(TargetFramework)', '$(TargetFramework)-$(TargetCompiler)'))</PublishDir>
16+
</PropertyGroup>
17+
</When>
18+
</Choose>
19+
20+
<PropertyGroup>
21+
<!-- Define an compiler identifier pre-processor constant. This enables to group targeting code under multi-targeting -->
22+
<_ImplicitCompilerIdentifierDefine>$(TargetCompilerIdentifier.ToUpperInvariant())</_ImplicitCompilerIdentifierDefine>
23+
<!-- If supported version list is given, then enable multi-version implicit defines -->
24+
<_EnableImplicitMultiVersionDefines Condition="'$(SupportedCompilerVersions)' != '' AND $(SupportedCompilerVersions.Contains(';'))" >true</_EnableImplicitMultiVersionDefines>
25+
<!-- Define a single version pre-processor constant, if the project does not need multi-version defines -->
26+
<_ImplicitCompilerVersionDefine Condition="'$(_ShortCompilerVersion)' != '' AND '$(_EnableImplicitMultiVersionDefines)' != 'true'">$(_ImplicitCompilerIdentifierDefine)_$(TargetCompilerVersion.Replace('.', '_'))</_ImplicitCompilerVersionDefine>
27+
</PropertyGroup>
28+
29+
<!--
30+
Add the symbols to @(_ImplicitDefineConstant) list which will be used to
31+
populate the $(DefineConstants) and $(FinalDefineConstants) in VB projects.
32+
-->
33+
<ItemGroup>
34+
<!-- Add implicit define constants for the target compiler -->
35+
<_ImplicitDefineConstant Include="$(_ImplicitCompilerIdentifierDefine)" />
36+
<_ImplicitDefineConstant Include="$(_ImplicitCompilerVersionDefine)" Condition="'$(_ImplicitCompilerVersionDefine)' != ''" />
37+
<!-- Add supported compiler versions to item list for expanding them into implicit defines -->
38+
<_SupportedCompilerVersion Include="$(SupportedCompilerVersions)" Condition="'$(_EnableImplicitMultiVersionDefines)' == 'true'" />
39+
</ItemGroup>
40+
41+
<!--
42+
====================================================================================================
43+
AddImplicitMultiVersionDefineConstants
44+
45+
Generate the multi-version pre-processor defines, so the source code can be multi-targeted
46+
across compiler and its versions. Be sure to insert all the defines into the SDK internal
47+
@(_ImplicitDefineConstant) list before the 'AddImplicitDefineConstants' target is run.
48+
====================================================================================================
49+
-->
50+
<Target Name="AddImplicitMultiVersionDefineConstants"
51+
Condition="'$(_EnableImplicitMultiVersionDefines)' == 'true'"
52+
BeforeTargets="AddImplicitDefineConstants">
53+
54+
<!-- Adding custom defines through conditional batching is only supported inside targets -->
55+
<ItemGroup>
56+
<TargetCompilerVersion Include="@(_SupportedCompilerVersion)" Condition="$([MSBuild]::VersionLessThanOrEquals(%(Identity), $(TargetCompilerVersion)))" />
57+
<!-- Generate the multi-version "<COMPILER>_<MAJOR>_<MINOR>_OR_GREATER" pre-processor defines -->
58+
<_ImplicitCompilerVersionDefine Include="@(TargetCompilerVersion->Replace('.', '_')->'$(_ImplicitCompilerIdentifierDefine)_%(Identity)_OR_GREATER')" />
59+
<_ImplicitDefineConstant Include="@(_ImplicitCompilerVersionDefine)" />
60+
</ItemGroup>
61+
</Target>
62+
63+
</Project>

src/CommunityToolkit.Mvvm.SourceGenerators.Roslyn401/CommunityToolkit.Mvvm.SourceGenerators.Roslyn401.csproj

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/CommunityToolkit.Mvvm.SourceGenerators.Roslyn431/CommunityToolkit.Mvvm.SourceGenerators.Roslyn431.csproj

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<IsPackable>false</IsPackable>
5+
<TargetFramework>netstandard2.0</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<Compile Remove="EmbeddedResources\*.cs" />
10+
<EmbeddedResource Include="EmbeddedResources\*.cs">
11+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
12+
<!-- The 'LogicalName' metadata changes the default manifest naming scheme -->
13+
<LogicalName>%(Filename)%(Extension)</LogicalName>
14+
</EmbeddedResource>
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<AdditionalFiles Include="AnalyzerReleases.Shipped.md" />
19+
<AdditionalFiles Include="AnalyzerReleases.Unshipped.md" />
20+
</ItemGroup>
21+
22+
<ItemGroup>
23+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" PrivateAssets="All" Pack="false" />
24+
</ItemGroup>
25+
26+
</Project>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<IsPackable>false</IsPackable>
5+
<TargetFramework>netstandard2.0</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<Compile Remove="EmbeddedResources\*.cs" />
10+
<EmbeddedResource Include="EmbeddedResources\*.cs">
11+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
12+
<!-- The 'LogicalName' metadata changes the default manifest naming scheme -->
13+
<LogicalName>%(Filename)%(Extension)</LogicalName>
14+
</EmbeddedResource>
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<AdditionalFiles Include="AnalyzerReleases.Shipped.md" />
19+
<AdditionalFiles Include="AnalyzerReleases.Unshipped.md" />
20+
</ItemGroup>
21+
22+
<ItemGroup>
23+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.1" PrivateAssets="All" Pack="false" />
24+
</ItemGroup>
25+
26+
</Project>

0 commit comments

Comments
 (0)