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

Support GitVersioning in .vcxprojs #135

Merged
merged 4 commits into from Jun 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/NerdBank.GitVersioning.Tests/BuildIntegrationTests.cs
Expand Up @@ -802,6 +802,29 @@ public async Task AssemblyInfo_SuppressedImplicitlyByTargetExt()
Assert.Empty(result.LoggedEvents.OfType<BuildWarningEventArgs>());
}

/// <summary>
/// Create a native resource .dll and verify that its version
/// information is set correctly.
/// </summary>
[Fact]
public async Task NativeVersionInfo_CreateNativeResourceDll()
{
this.testProject = this.CreateNativeProjectRootElement(this.projectDirectory, "test.vcxproj");
this.WriteVersionFile();
var result = await this.BuildAsync(Targets.Build, logVerbosity: LoggerVerbosity.Minimal);
Assert.Empty(result.LoggedEvents.OfType<BuildErrorEventArgs>());

string targetFile = Path.Combine(this.projectDirectory, result.BuildResult.ProjectStateAfterBuild.GetPropertyValue("TargetPath"));
Assert.True(File.Exists(targetFile));

var fileInfo = FileVersionInfo.GetVersionInfo(targetFile);
Assert.Equal("1.2", fileInfo.FileVersion);
Assert.Equal("1.2.0", fileInfo.ProductVersion);
Assert.Equal("test", fileInfo.InternalName);
Assert.Equal("NerdBank", fileInfo.CompanyName);
Assert.Equal($"Copyright (c) {DateTime.Now.Year}. All rights reserved.", fileInfo.LegalCopyright);
}

private static Version GetExpectedAssemblyVersion(VersionOptions versionOptions, Version version)
{
// Function should be very similar to VersionOracle.GetAssemblyVersion()
Expand Down Expand Up @@ -952,6 +975,17 @@ where name.StartsWith(prefix, StringComparison.Ordinal)
}
}

private ProjectRootElement CreateNativeProjectRootElement(string projectDirectory, string projectName)
{
using (var reader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream($"{ThisAssembly.RootNamespace}.test.vcprj")))
{
var pre = ProjectRootElement.Create(reader, this.projectCollection);
pre.FullPath = Path.Combine(projectDirectory, projectName);
pre.AddImport(Path.Combine(this.RepoPath, GitVersioningTargetsFileName));
return pre;
}
}

private ProjectRootElement CreateProjectRootElement(string projectDirectory, string projectName)
{
using (var reader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream($"{ThisAssembly.RootNamespace}.test.prj")))
Expand Down Expand Up @@ -1003,9 +1037,11 @@ private static class CloudBuild

private static class Targets
{
internal const string Build = "Build";
internal const string GetBuildVersion = "GetBuildVersion";
internal const string GetNuGetPackageVersion = "GetNuGetPackageVersion";
internal const string GenerateAssemblyVersionInfo = "GenerateAssemblyVersionInfo";
internal const string GenerateNativeVersionInfo = "GenerateNativeVersionInfo";
}

private class BuildResults
Expand Down
Expand Up @@ -13,6 +13,7 @@
<EmbeddedResource Include="Keys\*.snk" />
<EmbeddedResource Include="Keys\*.pfx" />
<EmbeddedResource Include="..\NerdBank.GitVersioning\version.schema.json" Link="version.schema.json" />
<EmbeddedResource Include="test.vcprj" />
<EmbeddedResource Include="test.prj" />
<EmbeddedResource Include="repos\submodules.7z" />
</ItemGroup>
Expand Down
123 changes: 123 additions & 0 deletions src/NerdBank.GitVersioning.Tests/test.vcprj
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{8FD9B6E8-A6E4-42A3-8B5A-E6F7ADC826F5}</ProjectGuid>
<RootNamespace>test</RootNamespace>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<ResourceOnlyDll>true</ResourceOnlyDll>
<AssemblyCompany>NerdBank</AssemblyCompany>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<NoEntryPoint>$(ResourceOnlyDll)</NoEntryPoint>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<NoEntryPoint>$(ResourceOnlyDll)</NoEntryPoint>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<NoEntryPoint>$(ResourceOnlyDll)</NoEntryPoint>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<NoEntryPoint>$(ResourceOnlyDll)</NoEntryPoint>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
Expand Up @@ -2,7 +2,11 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<VersionSourceFile>$(IntermediateOutputPath)\$(AssemblyName).Version$(DefaultLanguageSourceExtension)</VersionSourceFile>
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm curious why this had to be moved. I can't think of anyone who depends on this property being defined in MSBuild's evaluation model, but it's a risk. So is it justified?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved it because the value is now different for managed vs. native code. The $(DefaultLanguageSourceExtension) for C++ code is .cpp but we're generating a .rc file so I localized and specialized the value in the targets that used them.

If you're worried about the breaking change I could keep this value up here and override it in the native code target. Or could just use a different variable local to the target or global here (although I don't know what I'd call it 😄 ).

