如何在MSBuild中正确重写CLCompile处理源文件的方式?
在VS2017中通过自定义.targets文件适配ccache的CLCompile重写方案
核心思路
要让ccache适配VS2017的CL.exe批量编译逻辑,关键是把原批量编译拆成单个文件编译,同时保留项目所有编译参数,且不修改系统级的Microsoft.CppCommon.targets。我们可以通过自定义.targets文件覆盖ClCompile的编译逻辑,实现逐个文件调用ccache包裹CL.exe。
自定义ccache适配.targets文件编写
创建名为CcacheOverride.targets的文件,内容如下:
<?xml version="1.0" encoding="utf-8"?> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <!-- 标记启用ccache重写逻辑 --> <PropertyGroup> <CLTaskOverride>true</CLTaskOverride> </PropertyGroup> <!-- 重写ClCompile编译逻辑,逐个处理源文件 --> <Target Name="CcacheCompile" BeforeTargets="ClCompile" DependsOnTargets="PrepareForBuild"> <Exec Command="ccache.exe cl.exe %(ClCompile.PreprocessorDefinitions) %(ClCompile.AdditionalOptions) /c %(ClCompile.Identity) /Fo%(ClCompile.OutputFile) %(ClCompile.ForcedIncludeFiles)" Condition="'%(ClCompile.ExcludedFromBuild)' != 'true'" WorkingDirectory="$(ProjectDir)" /> </Target> <!-- 禁用原CL编译任务,避免重复编译 --> <PropertyGroup> <ClCompileDependsOn>$(ClCompileDependsOn);CcacheCompile</ClCompileDependsOn> <CLTaskEnabled>false</CLTaskEnabled> </PropertyGroup> </Project>
关键细节说明
- 逐个文件编译:通过
%(ClCompile.Identity)遍历每个源文件,确保ccache能单个处理输入输出,匹配其缓存机制。 - 保留编译参数:完整继承原项目中
ClCompile的所有参数(预定义宏、附加选项、输出路径等),保证编译行为和原项目一致。 - 禁用原CL任务:通过设置
CLTaskEnabled为false,避免原批量编译任务执行,防止重复编译和冲突。
导入到vcxproj项目中
打开你的.vcxproj文件,在末尾</Project>标签前添加以下导入语句:
<Import Project="$(SolutionDir)CcacheOverride.targets" />
(路径可根据实际文件位置调整:若targets文件与vcxproj同目录,替换为$(ProjectDir)CcacheOverride.targets)
验证与调试
- 编译项目时,查看输出日志,若出现
ccache.exe cl.exe的执行记录,说明配置生效。 - 若参数丢失,可在
Exec的Command前添加@echo前缀,打印完整命令行,检查参数传递是否正确。
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

