From ca47896204482bf4a6979e3838bf7f09f61cebeb Mon Sep 17 00:00:00 2001
From: giy <giy@omp-system.ru>
Date: Fri, 02 Sep 2022 14:16:56 +0300
Subject: [PATCH] Обновление до версии 2.9.0

---
 QtMSBuild/QtMsBuild/qt_globals.targets |  259 +++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 208 insertions(+), 51 deletions(-)

diff --git a/QtMSBuild/QtMsBuild/qt_globals.targets b/QtMSBuild/QtMsBuild/qt_globals.targets
index a8cb31c..966a084 100644
--- a/QtMSBuild/QtMsBuild/qt_globals.targets
+++ b/QtMSBuild/QtMsBuild/qt_globals.targets
@@ -84,6 +84,29 @@
 
   <!--
   /////////////////////////////////////////////////////////////////////////////////////////////////
+  // Set up inner build if Qt vars property file is outdated
+  // -->
+  <PropertyGroup Condition="'$(QtInnerBuild)' == ''">
+    <QtVarsOutdated>false</QtVarsOutdated>
+    <QtVarsOutdated
+      Condition="!Exists('$(QtVarsFilePath)')
+        OR '$(QtBkup_QtInstall)'                != '$(QtInstall)'
+        OR '$(QtBkup_QtModules)'                != '$(QtModules)'
+        OR '$(QtBkup_QtPathBinaries)'           != '$(QtPathBinaries)'
+        OR '$(QtBkup_QtPathLibraryExecutables)' != '$(QtPathLibraryExecutables)'
+        OR '$(QtBkup_QtHeaderSearchPath)'       != '$(QtHeaderSearchPath)'
+        OR '$(QtBkup_QtLibrarySearchPath)'      != '$(QtLibrarySearchPath)'
+        OR '$(QtBkup_QtVars)'                   != '$(QtVars)'
+        OR '$(QtBkup_QMakeCodeLines)'           != '$(QMakeCodeLines)'
+        OR '$(QtBkup_QtBuildConfig)'            != '$(QtBuildConfig)'"
+    >true</QtVarsOutdated>
+  </PropertyGroup>
+
+  <!-- // Enable inner build targets -->
+  <Import Condition="'$(QtVarsOutdated)' == 'true'" Project="qt_inner.targets"/>
+
+  <!--
+  /////////////////////////////////////////////////////////////////////////////////////////////////
   /// TARGET QtGetDefaultClCompile
   /////////////////////////////////////////////////////////////////////////////////////////////////
   // Get default C++ properties
@@ -201,7 +224,8 @@
                OR ('$(project_changed)' == 'true' AND '$(log_hash)' != '$(work_hash)')"
         >true</do_work>
       <skip_work
-        Condition="'$(do_work)' != 'true' OR '$(DesignTimeBuild)' == 'true'"
+        Condition="'$(do_work)' != 'true'
+          OR ('$(QtDesignTimeBuild)' == 'true' AND '$(QtToolsDesignTime)' != 'true')"
         >true</skip_work>
     </PropertyGroup>
 
@@ -268,8 +292,7 @@
     // -->
     <QtRunWork
       Condition="'$(ApplicationType)' != 'Linux' AND '@(QtWork)' != ''
-        AND '%(QtWork.ParallelBuild)' == 'true'
-        AND '$(DesignTimeBuild)' != 'true'"
+        AND '%(QtWork.ParallelBuild)' == 'true'"
       QtWork="@(QtWork)" QtMaxProcs="$(QtMaxProcs)" QtDebug="$(QtDebug)">
       <Output TaskParameter="Result" ItemName="QtWorkResult" />
     </QtRunWork>
@@ -280,8 +303,7 @@
     // -->
     <QtRunWork
       Condition="'$(ApplicationType)' != 'Linux' AND '@(QtWork)' != ''
-        AND '%(QtWork.ParallelBuild)' != 'true'
-        AND '$(DesignTimeBuild)' != 'true'"
+        AND '%(QtWork.ParallelBuild)' != 'true'"
       QtWork="@(QtWork)" QtMaxProcs="1" QtDebug="$(QtDebug)">
       <Output TaskParameter="Result" ItemName="QtWorkResult" />
     </QtRunWork>
