简体   繁体   中英

MSbuild build order issue - pre-build steps first or dependent projects first

I have a project A depending on project B. Project A has some pre-build tasks that is dependent of some generated files from project B. When I build in Visual Studio, no problem. But when using MSBuild.exe, then there is problem because the build order is:

  • A's pre-build steps <- failed because B hasn't been compiled
  • B is compiled <- expected to be executed first
  • A is compiled

Is it the expected behaviour using MSBuild? Is there a way to tell MSBuild to do B first before A's prebuild steps?

I am using VS2010 C# and C++/CLI. I don't think if offeres additional info but here is how it is called:

Running process (C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBUILD.exe "..\..\..\dev\build\MyProj.sln" /t:Clean /p:Configuration=Release;Platform=Win32)

Short answer

Remove your build event, and add something like the following to your project (.csproj):

<Target Name="AfterResolveReferences">
  <Exec Command="echo helloworld" />
</Target>

More info

You can read about customising the build process here: http://msdn.microsoft.com/en-us/library/ms366724%28v=vs.110%29.aspx

The Before Build event is fired before ResolveReferences, so if the project you reference has not already been built by the time it comes to your project's BeforeBuild event, then your BeforeBuild event will fail.

To overcome this, you should use a different entry point to customize the build process. In the above example, I use AfterResolveReferences, since this will ensure that all projects which you reference are already built.

Jack's answer seems to be working, but what I did not like about it is that support for editing the .csproj is not natively supported in the VS UI, other than the awkward "Unload project, Edit project (during which you can't click on your files as you normally would like to), Reload project" model. What I wanted was for the pre-build event to trigger after dependent projects built, and have this work the same in VS as in MSBuild. After struggling with this problem, I found a solution that works for me in MSBuild 4.0.

No matter what I tried, I could not alter the PreBuildEvents target to trigger after the dependent projects finished building. So what I did instead was to disable the PreBuildEvents target, and create a bastardized custom PreBuildEvents target that would run at the appropriate time:

<ItemGroup>
  <ProjectReference Include="..\YourProjectPath\YourProject.csproj">
    <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
  </ProjectReference>
</ItemGroup>
<Target Name="PreBuildEvent" AfterTargets="" BeforeTargets="" />
<Target Name="BastardPreBuildEvent" AfterTargets="ResolveReferences" BeforeTargets="CoreResGen">
  <Exec Command="$(PreBuildEvent)" />
</Target>

this is rather old issue but I've found this simple solution (it may apply for you too) Just add

<PreBuildEventDependsOn>ResolveReferences</PreBuildEventDependsOn>

before

<PreBuildEvent>

Unfortunately this must be done in editor, VS editor does not support it (at version 15.6.2).

This may be old but I recently ran into the same problem. Jack's answer was what I was trying to use but the ResolveReferences target is called when loading the projects in visual studio and this was bad for me because I was doing a fairly long process during my target that I only wanted to do before the build.

The solution I ended up using was similar to VeeTheSecond but a bit less involved:

<Target Name="BeforeBuild" DependsOnTargets="ResolveReferences">
    ... exec something using a dependant project's output exe ...
</Target>

This would force the BeforeBuild target to wait until all dependant projects are actually done building so the exec command can use the dependant project's output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM