Как неявно использовать цель для создания включенного файла? - PullRequest
4 голосов
/ 02 декабря 2010

Я по натуре парень (1).То, что я хочу сделать, является эквивалентом этого фрагмента make:

FILES = generated.cs

app.exe : $(FILES)
    csc -out:$@ $(FILES)

generated.cs :
    echo "// generated file" > $@

То есть $(FILES) содержит список файлов, некоторые из которых могут быть сгенерированы другими целями в Makefile.Это просто работает.

Я хотел бы сделать то же самое с MSBuild.К сожалению, моя попытка не удалась:

<Target Name="BuildGenerated"
    Outputs="Generated.cs"
    >
  <WriteLinesToFile
    File="Generated.cs"
    Lines="// generated file"
    Overwrite="True"
    />
</Target>
<ItemGroup>
  <Compile Include="Generated.cs" />
</ItemGroup>

То есть используйте <Compile/>, чтобы включить сгенерированный файл, и MSBuild делает вывод, что, поскольку Generated.cs не существует, он должен найти <Target/>сгенерирует этот файл, а затем выполнит его.

Похоже, что единственный способ сделать что-то вроде этого - добавить шаги перед сборкой, но это похоже на хак.Являются ли этапы предварительной сборки единственным способом сделать это?Или есть какой-то способ заставить MSBuild действовать так, как будто у него есть мозг?

Обновление 1 : для справки, это было бы заклинание перед сборкой, необходимое для его работы, и (снова) это то, чего я бы предпочел избежать, если это возможно:

<PropertyGroup>
  <CompileDependsOn>
    BuildGenerated;$(CompileDependsOn)
  </CompileDependsOn>
</PropertyGroup>

Это должно произойти после элемента <Import Project="..." />, определяющего <CompileDependsOn/>.

1 Ответ

2 голосов
/ 03 декабря 2010

Проблема в том, что ваш файл является сгенерированным, и MsBuild анализирует элемент и группу свойств только один раз (в начале вашей сборки).Таким образом, когда MsBuild пытается включить сгенерированный файл .cs, он еще не создан, а MsBuild вообще ничего не включает.

Правильный способ сделать это - включить часть включения внутриBuildGenerated target , что приведет к его динамической оценке.

<Target Name="BuildGenerated"
    Outputs="Generated.cs"
    >
  <WriteLinesToFile
    File="Generated.cs"
    Lines="// generated file"
    Overwrite="True"
    />
<ItemGroup>
  <Compile Include="Generated.cs" />
</ItemGroup>
</Target>

Дополнительная информация в моем ответе на этот вопрос: Папка с корзиной не копируется с MSBuild, Teamcity

EDIT Извините, я не правильно прочитал ваш вопрос.в вашем make-файле, в цели app.exe (по умолчанию), вы явно вызываете вашу цель сгенерированного .cs.Вы можете сделать то же самое с MsBuild.

По умолчанию MsBuild выполняет поиск цели Build («все» в make-файле), если вашей основной целью является «app.exe», вы должны вызывать цель BuildGenerated с помощьюодин из следующих параметров:

<Target Name="app.exe" DependsOnTargets="BuildGenerated>
  <!-- Stuff here -->
</Target>

или

<Target Name="app.exe">
  <CallTarget Targets="BuildGenerated"/>
  <!-- Stuff here -->
</Target>

Если вы не установите цель по умолчанию, вы можете сделать это либо из командной строки с параметром / t, либо вдекларация проекта:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="app.exe">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...