msbuild - microsoft - visual studio installer
Dirigirse a diferentes marcos utilizando MSBuild genera problemas con las dependencias (3)
Tengo un pequeño proyecto, y quiero tener 2 versiones compiladas de ese proyecto:
- uno que apunte al framework .NET 2.0
- uno que apunta al framework .NET 3.5
Todo va bien; He puesto mi proyecto en integración continua (usando CC.NET) y he creado 2 ''proyectos'' CC.NET. Un proyecto para cada objetivo-marco.
No entraré demasiado en detalles (irrelevantes), pero mi solución está configurada para apuntar al framework .NET 3.5 en VS.NET.
Tengo 2 tareas msbuild:
- una tarea que crea la solución para .NET 3.5 (simple y fácil)
una tarea que construye la solución para .NET 2.0
En esta tarea, llamo a MSBuild y especifico que TargetFrameworkVersion debe ser v2.0. También defino algunas condiciones de compilación adicionales (de modo que el código específico .NET3.5 no se construye en el ensamblado de destino .NET2.0).
Hasta aquí todo bien. Todo funciona bien Ahora, el problema sin embargo es este:
Mi solución tiene algunas dependencias (referencias a asambleas de terceros). En VS.NET, configuré ''copiar local'' en verdadero para estas dependencias. Cuando CC.NET construye mi versión .NET3.5 del ensamblado, las dependencias de terceros se copian a mi directorio de salida.
Sin embargo, cuando CC.NET crea mi versión .NET2.0 del ensamblado, las dependencias no se copian en mi directorio de salida. (Entonces, esto hace que mis pruebas de unidad fallen).
Mi pregunta ahora es: ¿Cómo puedo decirle a msbuild que algunas de las referencias de terceros deben copiarse localmente al compilar mi versión .NET2.0 de mi proyecto? O, ¿hay alguna otra forma de lograr esto, ya que no me gustaría especificar cada dependencia una vez más en mi build-script. Esto se convertiría rápidamente en una pesadilla de mantenimiento, supongo.
Pude resolver este problema asegurándome de que no hago referencia a los ensamblados del GAC. En su lugar, he creado un directorio ''lib'' en mi proyecto que contiene los ensamblajes de terceros. En mi solución, hago referencia a los ensamblados de terceros desde allí y configuro copy local == True.
Junto a eso, también debe asegurarse de que en su archivo csproj, los ensamblados a los que se hace referencia tengan una etiqueta privada cuyo valor esté establecido en verdadero. Me gusta esto:
<Reference Include="...">
<SpecificVersion>False</SpecificVersion>
<HintPath>...</HintPath>
<Private>True</Private>
</Reference>
He estado revisando este problema nuevamente, ya que no me gusta tener que cambiar manualmente el archivo csproj. (Cuando cambio mi referencia, no debo olvidar adaptar el archivo csproj nuevamente, para establecer el nodo Privado en verdadero de nuevo).
Entonces, he estado investigando en MSDN, y me encontré con esto:
Propiedad ResolveAssemblyReference.TargetFrameworkDirectories
Comentarios Esta propiedad es necesaria para determinar el estado de CopyLocal para los elementos resultantes.
Si no se especifica esta propiedad, los elementos resultantes tendrán un valor CopyLocal de verdadero a menos que tengan explícitamente un valor de metadata privado de verdadero en su elemento de origen.
Entonces, esto significa que existe otra posibilidad, y es establecer los TargetFrameworkDirectories de la tarea ResolveAssemblyReference. Sin embargo, ¿hay alguien que sepa cómo hacer esto?
He estado probando cosas diferentes, pero nada parece estar funcionando ...
He intentado esto:
<ItemGroup>
<TargetFrameworkDir Include="$(SystemRoot)/Microsoft.NET/Framework/v2.0.50727" />
</ItemGroup>
<PropertyGroup>
<TargetDirsToUse>@(TargetFrameworkDir)</TargetDirsToUse>
</PropertyGroup>
<ResolveAssemblyReference TargetFrameworkDirectories="$(TargetDirsToUse)" />
Pero fue en vano ... Tal vez alguien más sabe cómo hacer esto, o tiene un buen consejo. (Estuve pasando mucho tiempo hablando de este tema).
Una pregunta: ¿qué sucede si intenta compilar su solución 2.0 / proyectos dentro de VisualStudio? ¿Las referencias de terceros están copiadas automáticamente o no?
Es extraño que esto funcione para 3.5 y no para 2.0. No he hecho ninguna construcción en paralelo, pero cuando convertí mis proyectos de 2.0 a 3.5 todas las referencias de terceros fueron copiadas independientemente de la versión de .NET.
Por cierto: nunca referencia las bibliotecas de terceros de GAC (solo las de Microsoft, e incluso no todas). Siempre los copio en la estructura de mi directorio lib, los agrego al control de fuente y los referencia desde allí. Usar montajes de GAC es una mala práctica en lo que a mí respecta, ya que representa una dependencia innecesaria en la configuración de una máquina de desarrollo.
Ejemplo de dicho directorio: http://code.google.com/p/projectpilot/source/browse/#svn/trunk/lib