@@ -293,13 +315,13 @@
     <!-- // Translate local paths to host paths -->
     <Flatten
       Condition="'$(ApplicationType)' == 'Linux'
-        AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'"
+        AND '@(QtWork)' != '' AND '$(QtDesignTimeBuild)' != 'true'"
       Items="@(QtWork)" Metadata="ResourceFiles">
       <Output TaskParameter="Result" ItemName="ResourceFiles"/>
     </Flatten>
     <ItemGroup
       Condition="'$(ApplicationType)' == 'Linux'
-        AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'">
+        AND '@(QtWork)' != '' AND '$(QtDesignTimeBuild)' != 'true'">
       <LocalPath Include="%(QtWork.Identity)">
         <Name>InputPath</Name>
         <Item>%(QtWork.Identity)</Item>
@@ -320,7 +342,7 @@
     </ItemGroup>
     <HostTranslatePaths
       Condition="'$(ApplicationType)' == 'Linux'
-        AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'"
+        AND '@(QtWork)' != '' AND '$(QtDesignTimeBuild)' != 'true'"
       Items="@(LocalPath)" Names="InputPath;OutputPath">
       <Output TaskParameter="Result" ItemName="HostPath"/>
     </HostTranslatePaths>
@@ -332,7 +354,7 @@
     <!-- // Run command -->
     <HostExec
       Condition="'$(ApplicationType)' == 'Linux'
-        AND '%(Identity)' != '' AND '$(DesignTimeBuild)' != 'true'"
+        AND '%(Identity)' != '' AND '$(QtDesignTimeBuild)' != 'true'"
       Message="@(QtWork->'%(WorkType) %(Identity)')"
       Command="@(QtWork->'%(ToolPath) %(Options)')"
       Inputs="@(InputPath)"
@@ -344,7 +366,7 @@
     <!-- // Generate result item -->
     <ItemGroup
       Condition="'$(ApplicationType)' == 'Linux'
-        AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'">
+        AND '@(QtWork)' != '' AND '$(QtDesignTimeBuild)' != 'true'">
       <QtWorkResult Include="@(QtWork)">
         <ExitCode>0</ExitCode>
       </QtWorkResult>
@@ -354,9 +376,11 @@
     ///////////////////////////////////////////////////////////////////////////////////////////////
     // Save tracking log of files read during build; used by VS to check the up-to-date status
     // -->
-    <ItemGroup Condition="'$(DesignTimeBuild)' != 'true' AND '$(QtVSToolsBuild)' != 'true'">
+    <ItemGroup>
       <read_log Include="^%(QtWorkResult.FullPath);%(QtWorkResult.AdditionalDependencies)"
-        Condition="'%(QtWorkResult.ExitCode)' == '0' AND '%(QtWorkResult.DisableLog)' != 'true'">
+        Condition="'%(QtWorkResult.ExitCode)' == '0'
+               AND '%(QtWorkResult.DisableLog)' != 'true'
+               AND '%(QtWorkResult.Skipped)' != 'true'">
         <WorkType>%(QtWorkResult.WorkType)</WorkType>
       </read_log>
       <read_log>
@@ -377,9 +401,11 @@
     ///////////////////////////////////////////////////////////////////////////////////////////////
     // Save tracking log of files written during build; used by VS to check the up-to-date status
     // -->
-    <ItemGroup Condition="'$(DesignTimeBuild)' != 'true' AND '$(QtVSToolsBuild)' != 'true'">
+    <ItemGroup>
       <write_log Include="^%(QtWorkResult.FullPath);%(QtWorkResult.OutputFile)"
-        Condition="'%(QtWorkResult.ExitCode)' == '0' AND '%(QtWorkResult.DisableLog)' != 'true'">
+        Condition="'%(QtWorkResult.ExitCode)' == '0'
+               AND '%(QtWorkResult.DisableLog)' != 'true'
+               AND '%(QtWorkResult.Skipped)' != 'true'">
         <WorkType>%(QtWorkResult.WorkType)</WorkType>
       </write_log>
       <write_log>
@@ -398,7 +424,7 @@
     ///////////////////////////////////////////////////////////////////////////////////////////////
     // Log output files; this is used by VS to determine what files to delete on "Clean"
     // -->
