Build MSBuild target without dependencies

2019-01-17 15:04发布

问题:

Is there any way I can tell MSBuild 4.0 to build a target, but ignore any dependencies? I just want to build that target itself, nothing else.

回答1:

I would like to reiterate @EMP's solution (and I can't vote him up due to my puny reputation).

The correct way to avoid MSBuild's default behavior of rebuilding all the dependencies listed in the project file is to set the BuildProjectReferences property to false.

In his answer he invokes MSBuild from within an MSBuild script; here's an example from the command line:

MSBuild myproj.csproj /p:Configuration=Debug /p:BuildProjectReferences=false /t:Build


回答2:

It turns out the built-in Build target checks a property named BuildProjectReferences to tell whether to build references or not. I do need to run Build on the project itself (otherwise it doesn't work), just not on its dependencies. I ended up calling:

<MSBuild Projects="MyCloudProject.ccproj" Targets="CorePublish" Properties="Configuration=$(Configuration); BuildProjectReferences=false" />


回答3:

It may be possible to override the built-in target, add your own condition, and have your target duplicate the original, but this can get rather involved. If you can track down a single dependent built-in target this can be maintainable. Sometimes these "core" targets consist of nothing more than a list of DependsOnTargets, and sometimes even those are defined in a property, so overrideing it and adding a condition where they are missing is trivial. Sometimes though you need to do a big cut-and-paste to get it right.

Basically, MSBuild will only maintain the last target defined of any given name, so find where your project is importing the .target file that includes the target you want to override, then put your own .target file import that contains the override after it.

For example, adding a condition to the "CoreBuild" target from Microsoft.Common.targets is as easy as this, while keeping the same behavior otherwise (the Target condition with the $(SkipCoreBuild) property below):

<Target
    Name="CoreBuild"
    Condition="'$(SkipCoreBuild)' != 'true'"
    DependsOnTargets="$(CoreBuildDependsOn)">

    <OnError ExecuteTargets="_TimeStampAfterCompile;PostBuildEvent"
        Condition="'$(RunPostBuildEvent)'=='Always' or
            '$(RunPostBuildEvent)'=='OnOutputUpdated'"
        />
    <OnError ExecuteTargets="_CleanRecordFileWrites" />
</Target>

Placing the above in your own targets file and importing it in a C# project after the standard...

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

... will override the default implementation that doesn't have the condition you need to selectively disable it.

In any case, if you find a target that doesn't allow you to modify the condition, I would file a bug on Connect describing what you are trying to do, the MSBuild folks can be pretty responsive to this sort of thing (over time).



回答4:

It depends on the target you want to build.
If the target is builtin and has dependencies (like "Build") you cann't remove dependencies.
If it's your own target you can easily implement it:

<Target Name="YourTargetWithDependencies" 
        DependsOnTargets="YourTargetDependencies;YourTarget">
</Target>

<Target Name="YourTarget" >
</Target>

For CorePublish in Azure cloud computing project as well as any other with customizable DependsOn targets you can try to change the project to modify default list of dependencies:

<Target Name=CallPublish>
      <!-- Modified list of dependencies. Build is skipped here. -->
      <PropertyGroup>
        <CustomCorePublishDependsOn>
          PrepareForPackaging;
          CheckRoleInstanceCount;
          CopyServiceDefinitionAndConfiguration;
          ConfigureWebDeploy;
          IntelliTrace;
        </CustomCorePublishDependsOn>
      </PropertyGroup>

      <MSBuild Projects="$(MSBuildProjectFullPath)"
               Targets="CorePublish"
               Properties="CorePublishDependsOn=$(CustomCorePublishDependsOn);Configuration=$(Configuration);Platform=$(Platform)">
</Target>


回答5:

Usually a target's dependencies are specified with a property, eg:

<Target Name="Foo" DependsOnTargets="$(FooDependsOn)">..</Target>

In such a case you can invoke msbuild as

msbuild bar.proj /p:FooDependsOn=

which sets that property to nothing, and so no dependencies.