VS 2017中Build targets仅执行一次的原因咨询
解决VS 2017中MSBuild目标仅触发一次的问题
这个问题其实和MSBuild的增量构建逻辑以及VS的设计时构建行为密切相关,我来拆解原因和解决办法:
一、PreBuild目标只触发一次的核心原因
在VS 2017配套的MSBuild 15.x版本中,SDK-style项目的构建逻辑做了优化:
- 设计时构建触发:项目加载时,VS会执行一次"设计时构建"(用来生成IntelliSense、项目依赖信息等),这时候你的
PreBuild目标会被触发一次。 - 增量构建自动跳过:之后点击Build按钮时,MSBuild默认启用增量构建——如果目标没有指定
Inputs和Outputs,MSBuild会认为该目标已经处于"最新状态",不会重复执行。另外,绑定到PreBuildEvent目标的逻辑在SDK-style项目中也有调整,它本身就不是为每次Build都触发设计的。
二、带Inputs/Outputs的lex/yacc目标失效的可能原因
如果你的lex/yacc集成目标也出现同样问题,大概率是以下情况之一:
Inputs或Outputs的路径配置错误,MSBuild找不到对应文件,导致误判目标已最新;- 生成的
Outputs文件时间戳没有正确更新(比如生成命令执行失败但未抛出错误); - VS的增量构建缓存出现异常,忽略了输入文件的变化。
三、具体解决方案
1. 修复PreBuild目标的触发逻辑
修改目标定义,避开设计时构建并确保每次Build都执行:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> </PropertyGroup> <!-- 用BeforeTargets="Build"替代PreBuildEvent,并排除设计时构建 --> <Target Name="PreBuild" BeforeTargets="Build" Condition="'$(DesignTimeBuild)' != 'true'"> <Exec Command="echo Test" /> </Target> </Project>
Condition="'$(DesignTimeBuild)' != 'true'":确保目标只在实际构建时触发,而非项目加载阶段的设计时构建;BeforeTargets="Build":把目标绑定到Build流程的早期阶段,保证每次Build都会执行。
如果需要强制每次Build都触发(哪怕没有任何文件变化),也可以给目标添加一个临时输出文件,让MSBuild每次都认为需要更新:
<Target Name="PreBuild" BeforeTargets="Build" Inputs="$(MSBuildProjectFile)" Outputs="$(MSBuildProjectDirectory)/.prebuild.tmp"> <Exec Command="echo Test" /> <!-- 生成临时文件,标记目标已执行 --> <Touch Files="$(MSBuildProjectDirectory)/.prebuild.tmp" /> </Target>
2. 修复lex/yacc集成目标
确保Inputs和Outputs配置准确,且生成命令能正确生成输出文件:
<Target Name="GenerateLexYacc" BeforeTargets="CoreCompile" Inputs="MyLexer.l;MyParser.y" Outputs="GeneratedLexer.cs;GeneratedParser.cs"> <Exec Command="lex MyLexer.l -o GeneratedLexer.cs" /> <Exec Command="yacc MyParser.y -o GeneratedParser.cs" /> </Target>
- 验证路径:确保
Inputs里的lex/yacc源文件路径正确,Outputs里的生成文件路径和命令输出一致; - 查看详细日志:如果还是不触发,可以在VS中开启详细构建日志(Tools → Options → Projects and Solutions → Build and Run → 设置MSBuild输出详细度为"Detailed"),Build后查看日志中关于
GenerateLexYacc目标的判断信息,排查是路径错误还是输入输出已最新; - 清理缓存:尝试执行"Clean Solution",然后删除项目的
obj和bin目录,再重新Build,解决可能的缓存异常。
内容的提问来源于stack exchange,提问作者jasnevo
相关产品推荐
相关产品推荐

