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任务调用过程中输出当前编译的文件名的,不是在配置文件中输出的。具体的代码为:
private void ReadUnicodeOutput(object stateInfo)
{
uint num;
byte[] lpBuffer = new byte[0x400];
string str = string.Empty;
while (NativeMethodsShared.ReadFile(this.unicodePipeReadHandle, lpBuffer, 0x400, out num, NativeMethodsShared.NullIntPtr) && (num != 0))
{
string str2 = str + Encoding.Unicode.GetString(lpBuffer, 0, (int)num);
while (true)
{
int length = -1;
length = str2.IndexOf('\n');
if (length == -1)
{
str = str2;
break;
}
string lineOfText = str2.Substring(0, length);
str2 = str2.Substring(length + 1);
if ((lineOfText.Length > 0) && lineOfText.EndsWith("\r", StringComparison.Ordinal))
{
lineOfText = lineOfText.Substring(0, lineOfText.Length - 1);
}
base.Log.LogMessageFromText(lineOfText, base.StandardOutputImportanceToUse);
}
}
if (!string.IsNullOrEmpty(str))
{
base.Log.LogMessageFromText(str, base.StandardOutputImportanceToUse);
}
this.unicodeOutputEnded.Set();
}
它是利用了MS的CL编译器在编译时会输出文件名的功能,从管道中读取的。而Clang编译器在编译过程中是不会输出当前正在编译的文件名的,从管道中无法读取,所以不能显示当前编译进度。
为了使其显示编译进度,以VS2015为例,需要做出如下处理:
1.新建一个C#类库工程,取名为VSClang
2.新建一个类ClangCl,写下如下代码:
namespace VSClang
{
using Microsoft.Build.Framework;
using System.IO;
public class ClangCl : Microsoft.Build.CPPTasks.CL
{
protected override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands)
{
foreach (ITaskItem item in base.SourcesCompiled)
{
base.Log.LogMessage(MessageImportance.High, Path.GetFileName(item.ItemSpec), new object[0]);
}
return base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands);
}
}
}
3.编译成功后,将生成的VSClang.dll复制到MSBuild安装目录下与Microsoft.Build.CppTasks.Common.dll同一位置,笔者的在C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140下。
<ObjectFileName>$(IntDir)%(filename).objObjectFileName>
是为了让MSBuild在执行编译任务时一次只编译一个源文件,否则会有多个源文件进入编译任务,输出进度与实际编译进度会不匹配。
2. 修改x64以及Win32目录下toolset-vs2014.targets以及toolset-vs2014_xp.targets,
在
Project>
结束标志之前添加如下配置:
<UsingTask TaskName="ClangCl" AssemblyFile="$(VCTargetsPath)\VSClang.dll"/>
<Target Name="ClCompile"
Condition="'@(ClCompile)' != ''"
DependsOnTargets="SelectClCompile">
<PropertyGroup>
<CLToolArchitecture Condition="'$(CLToolArchitecture)' == ''">$(VCToolArchitecture)CLToolArchitecture>
<CLDeleteOutputOnExecute Condition="'$(CLDeleteOutputOnExecute)' == ''">trueCLDeleteOutputOnExecute>
PropertyGroup>
<ItemGroup>
<ClNoDependencies Condition="'@(ClNoDependencies)' == '' and '%(ClInclude.NoDependency)' == 'true'" Include="@(ClInclude)"/>
<ClNoDependencies Condition="'$(NoDependencies)' != ''" Include="$(NoDependencies)" />
ItemGroup>
<Delete Condition="'%(ClCompile.DebugInformationFormat)' != '' and '%(ClCompile.DebugInformationFormat)' != 'None' and '%(ClCompile.DebugInformationFormat)' != 'OldStyle' and '%(ClCompile.ProgramDataBaseFileName)' != '' and !Exists(%(ClCompile.ProgramDataBaseFileName))"
Files="%(ClCompile.PrecompiledHeaderOutputFile)" />
ClangCl>
ClangCl>
<OnError Condition="'$(OnXamlPreCompileErrorTarget)' != ''" ExecuteTargets="$(OnXamlPreCompileErrorTarget)" />
Target>
经过这些处理,在VS2015下使用LLVM-vs2014平台工具集即可看到编译进度。
由于clang-cl编译器是期望与微软的cl编译器兼容的,所以在跨平台方面会有问题,所以最好是直接使用clang编译器,这样各个平台的编译效果会最大程度地一致(目前使用Clang在Windows下编译还是有一些问题,需要特殊处理)。
笔者依旧以VS2015为例来说明,由于VS2015本身是支持Clang编译器的,可以在安装的时候进行选择安装Clang编译器,但是由于编译器版本太低,所以不推荐。我们完全可以安装最新的Clang编译器。
虽然我们没有安装VS自带的Clang编译器,但是VS默认还是安装了Clang的MSBuild编译配置,大家可以看看图示目录下是否有Microsoft.Cpp.Clang.props和Microsoft.Cpp.Clang.targets两个文件,如果没有可以在后面复制。
在Platforms下的x64以及Win32下添加工具集,比如笔者在x64下添加一个clang工具集,即在
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Platforms\x64\PlatformToolsets
目录下新建一个clang目录,并在其中添加Toolset.props和Toolset.targets两个文件,
Toolset.props文件内容如下:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildThisFileDirectory)ImportBefore\*.props" Condition="Exists('$(MSBuildThisFileDirectory)ImportBefore')" />
<PropertyGroup>
<ClangTarget>amd64-pc-windows-msvcClangTarget>
PropertyGroup>
<PropertyGroup>
<OutDirWasSpecified Condition=" '$(OutDir)'!='' AND '$(OutDirWasSpecified)'=='' ">trueOutDirWasSpecified>
<OutDirWasSpecified Condition=" '$(OutDir)'=='' AND '$(OutDirWasSpecified)'=='' ">falseOutDirWasSpecified>
<IntDir Condition="'$(IntDir)'=='' AND '$(IntermediateOutputPath)'!=''">$(IntermediateOutputPath)IntDir>
<IntDir Condition="'$(IntDir)'=='' AND '$(IntermediateOutputPath)'==''">$(Platform)\$(Configuration)\IntDir>
<OutDir Condition="'$(OutDir)'=='' AND '$(SolutionDir)' == ''">$(IntDir)OutDir>
<OutDir Condition="'$(OutDir)'=='' AND '$(SolutionDir)' != ''">$(SolutionDir)$(Platform)\$(Configuration)\OutDir>
PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.WindowsSDK.props" Condition="Exists('$(VCTargetsPath)\Microsoft.Cpp.WindowsSDK.props')"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Common.props" />
<PropertyGroup>
<GNUMode>trueGNUMode>
<MSVCErrorReport>trueMSVCErrorReport>
<ToolsetISenseIdentifier>Clang.WindowsToolsetISenseIdentifier>
PropertyGroup>
<PropertyGroup>
<VCClangInstallDir Condition="'$(VCClangInstallDir)' == ''">$(VCInstallDir)ClangC2\VCClangInstallDir>
<VCClangBinDir Condition="'$(VCToolArchitecture)' == 'Native64Bit'">$(VCClangInstallDir)bin\amd64VCClangBinDir>
<VCClangBinDir Condition="'$(VCToolArchitecture)' != 'Native64Bit'">$(VCClangInstallDir)bin\x86VCClangBinDir>
PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<MSExtensions>falseMSExtensions>
<MSCompatibility>falseMSCompatibility>
<PreprocessorDefinitions Condition="'$(UseDebugLibraries)' != 'true'">NDEBUG;%(PreprocessorDefinitions)PreprocessorDefinitions>
<AdditionalOptions>-g -gcodeview -fdiagnostics-absolute-paths -fno-delayed-template-parsing -Xclang -flto-visibility-public-std %(AdditionalOptions)AdditionalOptions>
ClCompile>
ItemDefinitionGroup>
<PropertyGroup>
<ExecutablePath Condition="'$(ExecutablePath)' == ''">$(VCClangBinDir)\amd64;$(VCClangBinDir);$(VC_ExecutablePath_x64);$(WindowsSDK_ExecutablePath);$(VS_ExecutablePath);$(MSBuild_ExecutablePath);$(FxCopDir);$(PATH);ExecutablePath>
<IncludePath Condition="'$(IncludePath)' == ''">$(VCClangInstallDir)include;$(VC_IncludePath);$(WindowsSDK_IncludePath);IncludePath>
<ReferencePath Condition="'$(ReferencePath)' == ''">$(VC_ReferencesPath_x64);ReferencePath>
<LibraryPath Condition="'$(LibraryPath)' == ''">$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64LibraryPath>
<LibraryWPath Condition="'$(LibraryWPath)' == ''">$(WindowsSDK_MetadataPath);LibraryWPath>
<SourcePath Condition="'$(SourcePath)' == ''">$(VC_SourcePath);SourcePath>
<ExcludePath Condition="'$(ExcludePath)' == ''">$(VC_IncludePath);$(WindowsSDK_IncludePath);$(MSBuild_ExecutablePath);$(VC_LibraryPath_x64);ExcludePath>
<DebugCppRuntimeFilesPath Condition="'$(DebugCppRuntimeFilesPath)' == ''">$(VCInstallDir)redist\Debug_NonRedist\x64DebugCppRuntimeFilesPath>
PropertyGroup>
<Import Project="$(MSBuildThisFileDirectory)ImportAfter\*.props" Condition="Exists('$(MSBuildThisFileDirectory)ImportAfter')" />
<Import Project="$(_PlatformFolder)Platform.Common.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Clang.props" />
<ItemDefinitionGroup>
<ClCompile>
<MSExtensions>trueMSExtensions>
<MSCompatibility>trueMSCompatibility>
<PositionIndependentCode>falsePositionIndependentCode>
<RuntimeTypeInfo>trueRuntimeTypeInfo>
<DebugInformationFormat>LineNumberDebugInformationFormat>
<WarningLevel>EnableAllWarningsWarningLevel>
<UseMultiToolTask>trueUseMultiToolTask>
ClCompile>
ItemDefinitionGroup>
Project>
Toolset.targets文件内容如下:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildThisFileDirectory)ImportBefore\*.targets" Condition="Exists('$(MSBuildThisFileDirectory)ImportBefore')" />
<Import Project="$(VCTargetsPath)\Microsoft.CppCommon.targets" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Clang.targets" />
<Import Project="$(MSBuildThisFileDirectory)ImportAfter\*.targets" Condition="Exists('$(MSBuildThisFileDirectory)ImportAfter')" />
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完整内容如下:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildThisFileDirectory)ImportBefore\*.props" Condition="Exists('$(MSBuildThisFileDirectory)ImportBefore')" />
<ItemDefinitionGroup>
<ClCompile>
<ClangMode>trueClangMode>
<WarningLevel>EnableAllWarningsWarningLevel>
<DebugInformationFormat Condition="'$(UseDebugLibraries)' == 'true'">FullDebugDebugInformationFormat>
<DebugInformationFormat Condition="'$(UseDebugLibraries)' != 'true'">LineNumberDebugInformationFormat>
<PreprocessorDefinitions Condition="'$(UseDebugLibraries)' == 'true'">NDEBUG;%(PreprocessorDefinitions)PreprocessorDefinitions>
<Optimization Condition="'$(UseDebugLibraries)' == 'true'">DisabledOptimization>
<Optimization Condition="'$(UseDebugLibraries)' != 'true'">FullOptimization>
<StrictAliasing>falseStrictAliasing>
<ProgramDatabaseFileName>$(IntDir)ProgramDatabaseFileName>
<OmitFramePointers Condition="'$(UseDebugLibraries)' == 'true'">falseOmitFramePointers>
<OmitFramePointers Condition="'$(UseDebugLibraries)' != 'true'">trueOmitFramePointers>
<ExceptionHandling>EnabledExceptionHandling>
<FunctionLevelLinking Condition="'$(UseDebugLibraries)' == 'true'">falseFunctionLevelLinking>
<FunctionLevelLinking Condition="'$(UseDebugLibraries)' != 'true'">trueFunctionLevelLinking>
<DataLevelLinking Condition="'$(UseDebugLibraries)' == 'true'">falseDataLevelLinking>
<DataLevelLinking Condition="'$(UseDebugLibraries)' != 'true'">trueDataLevelLinking>
<BufferSecurityCheck>trueBufferSecurityCheck>
<PositionIndependentCode>truePositionIndependentCode>
<UseShortEnums>falseUseShortEnums>
<RuntimeTypeInfo>falseRuntimeTypeInfo>
<CLanguageStandard>DefaultCLanguageStandard>
<CppLanguageStandard>DefaultCppLanguageStandard>
<PrecompiledHeader>NotUsingPrecompiledHeader>
<ObjectFileName>$(IntDir)%(filename).objObjectFileName>
<CompileAs>DefaultCompileAs>
<TreatWarningAsError>falseTreatWarningAsError>
<Verbose>falseVerbose>
<EnablePREfast Condition="'%(ClCompile.EnablePREfast)' == ''">falseEnablePREfast>
<OmitFramePointers Condition="'%(ClCompile.OmitFramePointers)' == ''">falseOmitFramePointers>
<MinimalRebuildFromTracking>trueMinimalRebuildFromTracking>
<PrecompiledHeaderOutputFileDirectory>$(IntDir)PrecompiledHeaderOutputFileDirectory>
<PrecompiledHeaderOutputFile>PrecompiledHeaderOutputFile>
<PrecompiledHeaderCompileAs>CompileAsCppPrecompiledHeaderCompileAs>
ClCompile>
ItemDefinitionGroup>
<Import Project="$(MSBuildThisFileDirectory)ImportAfter\*.props" Condition="Exists('$(MSBuildThisFileDirectory)ImportAfter')" />
Project>
Microsoft.Cpp.Clang.targets完整内容如下:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="ClangCompile" AssemblyFile="$(VCTargetsPath)Microsoft.Build.CppTasks.Common.dll"/>
<Target Name="FixupCLCompileOptions"
Condition="'@(ClCompile)' != ''">
<ItemGroup>
<ClCompile>
<PrecompiledHeaderOutputFileDirectory Condition="'%(ClCompile.PrecompiledHeaderOutputFileDirectory)' != '' and !HasTrailingSlash('%(ClCompile.PrecompiledHeaderOutputFileDirectory)')">%(ClCompile.PrecompiledHeaderOutputFileDirectory)\PrecompiledHeaderOutputFileDirectory>
ClCompile>
<ClCompilePCH Condition="'%(ClCompile.PrecompiledHeaderFile)' != '' and '%(ClCompile.PrecompiledHeader)' == 'Use'" Include="@(ClCompile->Metadata(PrecompiledHeaderFile)->Fullpath()->Distinct()->ClearMetadata())">
<CompileAs/>
<ForcedIncludeFiles/>
<PrecompiledHeaderFile/>
<PrecompiledHeader>CreatePrecompiledHeader>
<PrecompiledHeaderCompileAs>%(ClCompile.PrecompiledHeaderCompileAs)PrecompiledHeaderCompileAs>
<PrecompiledHeaderOutputFileDirectory>%(ClCompile.PrecompiledHeaderOutputFileDirectory)PrecompiledHeaderOutputFileDirectory>
<LibCompiled>falseLibCompiled>
<LinkCompiled>falseLinkCompiled>
ClCompilePCH>
<ClCompilePCH>
<ObjectFileName>%(ClCompilePCH.PrecompiledHeaderOutputFileDirectory)%(FileName)%(Extension).gchObjectFileName>
ClCompilePCH>
<ClCompile Condition="'%(ClCompile.PrecompiledHeader)' == 'Use' and '$(DesignTimeBuild)' == 'true'">
<ForcedIncludeFiles>%(ClCompile.PrecompiledHeaderFile);%(ClCompile.ForcedIncludeFiles)ForcedIncludeFiles>
<PrecompiledHeaderOutputFile>%(PrecompiledHeaderOutputFileDirectory)%(ClCompile.PrecompiledHeaderFile).gchPrecompiledHeaderOutputFile>
ClCompile>
<ClCompile Condition="'%(ClCompile.PrecompiledHeader)' == 'Use' and '$(DesignTimeBuild)' != 'true' and '%(Identity)' != ''">
<ForcedIncludeFiles>@(ClCompile->Metadata(PrecompiledHeaderFile)->'%(PrecompiledHeaderOutputFileDirectory)%(FileName)%(Extension)');%(ClCompile.ForcedIncludeFiles)ForcedIncludeFiles>
<MultiToolTaskDependency>@(ClCompile->Metadata(PrecompiledHeaderFile)->Fullpath()->Distinct()->ClearMetadata())MultiToolTaskDependency>
ClCompile>
<ClCompile>
<PrecompiledHeaderFile />
<PrecompiledHeaderCompileAs />
<PrecompiledHeaderOutputFileDirectory />
ClCompile>
<ClCompilePCH>
<PrecompiledHeaderOutputFileDirectory />
<RuntimeTypeInfo Condition="'%(ClCompilePCH.PrecompiledHeaderCompileAs)' == 'CompileAsC'" />
ClCompilePCH>
<ClCompile Condition="'$(DesignTimeBuild)' != 'true'" Include="@(ClCompilePCH)" />
<ClCompile>
<BuildingInIDE>$(BuildingInsideVisualStudio)BuildingInIDE>
<GNUMode>$(GNUMode)GNUMode>
<MSVCErrorReport>$(MSVCErrorReport)MSVCErrorReport>
<GccToolChain>$(GccToolchainPrebuiltPath)GccToolChain>
<Sysroot>$(Sysroot)Sysroot>
<TargetArch>$(ClangTarget)TargetArch>
<MinimalRebuildFromTracking Condition="'$(_BuildActionType)' != 'Build' or '$(ForceRebuild)' == 'true'">falseMinimalRebuildFromTracking>
<WarningLevel Condition="'%(WarningLevel)' == 'Level1' or '%(WarningLevel)' == 'Level2' or '%(WarningLevel)' == 'Level3'">EnableAllWarningsWarningLevel>
<CompileAs Condition="'%(ClCompile.CompileAs)' == 'Default' and '%(ClCompile.Extension)' == '.c'">CompileAsCCompileAs>
<CompileAs Condition="'%(ClCompile.CompileAs)' == 'Default' and '%(ClCompile.Extension)' != '.c'">CompileAsCppCompileAs>
ClCompile>
<ClCompile>
<CLanguageStandard Condition="'%(ClCompile.CompileAs)' == 'CompileAsCpp'">CLanguageStandard>
<CppLanguageStandard Condition="'%(ClCompile.CompileAs)' == 'CompileAsC'">CppLanguageStandard>
<RuntimeTypeInfo Condition="'%(ClCompile.CompileAs)' == 'CompileAsC'" />
ClCompile>
<ClCompile Condition="'$(DesignTimeBuild)' != 'true'">
<AdditionalOptions Condition="'%(ClCompile.RuntimeLibrary)' == 'MultiThreaded'">%(ClCompile.AdditionalOptions) -D_MT -Xclang --dependent-lib=libcmt -Xclang --dependent-lib=oldnamesAdditionalOptions>
<AdditionalOptions Condition="'%(ClCompile.RuntimeLibrary)' == 'MultiThreadedDebug'">%(ClCompile.AdditionalOptions) -D_DEBUG -D_MT -Xclang --dependent-lib=libcmtd -Xclang --dependent-lib=oldnamesAdditionalOptions>
<AdditionalOptions Condition="'%(ClCompile.RuntimeLibrary)' == 'MultiThreadedDLL'">%(ClCompile.AdditionalOptions) -D_MT -D_DLL -Xclang --dependent-lib=msvcrt -Xclang --dependent-lib=oldnamesAdditionalOptions>
<AdditionalOptions Condition="'%(ClCompile.RuntimeLibrary)' == 'MultiThreadedDebugDLL'">%(ClCompile.AdditionalOptions) -D_DEBUG -D_MT -D_DLL -Xclang --dependent-lib=msvcrtd -Xclang --dependent-lib=oldnamesAdditionalOptions>
ClCompile>
ItemGroup>
Target>
<Target Name="ClCompile"
Condition="'@(ClCompile)' != ''"
DependsOnTargets="SelectClCompile" >
<PropertyGroup>
<CLToolArchitecture Condition="'$(CLToolArchitecture)' == ''">$(VCToolArchitecture)CLToolArchitecture>
<CLDeleteOutputOnExecute Condition="'$(CLDeleteOutputOnExecute)' == ''">trueCLDeleteOutputOnExecute>
<ClMutliToolTaskMinimalRebuild>trueClMutliToolTaskMinimalRebuild>
<ClMutliToolTaskMinimalRebuild Condition="'$(_BuildActionType)' != 'Build' or '$(ForceRebuild)' == 'true'">falseClMutliToolTaskMinimalRebuild>
<ProcessorNumber Condition="'$(ProcessorNumber)' == ''">$(CL_MPCount)ProcessorNumber>
PropertyGroup>
<ItemGroup>
<ClCompile>
<AdditionalIncludeDirectories>%(ClCompile.AdditionalIncludeDirectories);$(IncludePath)AdditionalIncludeDirectories>
ClCompile>
ItemGroup>
<Message Condition="'$(_DebugMessages)' == 'true'" Importance="high" Text="ClCompilePCH = '@(ClCompilePCH)'"/>
<Message Condition="'$(_DebugMessages)' == 'true'" Importance="high" Text="ClCompilePCH.ObjectFileName = '%(ClCompilePCH.ObjectFileName)'"/>
<MultiToolTask Condition="'%(ClCompile.ExcludedFromBuild)' != 'true' and '$(UseMultiToolTask)' == 'true'"
TaskName="Microsoft.Build.CPPTasks.ClangCompile"
TaskAssemblyName="$(VCTargetsPath)Microsoft.Build.CppTasks.Common.dll"
Sources="@(ClCompile)"
SchedulerVerbose="$(MultiToolTaskVerbose)"
SemaphoreProcCount="$(ProcessorNumber)"
TrackFileAccess="$(TrackFileAccess)"
TrackerLogDirectory="$(TLogLocation)"
MinimalRebuildFromTracking="$(ClMutliToolTaskMinimalRebuild)"
TLogReadFiles="@(CLTLogReadFiles)"
TLogWriteFiles="@(CLTLogWriteFiles)"
ToolExe="$(ClangToolExe)"
ToolPath="$(ClangToolPath)"
ToolArchitecture="$(CLToolArchitecture)"
TrackerFrameworkPath="$(CLTrackerFrameworkPath)"
TrackerSdkPath="$(CLTrackerSdkPath)"
EnableExecuteTool="$(ClangEnableExecuteTool)"
>
MultiToolTask>
ClangCompile>
ClangCompile>
Target>
<ItemGroup Condition="'$(ConfigurationType)' != 'Utility'">
<PropertyPageSchema Condition="'$(ConfigurationType)' != 'Utility'" Include="$(VCTargetsPath)$(LangID)\clang.xml"/>
ItemGroup>
Project>
通过上面的修改后,基本上可以正常使用了,但是可能会有如下问题
-g -gcodeview
即可(上面的clang工具集配置已经默认添加了该参数)。
extern "C++"
{
interface IUnknown; // 这里添加一个声明,以免Clang编译器报错
template<typename T> _Post_equal_to_(pp) _Post_satisfies_(return == pp) void** IID_PPV_ARGS_Helper(T** pp)
{
#pragma prefast(suppress: 6269, "Tool issue with unused static_cast")
static_cast<IUnknown*>(*pp); // make sure everyone derives from IUnknown
return reinterpret_cast<void**>(pp);
}
}
BOOST_USE_WINDOWS_H
BOOST_THREAD_USE_LIB
否则在exe项目中使用自己的静态库时会出现链接错误。
error LNK2001: 无法解析的外部符号 "__declspec(dllimport) public: __cdecl boost::thread::~thread(void)" (__imp_??1thread@boost@@QEAA@XZ)
error LNK2019: 无法解析的外部符号 "__declspec(dllimport) private: void __cdecl boost::thread::start_thread(void)" (__imp_?start_thread@thread@boost@@AEAAXXZ)
error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: void __cdecl boost::thread::join(void)" (__imp_?join@thread@boost@@QEAAXXZ)
_WIN32_WINNT=0x0501
需要删除,或者定义成
_WIN32_WINNT=0x0600
否则会出现错误
boost_1_58_0\boost\thread\win32\thread_primitives.hpp(75,21): error : no member named 'GetTickCount64' in the global namespace; did you mean 'GetTickCount'?
using ::GetTickCount64;
~~^
C:\Program Files (x86)\Windows Kits\8.1\Include\um\sysinfoapi.h(203,1): note: 'GetTickCount' declared here
GetTickCount(
^
In file included from :1:
参见C:\Program Files (x86)\Windows Kits\8.1\Include\um\sysinfoapi.h(221,1)中GetTickCount64定义:
#if (_WIN32_WINNT >= 0x0600)
WINBASEAPI
ULONGLONG
WINAPI
GetTickCount64(
VOID
);
#endif
boost\thread\win32\thread_primitives.hpp(225,67): error : functions that differ only in their return type cannot be overloaded
#if BOOST_PLAT_WINDOWS_RUNTIME
#include
#endif
的前面添加如下代码:
#if __clang__
#ifdef BOOST_PLAT_WINDOWS_RUNTIME
#undef BOOST_PLAT_WINDOWS_RUNTIME
#define BOOST_PLAT_WINDOWS_RUNTIME 1
#endif
#endif
通过这些修改就大功告成了,当然如果使用其它第三方库,可能会遇到一些问题,就需要自行探索解决了。
祝玩得开心,如果喜欢本文请记得点赞哦!