Я работаю над настройкой собственного сервера сборки, адаптированной к потребностям команды. Он должен автоматически создавать наши решения. net. Я делаю все возможное, чтобы ничего не менять в .sln или файлах проекта.
Очевидным инструментом для сборки является msbuild
. Я понял, что на самом деле успешно скомпилировал наши решения из файлов .sln.
Следующим шагом является тестирование сценария, когда некоторые проекты решения не работают. И тут я столкнулся со странной разницей в поведении между devenv
и msbuild
в следующей ситуации. Есть 3 проекта, где 2-й зависит от 1-го, а 3-й является независимым и не работает. devenv
компилирует 1-й и 2-й и завершает работу 3-го, как и ожидалось; msbuild
компилирует 1-е, терпит неудачу 3-е и - неожиданно - не пытается 2-е.
Пример решения (4 файла: Complete.sln, 1.csproj, 2.csproj, 3.csproj)
--- 1.csproj
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>2.0</OldToolsVersion>
</PropertyGroup>
<Target Name="Build">
<Message Importance="High" Text="Project 1" />
</Target>
</Project>
--- 2.csproj
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>2.0</OldToolsVersion>
</PropertyGroup>
<Target Name="Build">
<Message Importance="High" Text="Project 2" />
</Target>
</Project>
--- 3.csproj
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>2.0</OldToolsVersion>
</PropertyGroup>
<Target Name="Build">
<Message Importance="High" Text="Project 3" />
<Error Text="Build failed" />
</Target>
</Project>
--- Complete.sln
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29709.97
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "1", "1.csproj", "{AA88BE9A-5006-4CCE-8871-A67F413DBADF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "2", "2.csproj", "{BAF51480-4B90-454A-96F5-E63A05A486EF}"
ProjectSection(ProjectDependencies) = postProject
{AA88BE9A-5006-4CCE-8871-A67F413DBADF} = {AA88BE9A-5006-4CCE-8871-A67F413DBADF}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "3", "3.csproj", "{12C30CFB-7387-4CD2-81D4-87E14209C408}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AA88BE9A-5006-4CCE-8871-A67F413DBADF}.Debug|x86.ActiveCfg = Debug|x86
{AA88BE9A-5006-4CCE-8871-A67F413DBADF}.Debug|x86.Build.0 = Debug|x86
{BAF51480-4B90-454A-96F5-E63A05A486EF}.Debug|x86.ActiveCfg = Debug|x86
{BAF51480-4B90-454A-96F5-E63A05A486EF}.Debug|x86.Build.0 = Debug|x86
{12C30CFB-7387-4CD2-81D4-87E14209C408}.Debug|x86.ActiveCfg = Debug|x86
{12C30CFB-7387-4CD2-81D4-87E14209C408}.Debug|x86.Build.0 = Debug|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {75E95C15-489D-4D3F-82CA-735FB7B88910}
EndGlobalSection
EndGlobal
Вывод на консоль из «Командная строка разработчика для VS 2019» выглядит следующим образом:
e>devenv /Build Debug Complete.sln
Microsoft Visual Studio 2019 Version 16.4.3.
Copyright (C) Microsoft Corp. All rights reserved.
1>------ Build started: Project: 1, Configuration: Debug x86 ------
2>------ Build started: Project: 3, Configuration: Debug x86 ------
1> Project 1
2> Project 3
2>C:\temp\msbuild\TestSolution\Complete\3.csproj(11,2): error : Build failed
3>------ Build started: Project: 2, Configuration: Debug x86 ------
3> Project 2
========== Build: 2 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
>msbuild Complete.sln /p:Configuration=Debug /p:Platform=x86 /m
Microsoft (R) Build Engine version 16.4.0+e901037fe for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Build started 23.01.2020 11:10:38.
1>Project "c:\temp\msbuild\TestSolution\Complete\Complete.sln" on node 1 (default targets).
1>ValidateSolutionConfiguration:
Building solution configuration "Debug|x86".
1>Project "c:\temp\msbuild\TestSolution\Complete\Complete.sln" (1) is building "c:\temp\msbuild\TestSolution\Complete\1.cs
proj" (2) on node 1 (default targets).
2>Build:
Project 1
2>Done Building Project "c:\temp\msbuild\TestSolution\Complete\1.csproj" (default targets).
1>Project "c:\temp\msbuild\TestSolution\Complete\Complete.sln" (1) is building "c:\temp\msbuild\TestSolution\Complete\3.cs
proj" (3) on node 2 (default targets).
3>Build:
Project 3
3>c:\temp\msbuild\TestSolution\Complete\3.csproj(11,5): error : Build failed
3>Done Building Project "c:\temp\msbuild\TestSolution\Complete\3.csproj" (default targets) -- FAILED.
1>Done Building Project "c:\temp\msbuild\TestSolution\Complete\Complete.sln" (default targets) -- FAILED.
Build FAILED.
"c:\temp\msbuild\TestSolution\Complete\Complete.sln" (default target) (1) ->
"c:\temp\msbuild\TestSolution\Complete\3.csproj" (default target) (3) ->
(Build target) ->
c:\temp\msbuild\TestSolution\Complete\3.csproj(11,5): error : Build failed
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:00.65
Обратите внимание, что в msbuild
выводится сообщение Project 2
.
Есть ли (ненавязчивый) способ заставить msbuild
продолжать компиляцию других проектов?
Лучшее, что я до сих пор придумывал, - это создание Directory.Solution.targets
в какой-то папке вверх от Complete.sln
(см. msdn ) со следующим содержимым.
<Project>
<Target Name="SetSkip">
<ItemGroup>
<ProjectReference Update="*">
<SkipNonexistentProjects>Build</SkipNonexistentProjects>
</ProjectReference>
</ItemGroup>
</Target>
<Target Name="BuildAll" DependsOnTargets="SetSkip">
<CallTarget Targets="Build"/>
</Target>
</Project>
Примечание SkipNonexistentProjects
установлено на Build
, а не True
. Когда установлено значение True
, второй проект пропускается с Skipping project "2.csproj.metaproj" because it was not found.
.
, а затем вызывается msbuild
с /t:BuildAll
вместо /t:Build
. Но мне нужно было бы сделать это для каждого возможного решения и каждой возможной цели, и я бы действительно хотел какой-нибудь лучший способ, возможно, переключатель командной строки, который я пока не смог найти (/p:ContinueOnError=true;StopOnFirstFailure=false;SkipNonexistentProjects=true
не помогает).
ОБНОВЛЕНИЕ улучшил мой обходной путь: теперь требуется только один дополнительный файл в папке root.