-    <ItemGroup Condition="'$(DesignTimeBuild)' != 'true' AND '$(QtVSToolsBuild)' != 'true'">
+    <ItemGroup>
       <clean_log Include="%(QtWorkResult.OutputFile)"
         Condition="'%(QtWorkResult.ExitCode)' == '0'">
         <Source>@(QtWorkResult, '|')</Source>
@@ -414,7 +440,7 @@
     ///////////////////////////////////////////////////////////////////////////////////////////////
     // Log calls to Qt tools; used in QtWorkPrepare to detect changes to the options of Qt tools
     // -->
-    <WriteLinesToFile Condition="'@(QtWorkLog)' != '' AND '$(DesignTimeBuild)' != 'true'"
+    <WriteLinesToFile Condition="'@(QtWorkLog)' != ''"
       File="$(QtLogFilePath)"
       Lines="@(QtWorkLog->'%(Identity)|%(Hash)')"
       Overwrite="true" Encoding="Unicode"/>
@@ -425,8 +451,7 @@
     // -->
     <Error
       Condition="'%(QtWorkResult.ExitCode)' != ''
-        AND '%(QtWorkResult.ExitCode)' != '0'
-        AND '$(DesignTimeBuild)' != 'true'"
+        AND '%(QtWorkResult.ExitCode)' != '0'"
       File="%(QtWorkResult.Identity)" Code="%(QtWorkResult.ExitCode)"
       Text="%(QtWorkResult.WorkType) (%(QtWorkResult.ToolPath))"/>
 
@@ -513,6 +538,7 @@
     // Clean-up
     // -->
     <ItemGroup>
+      <ClCompile    Remove="DefaultClCompile" />
       <QtWork       Remove="@(QtWork)"/>
       <QtWorkResult Remove="@(QtWorkResult)"/>
       <QtWorkLog    Remove="@(QtWorkLog)"/>
@@ -524,51 +550,158 @@
 
   <!--
   /////////////////////////////////////////////////////////////////////////////////////////////////
-  /// TARGET Qt
+  /// TARGET QtSetAdditionalOptions
   /////////////////////////////////////////////////////////////////////////////////////////////////
-  // Root Qt target
+  // Adds additional compiler options flowing from Qt.
+  // Skips options that are already specified in the user project.
   // -->
-  <Target Name="Qt" DependsOnTargets="QtPrepare;QtWork" BeforeTargets="FixupCLCompileOptions">
+  <Target Name="QtSetAdditionalOptions" Condition="'@(ClCompile)' != ''">
+
+    <!-- Command line parser regex -->
+    <PropertyGroup>
+      <CmdLineParser>"[^"]*"|[^\s]+</CmdLineParser>
+    </PropertyGroup>
+
+    <!-- Parse compiler options from Qt -->
+    <PropertyGroup>
+      <QtCmdLine
+          >$([System.Text.RegularExpressions.Regex]::Matches(
+            '$(Qt_CL_OPTIONS_)', '$(CmdLineParser)'))</QtCmdLine>
+    </PropertyGroup>
+
+    <!-- Calculate command line for each source file in the project -->
+    <QtRunTask
+      Items="@(ClCompile)"
+      AssemblyPath="$(VCTargetsPath)\Microsoft.Build.CPPTasks.Common.dll"
+      TaskName="Microsoft.Build.CPPTasks.CLCommandLine"
+      TaskInput="Sources"
+      TaskOutput="CommandLines"
+      NewMetadata="ProjectOptions">
+      <Output TaskParameter="Result" ItemName="ClCompile_CmdLine" />
+    </QtRunTask>
+
+    <!-- Append excluded Qt options to calculated command line -->
     <ItemGroup>
-      <ClCompile Remove="DefaultClCompile" />
+      <ClCompile_CmdLine Condition="'$(QtExcludedOptions)' != ''">
+        <ProjectOptions>%(ProjectOptions) $(QtExcludedOptions)</ProjectOptions>
+      </ClCompile_CmdLine>
     </ItemGroup>
