20

我正在调试我的构建过程中偶尔发生的错误,但我无法直接重现它。我正在将 msbuild 与 teamcity 一起使用。

我有一个这样的依赖层次结构:

Some.Interop.dll
   Dependency-> SharedDllABC.dll

SomeService.exe
   Depenendcy-> Some.Interop

通常最终的服务可执行文件进入其发布目录:

Some.Interop
SharedDllABC.Dll
ServiceExectuable.exe

但是,我可以在我们的 msbuild 日志中看到,有时在构建所有内容后的增量清理过程中会删除三级依赖项,从而导致:

Some.Interop
ServiceExectuable.exe

您可以在 msbuild 日志中看到它:

[src\SomeService\SomeService.csproj] _TimeStampAfterCompile
[12:32:43]:  [src\SomeService\SomeService.csproj] Compile

// some other targets

[12:32:43]:  [src\SomeService\SomeService.csproj] _CopyFilesMarkedCopyLocal
[12:32:43]:      [_CopyFilesMarkedCopyLocal] Copy
[12:32:43]:          [Copy] Copying file from "C:Projects\trunk\src\Some.Interop\bin\Release\Some.Interop.dll" to "bin\Release\Some.Interop.dll".

// some other targets

[src\Project\SomeService\SomeService.csproj] IncrementalClean
[18:54:42]:         [IncrementalClean] Delete
[18:54:42]:             [Delete] Deleting file "C:\Projects\trunk\src\Project\SomeService\bin\Release\SharedDllABC.dll".
[18:54:42]:             [Delete] Deleting file "C:\Projects\trunk\src\Project\SomeServiceService\bin\Release\SharedDllABC.pdb".
[18:54:42]:     [src\Project\SomeService\SomeService.csproj] CoreBuild
[18:54:42]:     [src\Project\SomeService\SomeService.csproj] AfterBuild
[18:54:42]:     [src\Project\SomeService\SomeService.csproj] Build

这是我的直接 msbuild 输出,我只是更改了项目名称/dll 名称以匹配我的示例。到此增量清理发生时,SomeService.csproj已经构建好了。你可以看到它没有被复制。但是,在其他 msbuild 日志中,它确实被正确复制,然后增量清理不会删除它。

我认为这篇文章中的增量清理应该清理从以前的版本创建的 dll,但这并不能解释这个 dll 在大多数情况下是如何构建的。在视觉工作室中,这也总是有效的。

我想我只是想知道究竟是Incremental clean什么,是什么导致它启动,也许在调试这样的情况时我应该寻找什么(程序集版本、时间戳等?)

4

4 回答 4

3

尝试以下操作:

添加:

<Target Name="IncrementalClean" />

到包含在所有项目中的 .targets 文件。

来自 --> https://github.com/Microsoft/msbuild/issues/1054

于 2017-07-13T15:17:58.383 回答
1

@Kebabbi 建议通过编辑 csproj 文件来修复。从 MSBuild 15 开始,有一种简单的方法可以将其应用于所有 CSPROJ 文件,而不是编辑每个 csproj 文件。

https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?view=vs-2017

Directory.Build.props 和 Directory.Build.targets 在 MSBuild 版本 15 之前,如果您想为解决方案中的项目提供新的自定义属性,您必须手动将对该属性的引用添加到解决方案中的每个项目文件. 或者,您必须在 .props 文件中定义属性,然后在解决方案中的每个项目中显式导入 .props 文件,等等。

但是,现在您可以通过在包含源代码的根文件夹中名为 Directory.Build.props 的单个文件中定义一个新属性,一步向每个项目添加一个新属性。当 MSBuild 运行时,Microsoft.Common.props 会在您的目录结构中搜索 Directory.Build.props 文件(Microsoft.Common.targets 会搜索 Directory.Build.targets)。如果它找到一个,它会导入该属性。Directory.Build.props 是一个用户定义的文件,它为目录下的项目提供自定义。

创建一个文件Directory.Build.props,并将其与 SLN 文件相邻放置。

<Project>
   <Target
     Name="ForceAssignProjectConfigurationBeforeSplitProjectReferencesByFileExistence_KLUDGE" 
     BeforeTargets="_SplitProjectReferencesByFileExistence" 
     DependsOnTargets="AssignProjectConfiguration" />
</Project>
于 2019-02-05T19:49:13.153 回答
1

这可能是由 MsBuild 中的错误引起的:https ://github.com/Microsoft/msbuild/issues/1054 。评论中提出了修复建议:https ://github.com/Microsoft/msbuild/issues/1054#issuecomment-406438561

当 MsBuild 确定要从引用的项目中复制哪些项目时,它应该递归地执行此操作,但不会正确执行此操作。

作为解决方法,可以将以下内容添加到每个 csproj。

<Target
    Name="ForceAssignProjectConfigurationBeforeSplitProjectReferencesByFileExistence_KLUDGE" 
    BeforeTargets="_SplitProjectReferencesByFileExistence" 
    DependsOnTargets="AssignProjectConfiguration" 
/>
于 2018-11-01T09:21:46.670 回答
0

我只是花了几天时间试图用类似的模式来解决这个问题。在我们的例子中,从输出文件夹中删除的是 nuget 文件。

NugetPackage (that drops files in x86/x64 subfolders in output folder)

LibraryA.dll
   Dependency-> NugetPackage

LibraryB.dll
   Dependency-> LibraryA.dll

在我们的例子中,我们有许多解决方案文件,它们按特定顺序构建为 msbuild 脚本的一部分。问题是 LibraryB.csproj 包含在两个解决方案文件中。

解决方案 1 构建和输出文件都存在。

解决方案 2 构建并看到 LibraryB.dll 存在并且是最新的,因此由于某种原因触发了从输出文件夹中删除 NugetPackage 文件的 IncrementalClean。

从解决方案 2 中删除 LibraryB.csproj 后,问题就解决了,文件出现在输出文件夹中。

于 2021-03-19T12:45:00.667 回答