Do you want me to do one of those?

Copy link
Collaborator

Choose a reason for hiding this comment

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

At this point, no. Thanks for the background of this change. I'm ok to wait to hear that it broke someone before changing it. But now that I know the reasoning, we can change it with confidence should the need arise.


<PrepareForBuildDependsOn>
GenerateNativeVersionInfo;
$(PrepareForBuildDependsOn);
</PrepareForBuildDependsOn>

<PrepareResourcesDependsOn>
GenerateAssemblyVersionInfo;
Expand Down Expand Up @@ -39,6 +43,7 @@
</PropertyGroup>

<UsingTask AssemblyFile="$(NerdbankGitVersioningTasksPath)Nerdbank.GitVersioning.Tasks.dll" TaskName="Nerdbank.GitVersioning.Tasks.AssemblyVersionInfo"/>
<UsingTask AssemblyFile="$(NerdbankGitVersioningTasksPath)Nerdbank.GitVersioning.Tasks.dll" TaskName="Nerdbank.GitVersioning.Tasks.NativeVersionInfo"/>
<UsingTask AssemblyFile="$(NerdbankGitVersioningTasksPath)Nerdbank.GitVersioning.Tasks.dll" TaskName="Nerdbank.GitVersioning.Tasks.SetCloudBuildVariables"/>
<UsingTask AssemblyFile="$(NerdbankGitVersioningTasksPath)Nerdbank.GitVersioning.Tasks.dll" TaskName="Nerdbank.GitVersioning.Tasks.GetBuildVersion"/>
<UsingTask AssemblyFile="$(NerdbankGitVersioningTasksPath)Nerdbank.GitVersioning.Tasks.dll" TaskName="Nerdbank.GitVersioning.Tasks.CompareFiles"/>
Expand Down Expand Up @@ -121,6 +126,7 @@

<Target Name="GenerateAssemblyVersionInfo" DependsOnTargets="GetBuildVersion" Condition=" '$(GenerateAssemblyVersionInfo)' != 'false' ">
<PropertyGroup>
<VersionSourceFile>$(IntermediateOutputPath)\$(AssemblyName).Version$(DefaultLanguageSourceExtension)</VersionSourceFile>
<NewVersionSourceFile>$(VersionSourceFile).new</NewVersionSourceFile>
<UltimateResourceFallbackLocation Condition=" '$(DevDivProjectSubType)' != 'portable' ">UltimateResourceFallbackLocation.MainAssembly</UltimateResourceFallbackLocation>
</PropertyGroup>
Expand Down Expand Up @@ -152,6 +158,39 @@
</ItemGroup>
</Target>

<Target Name="GenerateNativeVersionInfo" DependsOnTargets="GetBuildVersion" Condition=" '$(Language)'=='C++' and '$(GenerateAssemblyVersionInfo)' != 'false' ">
<PropertyGroup>
<VersionSourceFile>$(IntermediateOutputPath)\$(AssemblyName).Version.rc</VersionSourceFile>
<NewVersionSourceFile>$(VersionSourceFile).new</NewVersionSourceFile>
</PropertyGroup>
<MakeDir Directories="$(IntermediatePath)"/>
<Nerdbank.GitVersioning.Tasks.NativeVersionInfo
OutputFile="$(NewVersionSourceFile)"
CodeLanguage="$(Language)"
ConfigurationType="$(ConfigurationType)"
AssemblyName="$(AssemblyName)"
AssemblyVersion="$(AssemblyVersion)"
AssemblyFileVersion="$(AssemblyFileVersion)"
AssemblyInformationalVersion="$(AssemblyInformationalVersion)"
AssemblyTitle="$(AssemblyTitle)"
AssemblyProduct="$(AssemblyProduct)"
AssemblyCopyright="$(AssemblyCopyright)"
AssemblyCompany="$(AssemblyCompany)"
AssemblyLanguage="$(AssemblyLanguage)"
AssemblyCodepage="$(AssemblyCodepage)"
TargetFileName="$(TargetFileName)"
/>
<!-- Avoid applying the newly generated Version.rc file to the build
unless it has changed in order to allow for incremental building. -->
<Nerdbank.GitVersioning.Tasks.CompareFiles OriginalItems="$(VersionSourceFile)" NewItems="$(NewVersionSourceFile)">
<Output TaskParameter="AreChanged" PropertyName="_NativeVersionInfoChanged" />
</Nerdbank.GitVersioning.Tasks.CompareFiles>
<Copy Condition=" '$(_NativeVersionInfoChanged)' == 'true' " SourceFiles="$(NewVersionSourceFile)" DestinationFiles="$(VersionSourceFile)" />
<ItemGroup>
<ResourceCompile Include="$(VersionSourceFile)" />
</ItemGroup>
</Target>

<!-- Support for pattern found in users of Tvl.NuGet.BuildTasks. -->
<Target Name="SupplyNuGetManifestVersion"
DependsOnTargets="GetBuildVersion"
Expand Down