Eu tenho essa seção em .csproj:
<Target Name="Date" BeforeTargets="BeforeBuild">
<WriteLinesToFile File="$(IntermediateOutputPath)BuildInfo.gen.cs"
Lines="...."/>
</Target>
<ItemGroup>
<Compile Include="$(IntermediateOutputPath)BuildInfo.gen.cs"
Condition="Exists('$(IntermediateOutputPath)BuildInfo.gen.cs')"/>
</ItemGroup>
IntermediateOutputPath
foi resolvido conforme o esperado, está tudo bem. Mas como todo esse caminho é repetido 3 vezes no meu .csproj, pensei em limpar isso e criar uma variável personalizada:
<PropertyGroup>
<BuildInfoPath>$(IntermediateOutputPath)BuildInfo.gen.cs</BuildInfoPath>
</PropertyGroup>
<Target Name="Date" BeforeTargets="BeforeBuild">
<WriteLinesToFile File="$(BuildInfoPath)" Lines="...."/>
</Target>
<ItemGroup>
<Compile Include="$(BuildInfoPath)"
Condition="Exists('$(BuildInfoPath)')"/>
</ItemGroup>
Minha variável foi resolvida, mas seu conteúdo não está totalmente correto - tenho o efeito IntermediateOutputPath
de uma string vazia.
Então, como posso definir minha própria referência de variável IntermediateOutputPath
?
Eu já descobri que, se eu agrupar minha definição de variável, Target
ela funcionaria parcialmente - ou seja, a Target
seção mostrada acima obteria a variável adequada, mas, por sua vez, ItemGroup
minha variável ficaria vazia.
O MSBuild tem duas fases: Avaliação e Execução. Consulte " Como o MSBuild cria projetos ".
ItemGroup
ePropertyGroup
os elementos de “nível superior”, ou seja, filhos diretos doProject
elemento raiz do documento, são avaliados na fase de avaliação.ItemGroup
ePropertyGroup
os elementos dentro de aTarget
são avaliados durante a fase de execução.Presumo que este seja um projeto no estilo SDK . Nos bastidores, um conjunto de arquivos é importado com base no tipo de SDK. Alguns arquivos são importados antes e outros depois do conteúdo do arquivo de projeto .csproj. A
IntermediateOutputPath
propriedade é definida na fase de avaliação mas em um arquivo que é importado após o conteúdo do .csproj.Dentro do conteúdo do arquivo do projeto durante a fase de avaliação, a propriedade ainda não está definida e usar a propriedade antes de ser definida produz uma string vazia - como você observou.
Em um projeto estilo SDK, use apenas a
IntermediateOutputPath
propriedade dentro de um destino.Você ainda pode definir suas próprias propriedades e itens dos quais dependem,
IntermediateOutputPath
mas precisa agrupar as definições em destinos e garantir que as definições sejam executadas antes dos valores serem usados, por exemplo: