2013-04-07 20 views
7

Solution1.sln zawiera dwa projekty:MSBuild: Ignoruj ​​cele, które nie istnieją

  • ProjectA.csproj
  • ProjectB.csproj

ProjectB ma cel niestandardowej nazwie "Foo". Chcę uruchomić:

msbuild Solution1.sln/t: Foo

To nie dlatego Projecta nie definiuje "foo" cel.

Czy istnieje sposób, aby rozwiązanie zignorowało brakujący cel? (Np. Nic nie robić, jeśli cel nie istnieje dla konkretnego projektu) bez modyfikowania plików SLN lub plików projektu?

Odpowiedz

6

Istnieje dwuczęściowe rozwiązanie, jeśli nie chcesz edytować rozwiązania lub plików projektu i jesteś zadowolony, że działa z wiersza poleceń MSBuild, ale nie z Visual Studio.

Po pierwsze, błąd pojawia się po uruchomieniu:

MSBuild Solution1.sln /t:Foo 

Czy to nie Projecta nie zawiera cel Foo ale że sama rozwiązanie nie zawiera cel Foo. Jak sugeruje @Jaykul, ustawienie zmiennej środowiskowej MSBuildEmitSolution ujawni domyślne cele zawarte w metaproj rozwiązania.

Używanie metaproj jako inspiracji można przedstawić nowy plik „before.Solution1.sln.targets” obok pliku rozwiązanie (wzór nazwy pliku jest ważne) o treści jak poniżej:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <Target Name="Foo"> 
    <MSBuild Projects="@(ProjectReference)" Targets="Foo" BuildInParallel="True" Properties="CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" SkipNonexistentProjects="%(ProjectReference.SkipNonexistentProjects)" /> 
    </Target> 
</Project> 

Element MSBuild jest głównie kopiowany z rozwiązania Opublikuj cel metaprona. Dostosuj nazwę celu i inne szczegóły, aby pasowały do ​​Twojego scenariusza.

Po utworzeniu tego pliku pojawi się błąd, że ProjectA nie zawiera celu Foo. ProjectB może, ale nie musi, budować w każdym razie w zależności od zależności między projektami.

Po drugie, aby rozwiązać ten problem, musimy nadać każdemu projektowi pusty cel Foo, który zostanie nadpisany w projektach, które już go zawierają.

Robimy to poprzez wprowadzenie innego pliku, np. "EmptyFoo.cele”(nazwa nie ma znaczenia), które wygląda następująco:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <Target Name="Foo" /> 
</Project> 

A potem dostać każdy projekt automatycznego importowania pliku Ta cele poprzez prowadzenie MSBuild z dodatkową własność, np

MSBuild Solution1.sln /t:Foo /p:CustomBeforeMicrosoftCommonTargets=c:\full_path_to\EmptyFoo.targets 

Or dołączyć właściwość CustomerBeforeMicrosoftCommonTargets do atrybutu Właściwości elementu MSBuild w pierwszym pliku celów, gdzie można opcjonalnie podać pełną ścieżkę do właściwości $ (SolutionDir). n przy użyciu dowolnego z domyślnych celów rozwiązania (tj. buduj, przebudowuj, czyść lub publikuj) możesz zainspirować się, w jaki sposób Pipeline publikowania w witrynie MSBuild używa właściwości DeployOnBuild do wywoływania celu publikowania w projektach sieci Web w rozwiązaniu zawierającym inny projekt typy, które nie obsługują publikowania.


Więcej informacji na before.Solution1.sln.targets złożyć tutaj: http://sedodream.com/2010/10/22/MSBuildExtendingTheSolutionBuild.aspx

1

Może nie najlepsza odpowiedź, ale rozsądny hack.

msbuild ProjectA.csproj 
msbuild ProjectB.csproj /t:Foo 
1

Możesz kierować je według nazwy projektu, np./T: projekt: cel (może potrzebować cytatów, nie pamiętam).

Możesz znaleźć wszystkie wygenerowane cele, ustawiając zmienną środowiskową MSBuildEmitSolution = 1 ... co powoduje, że msbuild zapisuje na dysku plik temp.metaproj, który generuje dla twojego rozwiązania. Ten plik ma wszystkie zdefiniowane w nim cele, po prostu otwórz go i spójrz;)

1

Kiedy msbuild buduje rozwiązanie - msbuild emituje tylko ograniczony zestaw celów do jego pliku .metaproj, a afaik - nie możesz budować niestandardowy cel poprzez budowanie pliku sln, musisz użyć oryginalnego project1.csproj lub niestandardowego skryptu budowania.

Powiązane problemy