2009-03-10 19 views
10

Tengo un archivo SLN normal, y estoy compilando bien con msbuild desde la línea de comandos. Hago esto:msbuild SLN y aún obtener salidas de proyecto por separado?

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

Y que vuelca todo en C: \ slnbin, a excepción de sitios web, que se despliegan a C: \ slnbin_PublishedWebsites \.

Lo que me gustaría es no solo tener todos los binarios caídos en el directorio bin, sino también tener cada programa ejecutable con su propia carpeta "desplegada", similar a la que obtiene cada sitio web.

Así, por ejemplo, si tengo los siguientes proyectos: - Común - Lib1 - service1 - de Lib2 - Servicio2

que quiere conseguir:

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

Intenté hacer cosas como "msbuild/p: OutDir = C: \ slnbin \ $ (ProjectName)", pero solo lo trata como un literal y crea un subdirectorio "$ (ProjectName)" real.

Preferiblemente, no tendría que modificar cada proyecto individual y así sucesivamente.

¿Esto es posible? ¿Fácil?

Respuesta

13

Como dijo John Saunders, debe tener un archivo maestro de MSBuild que maneje el proceso.

que aquí hay una muestra usando MSBuild Community Tasks: GetSolutionProjects que obtiene los proyectos para una solución dada

<?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

Esto funciona muy bien para nosotros. Una pregunta: cuando llamas a MSBuild para pasar Projects = "% (ProjectFiles.Fullpath)", ¿es MSBuild lo suficientemente inteligente como para construir solo cada proyecto una sola vez? Por ejemplo, si tiene foo.dll que está en la Solución y otros 4 proyectos de referencia, ¿creará foo.dll una vez, o 4 veces o 5 veces? –

+2

"A diferencia del uso de la tarea Exec para iniciar MSBuild.exe, esta tarea utiliza el mismo proceso de MSBuild para compilar los proyectos secundarios. La lista de destinos ya construidos que se pueden omitir se comparte entre las compilaciones padre e hijo. más rápido porque no se crea un nuevo proceso de MSBuild ". Así que supongo que foo.dll se compilará una vez, pero no estoy seguro. –

+2

¿Cuál es la línea de comando necesaria para construir esto? –

1

Tendrás que hacer esto "a mano". Cree un archivo de proyecto maestro MSBUILD que genere la solución, luego copie todos los resultados de la solución donde los desee. Esto es (más o menos) cómo lo hace Visual Studio Team Build.

+1

Así que no puedo aprovechar el hecho de que los archivos csproj conocen todas sus dependencias? ¿Esto significa que tengo que mantener las dependencias en dos ubicaciones (csprojs y msbuild)? – MichaelGG

Cuestiones relacionadas