Search code examples
visual-c++visual-studio-2012msbuildbuild-process

Can Visual Studio 2012 do a custom build such as: compile project A > compile and link project B > link project A?


I am looking for a way to builds projects in this order with Visual Studio 2012 (C++ but might be a general question):

  • Compile ProjectA (I just need the .objs)
  • Compile and link ProjectB
  • Link ProjectA

I can't simply use a reference/dependency of ProjectA in ProjectB because it will perform the link of ProjectA too early.

I used to do this with VS 2008 this way:

  • PreBuild Event on ProjectB: vcbuild /pass0 /pass1 ProjectA
  • Compile and link ProjectB (which is a dependency of ProjectA)
  • Compile (actually does nothing as it was already built) and link ProjectA

But vcbuild is gone from VS 2012 and I replaced the command with:

msbuild /t:BuildGenerateSources /t:BuildCompile

The problem here is that at the 3rd step where it's supposed to only link (since msbuild already compiled) it now compiles again ProjectA and then links it. Enabling diagnostic verbosity with msbuild showed me this: Forcing rebuild of all source files due to a change in the command line since the last build.. And pretty much no one (including Visual Studio 2010 randomly says the command line changed, and rebuilds) has a solution for this as it's impossible to see what 2 commands are being compared.

The other benefit of doing what I'm looking for directly with Visual Studio (without a prebuild event that launches msbuild in a command line), would be to have compile errors reported to the Errors list and clickable in the Output window.

Maybe under the hood this would use msbuild and Targets specified in vcxprojs but I'd like to know if it's doable at all.

Edit: I have already tried to replace the command calling msbuild by devenv but there is no switch for devenv that can specify compile only (no linking), so it can't be used either.

Edit2: Sound like someone already asked something similar here (no solution) Is it possible for Visual Studio C++ to compile objects without linking


Solution

  • Ok so it can be done by overriding BuildSteps in the .vcxproj and removing the target BuildLink.

    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
          <BuildSteps Condition="'$(BuildSteps)' == '' or '$(SkipLink)'!='false'">
                ResolveReferences;
                PrepareForBuild;
                InitializeBuildStatus;
                BuildGenerateSources;
                BuildCompile;
                <!-- BuildLink; -->
          </BuildSteps>
    </PropertyGroup>
    

    When VS builds it will not perform the link step. The original BuildSteps are defined in C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.BuildSteps.target

    To finally link the project on the command line later (from a build event on another project for example) we call:

    msbuild /t:BuildLink /p:VisualStudioVersion=11.0 /p:Configuration=Debug /p:Platform=x64 /p:SkipLink=false "ProjectA.vcxproj"
    

    Notice that a condition SkipLink has been added to the BuildSteps override so we can specify when to perform the BuildLink and when not to.