web-dev-qa-db-fra.com

Existe-t-il un moyen simple de faire en sorte que Visual Studio 2015 utilise une version ToolsVersion spécifique?

Lors de la création d'un projet ou d'une solution à l'aide d'une version spécifique de msbuild je peux sélectionner une chaîne d'outils .net antérieure à l'aide de /toolsversion ou /tv commutateur:

"C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:12.0 amazing.sln

Cela fonctionne pour toutes les versions de msbuild et la version de csc.exe etc. est correctement choisi sur la base de ce qui précède:

> "C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:4.0 amazing.sln
...
CoreCompile:
  C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe ...
...

> "C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:12.0 amazing.sln
...
CoreCompile:
  C:\Program Files (x86)\MSBuild\12.0\bin\Csc.exe ...
...

Si je ne le faites pas spécifiez /tv, puis en fonction de la version de msbuild que j'utilise et d'un certain nombre de variables d'environnement, je peux obtenir l'un des éléments suivants:

  • ToolsVersion spécifié dans l'élément de niveau supérieur dans le fichier de projet
  • ToolsVersion correspondant à la version de msbuild.exe J'utilise
  • Une valeur de msbuild.exe.config
  • Une valeur du registre

(Voir la différentes versions de la page Overriding ToolsVersion sur MSDN ).

Donc, pour avoir des builds qui ont des résultats cohérents sur le serveur de build et sur ma machine locale, j'utilise /tv lors de l'exécution msbuild.exe (en fait, cela est appliqué dans un script psake, qui garantit également qu'il utilise la version correspondante de msbuild.exe).

Cependant je ne peux pas utiliser le /tv basculer lors de la génération avec Visual Studio. À la place, Visual Studio 2013 et versions ultérieures utiliseront la chaîne d'outils .net fournie avec cette version de Visual Studio sauf:

  • La variable d'environnement MSBUILDLEGACYDEFAULTTOOLSVERSION est définie et ...
  • ... tous les fichiers de projet ont l'attribut ToolsVersion défini sur la version que je veux utiliser.

C'est tellement baroque que je ne peux pas croire que quelqu'un le fasse réellement. Mes questions sont donc:

  • Est-ce quelqu'un qui fait la chose MSBUILDLEGACYDEFAULTTOOLSVERSION?
  • Si ce n'est pas le cas, existe-t-il un autre moyen de faire utiliser Visual Studio une version ToolsVersion spécifique à court d'utiliser la version de Visual Studio fournie avec cette version ToolsVersion? Quelque chose qui pourrait être stocké dans le contrôle de version (donc dans un projet ou un autre fichier de paramètres) serait idéal.

Et enfin:

  • Dois-je même m'en soucier? Étant donné que chaque version successive du compilateur C # devrait être capable de gérer l'entrée des versions précédentes, et que je peux définir le framework .net cible et le niveau de langage C # dans le fichier de projet, est-ce suffisant pour garantir des builds reproductibles?

(Mon préjugé est que je devrais attention, car:

  • Je veux que les builds dans le IDE et sur le serveur de build soient les mêmes (bien sûr)
  • Je veux pouvoir utiliser VS2015 (et les versions futures) car c'est un meilleur IDE que les versions précédentes, mais je ne veux pas être obligé d'utiliser la nouvelle chaîne d'outils jusqu'à ce que j'en décide.

Peut-être que j'en veux trop ...)

Pour un exemple concret du problème, veuillez consulter mon référentiel msbuild-vs-vs2015-toolsversion sur github.


Un peu de contexte: je pose cette question parce que nous avons récemment eu une erreur de construction de CI lorsque l'un de mes collègues a soumis du code C # 6.0 qui s'est bien compilé avec Roslyn sur leur copie de Visual Studio 2015, mais a échoué dans CI parce que ça utilise la version précédente de la chaîne d'outils .net (ils avaient utilisé une propriété automatique sans setter, ce qui est bien dans Roslyn mais pas dans les versions antérieures). Nous mettrons à jour la build CI vers Roslyn, mais je voulais voir si nous pouvions empêcher ce genre de chose de se produire à l'avenir.

47
Guy Bolton King

J'ai résolu ce problème en écrivant une extension Visual Studio qui définit temporairement la variable d'environnement MSBUILDDEFAULTTOOLSVERSION pour la durée d'une build; la valeur à utiliser est lue dans un fichier .toolsversion dans le même répertoire que le .sln fichier. Le script psake lit le même .toolsversion fichier et transmet la valeur au /tv commutateur.

Le code de l'extension peut être trouvé ici: https://github.com/guyboltonking/set-toolsversion-extension . Malheureusement, je ne travaille pas avec C++, ni même avec Visual Studio, pour le moment, donc je ne peux pas fournir de support pour cela (mais je peux vous dire que je l'ai utilisé sans aucun problème pendant plusieurs mois).

Félicitations à @efaruk pour m'avoir rappelé l'existence de MSBUILDDEFAULTTOOLSVERSION.

Edit: Grâce à @ mbadawi23, il est désormais possible d'utiliser l'extension avec VS2015 et VS2017.

6
Guy Bolton King

Pour forcer une version C # spécifique dans Visual Studio 2015, vous pouvez aller dans les propriétés du projet -> Build -> Advanced -> Language Version.

Si vous définissez cette valeur sur 5, le compilateur se plaindra des fonctionnalités C # 6 avec: La fonctionnalité '...' n'est pas disponible dans C # 5. Veuillez utiliser la version linguistique 6 ou supérieure.

Alternativement, ReSharper dispose également de quelques outils pour cela.

3
oddbear

Remarque: Vous pouvez toujours créer un fichier msbuild pour créer votre projet à partir de son utilisation ou de la modification de votre projet lui-même et vous pouvez décider de la version de votre outil de manière conditionnelle ( https://msdn.Microsoft.com/en-us/library /7z253716.aspx ) (. Csproj est également un script msbuild structuré avec une extension différente et il sera également compatible avec VS).

Cordialement...

Modifier:

https://msdn.Microsoft.com/en-us/library/bb383985.aspx

en définissant la propriété $(ProjectToolsVersion) sur un projet dans une solution. Cela vous permet de créer un projet dans une solution avec une version de Toolset différente de celle des autres projets.

Donc, je pense que vous avez obtenu votre réponse;)

2
efaruk