| <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | 
 |   <Import Project="$(VCTargetsPath)\Microsoft.CppCommon.targets" /> | 
 |  | 
 |   <PropertyGroup> | 
 |     <!-- Set the path to clang-cl executable based on the value of the project- | 
 |          level setting.  This has to be done in the .targets file since values | 
 |          selected via the settings UI appear in the vcxproj (which is imported | 
 |          before the targets file but after the props file) and we need the path | 
 |          that the user may have overridden in the UI. --> | 
 |     <CLToolExe>$(ClangClExecutable)</CLToolExe> | 
 |   </PropertyGroup> | 
 |  | 
 |   <ItemGroup> | 
 |     <PropertyPageSchema Include="$(VCTargetsPath)$(LangID)\llvm-general.xml"> | 
 |       <Context>Project</Context> | 
 |     </PropertyPageSchema> | 
 |   </ItemGroup> | 
 |  | 
 |   <!-- We hook up a target to run every time ClCompile is about to run, the | 
 |        purpose of which is to sanitize the command line before it gets passed to | 
 |        the compiler.  Some options we silently discard, other options we warn on | 
 |        and then discard, and other options we generate a hard error. | 
 |  | 
 |        We try to keep hard errors to a minimum and reserve it for cases where | 
 |        the option implies fundamentally different assumptions about the way code | 
 |        should be compiled.  This code would probably generate an error anyway, | 
 |        but at least this way we give the user a more useful message about what | 
 |        the actual problem is, rather than relying on some obscure compilation | 
 |        error. | 
 |  | 
 |        For any options that clang-cl discards, we would prefer to not even pass | 
 |        them in on the command line.  So if a user starts with a cl projects and | 
 |        changes the toolset to clang, they could have set options such as /Gm | 
 |        (minimal rebuild), /sdl (Security Checks), etc.  The ClCompile task would | 
 |        then notice this and pass these through to clang-cl.exe.  Clang would of | 
 |        course ignore them, but in some cases (such as /Gm), they would generate | 
 |        -Wunused-command-line-argument warnings, so it's better if we can just | 
 |        strip them from the command line entirely.  This also has the side | 
 |        benefit of making command lines shorter which is always nice when trying | 
 |        to look at the tool output. | 
 |       --> | 
 |   <Target Name="BeforeClCompile" BeforeTargets="ClCompile"> | 
 |     <!-- Warn on /Zi and /ZI, then map them both to /Z7. --> | 
 |     <Warning Condition="'%(ClCompile.DebugInformationFormat)' == 'ProgramDatabase'" | 
 |              File="@(ClCompile)(0,0)" | 
 |              Text="clang-cl does not support /Zi (Program Database).  The file will be compiled as if /Z7 (C7 Compatible Debug Info) had been passed.  Update the Debug Information Format in project settings to silence this warning."/> | 
 |     <Warning Condition="'%(ClCompile.DebugInformationFormat)' == 'EditAndContinue'" | 
 |              File="@(ClCompile)(0,0)" | 
 |            Text="clang-cl does not support /ZI (Program Database for Edit and Continue).  The file will be compiled as if /Z7 (C7 Compatible Debug Info) had been passed.  Update the Debug Information Format in project settings to silence this warning."/> | 
 |  | 
 |     <!-- Warn if Fiber Safe Optimizations are enabled, and then ignore them. --> | 
 |     <Warning Condition="'%(ClCompile.EnableFiberSafeOptimizations)' == 'true'" | 
 |              File="@(ClCompile)(0,0)" | 
 |              Text="clang-cl does not support fiber safe optimizations (/GT).  Disable this option in compatibility settings to silence this warning."/> | 
 |  | 
 |     <!-- Warn if Whole Program Optimization is enabled, and then ignore it. --> | 
 |     <Warning Condition="'%(ClCompile.WholeProgramOptimization)' == 'true'" | 
 |              File="@(ClCompile)(0,0)" | 
 |              Text="clang-cl does not support MSVC Link Time Optimization.  Disable this option in compatibility settings to silence this warning."/> | 
 |  | 
 |     <!-- Warn if Ignore Standard Include Paths is non-empty, then ignore it. --> | 
 |     <Warning Condition="'%(ClCompile.IgnoreStandardIncludePath)' == 'true'" | 
 |              File="@(ClCompile)(0,0)" | 
 |              Text="clang-cl does not support Ignore Standard Include Path (/X).  Disable this option in compatibility settings to silence this warning."/> | 
 |  | 
 |     <!-- Warn if Smaller Type Check is enabled, then ignore it.--> | 
 |     <Warning Condition="'%(ClCompile.SmallerTypeCheck)' == 'true'" | 
 |              File="@(ClCompile)(0,0)" | 
 |              Text="clang-cl does not support Smaller Type Check (/RTCc).  Disable this option in compatibility settings to silence this warning."/> | 
 |  | 
 |     <!-- Warn if Runtime Checks are enabled, then ignore them.--> | 
 |     <Warning Condition="'%(ClCompile.BasicRuntimeChecks)' != 'Default'" | 
 |              File="@(ClCompile)(0,0)" | 
 |              Text="clang-cl does not support Basic Runtime Checks (/RTCu, /RTC1, /RTCs).  Disable this option in compatibility settings to silence this warning."/> | 
 |  | 
 |     <!-- Warn if parallel code generation on #pragma loop is enabled, then ignore. --> | 
 |     <Warning Condition="'(ClCompile.EnableParallelCodeGeneration)' == 'true'" | 
 |              File="@(ClCompile)(0,0)" | 
 |              Text="clang-cl does not support parallel code generation with #pragma loop(hint) (/Qpar).  Disable this option in compatibility settings to silence this warning."/> | 
 |  | 
 |     <!-- Warn if hotpatchable images are turned on --> | 
 |     <Warning Condition="'%(ClCompile.CreateHotpatchableImage)' == 'true'" | 
 |              File="@(ClCompile)(0,0)" | 
 |              Text="clang-cl does not support creating hotpatchable images (/hotpatch).  Disable this option in compatibility settings to silence this warning."/> | 
 |  | 
 |     <!-- Warn if /Zc:forScope- is specified, and then ignore it. --> | 
 |     <Warning Condition="'%(ClCompile.ForceConformanceInForLoopScope)' == 'false'" | 
 |              File="@(ClCompile)(0,0)" | 
 |              Text="clang-cl does not support disabling for loop scope conformance (/Zc:forScope-).  Disable this option in compatibility settings to silence this warning."/> | 
 |  | 
 |     <!-- Warn if /Zc:wchar_t- is specified, and then ignore it. --> | 
 |     <Warning Condition="'%(ClCompile.TreatWChar_tAsBuiltInType)' == 'false'" | 
 |              File="@(ClCompile)(0,0)" | 
 |              Text="clang-cl does not support treating wchar_t as a non builtin type (/Zc:wchar_t-).  Disable this option in compatibility settings to silence this warning."/> | 
 |  | 
 |     <!-- Warn if XML Documentation is generated, and then ignore it. --> | 
 |     <Warning Condition="'%(ClCompile.GenerateXMLDocumentationFiles)' == 'true'" | 
 |              File="@(ClCompile)(0,0)" | 
 |              Text="clang-cl does not support generating xml documentation comment files (/doc).  Disable this option in compatibility settings to silence this warning."/> | 
 |  | 
 |     <!-- Warn if Browse Information is generated, and then ignore it. --> | 
 |     <Warning Condition="'%(ClCompile.BrowseInformation)' == 'true'" | 
 |              File="@(ClCompile)(0,0)" | 
 |              Text="clang-cl does not support generating browse information (/FR).  Disable this option in compatibility settings to silence this warning."/> | 
 |  | 
 |     <!-- Warn if /analyze is passed, then ignore it. --> | 
 |     <Warning Condition="'%(ClCompile.EnablePREfast)' == 'true'" | 
 |              File="@(ClCompile)(0,0)" | 
 |              Text="clang-cl does not support MSVC code analysis functionality (/analyze).  Disable this option in compatibility settings to silence this warning."/> | 
 |  | 
 |     <!-- Error if they're trying to compile this file as managed code. --> | 
 |     <Error Condition="('%(ClCompile.CompileAsManaged)' != 'false') AND ('%(ClCompile.CompileAsManaged)' != '')" | 
 |            File="@(ClCompile)(0,0)" | 
 |            Text="clang-cl does not support compiling managed code (/clr).  This file cannot be compiled."/> | 
 |  | 
 |     <!-- Error if WinRT is being used. --> | 
 |     <Error Condition="('%(ClCompile.CompileAsWinRT)' == 'true') OR ('%(ClCompile.WinRTNoStdLib)' == 'true')" | 
 |            File="@(ClCompile)(0,0)" | 
 |            Text="clang-cl does not support Windows Runtime Language Extensions (/ZW, /ZW:nostdlib).  This file cannot be compiled."/> | 
 |  | 
 |     <!-- Error if OpenMP language extensions are enabled. --> | 
 |     <Error Condition="'%(ClCompile.OpenMPSupport)' == 'true'" | 
 |            File="@(ClCompile)(0,0)" | 
 |            Text="clang-cl does not support OpenMP (/openmp).  This file cannot be compiled."/> | 
 |  | 
 |     <!-- Error if C++ Modules are enabled.  Clang has its own notion of modules that are not compatible. --> | 
 |     <Error Condition="'%(ClCompile.EnableModules)' == 'true'" | 
 |            File="@(ClCompile)(0,0)" | 
 |            Text="clang-cl does not support MSVC Modules (/experimental:module).  This file cannot be compiled."/> | 
 |  | 
 |     <ItemGroup> | 
 |       <ClCompile> | 
 |         <!-- Map /ZI and /Zi to /Z7.  Clang internally does this, so if we were | 
 |              to just pass the option through, clang would work.  The problem is | 
 |              that MSBuild would not.  MSBuild detects /ZI and /Zi and then | 
 |              assumes (rightly) that there will be a compiler-generated PDB (e.g. | 
 |              vc141.pdb).  Since clang-cl will not emit this, MSBuild will always | 
 |              think that the compiler-generated PDB needs to be re-generated from | 
 |              scratch and trigger a full build.  The way to avoid this is to | 
 |              always give MSBuild accurate information about how we plan to | 
 |              generate debug info (which is to always using /Z7 semantics). | 
 |              --> | 
 |         <DebugInformationFormat Condition="'%(ClCompile.DebugInformationFormat)' == 'ProgramDatabase'">OldStyle</DebugInformationFormat> | 
 |         <DebugInformationFormat Condition="'%(ClCompile.DebugInformationFormat)' == 'EditAndContinue'">OldStyle</DebugInformationFormat> | 
 |  | 
 |         <!-- Unset any options that we either silently ignore or warn about due to compatibility. | 
 |              Generally when an option is set to no value, that means "Don't pass an option to the | 
 |              compiler at all." | 
 |              --> | 
 |         <WholeProgramOptimization/> | 
 |         <EnableFiberSafeOptimizations/> | 
 |         <IgnoreStandardIncludePath/> | 
 |         <EnableParallelCodeGeneration/> | 
 |         <ForceConformanceInForLoopScope/> | 
 |         <TreatWChar_tAsBuiltInType/> | 
 |         <SDLCheck/> | 
 |         <GenerateXMLDocumentationFiles/> | 
 |         <BrowseInformation/> | 
 |         <EnablePREfast/> | 
 |         <MinimalRebuild/> | 
 |         <StringPooling/> | 
 |         <ExpandAttributedSource/> | 
 |         <EnforceTypeConversionRules/> | 
 |         <ErrorReporting/> | 
 |         <DisableLanguageExtensions/> | 
 |         <ProgramDataBaseFileName/> | 
 |         <DisableSpecificWarnings/> | 
 |         <TreatSpecificWarningsAsErrors/> | 
 |         <ForcedUsingFiles/> | 
 |         <PREfastLog/> | 
 |         <PREfastAdditionalOptions/> | 
 |         <PREfastAdditionalPlugins/> | 
 |         <MultiProcessorCompilation/> | 
 |         <UseFullPaths/> | 
 |         <RemoveUnreferencedCodeData/> | 
 |  | 
 |         <!-- We can't just unset BasicRuntimeChecks, as that will pass /RTCu to the compiler. | 
 |              We have to explicitly set it to 'Default' to avoid passing anything. --> | 
 |         <BasicRuntimeChecks>Default</BasicRuntimeChecks> | 
 |       </ClCompile> | 
 |     </ItemGroup> | 
 |   </Target> | 
 |  | 
 | </Project> |