将LLVM/Clang编译器整合到Visual Studio中
一、集成clang-cl编译器
clang-cl是兼容微软cl的模式,它支持微软cl编译器的绝大多数编译选项,目前还有部分选项不支持。
从 官网下载编译好的Windows平台安装包,LLVM 6有提供MSBuild集成工具,后续的版本不再提供,所以我们需要先下载LLVM 6并且在安装后把集成工具复制出来,路径在安装目录下的tools目录中。 可以看看目录下的东西:
可以看到支持VS2010、VS2012、VS2013和VS2014(即VS2015),不支持VS2017和VS2019以及VS2010以前的版本,当然可以仔细研究一下这些配置文件,也可以自己做出相应VS版本的支持。(BTW:VS2017有专门的插件可以使用—— LLVM Compiler Toolchain,这个工具目前只支持VS2017)
再从官网下载最新的安装包进行安装,目前最新版本是 LLVM8.0.0,安装新包会自动卸载掉老包。
把之前复制出来的tools目录放回到安装目录下,打开所有的props文件,把
$(LLVMInstallDir)\lib\clang\6.0\lib\windows;
中的路径替换成当前安装的路径,比如安装了8.0.0的则为:
$(LLVMInstallDir)lib\clang\8.0.0\lib\windows;
然后在安装目录新建一个msbuild-bin目录,把bin目录中的clang-cl.exe复制到msbuild-bin目录,并改名为cl.exe
最后执行tools/msbuild/install.bat即可。
此时可以在项目属性中看到LLVM的踪影了,下图是VS2015的项目属性截图:
试试效果:
可以看到clang-cl的输出字样,说明成功了。
这里有一个问题,就是没有编译进度显示,即不知道当前编译的是哪个文件。研究了一下MSBuild,发现输出窗口的编译进度(当前编译的哪个文件)是在MSBuild的Microsoft.Build.CPPTasks.Common.dll中的CL任务调用过程中输出当前编译的文件名的,不是在配置文件中输出的。具体的代码为:
1private void ReadUnicodeOutput(object stateInfo)
2{
3 uint num;
4 byte[] lpBuffer = new byte[0x400];
5 string str = string.Empty;
6 while (NativeMethodsShared.ReadFile(this.unicodePipeReadHandle, lpBuffer, 0x400, out num, NativeMethodsShared.NullIntPtr) && (num != 0))
7 {
8 string str2 = str + Encoding.Unicode.GetString(lpBuffer, 0, (int)num);
9 while (true)
10 {
11 int length = -1;
12 length = str2.IndexOf('\n');
13 if (length == -1)
14 {
15 str = str2;
16 break;
17 }
18 string lineOfText = str2.Substring(0, length);
19 str2 = str2.Substring(length + 1);
20 if ((lineOfText.Length > 0) && lineOfText.EndsWith("\r", StringComparison.Ordinal))
21 {
22 lineOfText = lineOfText.Substring(0, lineOfText.Length - 1);
23 }
24 base.Log.LogMessageFromText(lineOfText, base.StandardOutputImportanceToUse);
25 }
26 }
27 if (!string.IsNullOrEmpty(str))
28 {
29 base.Log.LogMessageFromText(str, base.StandardOutputImportanceToUse);
30 }
31 this.unicodeOutputEnded.Set();
32}
它是利用了MS的CL编译器在编译时会输出文件名的功能,从管道中读取的。而Clang编译器在编译过程中是不会输出当前正在编译的文件名的,从管道中无法读取,所以不能显示当前编译进度。
为了使其显示编译进度,以VS2015为例,需要做出如下处理:
(一)、编写一个MSBuild任务dll
1.新建一个C#类库工程,取名为VSClang 2.新建一个类ClangCl,写下如下代码:
1namespace VSClang
2{
3 using Microsoft.Build.Framework;
4 using System.IO;
5
6 public class ClangCl : Microsoft.Build.CPPTasks.CL
7 {
8 protected override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands)
9 {
10 foreach (ITaskItem item in base.SourcesCompiled)
11 {
12 base.Log.LogMessage(MessageImportance.High, Path.GetFileName(item.ItemSpec), new object[0]);
13 }
14 return base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands);
15 }
16 }
17}
3.编译成功后,将生成的VSClang.dll复制到MSBuild安装目录下与Microsoft.Build.CppTasks.Common.dll同一位置,笔者的在C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140下。
(二)、修改安装前配置(如果已经安装过了,修改后再安装一次即可)
-
修改x64以及Win32目录下toolset-vs2014.props以及toolset-vs2014_xp.props,如下图所示:
-
添加-fdiagnostics-absolute-paths参数是为了让Clang在输出诊断信息是以绝对路径输出源文件,否则在Visual Studio中窗口无法双击诊断信息定位到源文件。
-
添加
1<ObjectFileName>$(IntDir)%(filename).obj</ObjectFileName>
是为了让MSBuild在执行编译任务时一次只编译一个源文件,否则会有多个源文件进入编译任务,输出进度与实际编译进度会不匹配。 2. 修改x64以及Win32目录下toolset-vs2014.targets以及toolset-vs2014_xp.targets, 在
1</Project>
结束标志之前添加如下配置:
1<UsingTask TaskName="ClangCl" AssemblyFile="$(VCTargetsPath)\VSClang.dll"/>
2
3<Target Name="ClCompile"
4 Condition="'@(ClCompile)' != ''"
5 DependsOnTargets="SelectClCompile">
6
7 <PropertyGroup>
8 <CLToolArchitecture Condition="'$(CLToolArchitecture)' == ''">$(VCToolArchitecture)</CLToolArchitecture>
9 <CLDeleteOutputOnExecute Condition="'$(CLDeleteOutputOnExecute)' == ''">true</CLDeleteOutputOnExecute>
10 </PropertyGroup>
11
12 <ItemGroup>
13 <ClNoDependencies Condition="'@(ClNoDependencies)' == '' and '%(ClInclude.NoDependency)' == 'true'" Include="@(ClInclude)"/>
14 <ClNoDependencies Condition="'$(NoDependencies)' != ''" Include="$(NoDependencies)" />
15 </ItemGroup>
16
17 <!-- Delete the pch file if the pdb file has been deleted. This will prevent a compiler warning about obsolete pch. -->
18 <Delete Condition="'%(ClCompile.DebugInformationFormat)' != '' and '%(ClCompile.DebugInformationFormat)' != 'None' and '%(ClCompile.DebugInformationFormat)' != 'OldStyle' and '%(ClCompile.ProgramDataBaseFileName)' != '' and !Exists(%(ClCompile.ProgramDataBaseFileName))"
19 Files="%(ClCompile.PrecompiledHeaderOutputFile)" />
20
21 <!-- Precompiled headers - need to build them first -->
22 <ClangCl Condition="'%(ClCompile.PrecompiledHeader)' == 'Create' and '%(ClCompile.ExcludedFromBuild)'!='true' and '%(ClCompile.CompilerIteration)' == ''"
23 BuildingInIDE ="$(BuildingInsideVisualStudio)"
24 Sources ="@(ClCompile)"
25
26 AdditionalIncludeDirectories ="%(ClCompile.AdditionalIncludeDirectories)"
27 AdditionalOptions ="%(ClCompile.AdditionalOptions)"
28 AdditionalUsingDirectories ="%(ClCompile.AdditionalUsingDirectories)"
29 AssemblerListingLocation ="%(ClCompile.AssemblerListingLocation)"
30 AssemblerOutput ="%(ClCompile.AssemblerOutput)"
31 BasicRuntimeChecks ="%(ClCompile.BasicRuntimeChecks)"
32 BrowseInformation ="%(ClCompile.BrowseInformation)"
33 BrowseInformationFile ="%(ClCompile.BrowseInformationFile)"
34 BufferSecurityCheck ="%(ClCompile.BufferSecurityCheck)"
35 CallingConvention ="%(ClCompile.CallingConvention)"
36 ControlFlowGuard ="%(ClCompile.ControlFlowGuard)"
37 CompileAsManaged ="%(ClCompile.CompileAsManaged)"
38 CompileAsWinRT ="%(ClCompile.CompileAsWinRT)"
39 CompileAs ="%(ClCompile.CompileAs)"
40 DebugInformationFormat ="%(ClCompile.DebugInformationFormat)"
41 DisableLanguageExtensions ="%(ClCompile.DisableLanguageExtensions)"
42 DisableSpecificWarnings ="%(ClCompile.DisableSpecificWarnings)"
43 EnableEnhancedInstructionSet ="%(ClCompile.EnableEnhancedInstructionSet)"
44 EnableFiberSafeOptimizations ="%(ClCompile.EnableFiberSafeOptimizations)"
45 EnableParallelCodeGeneration ="%(ClCompile.EnableParallelCodeGeneration)"
46 EnablePREfast ="%(ClCompile.EnablePREfast)"
47 EnforceTypeConversionRules ="%(ClCompile.EnforceTypeConversionRules)"
48 ErrorReporting ="%(ClCompile.ErrorReporting)"
49 ExceptionHandling ="%(ClCompile.ExceptionHandling)"
50 ExcludedInputPaths ="$(ExcludePath)"
51 ExpandAttributedSource ="%(ClCompile.ExpandAttributedSource)"
52 FavorSizeOrSpeed ="%(ClCompile.FavorSizeOrSpeed)"
53 FloatingPointExceptions ="%(ClCompile.FloatingPointExceptions)"
54 FloatingPointModel ="%(ClCompile.FloatingPointModel)"
55 ForceConformanceInForLoopScope ="%(ClCompile.ForceConformanceInForLoopScope)"
56 ForcedIncludeFiles ="%(ClCompile.ForcedIncludeFiles)"
57 ForcedUsingFiles ="%(ClCompile.ForcedUsingFiles)"
58 FunctionLevelLinking ="%(ClCompile.FunctionLevelLinking)"
59 GenerateXMLDocumentationFiles ="%(ClCompile.GenerateXMLDocumentationFiles)"
60 IgnoreStandardIncludePath ="%(ClCompile.IgnoreStandardIncludePath)"
61 InlineFunctionExpansion ="%(ClCompile.InlineFunctionExpansion)"
62 IntrinsicFunctions ="%(ClCompile.IntrinsicFunctions)"
63 MinimalRebuild ="%(ClCompile.MinimalRebuild)"
64 MultiProcessorCompilation ="%(ClCompile.MultiProcessorCompilation)"
65 ObjectFileName ="%(ClCompile.ObjectFileName)"
66 OmitDefaultLibName ="%(ClCompile.OmitDefaultLibName)"
67 OmitFramePointers ="%(ClCompile.OmitFramePointers)"
68 OpenMPSupport ="%(ClCompile.OpenMPSupport)"
69 Optimization ="%(ClCompile.Optimization)"
70 PrecompiledHeader ="%(ClCompile.PrecompiledHeader)"
71 PrecompiledHeaderFile ="%(ClCompile.PrecompiledHeaderFile)"
72 PrecompiledHeaderOutputFile ="%(ClCompile.PrecompiledHeaderOutputFile)"
73 PREfastAdditionalOptions ="%(ClCompile.PREfastAdditionalOptions)"
74 PREfastAdditionalPlugins ="%(ClCompile.PREfastAdditionalPlugins)"
75 PREfastLog ="%(ClCompile.PREfastLog)"
76 PreprocessKeepComments ="%(ClCompile.PreprocessKeepComments)"
77 PreprocessorDefinitions ="%(ClCompile.PreprocessorDefinitions)"
78 PreprocessSuppressLineNumbers ="%(ClCompile.PreprocessSuppressLineNumbers)"
79 PreprocessToFile ="%(ClCompile.PreprocessToFile)"
80 ProcessorNumber ="%(ClCompile.ProcessorNumber)"
81 ProgramDataBaseFileName ="%(ClCompile.ProgramDataBaseFileName)"
82 RemoveUnreferencedCodeData ="%(ClCompile.RemoveUnreferencedCodeData)"
83 RuntimeLibrary ="%(ClCompile.RuntimeLibrary)"
84 RuntimeTypeInfo ="%(ClCompile.RuntimeTypeInfo)"
85 SDLCheck ="%(ClCompile.SDLCheck)"
86 ShowIncludes ="%(ClCompile.ShowIncludes)"
87 WarningVersion ="%(ClCompile.WarningVersion)"
88 SmallerTypeCheck ="%(ClCompile.SmallerTypeCheck)"
89 StringPooling ="%(ClCompile.StringPooling)"
90 StructMemberAlignment ="%(ClCompile.StructMemberAlignment)"
91 SuppressStartupBanner ="%(ClCompile.SuppressStartupBanner)"
92 TreatSpecificWarningsAsErrors ="%(ClCompile.TreatSpecificWarningsAsErrors)"
93 TreatWarningAsError ="%(ClCompile.TreatWarningAsError)"
94 TreatWChar_tAsBuiltInType ="%(ClCompile.TreatWChar_tAsBuiltInType)"
95 UndefineAllPreprocessorDefinitions ="%(ClCompile.UndefineAllPreprocessorDefinitions)"
96 UndefinePreprocessorDefinitions ="%(ClCompile.UndefinePreprocessorDefinitions)"
97 UseFullPaths ="%(ClCompile.UseFullPaths)"
98 UseUnicodeForAssemblerListing ="%(ClCompile.UseUnicodeForAssemblerListing)"
99 WarningLevel ="%(ClCompile.WarningLevel)"
100 WholeProgramOptimization ="%(ClCompile.WholeProgramOptimization)"
101 WinRTNoStdLib ="%(ClCompile.WinRTNoStdLib)"
102 XMLDocumentationFileName ="%(ClCompile.XMLDocumentationFileName)"
103 CreateHotpatchableImage ="%(CLCompile.CreateHotpatchableImage)"
104
105 TrackerLogDirectory ="%(ClCompile.TrackerLogDirectory)"
106
107 TLogReadFiles ="@(CLTLogReadFiles)"
108 TLogWriteFiles ="@(CLTLogWriteFiles)"
109 ToolExe ="$(CLToolExe)"
110 ToolPath ="$(CLToolPath)"
111 TrackFileAccess ="$(TrackFileAccess)"
112 MinimalRebuildFromTracking ="%(ClCompile.MinimalRebuildFromTracking)"
113 ToolArchitecture ="$(CLToolArchitecture)"
114 TrackerFrameworkPath ="$(CLTrackerFrameworkPath)"
115 TrackerSdkPath ="$(CLTrackerSdkPath)"
116 TrackedInputFilesToIgnore ="@(ClNoDependencies)"
117 DeleteOutputOnExecute ="$(CLDeleteOutputOnExecute)"
118
119 AcceptableNonZeroExitCodes ="%(ClCompile.AcceptableNonZeroExitCodes)"
120 YieldDuringToolExecution ="$(ClYieldDuringToolExecution)"
121 >
122 </ClangCl>
123
124 <!-- Rest of the sources -->
125 <ClangCl Condition="'%(ClCompile.PrecompiledHeader)' != 'Create' and '%(ClCompile.ExcludedFromBuild)'!='true' and '%(ClCompile.CompilerIteration)' == '' and @(ClCompile) != ''"
126 BuildingInIDE ="$(BuildingInsideVisualStudio)"
127 Sources ="@(ClCompile)"
128
129 AdditionalIncludeDirectories ="%(ClCompile.AdditionalIncludeDirectories)"
130 AdditionalOptions ="%(ClCompile.AdditionalOptions)"
131 AdditionalUsingDirectories ="%(ClCompile.AdditionalUsingDirectories)"
132 AssemblerListingLocation ="%(ClCompile.AssemblerListingLocation)"
133 AssemblerOutput ="%(ClCompile.AssemblerOutput)"
134 BasicRuntimeChecks ="%(ClCompile.BasicRuntimeChecks)"
135 BrowseInformation ="%(ClCompile.BrowseInformation)"
136 BrowseInformationFile ="%(ClCompile.BrowseInformationFile)"
137 BufferSecurityCheck ="%(ClCompile.BufferSecurityCheck)"
138 CallingConvention ="%(ClCompile.CallingConvention)"
139 ControlFlowGuard ="%(ClCompile.ControlFlowGuard)"
140 CompileAsManaged ="%(ClCompile.CompileAsManaged)"
141 CompileAsWinRT ="%(ClCompile.CompileAsWinRT)"
142 CompileAs ="%(ClCompile.CompileAs)"
143 DebugInformationFormat ="%(ClCompile.DebugInformationFormat)"
144 DisableLanguageExtensions ="%(ClCompile.DisableLanguageExtensions)"
145 DisableSpecificWarnings ="%(ClCompile.DisableSpecificWarnings)"
146 EnableEnhancedInstructionSet ="%(ClCompile.EnableEnhancedInstructionSet)"
147 EnableFiberSafeOptimizations ="%(ClCompile.EnableFiberSafeOptimizations)"
148 EnableParallelCodeGeneration ="%(ClCompile.EnableParallelCodeGeneration)"
149 EnablePREfast ="%(ClCompile.EnablePREfast)"
150 EnforceTypeConversionRules ="%(ClCompile.EnforceTypeConversionRules)"
151 ErrorReporting ="%(ClCompile.ErrorReporting)"
152 ExceptionHandling ="%(ClCompile.ExceptionHandling)"
153 ExcludedInputPaths ="$(ExcludePath)"
154 ExpandAttributedSource ="%(ClCompile.ExpandAttributedSource)"
155 FavorSizeOrSpeed ="%(ClCompile.FavorSizeOrSpeed)"
156 FloatingPointExceptions ="%(ClCompile.FloatingPointExceptions)"
157 FloatingPointModel ="%(ClCompile.FloatingPointModel)"
158 ForceConformanceInForLoopScope ="%(ClCompile.ForceConformanceInForLoopScope)"
159 ForcedIncludeFiles ="%(ClCompile.ForcedIncludeFiles)"
160 ForcedUsingFiles ="%(ClCompile.ForcedUsingFiles)"
161 FunctionLevelLinking ="%(ClCompile.FunctionLevelLinking)"
162 GenerateXMLDocumentationFiles ="%(ClCompile.GenerateXMLDocumentationFiles)"
163 IgnoreStandardIncludePath ="%(ClCompile.IgnoreStandardIncludePath)"
164 InlineFunctionExpansion ="%(ClCompile.InlineFunctionExpansion)"
165 IntrinsicFunctions ="%(ClCompile.IntrinsicFunctions)"
166 MinimalRebuild ="%(ClCompile.MinimalRebuild)"
167 MultiProcessorCompilation ="%(ClCompile.MultiProcessorCompilation)"
168 ObjectFileName ="%(ClCompile.ObjectFileName)"
169 OmitDefaultLibName ="%(ClCompile.OmitDefaultLibName)"
170 OmitFramePointers ="%(ClCompile.OmitFramePointers)"
171 OpenMPSupport ="%(ClCompile.OpenMPSupport)"
172 Optimization ="%(ClCompile.Optimization)"
173 PrecompiledHeader ="%(ClCompile.PrecompiledHeader)"
174 PrecompiledHeaderFile ="%(ClCompile.PrecompiledHeaderFile)"
175 PrecompiledHeaderOutputFile ="%(ClCompile.PrecompiledHeaderOutputFile)"
176 PREfastAdditionalOptions ="%(ClCompile.PREfastAdditionalOptions)"
177 PREfastAdditionalPlugins ="%(ClCompile.PREfastAdditionalPlugins)"
178 PREfastLog ="%(ClCompile.PREfastLog)"
179 PreprocessKeepComments ="%(ClCompile.PreprocessKeepComments)"
180 PreprocessorDefinitions ="%(ClCompile.PreprocessorDefinitions)"
181 PreprocessSuppressLineNumbers ="%(ClCompile.PreprocessSuppressLineNumbers)"
182 PreprocessToFile ="%(ClCompile.PreprocessToFile)"
183 ProcessorNumber ="%(ClCompile.ProcessorNumber)"
184 ProgramDataBaseFileName ="%(ClCompile.ProgramDataBaseFileName)"
185 RemoveUnreferencedCodeData ="%(ClCompile.RemoveUnreferencedCodeData)"
186 RuntimeLibrary ="%(ClCompile.RuntimeLibrary)"
187 RuntimeTypeInfo ="%(ClCompile.RuntimeTypeInfo)"
188 SDLCheck ="%(ClCompile.SDLCheck)"
189 ShowIncludes ="%(ClCompile.ShowIncludes)"
190 WarningVersion ="%(ClCompile.WarningVersion)"
191 SmallerTypeCheck ="%(ClCompile.SmallerTypeCheck)"
192 StringPooling ="%(ClCompile.StringPooling)"
193 StructMemberAlignment ="%(ClCompile.StructMemberAlignment)"
194 SuppressStartupBanner ="%(ClCompile.SuppressStartupBanner)"
195 TreatSpecificWarningsAsErrors ="%(ClCompile.TreatSpecificWarningsAsErrors)"
196 TreatWarningAsError ="%(ClCompile.TreatWarningAsError)"
197 TreatWChar_tAsBuiltInType ="%(ClCompile.TreatWChar_tAsBuiltInType)"
198 UndefineAllPreprocessorDefinitions ="%(ClCompile.UndefineAllPreprocessorDefinitions)"
199 UndefinePreprocessorDefinitions ="%(ClCompile.UndefinePreprocessorDefinitions)"
200 UseFullPaths ="%(ClCompile.UseFullPaths)"
201 UseUnicodeForAssemblerListing ="%(ClCompile.UseUnicodeForAssemblerListing)"
202 WarningLevel ="%(ClCompile.WarningLevel)"
203 WholeProgramOptimization ="%(ClCompile.WholeProgramOptimization)"
204 WinRTNoStdLib ="%(ClCompile.WinRTNoStdLib)"
205 XMLDocumentationFileName ="%(ClCompile.XMLDocumentationFileName)"
206 CreateHotpatchableImage ="%(CLCompile.CreateHotpatchableImage)"
207
208 TrackerLogDirectory ="%(ClCompile.TrackerLogDirectory)"
209
210 TLogReadFiles ="@(CLTLogReadFiles)"
211 TLogWriteFiles ="@(CLTLogWriteFiles)"
212 ToolExe ="$(CLToolExe)"
213 ToolPath ="$(CLToolPath)"
214 TrackFileAccess ="$(TrackFileAccess)"
215 MinimalRebuildFromTracking ="%(ClCompile.MinimalRebuildFromTracking)"
216 ToolArchitecture ="$(CLToolArchitecture)"
217 TrackerFrameworkPath ="$(CLTrackerFrameworkPath)"
218 TrackerSdkPath ="$(CLTrackerSdkPath)"
219 TrackedInputFilesToIgnore ="@(ClNoDependencies)"
220 DeleteOutputOnExecute ="$(CLDeleteOutputOnExecute)"
221
222 AcceptableNonZeroExitCodes ="%(ClCompile.AcceptableNonZeroExitCodes)"
223 YieldDuringToolExecution ="$(ClYieldDuringToolExecution)"
224 >
225 </ClangCl>
226
227 <OnError Condition="'$(OnXamlPreCompileErrorTarget)' != ''" ExecuteTargets="$(OnXamlPreCompileErrorTarget)" />
228 </Target>
(三)、点击install.bat进行安装
经过这些处理,在VS2015下使用LLVM-vs2014平台工具集即可看到编译进度。
二、集成clang编译器
由于clang-cl编译器是期望与微软的cl编译器兼容的,所以在跨平台方面会有问题,所以最好是直接使用clang编译器,这样各个平台的编译效果会最大程度地一致(目前使用Clang在Windows下编译还是有一些问题,需要特殊处理)。
笔者依旧以VS2015为例来说明,由于VS2015本身是支持Clang编译器的,可以在安装的时候进行选择安装Clang编译器,但是由于编译器版本太低,所以不推荐。我们完全可以安装最新的Clang编译器。
虽然我们没有安装VS自带的Clang编译器,但是VS默认还是安装了Clang的MSBuild编译配置,大家可以看看图示目录下是否有Microsoft.Cpp.Clang.props和Microsoft.Cpp.Clang.targets两个文件,如果没有可以在后面复制。
(一)、添加toolset
在Platforms下的x64以及Win32下添加工具集,比如笔者在x64下添加一个clang工具集,即在
1C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Platforms\x64\PlatformToolsets
目录下新建一个clang目录,并在其中添加Toolset.props和Toolset.targets两个文件,
Toolset.props文件内容如下:
1<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Import Project="$(MSBuildThisFileDirectory)ImportBefore\*.props" Condition="Exists('$(MSBuildThisFileDirectory)ImportBefore')" />
3
4 <PropertyGroup>
5 <ClangTarget>amd64-pc-windows-msvc</ClangTarget>
6 </PropertyGroup>
7
8 <PropertyGroup>
9 <!-- Required for enabling Team Build for packaging Windows Store app projects -->
10 <OutDirWasSpecified Condition=" '$(OutDir)'!='' AND '$(OutDirWasSpecified)'=='' ">true</OutDirWasSpecified>
11 <OutDirWasSpecified Condition=" '$(OutDir)'=='' AND '$(OutDirWasSpecified)'=='' ">false</OutDirWasSpecified>
12
13 <IntDir Condition="'$(IntDir)'=='' AND '$(IntermediateOutputPath)'!=''">$(IntermediateOutputPath)</IntDir>
14 <IntDir Condition="'$(IntDir)'=='' AND '$(IntermediateOutputPath)'==''">$(Platform)\$(Configuration)\</IntDir>
15 <OutDir Condition="'$(OutDir)'=='' AND '$(SolutionDir)' == ''">$(IntDir)</OutDir>
16 <OutDir Condition="'$(OutDir)'=='' AND '$(SolutionDir)' != ''">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
17 </PropertyGroup>
18
19 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.WindowsSDK.props" Condition="Exists('$(VCTargetsPath)\Microsoft.Cpp.WindowsSDK.props')"/>
20 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Common.props" />
21
22 <!-- This sets Clang common defaults. -->
23 <PropertyGroup>
24 <GNUMode>true</GNUMode>
25 <MSVCErrorReport>true</MSVCErrorReport>
26 <ToolsetISenseIdentifier>Clang.Windows</ToolsetISenseIdentifier>
27 </PropertyGroup>
28
29 <PropertyGroup>
30 <VCClangInstallDir Condition="'$(VCClangInstallDir)' == ''">$(VCInstallDir)ClangC2\</VCClangInstallDir>
31 <VCClangBinDir Condition="'$(VCToolArchitecture)' == 'Native64Bit'">$(VCClangInstallDir)bin\amd64</VCClangBinDir>
32 <VCClangBinDir Condition="'$(VCToolArchitecture)' != 'Native64Bit'">$(VCClangInstallDir)bin\x86</VCClangBinDir>
33 </PropertyGroup>
34
35 <ItemDefinitionGroup>
36 <ClCompile>
37 <MSExtensions>false</MSExtensions>
38 <MSCompatibility>false</MSCompatibility>
39 <PreprocessorDefinitions Condition="'$(UseDebugLibraries)' != 'true'">NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
40 <AdditionalOptions>-g -gcodeview -fdiagnostics-absolute-paths -fno-delayed-template-parsing -Xclang -flto-visibility-public-std %(AdditionalOptions)</AdditionalOptions>
41 </ClCompile>
42 </ItemDefinitionGroup>
43
44 <PropertyGroup>
45 <ExecutablePath Condition="'$(ExecutablePath)' == ''">$(VCClangBinDir)\amd64;$(VCClangBinDir);$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(FxCopDir);$(PATH);</ExecutablePath>
46 <IncludePath Condition="'$(IncludePath)' == ''">$(VCClangInstallDir)include;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
47 <ReferencePath Condition="'$(ReferencePath)' == ''">$(VC_ReferencesPath_x64);</ReferencePath>
48 <LibraryPath Condition="'$(LibraryPath)' == ''">$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64</LibraryPath>
49 <LibraryWPath Condition="'$(LibraryWPath)' == ''">$(WindowsSDK_MetadataPath);</LibraryWPath>
50 <SourcePath Condition="'$(SourcePath)' == ''">$(VC_SourcePath);</SourcePath>
51 <ExcludePath Condition="'$(ExcludePath)' == ''">$(VC_IncludePath);$(WindowsSDK_IncludePath);$(MSBuild_ExecutablePath);$(VC_LibraryPath_x64);</ExcludePath>
52 <DebugCppRuntimeFilesPath Condition="'$(DebugCppRuntimeFilesPath)' == ''">$(VCInstallDir)redist\Debug_NonRedist\x64</DebugCppRuntimeFilesPath>
53 </PropertyGroup>
54
55 <Import Project="$(MSBuildThisFileDirectory)ImportAfter\*.props" Condition="Exists('$(MSBuildThisFileDirectory)ImportAfter')" />
56
57 <!-- This is intentially added after ImportAfter. -->
58 <Import Project="$(_PlatformFolder)Platform.Common.props" />
59
60 <!-- This overrides some of the platform defaults. -->
61 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Clang.props" />
62
63 <!-- 重载 -->
64 <ItemDefinitionGroup>
65 <ClCompile>
66 <MSExtensions>true</MSExtensions>
67 <MSCompatibility>true</MSCompatibility>
68 <PositionIndependentCode>false</PositionIndependentCode>
69 <RuntimeTypeInfo>true</RuntimeTypeInfo>
70 <DebugInformationFormat>LineNumber</DebugInformationFormat>
71 <WarningLevel>EnableAllWarnings</WarningLevel>
72 <UseMultiToolTask>true</UseMultiToolTask>
73 </ClCompile>
74 </ItemDefinitionGroup>
75</Project>
Toolset.targets文件内容如下:
1<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2
3 <Import Project="$(MSBuildThisFileDirectory)ImportBefore\*.targets" Condition="Exists('$(MSBuildThisFileDirectory)ImportBefore')" />
4
5 <Import Project="$(VCTargetsPath)\Microsoft.CppCommon.targets" />
6 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Clang.targets" />
7
8 <Import Project="$(MSBuildThisFileDirectory)ImportAfter\*.targets" Condition="Exists('$(MSBuildThisFileDirectory)ImportAfter')" />
9
10</Project>
添加了这两个文件后,就可以在VS中看到工具集了:
这样就大功告成了。如果没有Microsoft.Cpp.Clang.props与Microsoft.Cpp.Clang.targets两个文件,可以从下面复制出来放在
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140
目录即可。
VS 2015所带的Microsoft.Cpp.Clang.props完整内容如下:
1<!--
2***********************************************************************************************
3Microsoft.Cpp.Clang.props
4
5WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
6 created a backup copy. Incorrect changes to this file will make it
7 impossible to load or build your projects from the command-line or the IDE.
8
9Copyright (C) Microsoft Corporation. All rights reserved.
10***********************************************************************************************
11-->
12
13<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
14 <Import Project="$(MSBuildThisFileDirectory)ImportBefore\*.props" Condition="Exists('$(MSBuildThisFileDirectory)ImportBefore')" />
15
16 <ItemDefinitionGroup>
17 <ClCompile>
18 <ClangMode>true</ClangMode>
19 <WarningLevel>EnableAllWarnings</WarningLevel>
20 <DebugInformationFormat Condition="'$(UseDebugLibraries)' == 'true'">FullDebug</DebugInformationFormat>
21 <DebugInformationFormat Condition="'$(UseDebugLibraries)' != 'true'">LineNumber</DebugInformationFormat>
22 <PreprocessorDefinitions Condition="'$(UseDebugLibraries)' == 'true'">NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
23 <Optimization Condition="'$(UseDebugLibraries)' == 'true'">Disabled</Optimization>
24 <Optimization Condition="'$(UseDebugLibraries)' != 'true'">Full</Optimization>
25 <StrictAliasing>false</StrictAliasing>
26 <ProgramDatabaseFileName>$(IntDir)</ProgramDatabaseFileName>
27 <OmitFramePointers Condition="'$(UseDebugLibraries)' == 'true'">false</OmitFramePointers>
28 <OmitFramePointers Condition="'$(UseDebugLibraries)' != 'true'">true</OmitFramePointers>
29 <ExceptionHandling>Enabled</ExceptionHandling>
30 <FunctionLevelLinking Condition="'$(UseDebugLibraries)' == 'true'">false</FunctionLevelLinking>
31 <FunctionLevelLinking Condition="'$(UseDebugLibraries)' != 'true'">true</FunctionLevelLinking>
32 <DataLevelLinking Condition="'$(UseDebugLibraries)' == 'true'">false</DataLevelLinking>
33 <DataLevelLinking Condition="'$(UseDebugLibraries)' != 'true'">true</DataLevelLinking>
34 <BufferSecurityCheck>true</BufferSecurityCheck>
35 <PositionIndependentCode>true</PositionIndependentCode>
36 <UseShortEnums>false</UseShortEnums>
37 <RuntimeTypeInfo>false</RuntimeTypeInfo>
38 <CLanguageStandard>Default</CLanguageStandard>
39 <CppLanguageStandard>Default</CppLanguageStandard>
40 <PrecompiledHeader>NotUsing</PrecompiledHeader>
41 <ObjectFileName>$(IntDir)%(filename).obj</ObjectFileName>
42 <CompileAs>Default</CompileAs>
43 <TreatWarningAsError>false</TreatWarningAsError>
44 <Verbose>false</Verbose>
45 <EnablePREfast Condition="'%(ClCompile.EnablePREfast)' == ''">false</EnablePREfast>
46 <OmitFramePointers Condition="'%(ClCompile.OmitFramePointers)' == ''">false</OmitFramePointers>
47 <MinimalRebuildFromTracking>true</MinimalRebuildFromTracking>
48 <PrecompiledHeaderOutputFileDirectory>$(IntDir)</PrecompiledHeaderOutputFileDirectory>
49 <PrecompiledHeaderOutputFile></PrecompiledHeaderOutputFile>
50 <PrecompiledHeaderCompileAs>CompileAsCpp</PrecompiledHeaderCompileAs>
51 </ClCompile>
52 </ItemDefinitionGroup>
53
54 <Import Project="$(MSBuildThisFileDirectory)ImportAfter\*.props" Condition="Exists('$(MSBuildThisFileDirectory)ImportAfter')" />
55</Project>
Microsoft.Cpp.Clang.targets完整内容如下:
1<!--
2***********************************************************************************************
3Microsoft.Cpp.Clang.targets
4
5WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
6 created a backup copy. Incorrect changes to this file will make it
7 impossible to load or build your projects from the command-line or the IDE.
8
9This file defines the steps/targets required to build Visual C++ projects
10that use Clang Front-End.
11
12Copyright (C) Microsoft Corporation. All rights reserved.
13***********************************************************************************************
14-->
15
16<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
17 <UsingTask TaskName="ClangCompile" AssemblyFile="$(VCTargetsPath)Microsoft.Build.CppTasks.Common.dll"/>
18
19 <!-- *******************************************************************************************
20 Clang Compile
21 ******************************************************************************************* -->
22
23 <Target Name="FixupCLCompileOptions"
24 Condition="'@(ClCompile)' != ''">
25 <ItemGroup>
26 <ClCompile>
27 <PrecompiledHeaderOutputFileDirectory Condition="'%(ClCompile.PrecompiledHeaderOutputFileDirectory)' != '' and !HasTrailingSlash('%(ClCompile.PrecompiledHeaderOutputFileDirectory)')">%(ClCompile.PrecompiledHeaderOutputFileDirectory)\</PrecompiledHeaderOutputFileDirectory>
28 </ClCompile>
29
30 <!-- Add PCH to the list of compiles -->
31 <ClCompilePCH Condition="'%(ClCompile.PrecompiledHeaderFile)' != '' and '%(ClCompile.PrecompiledHeader)' == 'Use'" Include="@(ClCompile->Metadata(PrecompiledHeaderFile)->Fullpath()->Distinct()->ClearMetadata())">
32 <CompileAs/>
33 <ForcedIncludeFiles/>
34 <PrecompiledHeaderFile/>
35 <PrecompiledHeader>Create</PrecompiledHeader>
36 <PrecompiledHeaderCompileAs>%(ClCompile.PrecompiledHeaderCompileAs)</PrecompiledHeaderCompileAs>
37 <PrecompiledHeaderOutputFileDirectory>%(ClCompile.PrecompiledHeaderOutputFileDirectory)</PrecompiledHeaderOutputFileDirectory>
38 <!-- PCH are not part of the build, so exclude the output from the link step. -->
39 <LibCompiled>false</LibCompiled>
40 <LinkCompiled>false</LinkCompiled>
41 </ClCompilePCH>
42
43 <ClCompilePCH>
44 <ObjectFileName>%(ClCompilePCH.PrecompiledHeaderOutputFileDirectory)%(FileName)%(Extension).gch</ObjectFileName>
45 </ClCompilePCH>
46
47 <!-- Add PCH to the force include, and remove from PCH related flags. -->
48 <ClCompile Condition="'%(ClCompile.PrecompiledHeader)' == 'Use' and '$(DesignTimeBuild)' == 'true'">
49 <!-- Clang expect the output pch.h, which it will deduce pch.h.gch) -->
50 <!-- VC intellisense expect the source pch.h -->
51 <ForcedIncludeFiles>%(ClCompile.PrecompiledHeaderFile);%(ClCompile.ForcedIncludeFiles)</ForcedIncludeFiles>
52 <PrecompiledHeaderOutputFile>%(PrecompiledHeaderOutputFileDirectory)%(ClCompile.PrecompiledHeaderFile).gch</PrecompiledHeaderOutputFile>
53 </ClCompile>
54
55 <ClCompile Condition="'%(ClCompile.PrecompiledHeader)' == 'Use' and '$(DesignTimeBuild)' != 'true' and '%(Identity)' != ''">
56 <ForcedIncludeFiles>@(ClCompile->Metadata(PrecompiledHeaderFile)->'%(PrecompiledHeaderOutputFileDirectory)%(FileName)%(Extension)');%(ClCompile.ForcedIncludeFiles)</ForcedIncludeFiles>
57 <!-- Set MultiToolTask scheduler to wait for the PCH to finish. -->
58 <MultiToolTaskDependency>@(ClCompile->Metadata(PrecompiledHeaderFile)->Fullpath()->Distinct()->ClearMetadata())</MultiToolTaskDependency>
59 </ClCompile>
60
61 <!-- Done processing PCH, blank out the unused metadata. -->
62 <ClCompile>
63 <PrecompiledHeaderFile />
64 <PrecompiledHeaderCompileAs />
65 <PrecompiledHeaderOutputFileDirectory />
66 </ClCompile>
67
68 <ClCompilePCH>
69 <PrecompiledHeaderOutputFileDirectory />
70 <RuntimeTypeInfo Condition="'%(ClCompilePCH.PrecompiledHeaderCompileAs)' == 'CompileAsC'" />
71 </ClCompilePCH>
72
73 <ClCompile Condition="'$(DesignTimeBuild)' != 'true'" Include="@(ClCompilePCH)" />
74
75 <ClCompile>
76 <BuildingInIDE>$(BuildingInsideVisualStudio)</BuildingInIDE>
77 <GNUMode>$(GNUMode)</GNUMode>
78 <MSVCErrorReport>$(MSVCErrorReport)</MSVCErrorReport>
79 <GccToolChain>$(GccToolchainPrebuiltPath)</GccToolChain>
80 <Sysroot>$(Sysroot)</Sysroot>
81 <TargetArch>$(ClangTarget)</TargetArch>
82 <MinimalRebuildFromTracking Condition="'$(_BuildActionType)' != 'Build' or '$(ForceRebuild)' == 'true'">false</MinimalRebuildFromTracking>
83 <WarningLevel Condition="'%(WarningLevel)' == 'Level1' or '%(WarningLevel)' == 'Level2' or '%(WarningLevel)' == 'Level3'">EnableAllWarnings</WarningLevel>
84 <CompileAs Condition="'%(ClCompile.CompileAs)' == 'Default' and '%(ClCompile.Extension)' == '.c'">CompileAsC</CompileAs>
85 <CompileAs Condition="'%(ClCompile.CompileAs)' == 'Default' and '%(ClCompile.Extension)' != '.c'">CompileAsCpp</CompileAs>
86 </ClCompile>
87
88 <ClCompile>
89 <!-- Dont pass C standard to C++ and vice versa -->
90 <CLanguageStandard Condition="'%(ClCompile.CompileAs)' == 'CompileAsCpp'"></CLanguageStandard>
91 <CppLanguageStandard Condition="'%(ClCompile.CompileAs)' == 'CompileAsC'"></CppLanguageStandard>
92
93 <!-- C doesn't support 'RuntimeTypeInfo' -->
94 <RuntimeTypeInfo Condition="'%(ClCompile.CompileAs)' == 'CompileAsC'" />
95 </ClCompile>
96
97 <!-- Fixup Windows Runtime Library switches. -->
98 <ClCompile Condition="'$(DesignTimeBuild)' != 'true'">
99 <AdditionalOptions Condition="'%(ClCompile.RuntimeLibrary)' == 'MultiThreaded'">%(ClCompile.AdditionalOptions) -D_MT -Xclang --dependent-lib=libcmt -Xclang --dependent-lib=oldnames</AdditionalOptions>
100 <AdditionalOptions Condition="'%(ClCompile.RuntimeLibrary)' == 'MultiThreadedDebug'">%(ClCompile.AdditionalOptions) -D_DEBUG -D_MT -Xclang --dependent-lib=libcmtd -Xclang --dependent-lib=oldnames</AdditionalOptions>
101 <AdditionalOptions Condition="'%(ClCompile.RuntimeLibrary)' == 'MultiThreadedDLL'">%(ClCompile.AdditionalOptions) -D_MT -D_DLL -Xclang --dependent-lib=msvcrt -Xclang --dependent-lib=oldnames</AdditionalOptions>
102 <AdditionalOptions Condition="'%(ClCompile.RuntimeLibrary)' == 'MultiThreadedDebugDLL'">%(ClCompile.AdditionalOptions) -D_DEBUG -D_MT -D_DLL -Xclang --dependent-lib=msvcrtd -Xclang --dependent-lib=oldnames</AdditionalOptions>
103 </ClCompile>
104 </ItemGroup>
105 </Target>
106
107 <Target Name="ClCompile"
108 Condition="'@(ClCompile)' != ''"
109 DependsOnTargets="SelectClCompile" >
110
111 <PropertyGroup>
112 <CLToolArchitecture Condition="'$(CLToolArchitecture)' == ''">$(VCToolArchitecture)</CLToolArchitecture>
113 <CLDeleteOutputOnExecute Condition="'$(CLDeleteOutputOnExecute)' == ''">true</CLDeleteOutputOnExecute>
114 <ClMutliToolTaskMinimalRebuild>true</ClMutliToolTaskMinimalRebuild>
115 <ClMutliToolTaskMinimalRebuild Condition="'$(_BuildActionType)' != 'Build' or '$(ForceRebuild)' == 'true'">false</ClMutliToolTaskMinimalRebuild>
116 <ProcessorNumber Condition="'$(ProcessorNumber)' == ''">$(CL_MPCount)</ProcessorNumber>
117 </PropertyGroup>
118
119 <ItemGroup>
120 <ClCompile>
121 <!-- Moved to this target to avoid adding add $(IncludePath) for intellisense -->
122 <AdditionalIncludeDirectories>%(ClCompile.AdditionalIncludeDirectories);$(IncludePath)</AdditionalIncludeDirectories>
123 </ClCompile>
124 </ItemGroup>
125
126 <Message Condition="'$(_DebugMessages)' == 'true'" Importance="high" Text="ClCompilePCH = '@(ClCompilePCH)'"/>
127 <Message Condition="'$(_DebugMessages)' == 'true'" Importance="high" Text="ClCompilePCH.ObjectFileName = '%(ClCompilePCH.ObjectFileName)'"/>
128
129 <MultiToolTask Condition="'%(ClCompile.ExcludedFromBuild)' != 'true' and '$(UseMultiToolTask)' == 'true'"
130 TaskName="Microsoft.Build.CPPTasks.ClangCompile"
131 TaskAssemblyName="$(VCTargetsPath)Microsoft.Build.CppTasks.Common.dll"
132 Sources="@(ClCompile)"
133
134 SchedulerVerbose="$(MultiToolTaskVerbose)"
135 SemaphoreProcCount="$(ProcessorNumber)"
136 TrackFileAccess="$(TrackFileAccess)"
137 TrackerLogDirectory="$(TLogLocation)"
138 MinimalRebuildFromTracking="$(ClMutliToolTaskMinimalRebuild)"
139 TLogReadFiles="@(CLTLogReadFiles)"
140 TLogWriteFiles="@(CLTLogWriteFiles)"
141 ToolExe="$(ClangToolExe)"
142 ToolPath="$(ClangToolPath)"
143 ToolArchitecture="$(CLToolArchitecture)"
144 TrackerFrameworkPath="$(CLTrackerFrameworkPath)"
145 TrackerSdkPath="$(CLTrackerSdkPath)"
146 EnableExecuteTool="$(ClangEnableExecuteTool)"
147 >
148 </MultiToolTask>
149
150 <!-- Precompiled headers - need to build them first -->
151 <ClangCompile Condition="'%(ClCompile.PrecompiledHeader)' == 'Create' and '$(UseMultiToolTask)' != 'true'"
152
153 BuildingInIDE = "%(ClCompile.BuildingInsideVisualStudio)"
154 GNUMode="%(ClCompile.GNUMode)"
155 MSVCErrorReport="%(ClCompile.MSVCErrorReport)"
156
157 Sources="@(ClCompile)"
158 AdditionalIncludeDirectories="%(ClCompile.AdditionalIncludeDirectories)"
159 AdditionalOptions="%(ClCompile.AdditionalOptions)"
160 BufferSecurityCheck="%(ClCompile.BufferSecurityCheck)"
161 CLanguageStandard="%(ClCompile.CLanguageStandard)"
162 CppLanguageStandard="%(ClCompile.CppLanguageStandard)"
163 DataLevelLinking="%(ClCompile.DataLevelLinking)"
164 DebugInformationFormat="%(ClCompile.DebugInformationFormat)"
165 ExceptionHandling="%(ClCompile.ExceptionHandling)"
166 FloatABI="%(ClCompile.FloatABI)"
167 ForcedIncludeFiles="%(ClCompile.ForcedIncludeFiles)"
168 FunctionLevelLinking="%(ClCompile.FunctionLevelLinking)"
169 ObjectFileName="%(ClCompile.ObjectFileName)"
170 OmitFramePointers="%(ClCompile.OmitFramePointers)"
171 Optimization="%(ClCompile.Optimization)"
172 PositionIndependentCode="%(ClCompile.PositionIndependentCode)"
173 PrecompiledHeader="%(ClCompile.PrecompiledHeader)"
174 PrecompiledHeaderCompileAs="%(ClCompile.PrecompiledHeaderCompileAs)"
175 PreprocessorDefinitions="%(ClCompile.PreprocessorDefinitions)"
176 RuntimeLibrary="%(ClCompile.RuntimeLibrary)"
177 RuntimeTypeInfo="%(ClCompile.RuntimeTypeInfo)"
178 ShowIncludes="%(ClCompile.ShowIncludes)"
179 StrictAliasing="%(ClCompile.StrictAliasing)"
180 ThumbMode="%(ClCompile.ThumbMode)"
181 TreatWarningAsError="%(ClCompile.TreatWarningAsError)"
182 UndefineAllPreprocessorDefinitions="%(ClCompile.UndefineAllPreprocessorDefinitions)"
183 UndefinePreprocessorDefinitions="%(ClCompile.UndefinePreprocessorDefinitions)"
184 UseShortEnums="%(ClCompile.UseShortEnums)"
185 Verbose="%(ClCompile.Verbose)"
186 WarningLevel="%(ClCompile.WarningLevel)"
187
188 GccToolChain="%(ClCompile.GccToolChain)"
189 Sysroot="%(ClCompile.Sysroot)"
190 TargetArch="%(ClCompile.TargetArch)"
191
192 TrackFileAccess="$(TrackFileAccess)"
193 TrackerLogDirectory="$(TLogLocation)"
194 MinimalRebuildFromTracking="%(ClCompile.MinimalRebuildFromTracking)"
195 TLogReadFiles="@(CLTLogReadFiles)"
196 TLogWriteFiles="@(CLTLogWriteFiles)"
197 ToolExe="$(ClangToolExe)"
198 ToolPath="$(ClangToolPath)"
199 ToolArchitecture="$(CLToolArchitecture)"
200 TrackerFrameworkPath="$(CLTrackerFrameworkPath)"
201 TrackerSdkPath="$(CLTrackerSdkPath)"
202 EnableExecuteTool="$(ClangEnableExecuteTool)"
203 MSExtensions="%(ClCompile.MSExtensions)"
204 MSCompatibility="%(ClCompile.MSCompatibility)"
205 MSCompatibilityVersion="%(ClCompile.MSCompatibilityVersion)"
206 MSCompilerVersion="%(ClCompile.MSCompilerVersion)"
207 >
208 </ClangCompile>
209
210 <ClangCompile Condition="'%(ClCompile.ExcludedFromBuild)' != 'true' and '%(ClCompile.PrecompiledHeader)' != 'Create' and '$(UseMultiToolTask)' != 'true'"
211 BuildingInIDE = "%(ClCompile.BuildingInsideVisualStudio)"
212 GNUMode="%(ClCompile.GNUMode)"
213 MSVCErrorReport="%(ClCompile.MSVCErrorReport)"
214
215 Sources="@(ClCompile)"
216 AdditionalIncludeDirectories="%(ClCompile.AdditionalIncludeDirectories)"
217 AdditionalOptions="%(ClCompile.AdditionalOptions)"
218 BufferSecurityCheck="%(ClCompile.BufferSecurityCheck)"
219 CLanguageStandard="%(ClCompile.CLanguageStandard)"
220 CompileAs="%(ClCompile.CompileAs)"
221 CppLanguageStandard="%(ClCompile.CppLanguageStandard)"
222 DataLevelLinking="%(ClCompile.DataLevelLinking)"
223 DebugInformationFormat="%(ClCompile.DebugInformationFormat)"
224 ExceptionHandling="%(ClCompile.ExceptionHandling)"
225 FloatABI="%(ClCompile.FloatABI)"
226 ForcedIncludeFiles="%(ClCompile.ForcedIncludeFiles)"
227 FunctionLevelLinking="%(ClCompile.FunctionLevelLinking)"
228 ObjectFileName="%(ClCompile.ObjectFileName)"
229 OmitFramePointers="%(ClCompile.OmitFramePointers)"
230 Optimization="%(ClCompile.Optimization)"
231 PositionIndependentCode="%(ClCompile.PositionIndependentCode)"
232 PrecompiledHeader="%(ClCompile.PrecompiledHeader)"
233 PreprocessorDefinitions="%(ClCompile.PreprocessorDefinitions)"
234 RuntimeLibrary="%(ClCompile.RuntimeLibrary)"
235 RuntimeTypeInfo="%(ClCompile.RuntimeTypeInfo)"
236 ShowIncludes="%(ClCompile.ShowIncludes)"
237 StrictAliasing="%(ClCompile.StrictAliasing)"
238 ThumbMode="%(ClCompile.ThumbMode)"
239 TreatWarningAsError="%(ClCompile.TreatWarningAsError)"
240 UndefineAllPreprocessorDefinitions="%(ClCompile.UndefineAllPreprocessorDefinitions)"
241 UndefinePreprocessorDefinitions="%(ClCompile.UndefinePreprocessorDefinitions)"
242 UseShortEnums="%(ClCompile.UseShortEnums)"
243 Verbose="%(ClCompile.Verbose)"
244 WarningLevel="%(ClCompile.WarningLevel)"
245
246 GccToolChain="%(ClCompile.GccToolChain)"
247 Sysroot="%(ClCompile.Sysroot)"
248 TargetArch="%(ClCompile.TargetArch)"
249
250 TrackFileAccess="$(TrackFileAccess)"
251 TrackerLogDirectory="$(TLogLocation)"
252 MinimalRebuildFromTracking="%(ClCompile.MinimalRebuildFromTracking)"
253 TLogReadFiles="@(CLTLogReadFiles)"
254 TLogWriteFiles="@(CLTLogWriteFiles)"
255 ToolExe="$(ClangToolExe)"
256 ToolPath="$(ClangToolPath)"
257 ToolArchitecture="$(CLToolArchitecture)"
258 TrackerFrameworkPath="$(CLTrackerFrameworkPath)"
259 TrackerSdkPath="$(CLTrackerSdkPath)"
260 EnableExecuteTool="$(ClangEnableExecuteTool)"
261 MSExtensions="%(ClCompile.MSExtensions)"
262 MSCompatibility="%(ClCompile.MSCompatibility)"
263 MSCompatibilityVersion="%(ClCompile.MSCompatibilityVersion)"
264 MSCompilerVersion="%(ClCompile.MSCompilerVersion)"
265 >
266 </ClangCompile>
267 </Target>
268
269 <ItemGroup Condition="'$(ConfigurationType)' != 'Utility'">
270 <PropertyPageSchema Condition="'$(ConfigurationType)' != 'Utility'" Include="$(VCTargetsPath)$(LangID)\clang.xml"/>
271 </ItemGroup>
272
273</Project>
(二)、注意事项
通过上面的修改后,基本上可以正常使用了,但是可能会有如下问题
-
由于是使用的VS的头文件,所以需要把MS的兼容模式打开,否则会报错,同时建议把MS的扩展支持也打开(上面的clang工具集配置已经默认打开了这两项)。
-
由于clang默认是不会生成VS调试器可识别的PDB格式,所以要使用VS调试clang生成的程序,需要让Clang生成PDB格式的调试信息,添加:
-g -gcodeview
即可(上面的clang工具集配置已经默认添加了该参数)。
-
如果预编译头文件带路径,需要把路径写全;Clang不需要使用某个CPP来单独创建,直接在项目属性中设置需要使用的预编译头即可。
-
报错:C:\Program Files (x86)\Windows Kits\8.1\Include\um\combaseapi.h(229,21): error : unknown type name ‘IUnknown’ 可以直接在模板前面添加一个声明:
1extern "C++"
2{
3 interface IUnknown; // 这里添加一个声明,以免Clang编译器报错
4 template<typename T> _Post_equal_to_(pp) _Post_satisfies_(return == pp) void** IID_PPV_ARGS_Helper(T** pp)
5 {
6#pragma prefast(suppress: 6269, "Tool issue with unused static_cast")
7 static_cast<IUnknown*>(*pp); // make sure everyone derives from IUnknown
8 return reinterpret_cast<void**>(pp);
9 }
10}
-
关于Boost库的使用
-
如果要使用Boost,需要定义宏:
1BOOST_USE_WINDOWS_H
- 如果在自己的静态库中使用Boost的静态thread库,需要定义宏:
1BOOST_THREAD_USE_LIB
否则在exe项目中使用自己的静态库时会出现链接错误。
1error LNK2001: 无法解析的外部符号 "__declspec(dllimport) public: __cdecl boost::thread::~thread(void)" (__imp_??1thread@boost@@QEAA@XZ)
2error LNK2019: 无法解析的外部符号 "__declspec(dllimport) private: void __cdecl boost::thread::start_thread(void)" (__imp_?start_thread@thread@boost@@AEAAXXZ)
3error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: void __cdecl boost::thread::join(void)" (__imp_?join@thread@boost@@QEAAXXZ)
- 如果使用的是Windows8.1的SDK,项目中原来定义了宏:
1_WIN32_WINNT=0x0501
需要删除,或者定义成
1_WIN32_WINNT=0x0600
否则会出现错误
1boost_1_58_0\boost\thread\win32\thread_primitives.hpp(75,21): error : no member named 'GetTickCount64' in the global namespace; did you mean 'GetTickCount'?
2 using ::GetTickCount64;
3 ~~^
4 C:\Program Files (x86)\Windows Kits\8.1\Include\um\sysinfoapi.h(203,1): note: 'GetTickCount' declared here
5 GetTickCount(
6 ^
7 In file included from <built-in>:1:
参见C:\Program Files (x86)\Windows Kits\8.1\Include\um\sysinfoapi.h(221,1)中GetTickCount64定义:
1#if (_WIN32_WINNT >= 0x0600)
2WINBASEAPI
3ULONGLONG
4WINAPI
5GetTickCount64(
6 VOID
7 );
8#endif
- Boost1.58版会报错:
1boost\thread\win32\thread_primitives.hpp(225,67): error : functions that differ only in their return type cannot be overloaded
可以在thread_primitives.hpp代码:
1#if BOOST_PLAT_WINDOWS_RUNTIME
2#include <thread>
3#endif
的前面添加如下代码:
1#if __clang__
2#ifdef BOOST_PLAT_WINDOWS_RUNTIME
3#undef BOOST_PLAT_WINDOWS_RUNTIME
4#define BOOST_PLAT_WINDOWS_RUNTIME 1
5#endif
6#endif
通过这些修改就大功告成了,当然如果使用其它第三方库,可能会遇到一些问题,就需要自行探索解决了。
祝玩得开心,如果喜欢本文请记得点赞哦!
- 原文作者:Witton
- 原文链接:https://wittonbell.github.io/posts/2019/2019-04-13-将LLVM_Clang编译器整合到Visual-Studio中/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。