2009-03-10 17 views
10

Ho un normale file SLN e sto eseguendo la compilazione con msbuild dalla riga di comando. Faccio questo:msbuild SLN e ottieni ancora output di progetto separati?

C: \ slndir> msbuild/p: OutDir = C: \ slnbin \

Ed discariche tutto in C: \ slnbin, fatta eccezione per i siti web, che vengono distribuite in C: \ slnbin_PublishedWebsites \.

Quello che vorrei è non solo avere tutti i binari lasciati nella directory del cestino, ma anche che ogni programma eseguibile abbia la propria cartella "distribuita", simile a ciò che ottiene ogni sito.

Così, per esempio, se ho i seguenti progetti: - Comune - Lib1 - service1 - LIB2 - Service2

ho wan per ottenere:

C:\slnbin\ // Everything 
    C:\slbin\Deploy\Service1 // Common, Lib1, Service1 
    C:\slbin\Deploy\Service2 // Common, Lib2, Service2 

Ho provato a fare cose come "msbuild/p: OutDir = C: \ slnbin \ $ (ProjectName)", ma lo tratta come un letterale e crea un sottodir effettivo "$ (ProjectName)".

Preferibilmente, non avrei bisogno di modificare ogni singolo progetto e così via.

È possibile? Facile?

risposta

13

Come ha detto John Saunders, è necessario disporre di un file MSBuild master che gestisca il processo.

Ecco un esempio utilizzando MSBuild Community Tasks: GetSolutionProjects che ottiene i progetti per una data soluzione

<?xml version="1.0" encoding="utf-8"?> 
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Package"> 

    <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/> 

    <!-- Specify here, the solution you want to compile--> 
    <ItemGroup> 
    <Solution Include="C:\slndir\solution.sln"/> 
    </ItemGroup> 

    <PropertyGroup> 
    <Platform>AnyCPU</Platform> 
    <Configuration>Debug</Configuration> 

    <!-- Your deployment directory --> 
    <DeployDir>C:\slbin\Deploy</DeployDir> 
    </PropertyGroup> 

    <!-- Gets the projects composing the specified solution --> 
    <Target Name="GetProjectsFromSolution"> 
    <GetSolutionProjects Solution="%(Solution.Fullpath)"> 
     <Output ItemName="ProjectFiles" TaskParameter="Output"/> 
    </GetSolutionProjects> 
    </Target> 

    <Target Name="CompileProject" DependsOnTargets="GetProjectsFromSolution"> 
    <!-- 
     Foreach project files 
     Call MSBuild Build Target specifying the outputDir with the project filename. 
    --> 
    <MSBuild Projects="%(ProjectFiles.Fullpath)" 
      Properties="Platform=$(Platform); 
      Configuration=$(Configuration); 
      OutDir=$(DeployDir)\%(ProjectFiles.Filename)\" 
      Targets="Build"> 
    </MSBuild> 
    </Target> 
</Project> 
+1

Funziona alla grande per noi. Una domanda: quando chiami MSBuild che passa Progetti = "% (ProjectFiles.Fullpath)", MSBuild è abbastanza intelligente da costruire solo ogni progetto una volta sola? Ad esempio, se hai foo.dll che si trova nella Soluzione e viene referenziato da altri 4 progetti, compilerà foo.dll una volta, o 4 volte o 5 volte? –

+2

"A differenza dell'utilizzo del task Exec per avviare MSBuild.exe, questa attività utilizza lo stesso processo MSBuild per creare i progetti figlio.L'elenco di target già esistenti che possono essere saltati è condiviso tra le build padre e figlio. più veloce perché non viene creato nessun nuovo processo MSBuild. " Quindi suppongo che foo.dll verrà compilato una volta ma non ne sono sicuro. –

+2

Qual è la linea di comando necessaria per costruire questo? –

1

Dovrai farlo "a mano". Creare un file di progetto MSBUILD master che crea la soluzione, quindi copia tutti gli output della soluzione dove li desidera. Questo è (approssimativamente) come lo fa Team Build di Visual Studio.

+1

Quindi non posso sfruttare il fatto che i file csproj conoscono tutte le loro dipendenze? Ciò significa che devo mantenere le dipendenze in due posizioni (csprojs e msbuild)? – MichaelGG

Problemi correlati