msbuild - 如何隐式使用 Target 生成包含文件?

标签 msbuild

我本质上是一个 make(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/> 的元素.

最佳答案

问题是您的文件是生成的文件,并且 MsBuild 仅解析项目和属性组一次(在构建开始时)。因此,当 MsBuild 尝试包含生成的.cs 文件时,它尚未创建,而且 MsBuild 根本不包含任何内容。

正确的做法是在 BuildGenerated 目标中执行包含部分 这将导致它被动态评估。

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

我对这个问题的回答中的更多信息:Bin folder not being copied with MSBuild, Teamcity

编辑
抱歉,我没有正确阅读您的问题。在您的 makefile 中,在 app.exe 目标(默认目标)中,您明确调用了 generate.cs 目标。你可以用 MsBuild 做同样的事情。

默认情况下,MsBuild 会搜索 Build 目标(makefile 中的“all”),如果您的主要目标是“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">

关于msbuild - 如何隐式使用 Target 生成包含文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4338564/

相关文章:

c# - PartialClassGenerationTask 和 MarkupCompilePass1 如何一起工作/属于

visual-studio - 如何使用 msbuild 禁用预编译头?

msbuild - 如何在 MSBuild 中找到当前文件

c# - 未执行 MSBuild 脚本中覆盖的 AfterBuild 目标

.net - msbuild 失败 : MSB3086, MSB3091 : "AL.exe", "resgen.exe"未找到

.net - 在 C# 项目中覆盖 BuildDependsOn 时遇到问题

c++ - 项目配置与 PropertyGroup (MSBuild)

c# - Visual Studio/IIS Express 间歇性错误

visual-studio-2010 - 从 _bin_deployableAssemblies 目录中排除 .svn?

msbuild - 从 TeamCity 复制 msbuild 命令