3

我们正在尝试编写一个 msbuild 脚本,该脚本将构建解决方案并将所有已编译的二进制文件和依赖项复制到特定的输出文件夹。虽然我们拥有的构建脚本确实构建并复制二进制文件到一个公共文件夹,但我们没有复制依赖项。这可能与我们使用 msbuild 任务构建解决方案的方式有关,我们将任务的目标输出接受到项目组中并迭代项目组以将所有已编译的 dll 和 exe 复制到一个公共文件夹中。但这不包括放置在每个项目的单独 bin 文件夹中的依赖 dll。

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
    <ParentSolutionFile />
</PropertyGroup>
<ItemGroup>
    <Assemblies Include="*.dll, *.exe" />
</ItemGroup>
<Target Name="BuildAll">
    <CombinePath BasePath="$(MSBuildProjectDirectory)" Paths="Source\Solutions\xxx.sln">
        <Output TaskParameter="CombinedPaths" PropertyName="ParentSolutionFile" />
    </CombinePath>
    <Message Text="$(ParentSolutionFile)" />
    <MSBuild Projects="$(ParentSolutionFile)">
        <Output TaskParameter="TargetOutputs" ItemName="Assemblies" />
    </MSBuild>
    <Message Text="%(Assemblies.Identity)" />
    <Copy SourceFiles="%(Assemblies.Identity)" DestinationFolder="$(MSBuildProjectDirectory)\Binary" OverwriteReadOnlyFiles="True" SkipUnchangedFiles="True" />
</Target>

将所有二进制文件以及必要的依赖项复制到公共输出文件夹的首选方法是什么?

4

2 回答 2

2

不覆盖 OutputPath 就可以单独解决问题吗?

<MSBuild Projects="$(ParentSolutionFile)" Properties="OutputPath=$(MSBuildProjectDirectory)\Binary">
  <Output TaskParameter="TargetOutputs" ItemName="Assemblies" />
</MSBuild>

并完全忽略复制任务?

于 2013-05-15T13:18:27.570 回答
1

构建过程会将最终结果放在由 OutputPath 表示的目录中 - 至少在构建 c# 项目时是这样。对于 C/C++,内部结构和变量名是完全不同的。

因此,理论上,您可以在构建解决方案的 MsBuild 任务中传递 OutputPath。

<MsBuild Projects="$(ParentSolutionFile)"
    Properties="OutputPath=$(MSBuildProjectDirectory)\Binary"/>

但是,csproj 文件将使用以下代码无条件地覆盖该值:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <OutputPath>bin\Debug\</OutputPath>

我已经通过在每个 csproj 文件中注入我自己的构建系统来解决这个问题。

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\..\build\buildsystem.targets" />

该路径是相对于 csproj 文件的。绝对路径也可以,或者变量。诀窍是让它在所有开发机器以及构建代理上工作。

现在,在 buildsystem.targets 中,只要OutputPath你喜欢就重新定义。同样,诀窍是确保您获得相同的 - 或至少定义明确的 - 位置,而不管是谁构建它(开发人员,构建代理),也不管构建是如何启动的(VS,命令行)。

处理差异的一种简单方法是有条件地导入。

<Import Project="..\..\..\build\buildsystem.targets"
    Condition="'$(BuildingInsideVisualStudio)'!='true'"/>

如果从 VS 启动构建,以及从命令行构建时为代码进行的任何更改,这将不会给您带来任何变化。

——杰斯珀

于 2013-11-15T08:27:20.160 回答