2015-12-23 3 views
3

Чтобы эмулировать параметр «PerProject» в сборке XAML TFS 2013 в новых сборках на основе сборки Build 2015, я хотел бы иметь возможность передать SolutionName в msbuild аргументы командной строки без необходимости вручную устанавливать его каждый раз.

Я хотел бы сделать что-то вроде:

/p:OutputPath=$(Build.BinariesDirectory)\$(SolutionName)\ 

Где я хотел бы MsBuild вывести параметр $ (SolutionName). Но, передавая это в командной строке, новый бегун задачи заменит правильным целевым контуром и оставит $(SolutionName). К сожалению MsBuild впоследствии также оставляет имущество в покое:

Copying file from "obj\Debug\TFSBuild.exe" to "bin\debug\$(SolutionName)\TFSBuild.exe". 
TFSBuild -> b\$(SolutionName)\TFSBuild.exe 
Copying file from "obj\Debug\TFSBuild.pdb" to "b\$(SolutionName)\TFSBuild.pdb". 

Я не могу вспомнить, как передать свойство командной строки и это делать поздно-расширение ... Любые советы?

Для тех, кто хочет подражать SingleFolder или AsConfigured, те легко:

SingleFolder -> /p:OutputPath="$(Build.BinariesDirectory)" 
Asconfigured -> don't pass OutputPath 
PerProject -> /p:OutputPath="$(Build.BinariesDirectory)\HARDCODESOLUTIONNAME" 
+0

Как насчет передачи '/ p: MyOutputPathBaseDir = $ (Build.BinariesDirectory) ', а затем в файле проекта установите для свойства OutputPath значение' $ (MyOutputPathBaseDir) \ $ (SolutionName) '? – stijn

+0

Это потребует от меня редактирования всех файлов проекта, который работает, но тогда я мог бы также вставить мою собственную переменную и использовать AsConfigured – jessehouwing

+0

* Это потребует от меня редактирования всех файлов проекта * не обязательно, msbuild имеет несколько точек расширения, где он может импортируйте произвольные файлы, которые вы передаете в командной строке. В вашем случае этот файл просто установит свойство, как я описал. – stijn

ответ

1

Как я опасался, похоже, что нет простого способа переопределить свойство из командной строки и «ввести» значение другого свойства в него во время этапа оценки.

Есть несколько способов обойти это, но они не идеальны и, конечно, не универсальны для каждого языка, поддерживаемого MsBuild. Жалость.

Я отлаживал файлы целей MsBuild и нашел решение для воспроизведения старого поведения с эпохи 2005/2008. Не полностью для решения, но он перенаправляет проекты в подпапку.

/p:GenerateProjectSpecificOutputFolder=true /p:OutDirWasSpecified=true 
/p:OutputPath=$(Build.BinariesDirectory) 
0

Вы правы, что TFS vNext сборки не может распознать $(SolutionName) в OutputPath, так как $ (SolutionName) не перечисляет в Predefined variables.

В качестве альтернативы мы можем назвать определение сборки с именем решения, а затем указать аргумент MSBuild: /p:OutputPath="$(Build.BinariesDirectory)\$(Build.DefinitionName)" таким образом, мы можем получить результат под именем решения.

+0

Не вариант, так как опция «PerProject» имеет смысл только при создании нескольких решений. И это не сработает при создании нескольких решений. – jessehouwing

+0

Я понимаю, что это не предопределенная переменная в Build 2015, она находится в самой MsBuild. Поэтому моя надежда состоит в том, чтобы убедить MsBuild что-то сделать с переменной. – jessehouwing

+0

SolutionName * действительно определено в msbuild при построении решения (не при построении одного проекта) – stijn

1

Одним из решений является имитация такой «поздней оценки» путем изменения OutputPath с файлом проекта. Чтобы вручную не изменять каждый файл проекта, вы можете использовать точку расширения CustomBeforeMicrosoftCSharpTargets. Какой причудливый способ сказать, что это просто свойство, которое, когда оно обнаружено и указывает на существующий файл, приведет к тому, что этот файл будет импортирован где-то перед самой реальной логикой сборки. Вот идея: создайте файл, например, paths.targets где-нибудь - включите его в исходный элемент управления или вы можете сгенерировать его на лету как часть процесса сборки. Содержание:

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <PropertyGroup> 
    <OutputPath Condition="'$(OutputPathBaseDir)'!=''">$(OutputPathBaseDir)\$(SolutionName)</OutputPath> 
    </PropertyGroup> 
</Project> 

Так что это просто переопределяет OutputPath на какое-то базовое имя dir +. Затем, если вы строите решение как

msbuild my.sln /p:CustomBeforeMicrosoftCSharpTargets=paths.targets; 
        OutputPathBaseDir=$(Build.BinariesDirectory) 

каждый проект будет импортировать файл paths.targets и установить выходное свойство valueOfBinariesDirectory \ мой, который я думаю, что это именно то, что вы после этого.

+0

Но в сочетании C#, VB.NET и C++, которые не будут работать. Я понимаю, как это возможно, и я подозреваю, что есть еще три свойства, которые я мог бы попробовать переопределить. – jessehouwing

+0

Да для C++ есть ForceImportBeforeCppTargets, для VB я не знаю, но он будет похож. – stijn

Смежные вопросы