2009-08-09 6 views
2

Depuis que j'ai commencé à utiliser MSBuild pour nos projets, j'ai créé plusieurs scripts .proj qui sont partagés par plusieurs projets dans notre dépôt. Tous ces scripts partagés résident dans un seul répertoire.Comment créer un référentiel commun de fichiers MSBuild .proj?

Jusqu'à présent, j'ai référait aux scripts partagés en utilisant un chemin relatif, quelque chose comme ceci:

<MSBuild Projects="..\..\common\build\MyScriptA.proj" Properties="ABC=XYZ"/> 

Cependant, chaque projet importations ont également un script .proj commun comme ceci:

<Import Project="..\..\common\build\CommonImports.proj"/> 

qui <Import> s plusieurs autres choses et définit certaines propriétés.

Ce matin, j'ai pensé que je pourrais remplacer le chemin relatif par une variable, peut-être $(CommonDir), qui serait définie en important le CommonImports.proj mentionné ci-dessus. Cela me permettra d'appeler les tâches communes comme ceci:

<MSBuild Projects="$(CommonDir)\MyScriptA.proj" Properties="ABC=XYZ"/> 

Cependant, je ne peux pas trouver un moyen de définir cette variable $(CommonDir) de telle manière à le faire fonctionner dans tous les autres scripts MSBuild que l'importation , indépendamment de leur emplacement.

This question offre plusieurs façons de créer une propriété contenant un chemin absolu à partir d'un chemin relatif, mais aucune ne semble fonctionner si tout ce que je fais est <Import> le script définissant la propriété.

Question 1: Je suis assez nouveau pour MSBuild; Y at-il une meilleure façon de créer une "bibliothèque" de scripts .proj réutilisables que je pourrais exécuter via la tâche <MSBuild>? Je suis au courant de $(MSBuildExtensionsPath), mais je voudrais que les tâches courantes résident dans ma caisse afin que notre machine de construction obtienne automatiquement les dernières versions des tâches communes chaque fois qu'elle effectue une extraction.

Question 2: Comment définir l'intérieur $(CommonDir)CommonImports.proj afin de rendre contenir le chemin absolu du répertoire contenant CommonImports.proj?

+0

Comment utilisez-vous MSBuild? Est-ce la tâche NAnt? Si vous n'utilisez pas NAnt, pourriez-vous l'utiliser pour vous aider? Si vous utilisez NAnt, ignorez-moi complètement. –

+1

Ne pas utiliser NAnt et ne pas chercher une solution qui utiliserait NAnt. –

Répondre

1

Voici ce qui a fonctionné le mieux pour nous. Tout d'abord, archivez tous les éléments réutilisables dans un répertoire /common/build/ dans le VCS.

Ensuite, ajoutez un /common/build/CommonImports.proj, en regardant quelque chose comme ceci:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 
     ToolsVersion="4.0"> 
    <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/> 
    <Import Project="ILMerge.proj"/> 
    <Import Project="Mage.proj"/> 
    <Import Project="InnoSetup.proj"/> 
    <UsingTask TaskName="RT.Tasks.AssemblyVersion" AssemblyFile="Tasks\Release\RT.Tasks.dll"/> 
    <UsingTask TaskName="RT.Tasks.WaitForProcessesToTerminate" AssemblyFile="Tasks\Release\RT.Tasks.dll"/> 
    <PropertyGroup> 
    <BuildSingleProj>$(Root)\common\build\BuildSingle.proj</BuildSingleProj> 
    </PropertyGroup> 
</Project> 

Ceci importe quelques projets et tâches que tout utilise, et définit un groupe immobilier qui est partagé par tout. Ensuite, ajoutez dans chaque script de construction:

<PropertyGroup> 
    <Root>..\..</Root> 
    [... other global properties ...] 
</PropertyGroup> 
<Import Project="$(Root)\common\build\CommonImports.proj"/> 
2

Je me demande si vous ne devriez pas le mettre dans le chemin MSBuild:

Par exemple, this project est consommé par:

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

et s'installe dans:

{program files}\MSBuild\MSBuildCommunityTasks 

Alors peut-être définir votre propre sous-dossier spécifique, et utiliser à partir de là?

<Import Project="$(MSBuildExtensionsPath)\romkyns\CommonImports.proj"/> 

etc. Comme la variable $MSBuildExtensionsPath est définie séparément, vous ne devriez pas avoir autant de difficultés avec elle. Peut être.

+0

Merci, en effet j'ai remarqué que msbuildtasks s'installe là-bas. Cependant, nos tâches communes changent plus fréquemment (pour l'instant au moins) que msbuildtasks - c'est pourquoi je cherche un moyen de laisser les tâches référencées dans la caisse. En prime, si je me synchronise avec le passé et que j'appelle une build, j'utiliserai les mêmes tâches courantes que j'ai faites quand une version a été faite, sans tracas supplémentaires. –

1

Ce n'est pas une réponse détaillée, mais voici quelques notes qui sont généralement très utiles quand les gens résolvent ce problème. Tous nécessitent MSBuild 4.0 ou plus tard.

(1) La propriété $ (MSBuildThisFile) et propriétés similaires. Il permet aux fichiers importés de faire référence à des fichiers relatifs à eux-mêmes, plutôt qu'au projet dans lequel ils sont importés. Cela les déconnecte du projet dans lequel ils sont importés.

(2) La fonction "GetDirectoryNameOfFileAbove". Voir here. Cette fonction merveilleusement utile permet aux projets d'importer des fichiers dont ils ne connaissent pas l'emplacement. Placez les fichiers partagés (ou un seul fichier partagé stub qui importe les autres quelque part) en haut de votre arborescence source. Ensuite, utilisez cette fonction dans les projets ci-dessous pour trouver ce talon et l'importer et ainsi tout votre processus de construction partagé.

(3) La balise d'importation permet les caractères génériques. Cela permet d'importer un fichier - en d'autres termes, d'étendre un processus de construction - en le déposant simplement dans un emplacement particulier et en ne modifiant aucun fichier existant.

Questions connexes