При создании проекта или решения с использованием определенной версии msbuild
я могу выбрать более раннюю цепочку инструментов .net с помощью переключателя /toolsversion
или /tv
:
"C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:12.0 amazing.sln
Это Just Works для всех версий msbuild
, а версия csc.exe
и т.д. правильно выбрана на основе вышеперечисленного:
> "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 ...
...
Если я не укажу /tv
, то в зависимости от какой версии msbuild, которую я использую, и ряда переменных среды, я могу получить любой из:
- Инструмент ToolsVersion, указанный в элементе верхнего уровня в файле проекта
- Инструмент ToolsVersion, соответствующий версии
msbuild.exe
Я использую - Значение из
msbuild.exe.config
- Значение из реестра
(см. различные версии страницы "Параметры переопределения параметров инструмента" в MSDN).
Итак, чтобы иметь сборки, которые имеют согласованные результаты на сервере сборки и на моей локальной машине, я использую /tv
при запуске msbuild.exe
(на самом деле это принудительно применяется в psake
script, который также гарантирует, что он использует соответствующую версию msbuild.exe
).
Однако Я не могу использовать переключатель /tv
при создании с помощью Visual Studio. Вместо этого Visual Studio 2013 и выше будут использовать инструментальную цепочку .net, поставляемую с этой версией Visual Studio, если:
- Установлена переменная среды
MSBUILDLEGACYDEFAULTTOOLSVERSION
и... - ... все файлы проекта имеют атрибут ToolsVersion, установленный для версии, которую я хочу использовать.
Это так барокко, что я не могу поверить, что кто-то на самом деле это делает. Мои вопросы таковы:
- Кто-нибудь делает
MSBUILDLEGACYDEFAULTTOOLSVERSION
вещь? - Если нет, существует ли другой способ заставить Visual Studio использовать конкретную утилиту ToolsVersion, не использующую версию Visual Studio, поставляемую с этой утилитой ToolsVersion? Что-то, что можно было бы сохранить в контроле версий (например, в проекте или в каком-либо другом файле настроек) было бы идеальным.
И наконец:
- Мне все равно? Учитывая, что каждая последующая версия компилятора С# должна иметь возможность обрабатывать входные данные предыдущих версий, и я могу установить целевую структуру .net и уровень языка С# в файле проекта, достаточно ли этого для обеспечения повторяемости сборки?
(Мое предубеждение в том, что я должен заботиться, поскольку:
- Я хочу, чтобы сборки в среде IDE и на сервере сборки были одинаковыми (конечно)
- Я хочу иметь возможность использовать VS2015 (и будущие версии), потому что это лучшая среда IDE, чем предыдущие, но я не хочу быть обязанным использовать новую инструментальную цепочку, пока не решит.
Возможно, я хочу слишком много...)
Для конкретного примера проблемы см. мой репозиторий msbuild-vs-vs2015-toolsversion в github.
Некоторое предположение: я спрашиваю об этом, потому что у нас недавно возникла ошибка построения CI, когда один из моих коллег представил код С# 6.0, который скомпилирован с Roslyn на их копии Visual Studio 2015, но не прошел в CI, потому что использует предыдущий релиз .net toolchain (они использовали автоматическое свойство без сеттера, что прекрасно в Roslyn, но не в более ранних версиях). Мы будем обновлять сборку CI до Roslyn, но я хотел посмотреть, не можем ли мы предотвратить подобное событие в будущем.