-    <CriticalSection Lock="false" Name="$(ProjectGuid)" />
-    <OnError ExecuteTargets="QtLeaveCriticalSection_OnError"/>
+
+    <!-- Parse compiler command line of each source file -->
+    <ItemGroup>
+      <ClCompile_CmdLine>
+        <ProjectOptions
+          >$([System.Text.RegularExpressions.Regex]::Matches(
+            '%(ProjectOptions)', '$(CmdLineParser)'))</ProjectOptions>
+      </ClCompile_CmdLine>
+    </ItemGroup>
+
+    <!-- Add (previously parsed) Qt options to each source file -->
+    <ItemGroup>
+      <ClCompile_CmdLine>
+        <QtOptions>$(QtCmdLine)</QtOptions>
+      </ClCompile_CmdLine>
+    </ItemGroup>
+
+    <!-- Result of parsing command lines, per source file:
+          * ClCompile_CmdLine ::= (Item x ProjectOptions x QtOptions), where:
+             * Item ::= source file
+             * ProjectOptions ::= list of tokens from the compiler command line for Item
+             * QtOptions ::= list of tokens from the Qt additional options -->
+
+    <!-- Flatten results into a list of tokens per source file:
+          * ClOptions ::= (Item x Name x Value), where:
+             * Item  ::= source file
+             * Name  ::= token origin: from compiler command line or from Qt
+             * Value ::= token value -->
+    <Flatten Items="@(ClCompile_CmdLine)" Metadata="ProjectOptions;QtOptions">
+      <Output TaskParameter="Result" ItemName="ClOptions" />
+    </Flatten>
+
+    <!-- Remove non-switch tokens, i.e. tokens that do not start with '/' or '-' -->
+    <ItemGroup>
+      <ClOptions
+        Remove="@(ClOptions)"
+        Condition="!$([System.String]::Copy('%(Value)').StartsWith('-'))
+               AND !$([System.String]::Copy('%(Value)').StartsWith('/'))"/>
+    </ItemGroup>
+
+    <!-- Calculate option id: token without leading '/' or '-', and without trailing '-' -->
+    <ItemGroup>
+      <ClOptions>
+        <OptionId>$([System.String]::Copy('%(Value)').Substring(1).TrimEnd('-'))</OptionId>
+      </ClOptions>
+    </ItemGroup>
+
+    <!-- Split into list of Qt options and list of project options -->
+    <ItemGroup>
+      <QtOptions
+        Include="@(ClOptions->'%(Item)')"
+        Condition="'%(ClOptions.Name)' == 'QtOptions'"/>
+      <ProjectOptions
+        Include="@(ClOptions->'%(Item)')"
+        Condition="'%(ClOptions.Name)' == 'ProjectOptions'"/>
+    </ItemGroup>
+
+    <!-- Find conflicting options, i.e. defined both in Qt options and project options -->
+    <ItemGroup>
+      <QtOptions
+        Condition="'@(QtOptions)' != ''
+               AND '@(ProjectOptions)' != ''
+               AND '%(Item)' != ''
+               AND '%(OptionId)' != ''">
+        <Conflict>true</Conflict>
+      </QtOptions>
+    </ItemGroup>
+
+    <!-- Set additional compiler options for all source files -->
+    <ItemGroup>
+      <ClCompile Condition="'%(Identity)' != '' AND '%(QtOptions.Conflict)' != 'true'">
+        <AdditionalOptions
+          >@(QtOptions->'%(Value)', ' ') @(ClCompile->'%(AdditionalOptions)')</AdditionalOptions>
+      </ClCompile>
+      <ClCompile Condition="'%(AdditionalOptions)' != ''">
+        <AdditionalOptions
+          >$([System.String]::Copy('%(AdditionalOptions)').Trim())</AdditionalOptions>
+      </ClCompile>
+    </ItemGroup>
+
+    <!-- Print result to build log, if requested -->
+    <Message
+      Condition="'$(QtOptionsBuildLog)' == 'true'"
+      Importance="High"
+      Text=" Qt - Additional Compiler Options"/>
+    <Message
+      Condition="'$(QtOptionsBuildLog)' == 'true'
+             AND '%(Identity)' != '' AND '%(QtOptions.Conflict)' != 'true'"
+      Importance="High"
+      Text="    [%(Identity)]: @(QtOptions->'%(Value)', ' ')"/>
+
+    <!-- Clean-up -->
+    <PropertyGroup>
+      <CmdLineParser/>
+      <QtCmdLine/>
+    </PropertyGroup>
+    <ItemGroup>
+      <ClCompile_CmdLine Remove="@(ClCompile_CmdLine)"/>
+      <ClOptions Remove="@(ClOptions)"/>
+      <ProjectOptions Remove="@(ProjectOptions)"/>
+      <QtOptions Remove="@(QtOptions)"/>
+    </ItemGroup>
   </Target>
 
   <!--
   /////////////////////////////////////////////////////////////////////////////////////////////////
