Udostępnij przez


Uruchom cel dokładnie raz

Jeśli tworzysz projekt platformy .NET dla wielu platform przy użyciu wielotargetowania zestawu .NET SDK, zazwyczaj każda kompilacja jest kompletną kompilacją wszystkich odpowiednich celów. Jednak w niektórych przypadkach chcesz, aby określony cel był uruchamiany tylko raz, na przykład cel, który inkrementuje wersję.

Konfigurowanie obiektów docelowych

Przedstawione tutaj rozwiązanie uruchamia MyBeforeBuildTarget tylko raz, niezależnie od tego, czy jest budowany pojedynczy framework, czy też budowane są wiele frameworków, bez zmiany w samym obiekcie docelowym.

  1. Dodaj wyrażenia Condition, które używają właściwości Multitarget, aby określić, czy utworzyć wiele struktur, czy tylko jedną.

    <PropertyGroup>
     <TargetFrameworks Condition=" '$(Multitarget)' == 'true' ">net7.0;net8.0</TargetFrameworks>
     <TargetFramework  Condition=" '$(Multitarget)' != 'true' ">net8.0</TargetFramework>
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
     <SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
    </PropertyGroup>
    
  2. Dodaj trzy cele do projektu, twój, który chcesz uruchomić tylko raz (MyBeforeBuildTarget), pozostałe dwa, jak pokazano tutaj.

    <Project Sdk="Microsoft.NET.Sdk">
    
    <PropertyGroup>
        <TargetFrameworks Condition=" '$(Multitarget)' == 'true' ">net7.0;net8.0</TargetFrameworks>
        <TargetFramework  Condition=" '$(Multitarget)' != 'true' ">net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
    </PropertyGroup>
    
    <Target Name="MyBeforeBuildTarget">
        <Warning Text="MyBeforeBuildTarget" />
    </Target>
    
    <Target Name="BuildMyBeforeBuildTargetBeforeOuterBuild"
            DependsOnTargets="MyBeforeBuildTarget"
            BeforeTargets="DispatchToInnerBuilds"
            />
    
    <Target Name="BuildMyBeforeBuildTargetBeforeInnerBuild"
            BeforeTargets="BeforeBuild">
       <MSBuild Projects="$(MSBuildProjectFullPath)"
             Targets="MyBeforeBuildTarget"
             RemoveProperties="TargetFramework" />
    </Target>
    
    </Project>
    

Ta metoda opiera się na sposobie działania wielotargetowania w projektach zestawu SDK platformy .NET. Zewnętrzna kompilacja ustawia TargetFrameworks, ale wewnętrzne kompilacje ustawiają TargetFramework dla każdego żądanego celu. W związku z tym, aby skompilować raz dla kompilacji wewnętrznej, usuń TargetFramework właściwość . Spowoduje to wywołanie kompilacji zewnętrznej z żądanym elementem docelowym zamiast uruchamiania go w każdej kompilacji wewnętrznej.

Budowanie projektu

  1. Z poziomu wiersza polecenia skompiluj bez wielotargetowania:

    dotnet msbuild -nologo -tl:false -bl -clp:nosummary -p:Multitarget=false

    ExtendMaybeMultitargeted.csproj(12,5): warning : MyBeforeBuildTarget
    ExtendMaybeMultitargeted -> ExtendMaybeMultitargeted\bin\Debug\net8.0\ExtendMaybeMultitargeted.dll
    
  2. Teraz spróbuj utworzyć za pomocą wielotargetingu:

    dotnet msbuild -nologo -tl:false -bl -clp:nosummary -p:Multitarget=true

    ExtendMaybeMultitargeted\ExtendMaybeMultitargeted.csproj(12,5): warning : MyBeforeBuildTarget
      ExtendMaybeMultitargeted -> ExtendMaybeMultitargeted\bin\Debug\net8.0\ExtendMaybeMultitargeted.dll
      ExtendMaybeMultitargeted -> ExtendMaybeMultitargeted\bin\Debug\net7.0\ExtendMaybeMultitargeted.dll
    

Jak widać w danych wyjściowych, ostrzeżenie było emitowane tylko raz, niezależnie od tego, czy użyto multitargetingu, czy nie.

Przedstawione tutaj rozwiązanie działa, ponieważ element docelowy, który chcesz uruchomić jeden raz, MyBeforeBuildTarget jest powiązany z innym elementem docelowym przy użyciu BeforeTargets, ale niezależnie od tego, czy wielotargetowanie ma wartość true, czy false, element docelowy, do którego jest dołączony, zawsze uruchamia się raz. Kompilacja zewnętrzna jest pojedynczym elementem docelowym, DispatchToInnerBuilds, który uruchamia wewnętrzną kompilację dla wszystkich różnych struktur określonych w TargetFrameworks; DispatchToInnerBuilds sam jest uruchamiany tylko raz dla kompilacji wielokierunkowej, ale w przypadku pojedynczej docelowej kompilacji w ogóle nie jest uruchamiany. W przypadku pojedynczej docelowej kompilacji należy ustawić BeforeTargets na BeforeBuild tak jak zwykle, aby uruchomić cel, ale Condition upewnia się, że jest on dołączony tylko do BeforeBuild w pojedynczym przypadku docelowym.

zestaw .NET SDK wielotargetingowy