<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- By default, binplace our output under the bin/ directory in the root of
       the project. -->
  <PropertyGroup>
    <!-- We're controlling the output paths manually; do not let the rest of VS override them. -->
    <GenerateProjectSpecificOutputFolder>false</GenerateProjectSpecificOutputFolder>

    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
    <!-- C++/WinRT projects get their own project-specific output directories. -->
    <OutDir Condition="'$(OpenConsoleCppWinRTProject)'=='true'">$(SolutionDir)bin\$(Platform)\$(Configuration)\$(ProjectName)\</OutDir>
    <OutputPath>$(OutDir)</OutputPath>

    <IntDir>$(SolutionDir)obj\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
    <IntermediateOutputPath>$(IntDir)</IntermediateOutputPath>

    <!-- Both pairs of OutDir/OutputPath and IntDir/IntermediateOutputPath must be set;
         different parts of the project infrastructure use them (without rhyme or reason.) -->
  </PropertyGroup>

  <PropertyGroup>
    <!-- This one is always set so that non-redirected projects can depend on it. -->
    <OpenConsoleCommonOutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OpenConsoleCommonOutDir>
  </PropertyGroup>

  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="AuditMode|Win32">
      <Configuration>AuditMode</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="AuditMode|x64">
      <Configuration>AuditMode</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Fuzzing|Win32">
      <Configuration>Fuzzing</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>
    <ProjectConfiguration Include="Fuzzing|x64">
      <Configuration>Fuzzing</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="AuditMode|ARM64">
      <Configuration>AuditMode</Configuration>
      <Platform>ARM64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|ARM64">
      <Configuration>Debug</Configuration>
      <Platform>ARM64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|ARM64">
      <Configuration>Release</Configuration>
      <Platform>ARM64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Fuzzing|ARM64">
      <Configuration>Fuzzing</Configuration>
      <Platform>ARM64</Platform>
    </ProjectConfiguration>
  </ItemGroup>

  <PropertyGroup Label="Globals">
    <WindowsTargetPlatformVersion Condition="'$(WindowsTargetPlatformVersion)' == ''">10.0.19041.0</WindowsTargetPlatformVersion>
    <WindowsTargetPlatformMinVersion Condition="'$(WindowsTargetPlatformMinVersion)' == ''">10.0.18362.0</WindowsTargetPlatformMinVersion>
  </PropertyGroup>

  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

  <!-- For ALL build types-->
  <PropertyGroup Label="Configuration">
    <PlatformToolset Condition="$(MSBuildVersion) &lt; '17.0.0'">v142</PlatformToolset>
    <PlatformToolset Condition="$(MSBuildVersion) &gt;= '17.0.0'">v143</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
    <LinkIncremental>false</LinkIncremental>
    <PreferredToolArchitecture>x64</PreferredToolArchitecture>
  </PropertyGroup>

  <ItemDefinitionGroup>
    <ClCompile>
      <PrecompiledHeader>Use</PrecompiledHeader>
      <WarningLevel>Level4</WarningLevel>
      <TreatSpecificWarningsAsErrors>4189;4100;4242;4389;4244</TreatSpecificWarningsAsErrors>
      <!--<WarningLevel>EnableAllWarnings</WarningLevel>-->
      <TreatWarningAsError>true</TreatWarningAsError>
      <!--
        C4103: alignment changed after including header, may be due to missing #pragma pack(pop)
          Caused by a regression in VS 16.10, it detects the use of /pshpack[1248].h/ in system headers.
        C4201: nonstandard extension used: nameless struct/union
          Conhost code uses a lot of nameless structs/unions.
        C4312: 'type cast': conversion from 'A' to 'B' of greater size
          Conhost code converts DWORDs to HANDLEs for instance.
        C4467: usage of ATL attributes is deprecated
          Conhost code still uses ATL.
      -->
      <DisableSpecificWarnings>4103;4201;4312;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
      <PreprocessorDefinitions>_WINDOWS;EXTERNAL_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <SDLCheck>true</SDLCheck>
      <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <AdditionalIncludeDirectories>$(SolutionDir)\src\inc;$(SolutionDir)\dep;$(SolutionDir)\dep\Console;$(SolutionDir)\dep\Win32K;$(SolutionDir)\dep\gsl\include;$(SolutionDir)\dep\wil\include;$(SolutionDir)\oss\chromium;$(SolutionDir)\oss\fmt\include;$(SolutionDir)\oss\dynamic_bitset;$(SolutionDir)\oss\libpopcnt;$(SolutionDir)\oss\interval_tree;$(SolutionDir)\oss\boost\boost_1_73_0;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
      <MultiProcessorCompilation>true</MultiProcessorCompilation>
      <MinimalRebuild>false</MinimalRebuild>
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
      <LanguageStandard>stdcpp17</LanguageStandard>
      <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
      <ControlFlowGuard>Guard</ControlFlowGuard>
    </ClCompile>
    <ResourceCompile>
      <PreprocessorDefinitions>EXTERNAL_BUILD;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ResourceCompile>
    <Link>
      <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
      <SubSystem>Windows</SubSystem>
      <SetChecksum>true</SetChecksum>
      <!-- Force full debugging info (not fastlink) in all configurations.
           Our "App container" or WinRT projects already do this in Release,
           and it can only help in debug. -->
      <GenerateDebugInformation>DebugFull</GenerateDebugInformation>
    </Link>
  </ItemDefinitionGroup>

  <!-- For Debug ONLY -->
  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
    <UseDebugLibraries>true</UseDebugLibraries>
    <LinkIncremental>true</LinkIncremental>
  </PropertyGroup>

  <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
    <ClCompile>
      <Optimization>Disabled</Optimization>
      <PreprocessorDefinitions>_DEBUG;DBG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
  </ItemDefinitionGroup>

  <!-- For Release ONLY -->
  <PropertyGroup Condition="'$(Configuration)'=='Release' Or '$(Configuration)'=='AuditMode' Or '$(Configuration)'=='Fuzzing'" Label="Configuration">
    <UseDebugLibraries>false</UseDebugLibraries>
    <WholeProgramOptimization>true</WholeProgramOptimization>
  </PropertyGroup>

  <ItemDefinitionGroup Condition="'$(Configuration)'=='Release' Or '$(Configuration)'=='AuditMode' Or '$(Configuration)'=='Fuzzing'">
    <ClCompile>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
    </ClCompile>
    <Link>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
      <AdditionalOptions>/debugtype:cv,fixup %(AdditionalOptions)</AdditionalOptions>
    </Link>
  </ItemDefinitionGroup>

  <Import Condition="'$(PgoTarget)' == 'true' And '$(Configuration)' == 'Release'" Project="$(SolutionDir)\src\common.pgo.compile.props" />
  <Import Condition="'$(PgoTarget)' == 'true' And '$(PGOBuildMode)' == 'Optimize'" Project="$(SolutionDir)\tools\PGODatabase\PGO.version.props" />

  <!-- For Win32 (x86) ONLY ... we use all defaults for AMD64. No def for those. -->
  <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
    <ClCompile>
      <PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
  </ItemDefinitionGroup>

  <!-- For our Audit mode -->
  <PropertyGroup Condition="'$(Configuration)'=='AuditMode'">
    <CodeAnalysisRuleSet>$(SolutionDir)\src\StaticAnalysis.ruleset</CodeAnalysisRuleSet>
    <EnableCppCoreCheck>true</EnableCppCoreCheck>
    <RunCodeAnalysis>true</RunCodeAnalysis>
    <CAExcludePath>$(CAExcludePath);$(SolutionDir)\dep;$(SolutionDir)\oss;$(SolutionDir)\packages</CAExcludePath>
    <OpenConsoleVcpkgConfiguration>Release</OpenConsoleVcpkgConfiguration>
    <OpenConsoleTppVcpkgConfiguration>Release</OpenConsoleTppVcpkgConfiguration>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)'=='AuditMode'">
    <ClCompile>
      <EnablePREfast>true</EnablePREfast>
    </ClCompile>
  </ItemDefinitionGroup>

  <PropertyGroup Condition="'$(Configuration)'=='Fuzzing'">
    <OCClangArchitectureName Condition="'$(Platform)'=='x64'">x86_64</OCClangArchitectureName>
    <OCClangArchitectureName Condition="'$(Platform)'=='Win32'">i386</OCClangArchitectureName>
    <OCClangArchitectureName Condition="'$(Platform)'=='x86'">i386</OCClangArchitectureName>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)'=='Fuzzing'">
    <ClCompile>
      <!-- Enable all the ASAN and Coverage flags! -->
      <AdditionalOptions>/fsanitize=address /fsanitize-coverage=inline-bool-flag /fsanitize-coverage=edge /fsanitize-coverage=trace-cmp /fsanitize-coverage=trace-div %(AdditionalOptions)</AdditionalOptions>
      <!-- The fuzzer requires a static CRT -->
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
      <PreprocessorDefinitions>FUZZING_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
    <Link>
      <AdditionalDependencies>libsancov.lib;clang_rt.asan-$(OCClangArchitectureName).lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
  </ItemDefinitionGroup>

  <!-- Sanity check: Make sure the user followed the README and initialized git submodules. -->
  <Target Name="EnsureSubmodulesExist" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references git submodule(s) that are missing on this computer. Use `git submodule update --init --recursive` to download them.  For more information, see https://github.com/microsoft/terminal#building-the-code. </ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('$(SolutionDir)\dep\wil\README.md') Or !Exists('$(SolutionDir)\dep\gsl\README.md')" Text="$([System.String]::Format('$(ErrorText)'))" />
  </Target>

  <Import Project="$(MSBuildThisFileDirectory)..\build\rules\Branding.targets" />
</Project>