-  /// TARGET QtOuterBuild
+  /// TARGET Qt
   /////////////////////////////////////////////////////////////////////////////////////////////////
-  // Run targets in $(QtOuterBuildDependsOn) and then recursively invoke build
+  // Root Qt target
   // -->
-  <Target Name="QtOuterBuild" DependsOnTargets="$(QtOuterBuildDependsOn)">
-    <!--// Invoke inner build: recursive build in second MSBuild instance -->
-    <MSBuild
-      Projects="$(MSBuildProjectFullPath)"
-      Targets="Build"
-      Properties="QtInnerBuild=$(MSBuildProjectFullPath);RandomFileName=$(RandomFileName);BuildProjectReferences=false">
-    </MSBuild>
+  <Target
+    Name="Qt"
+    DependsOnTargets="QtPrepare;QtWork;QtSetAdditionalOptions">
+    <CriticalSection Lock="false" Name="$(ProjectGuid)" />
     <OnError ExecuteTargets="QtLeaveCriticalSection_OnError"/>
   </Target>
-
-  <PropertyGroup
-    Condition="'$(QtInnerBuild)' == '' AND '$(DesignTimeBuild)' != 'true'">
-    <!--// Outer build: invoke inner build -->
-    <BuildDependsOn>
-      $(QtOuterBuildPrepare);
-      QtOuterBuild;
-      $(QtOuterBuildFinalize)
-    </BuildDependsOn>
-    <QtInnerBuild>$(MSBuildProjectFullPath)</QtInnerBuild>
-    <RandomFileName>$([System.IO.Path]::GetRandomFileName())</RandomFileName>
-  </PropertyGroup>
-
-  <PropertyGroup
-    Condition="'$(QtInnerBuild)' != '$(MSBuildProjectFullPath)' AND '$(DesignTimeBuild)' != 'true'">
-    <!--// Dependent project inner build: skip build -->
-    <BuildDependsOn>$(QtOuterBuildPrepare);$(QtOuterBuildFinalize)</BuildDependsOn>
-  </PropertyGroup>
 
   <!--
   /////////////////////////////////////////////////////////////////////////////////////////////////
@@ -633,4 +766,28 @@
   <Target Name="QtLeaveCriticalSection_OnError">
     <CriticalSection Lock="false" Name="$(ProjectGuid)" />
   </Target>
+
+  <!--
+  /////////////////////////////////////////////////////////////////////////////////////////////////
+  /// TARGET QtNatvis
+  /////////////////////////////////////////////////////////////////////////////////////////////////
+  // Copies the .natvis file matching the Qt version and replaces the namespace placeholder
+  // -->
+  <Target Name="QtNatvis" BeforeTargets="Link"
+          Condition="'$(Configuration)' == 'Debug' AND '$(LinkNatvisFile)' == 'true'"
+          Inputs="$(MSBuildProjectFile);$(QtMsBuild)\qt$(QtVersionMajor).natvis.xml"
+          Outputs="$(IntDir)\qt.natvis">
+    <PropertyGroup>
+      <InputFile>$(QtMsBuild)\qt$(QtVersionMajor).natvis.xml</InputFile>
+    </PropertyGroup>
+    <WriteLinesToFile Condition="'$(QtNamespace)' == ''"
+      Overwrite="true"
+      File="$(IntDir)\qt.natvis"
+      Lines="$([System.IO.File]::ReadAllText($(InputFile)).Replace('##NAMESPACE##::',''))" />
+    <WriteLinesToFile Condition="'$(QtNamespace)' != ''"
+      Overwrite="true"
+      File="$(IntDir)\qt.natvis"
+      Lines="$([System.IO.File]::ReadAllText($(InputFile)).Replace('##NAMESPACE##','$(QtNamespace)'))" />
+  </Target>
+
 </Project>

--
Gitblit v1.9.1