From 8d741f36b6b254702cb49845a10fa7c010be7fe6 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Thu, 10 Feb 2022 14:18:11 -0500 Subject: [PATCH] [Java.Interop] $(Version) depends on TargetFramework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Context: 2d5431f765928e5377288d3284ace3c5d871755a Context: 88d6093c506f6b8bfe47ef0045b16f07d771a890 Context: https://github.com/xamarin/java.interop/pull/936 Context: https://github.com/jonpryor/java.interop/commits/jonp-registration-scope Versioning is hard. Way back in 3e6a6232 we tried to use the `GitInfo` NuGet package so that *all* assemblies would have a version number which contained the number of commits since `GitInfo.txt` changed. This turned out to have unanticipated breakage, and was largely reverted in 2d5431f7 for "core" libs like `Java.Interop.dll`, but retained for "utility" apps and libs like `generator.exe`. This still presents a problem, though: the *point* to assembly versioning is to prevent accidental breaking of referencing assemblies. If we add a new member to `Java.Interop.dll` but *fail to update the version*, then that *permits* a scenario in which an app/lib depends on the new member, but is built against a version missing that member. This results in runtime exceptions. The whole reason this hasn't been a problem so far is because `Java.Interop.dll` has barely changed in *years*. (Plus, most usage is hidden behind other layers and libs…) However, *I want this to change*: xamarin/java.interop#936 and jonpryor/java.interop/jonp-registration-scope both *add* new public API to `Java.Interop.dll`, and there are other features and optimizations we're considering that would also require API changes. A policy of "no changes" isn't tenable. Thus: allow `Java.Interop.dll` built for .NET 6 to have a different `$(Version)` than the one built for .NET Standard 2.0. Fixing this was unexpectedly problematic, as commit 88d6093c: > Update[d] `Java.Interop.BootstrapTasks.csproj` to *no longer* > `` `VersionInfo.targets`, as this causes a circular > dependency (`VersionInfo.targets` uses tasks from > `Java.Interop.BootstrapTasks.dll`). This is fine, as > `Java.Interop.BootstrapTasks.dll` doesn't need to be versioned. `Java.Interop.BootstrapTasks.dll` doesn't need to be versioned, but *other assemblies **do***, and this change change meant that `VersionInfo.targets` was *never* used, which in turn meant that e.g. `bin/BuildDebug/Version.props` was never created. This change *also* implicitly reverted all remaining 3e6a6232 behavior; in commit 13def0e1 (one prior to 88d6093c), `generator.exe` *had* a version of 0.1.45.0. Starting with commit 88d6093c, `generator.exe` had version 1.0.0.0, which re-introduces the "baseline" scenario which first necessitated 3e6a6232! Re-think this process, while avoiding the circular dependency: 1. `Java.Interop.BootstrapTasks.targets` now *generates* a `Version.props` file, re-introducing its existence. `Version.props` now contains *four* version values: * `$(JINetToolVersion)`: Version to use for "utility" assemblies which target .NET. * `$(JINetCoreLibVersion)`: Version to use for "core library" assemblies which target .NET. * `$(JIOldToolVersion)`: Version to use for "utility" assemblies which target .NET Standard/Framework/etc. * `$(JIOldCoreLibVersion)`: Version to use for "core library" assemblies which target .NET Standard/Framework/etc. The `$(JINet*)` values derive their major, minor, and patch values from `GitInfo`, while the `$(JIOld*)` values are backward compatible (-ish). 2. Update/replace `VersionInfo.targets` with a `_SetInformationalVersion` target, which sets the `$(InformationalVersion)` MSBuild property based on the value of `$(Version)` and various other properties. 3. `Directory.Build.props` is updated to provide new `$(JIUtilityVersion)` and `$(JICoreLibVersion)` properties, which are set based on the `$(TargetFramework)` value. 4. Set the default `$(Version)` value to `$(JIUtilityVersion)`. "Core library" assemblies must explicitly set `$(Version)` in their `.csproj` to instead be `$(JICoreLibVersion)`. The result is that for "core libraries" such as `Java.Interop.dll`, when building for .NET Standard or MonoAndroid they will continue to use version 0.1.0.0 (see also 2d5431f7), while these assemblies will use version 6.0.0.0 when built for .NET Core/6. "Utility" assemblies such as `generator.exe` will contain a version number which changes based on when `GitInfo.txt` was last changed. When building for .NET Standard, they will use version `0.2.$(GitBaseVersionPatch).$(GitCommits)`, which differs from the pre-88d6093c pattern of `0.1.$(GitSemVerPatch).0`, but as my current system Xamarin.Android v12.1.99.117 install shows that `generator.exe` has version 0.1.31.0, "rebasing" on 0.2.x feels easiest. When utility assemblies are built for .NET, they will instead use the values from `GitInfo.txt`, e.g. `6.0.0.$(GitCommits)`. Finally, *always* set `$(FileVersion)` to: $(GitBaseVersionMajor).$(GitBaseVersionMinor).$(GitBaseVersionPatch).$(GitCommits) [`$(FileVersion)`][0] is used to set [`$(AssemblyFileVersionAttribute)`][1], which is *not* used for assembly binding, but *is* shown in the Windows File Properties dialog, and can be used to (indirectly) determine which commit an assembly was built from. [0]: https://docs.microsoft.com/en-us/dotnet/core/project-sdk/msbuild-props [1]: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assemblyfileversionattribute?view=net-6.0 --- Directory.Build.props | 8 +++++ Directory.Build.targets | 2 ++ GitInfo.txt | 2 +- .../Java.Interop.BootstrapTasks.csproj | 6 ++++ .../Java.Interop.BootstrapTasks.targets | 33 +++++++++++++++++++ build-tools/scripts/Version.props.in | 8 ----- build-tools/scripts/VersionInfo.targets | 32 ++++-------------- src/Java.Base/Java.Base.csproj | 1 + .../Java.Interop.Dynamic.csproj | 2 +- .../Java.Interop.Export.csproj | 2 +- .../Java.Interop.GenericMarshaler.csproj | 1 + src/Java.Interop/Java.Interop.csproj | 2 +- .../Java.Runtime.Environment.csproj | 1 + 13 files changed, 63 insertions(+), 37 deletions(-) delete mode 100644 build-tools/scripts/Version.props.in diff --git a/Directory.Build.props b/Directory.Build.props index 3c8b96e99..2b2343a4d 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -62,6 +62,8 @@ $(UtilityOutputFullPathCoreApps) $(ToolOutputFullPath) Major + $(JINetToolVersion) + $(JINetCoreLibVersion) $(BaseIntermediateOutputPath)\$(Configuration) @@ -69,6 +71,8 @@ $(MSBuildThisFileDirectory)bin\$(Configuration)\ $(MSBuildThisFileDirectory)bin\Test$(Configuration)\ $(ToolOutputFullPath) + $(JIOldToolVersion) + $(JIOldCoreLibVersion) $(MSBuildThisFileDirectory)external\xamarin-android-tools @@ -119,4 +123,8 @@ $(NoWarn);CA1307;CA1309;CA1310 + + $(JIUtilityVersion) + + diff --git a/Directory.Build.targets b/Directory.Build.targets index 5a6438555..ea649d951 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -34,4 +34,6 @@ + + diff --git a/GitInfo.txt b/GitInfo.txt index ceab6e11e..e0ea36fee 100644 --- a/GitInfo.txt +++ b/GitInfo.txt @@ -1 +1 @@ -0.1 \ No newline at end of file +6.0 diff --git a/build-tools/Java.Interop.BootstrapTasks/Java.Interop.BootstrapTasks.csproj b/build-tools/Java.Interop.BootstrapTasks/Java.Interop.BootstrapTasks.csproj index 82b53b925..2ea9769b5 100644 --- a/build-tools/Java.Interop.BootstrapTasks/Java.Interop.BootstrapTasks.csproj +++ b/build-tools/Java.Interop.BootstrapTasks/Java.Interop.BootstrapTasks.csproj @@ -6,7 +6,13 @@ $(BuildToolOutputFullPath) + + main + false + + + diff --git a/build-tools/Java.Interop.BootstrapTasks/Java.Interop.BootstrapTasks.targets b/build-tools/Java.Interop.BootstrapTasks/Java.Interop.BootstrapTasks.targets index 931ea5c70..51cb25fa1 100644 --- a/build-tools/Java.Interop.BootstrapTasks/Java.Interop.BootstrapTasks.targets +++ b/build-tools/Java.Interop.BootstrapTasks/Java.Interop.BootstrapTasks.targets @@ -105,4 +105,37 @@ + + + <_NetToolVersion>$(GitBaseVersionMajor).$(GitBaseVersionMinor).$(GitBaseVersionPatch).$(GitCommits) + <_OldToolVersion>0.2.$(GitBaseVersionPatch).$(GitCommits) + <_NetCoreLibVersion>$(GitBaseVersionMajor).$(GitBaseVersionMinor).0.0 + <_OldCoreLibVersion>0.1.0.0 + <_FileVersion>$(GitBaseVersionMajor).$(GitBaseVersionMinor).$(GitBaseVersionPatch).$(GitCommits) + + + <_VersionsLine Include="<Project>" /> + <_VersionsLine Include=" <PropertyGroup>" /> + <_VersionsLine Include=" <FileVersion>$(_FileVersion)</FileVersion>" /> + <_VersionsLine Include=" <JINetToolVersion>$(_NetToolVersion)</JINetToolVersion>" /> + <_VersionsLine Include=" <JIOldToolVersion>$(_OldToolVersion)</JIOldToolVersion>" /> + <_VersionsLine Include=" <JINetCoreLibVersion>$(_NetCoreLibVersion)</JINetCoreLibVersion>" /> + <_VersionsLine Include=" <JIOldCoreLibVersion>$(_OldCoreLibVersion)</JIOldCoreLibVersion>" /> + <_VersionsLine Include=" <JIBuildBranch>$(GitBranch)</JIBuildBranch>" /> + <_VersionsLine Include=" <JIBuildCommit>$(GitCommit)</JIBuildCommit>" /> + <_VersionsLine Include=" </PropertyGroup>" /> + <_VersionsLine Include="</Project>" /> + + + + + diff --git a/build-tools/scripts/Version.props.in b/build-tools/scripts/Version.props.in deleted file mode 100644 index a414f3475..000000000 --- a/build-tools/scripts/Version.props.in +++ /dev/null @@ -1,8 +0,0 @@ - - - @VERSION@ - @VERSION@ git-rev-head:@COMMIT@ git-branch:@BRANCH@ - Microsoft Corporation - Microsoft Corporation - - \ No newline at end of file diff --git a/build-tools/scripts/VersionInfo.targets b/build-tools/scripts/VersionInfo.targets index 5636ef5d3..c86a53c5f 100644 --- a/build-tools/scripts/VersionInfo.targets +++ b/build-tools/scripts/VersionInfo.targets @@ -1,29 +1,11 @@ - + - - - main - false - - - - - - - - - - - - + + + $(Version) git-rev-head:$(JIBuildCommit) git-branch:$(JIBuildBranch) + + \ No newline at end of file diff --git a/src/Java.Base/Java.Base.csproj b/src/Java.Base/Java.Base.csproj index 5be4deceb..81bd6cc7d 100644 --- a/src/Java.Base/Java.Base.csproj +++ b/src/Java.Base/Java.Base.csproj @@ -5,6 +5,7 @@ true enable $(NoWarn);8764 + $(JICoreLibVersion) diff --git a/src/Java.Interop.Dynamic/Java.Interop.Dynamic.csproj b/src/Java.Interop.Dynamic/Java.Interop.Dynamic.csproj index 051223abd..df7c6b40d 100644 --- a/src/Java.Interop.Dynamic/Java.Interop.Dynamic.csproj +++ b/src/Java.Interop.Dynamic/Java.Interop.Dynamic.csproj @@ -7,7 +7,7 @@ true ..\..\product.snk Java.Interop.Dynamic - 0.1.0.0 + $(JICoreLibVersion) $(ToolOutputFullPath) diff --git a/src/Java.Interop.Export/Java.Interop.Export.csproj b/src/Java.Interop.Export/Java.Interop.Export.csproj index bc3170252..50ded2320 100644 --- a/src/Java.Interop.Export/Java.Interop.Export.csproj +++ b/src/Java.Interop.Export/Java.Interop.Export.csproj @@ -7,7 +7,7 @@ true ..\..\product.snk Java.Interop.Export - 0.1.0.0 + $(JICoreLibVersion) $(ToolOutputFullPath) diff --git a/src/Java.Interop.GenericMarshaler/Java.Interop.GenericMarshaler.csproj b/src/Java.Interop.GenericMarshaler/Java.Interop.GenericMarshaler.csproj index 1b69c773e..4f23b6ca6 100644 --- a/src/Java.Interop.GenericMarshaler/Java.Interop.GenericMarshaler.csproj +++ b/src/Java.Interop.GenericMarshaler/Java.Interop.GenericMarshaler.csproj @@ -10,6 +10,7 @@ $(ToolOutputFullPath) + $(JICoreLibVersion) diff --git a/src/Java.Interop/Java.Interop.csproj b/src/Java.Interop/Java.Interop.csproj index 1ee9e3c10..0d666353f 100644 --- a/src/Java.Interop/Java.Interop.csproj +++ b/src/Java.Interop/Java.Interop.csproj @@ -30,7 +30,7 @@ enable true NU1702 - 0.1.0.0 + $(JICoreLibVersion) DEBUG;$(DefineConstants) diff --git a/src/Java.Runtime.Environment/Java.Runtime.Environment.csproj b/src/Java.Runtime.Environment/Java.Runtime.Environment.csproj index 264005096..1ff8f04bf 100644 --- a/src/Java.Runtime.Environment/Java.Runtime.Environment.csproj +++ b/src/Java.Runtime.Environment/Java.Runtime.Environment.csproj @@ -12,6 +12,7 @@ $(TestOutputFullPath) + $(JICoreLibVersion)