【发布时间】:2022-01-08 15:02:04
【问题描述】:
我所说的实用程序是指没有任何 C# 文件、不生成 .NET 程序集但实现一些自定义构建逻辑的项目。
我本可以将其安排为感兴趣的 C# 项目中的 AfterBuild 目标,但我不想增加该 C# 项目的构建时间。相反,我希望 msbuild 与该 C# 项目的其他依赖项并行运行此逻辑。
一种解决方案是创建一个虚拟 C# 项目,该项目将真正构建一些虚拟代码并将我的逻辑放在 AfterBuild 目标中。但这很丑。
所以,这是我的解决方案(剧透警告 - 它不起作用):
目录结构
C:\work\u [master]> tree /F
Folder PATH listing for volume OSDisk
Volume serial number is F6C4-7BEF
C:.
│ .gitignore
│ Deployer.sln
│
├───Deployer
│ Deployer.csproj
│
├───DeploymentEngine
│ DeploymentEngine.csproj
│
└───Utility
Utility.csproj
C:\work\u [master]>
Deployer.csproj
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{B451936B-54B7-41D1-A359-4B06865248CE}</ProjectGuid>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<OutputType>Library</OutputType>
<BaseOutputPath>bin</BaseOutputPath>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DeploymentEngine\DeploymentEngine.csproj">
<Project>{901487BE-C604-4251-8485-3E96D5993145}</Project>
<Name>DeploymentEngine</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="TakeTime" AfterTargets="Build">
<Exec Command="powershell -NoProfile -Command Start-Sleep -Seconds 5" />
</Target>
</Project>
是的,这是一个遗留风格的项目,因为真正的解决方案是遗留和 SDK 风格项目的混合。
DeploymentEngine.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>
<Target Name="TakeTime" AfterTargets="Build">
<Exec Command="powershell -NoProfile -Command Start-Sleep -Seconds 5" />
</Target>
</Project>
Utility.csproj
<Project>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<EnableDefaultItems>False</EnableDefaultItems>
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
</PropertyGroup>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
<Target Name="Build">
<Message Text="*** Good" Importance="high" Condition="Exists('..\DeploymentEngine\bin\Debug\net472\DeploymentEngine.dll')" />
<Message Text="*** Bad" Importance="high" Condition="!Exists('..\DeploymentEngine\bin\Debug\net472\DeploymentEngine.dll')" />
</Target>
<Target Name="Clean" />
<Target Name="Rebuild" DependsOnTargets="Clean;Build" />
<ItemGroup>
<ProjectReference Include="..\DeploymentEngine\DeploymentEngine.csproj" />
</ItemGroup>
</Project>
Deployer.sln
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31205.134
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deployer", "Deployer\Deployer.csproj", "{B451936B-54B7-41D1-A359-4B06865248CE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeploymentEngine", "DeploymentEngine\DeploymentEngine.csproj", "{901487BE-C604-4251-8485-3E96D5993145}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Utility", "Utility\Utility.csproj", "{9369D18D-D81D-4CA3-A287-C62C89BFB751}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B451936B-54B7-41D1-A359-4B06865248CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B451936B-54B7-41D1-A359-4B06865248CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B451936B-54B7-41D1-A359-4B06865248CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B451936B-54B7-41D1-A359-4B06865248CE}.Release|Any CPU.Build.0 = Release|Any CPU
{901487BE-C604-4251-8485-3E96D5993145}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{901487BE-C604-4251-8485-3E96D5993145}.Debug|Any CPU.Build.0 = Debug|Any CPU
{901487BE-C604-4251-8485-3E96D5993145}.Release|Any CPU.ActiveCfg = Release|Any CPU
{901487BE-C604-4251-8485-3E96D5993145}.Release|Any CPU.Build.0 = Release|Any CPU
{9369D18D-D81D-4CA3-A287-C62C89BFB751}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9369D18D-D81D-4CA3-A287-C62C89BFB751}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9369D18D-D81D-4CA3-A287-C62C89BFB751}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9369D18D-D81D-4CA3-A287-C62C89BFB751}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A70FF6AB-85B1-49F0-B2B0-25E20256A88F}
EndGlobalSection
EndGlobal
注意事项:
- 我对两个“真正的”C# 项目进行了人为延迟。
- 实用程序项目在其声明的依赖项之后运行时输出
*** Bad,即不是在部署引擎项目之后。
现在让我们运行它:
C:\work\u [master]> git clean -qdfx ; msbuild /v:m /restore /m
Microsoft (R) Build Engine version 16.11.0+0538acc04 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
Restored C:\work\u\DeploymentEngine\DeploymentEngine.csproj (in 171 ms).
Restored C:\work\u\Utility\Utility.csproj (in 172 ms).
*** Bad
DeploymentEngine -> C:\work\u\DeploymentEngine\bin\Debug\net472\DeploymentEngine.dll
CSC : warning CS2008: No source files specified. [C:\work\u\Deployer\Deployer.csproj]
Deployer -> C:\work\u\Deployer\bin\Debug\Deployer.dll
C:\work\u [master]>
输出表明 Utility 项目是首先构建的,尽管声明的意图是依赖于 DeploymentEngine 项目。
注意,如果我运行构建单线程输出将是*** Good,所以输出逻辑确实可以正常工作:
C:\work\u [master]> git clean -qdfx ; msbuild /v:m /restore
Microsoft (R) Build Engine version 16.11.0+0538acc04 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
Restored C:\work\u\Utility\Utility.csproj (in 172 ms).
Restored C:\work\u\DeploymentEngine\DeploymentEngine.csproj (in 172 ms).
DeploymentEngine -> C:\work\u\DeploymentEngine\bin\Debug\net472\DeploymentEngine.dll
CSC : warning CS2008: No source files specified. [C:\work\u\Deployer\Deployer.csproj]
Deployer -> C:\work\u\Deployer\bin\Debug\Deployer.dll
*** Good
C:\work\u [master]>
所以仅仅声明ProjectReference 是不够的。似乎我应该实现某种目标以使其工作。
那么我错过了什么?我应该添加什么来让 msbuild 知道 Utility 项目必须在 DeploymentEngine 之后构建?
编辑 1
我知道我可以在解决方案文件中设置依赖项。但是,出于各种原因,我不想这样做。
编辑 2
我的最终目标是拥有一个在一个或多个“真实”C# 项目之后运行的基本实用程序项目。 IE。尽可能少的 .NET 构建导入。如果它可以有.proj 扩展,而不是.csproj - 最好。
【问题讨论】:
-
你是否尝试在VS的解决方案级别设置项目依赖项(右键单击解决方案->项目依赖项)?
-
我忘了说我不想这样做。让我更新帖子。
-
您是否手动创建了解决方案?如果我将像您这样的项目添加到解决方案中,它似乎会自动找出 ProjectReference 表示依赖项并在项目依赖项中显示它。因此,事情以正确的构建顺序工作。此外,不允许删除该依赖项:“此依赖项是由项目系统添加的,无法删除”(另一方面,.sln 中也没有来自它的跟踪,所以似乎只是 ProjectReference 负责处理它)。 tldr;也不能在命令行上重现。提供最少的样本?
-
@stijn - 我已经用最少的复制更新了这个问题。非常感谢。
-
好吧,我错过了前面的
-m,确实引入了问题
标签: msbuild