Пошаговое руководство. Создание файла проекта MSBuild с нуля
Языки программирования, предназначенные для платформы .NET Framework, используют файлы проекта MSBuild для описания и контроля процесса построения приложения. Если для создания файла проекта MSBuild используется Visual Studio, соответствующий XML добавляется в файл автоматически. Тем не менее, понимание принципов организации XML и способов его изменения, позволяющих контролировать построение, может вам пригодиться.
Примечание.
Эта статья описывает основные принципы работы MSBuild независимо от пакетов SDK. Здесь не рассматривается сборка с помощью пакета SDK, например при использовании dotnet build
или добавлении атрибута Sdk
в корневой элемент проекта. См. Пакеты SDK для проектов .NET.
Сведения о создании файла проекта для проекта C++ см. в разделе MSBuild (C++).
Это пошаговое руководство содержит описание способов создания основного файла с использованием только текстового редактора. Руководство включает следующие шаги.
Расширение переменной среды PATH.
Создание минимального исходного файла приложения.
Создание минимального файла проекта MSBuild.
Построение приложения с помощью файла проекта.
Добавление свойств для управления построением.
Управление построением с помощью изменений значений свойства.
Добавление целей к построению.
Управление построением путем указания целей.
Инкрементная сборка.
В этом пошаговом руководстве показан способ построения проекта в командной строке и проверка результатов. Дополнительные сведения о платформе MSBuild и ее запуске из командной строки см. в статье Пошаговое руководство. Использование MSBuild.
Для выполнения пошагового руководства необходимо установить решение Visual Studio, которое включает MSBuild и компилятор C#.
Расширение пути
Прежде чем использовать MSBuild, необходимо расширить переменную среду PATH, чтобы включить все необходимые средства. Для этого можно использовать командную строку разработчика для Visual Studio. В Windows 10 ее можно найти в поле поиска на панели задач Windows. Чтобы настроить среду в обычной командой строке или в среде скриптов, запустите файл VSDevCmd.bat, находящийся в подпапке Common7/Tools каталога, в котором установлено решение Visual Studio.
Создание минимального приложения
Этот раздел описывает процедуру создания исходного файла минимального приложения C# с помощью текстового редактора.
В командной строке перейдите к папке, в которой необходимо создать приложение, например \Мои документы\ или \Рабочий стол\.
Создайте вложенную папку \HelloWorld\ и перейдите в нее.
В текстовом редакторе создайте файл HelloWorld.cs, а затем скопируйте и вставьте следующий код:
using System; class HelloWorld { static void Main() { #if DebugConfig Console.WriteLine("WE ARE IN THE DEBUG CONFIGURATION"); #endif Console.WriteLine("Hello, world!"); } }
Создайте приложение, указав в командной строке csc helloworld.cs.
Проверьте приложение, указав в командной строке helloworld.
Должно появиться сообщение Hello, world!.
Удалите исполняемый файл.
Создание минимального файла проекта MSBuild
Теперь, когда у вас есть минимальный исходный файл приложения, вы можете создать минимальный файл проекта для построения приложения. Такой файл проекта содержит следующие элементы.
Необходимый корневой узел
Project
.Узел
ItemGroup
для хранения элементов.Элемент, который ссылается на исходный файл приложения.
Узел
Target
для хранения задач, которые требуются для построения приложения.Элемент
Task
для запуска компилятора C# для сборки приложения.
Создание файла минимального проекта MSBuild
В текстовом редакторе создайте файл HelloWorld.csproj и введите следующий код:
<Project> <ItemGroup> <Compile Include="helloworld.cs" /> </ItemGroup> </Project>
ItemGroup
содержит элементCompile
и указывает один исходный файл в качестве элемента.Добавьте узел
Target
в качестве дочернего элемента узлаProject
. Назовите узелBuild
.<Target Name="Build"> </Target>
Вставьте следующий элемент задачи в качестве дочернего элемента узла
Target
.<Csc Sources="@(Compile)"/>
Сохраните этот файл проекта и назовите его Helloworld.csproj.
Минимальный файл проекта должен выглядеть следующим образом:
<Project>
<ItemGroup>
<Compile Include="helloworld.cs"/>
</ItemGroup>
<Target Name="Build">
<Csc Sources="@(Compile)"/>
</Target>
</Project>
Задачи в целевом объекте сборки выполняются последовательно. В этом случае задача Csc
компилятора C# является единственной. Она ожидает список исходных файлов для компилирования, который задается значением элемента Compile
. Элемент Compile
ссылается на единственный исходный файл Helloworld.cs.
Примечание.
В элементе можно использовать подстановочный знак "звездочка" (*) для ссылки на все файлы, которые имеют расширение имени файла .cs, как показано ниже:
<Compile Include="*.cs" />
Сборка приложения
Теперь используйте только что созданный файл проекта для построения приложения.
В командной строке введите msbuild helloworld.csproj -t:Build.
После этого для создания приложения "Helloworld" будет вызван компилятор C# и построен целевой объект построения файла проекта Helloworld.
Протестируйте приложение, указав в командной строке helloworld.
Должно появиться сообщение Hello, world!.
Примечание.
Чтобы получить более подробную информацию о построении, увеличьте уровень детализации. Чтобы задать "подробный" уровень детализации, введите в командной строке следующую команду:
msbuild helloworld.csproj -t:Build -verbosity:detailed
Добавление свойств построения
Для дальнейшего управления построением можно добавлять свойства построения к файлу проекта. Добавьте следующие свойства.
Свойство
AssemblyName
, чтобы указать имя приложения.Свойство
OutputPath
, чтобы указать папку для хранения приложения.
Добавление свойств построения
Удалите существующий исполняемый файл приложения (позже вы добавите целевой объект
Clean
для обработки удаления старых выходных файлов).В файле проекта вставьте этот элемент
PropertyGroup
сразу после начала элементаProject
:<PropertyGroup> <AssemblyName>MSBuildSample</AssemblyName> <OutputPath>Bin\</OutputPath> </PropertyGroup>
Добавьте задачу в целевой объект построения непосредственно перед задачей
Csc
:<MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
Задача
MakeDir
создает папку, которой присваивается имя свойстваOutputPath
, при условии, что папка с таким именем не существует.Добавьте следующий атрибут
OutputAssembly
к задачеCsc
:<Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
Он поручает компилятору C# создать сборку, присвоить ей имя свойства
AssemblyName
и вставить в папку, которой присвоено имя свойстваOutputPath
.Сохранение изменений.
Файл проекта должен выглядеть следующим образом:
<Project>
<PropertyGroup>
<AssemblyName>MSBuildSample</AssemblyName>
<OutputPath>Bin\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Compile Include="helloworld.cs" />
</ItemGroup>
<Target Name="Build">
<MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
<Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
</Target>
</Project>
Примечание.
Мы рекомендуем добавить разделитель пути в виде обратной косой черты (\) в конце имени папки при его указании в элементе OutputPath
, вместо добавления его в атрибут OutputAssembly
задачи Csc
. Таким образом,
<OutputPath>Bin\</OutputPath>
OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
лучше, чем
<OutputPath>Bin</OutputPath>
OutputAssembly="$(OutputPath)\$(AssemblyName).exe" />
Тестирование свойств построения
Теперь вы можете построить приложение с использованием файла проекта, в котором использовались свойства построения, и указать папку вывода и имя приложения.
В командной строке введите msbuild helloworld.csproj -t:Build.
После этого программа создаст папку \Bin, вызовет компилятор C# для создания приложения MSBuildSample и разместит его в папку \Bin.
Чтобы убедиться, что папка \Bin\ создана и содержит приложение MSBuildSample, введите dir Bin.
Протестируйте приложение, введя Bin\MSBuildSample для запуска исполняемого файла.
Должно появиться сообщение Hello, world!.
Добавление целей построения
Теперь добавьте к файлу проекта еще две цели.
Цель "Очистить", которая удаляет старые файлы.
Цель "Перестроить", которая использует атрибут
DependsOnTargets
для принудительного запуска задачи "Очистить" перед выполнением задачи "Построение".
Теперь, когда целей несколько, можно задать в качестве цели по умолчанию цель "Построение".
Добавление целей построения
В файле проекта добавьте эти две цели сразу после цели "Построение":
<Target Name="Clean" > <Delete Files="$(OutputPath)$(AssemblyName).exe" /> </Target> <Target Name="Rebuild" DependsOnTargets="Clean;Build" />
Цель "Очистить" вызывает задачу "Удалить", чтобы удалить приложение. Цель "Перестроить" не запускается, пока не будут выполнены цели "Очистить" и "Построение". Несмотря на то, что цель "Перестроить" не имеет задач, она вызывает выполнение цели "Очистить" до выполнения цели "Построение".
Добавьте следующий атрибут
DefaultTargets
в начало элементаProject
:<Project DefaultTargets="Build">
Это сделает цель "Построение" целью по умолчанию.
Файл проекта должен выглядеть следующим образом:
<Project DefaultTargets="Build">
<PropertyGroup>
<AssemblyName>MSBuildSample</AssemblyName>
<OutputPath>Bin\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Compile Include="helloworld.cs" />
</ItemGroup>
<Target Name="Build">
<MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
<Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
</Target>
<Target Name="Clean" >
<Delete Files="$(OutputPath)$(AssemblyName).exe" />
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build" />
</Project>
Тестирование целей построения
Для тестирования этих функций файла проекта можно запустить новые цели построения.
Построение по умолчанию.
Задание имени приложения в командной строке.
Удаление приложения перед построением другого приложения.
Удаление приложения без построения другого приложения.
Тестирование целей построения
В командной строке введите msbuild helloworld.csproj -p:AssemblyName=Greetings.
Так как параметр -t для задания цели напрямую не использовался, MSBuild запускает стандартную цель "Сборка". Параметр -p переопределяет свойство
AssemblyName
и присваивает ему новое значениеGreetings
. В результате в папке \Bin\ создается новое приложение Greetings.exe.Чтобы убедиться, что в папке \Bin\ содержатся приложение MSBuildSample и новое приложение Greetings, введите dir Bin.
Протестируйте приложение Greetings (например, введя Bin\Greetings в Windows).
Должно появиться сообщение Hello, world!.
Удалите приложение MSBuildSample с помощью команды msbuild helloworld.csproj -t:clean.
Это запустит задачу "Очистить" и позволит удалить приложение со значением свойства
AssemblyName
по умолчанию —MSBuildSample
.Удалите приложение Greetings с помощью команды msbuild helloworld.csproj -t:clean -p:AssemblyName=Greetings.
Это запустит задачу "Очистить" и позволит удалить приложение с заданным значением свойства AssemblyName по умолчанию —
Greetings
.Чтобы убедиться, что папка \Bin\ пуста, введите dir Bin.
Введите команду msbuild.
Несмотря на то что файл проекта не указан, MSBuild строит файл helloworld.csproj, поскольку в текущей папке присутствует только один файл проекта. В результате в папке \Bin\ создается новое приложение MSBuildSample.
Чтобы убедиться, что в папке \Bin\ появилось приложение MSBuildSample, введите dir Bin.
Инкрементная сборка
MSBuild можно настроить таким образом, чтобы цель строилась только в случае изменения исходного файла или целевых файлов, от которых зависит цель. MSBuild определяет факт изменения файла по отметке времени.
Последовательное построение
В файле проекта добавьте к открытой цели "Построение" следующие два атрибута:
Inputs="@(Compile)" Outputs="$(OutputPath)$(AssemblyName).exe"
Они показывают, что цель "Построение" зависит от входных файлов, указанных в группе элементов
Compile
, и что цель вывода является файлом приложения.Полученная цель "Построение" должна выглядеть следующим образом:
<Target Name="Build" Inputs="@(Compile)" Outputs="$(OutputPath)$(AssemblyName).exe"> <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" /> <Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" /> </Target>
Протестируйте цель "Сборка" с помощью команды msbuild -v:d.
Помните, что helloworld.csproj является файлом проекта по умолчанию, а построение — целью по умолчанию.
Параметр -v:d — это сокращенное обозначение -verbosity:detailed, которое вы использовали ранее.
Если вы уже создали выходные данные, эти строки должны отображаться:
Целевой объект "Сборка" пропускается, так как все выходные файлы актуальны по отношению к входным.
MSBuild пропускает цель "Построение", так как с последнего построения приложения ни один из исходных файлов не изменился.
Пример C#
В следующем примере показан файл проекта, который компилирует приложение C# и записывает сообщение, содержащее имя файла вывода.
Код
<Project DefaultTargets = "Compile">
<!-- Set the application name as a property -->
<PropertyGroup>
<appname>HelloWorldCS</appname>
</PropertyGroup>
<!-- Specify the inputs by type and file name -->
<ItemGroup>
<CSFile Include = "*.cs"/>
</ItemGroup>
<Target Name="Compile">
<!-- Run the C# compilation using input files of type CSFile -->
<CSC
Sources = "@(CSFile)"
OutputAssembly = "$(appname).exe">
<!-- Set the OutputAssembly attribute of the CSC task
to the name of the executable file that is created -->
<Output
TaskParameter = "OutputAssembly"
ItemName = "EXEFile" />
</CSC>
<!-- Log the file name of the output file -->
<Message Text="The output file is @(EXEFile)"/>
</Target>
</Project>
Пример в Visual Basic
В следующем примере показан файл проекта, который компилирует приложение Visual Basic и записывает сообщение, содержащее имя файла вывода.
Код
<Project DefaultTargets = "Compile">
<!-- Set the application name as a property -->
<PropertyGroup>
<appname>HelloWorldVB</appname>
</PropertyGroup>
<!-- Specify the inputs by type and file name -->
<ItemGroup>
<VBFile Include = "consolehwvb1.vb"/>
</ItemGroup>
<Target Name = "Compile">
<!-- Run the Visual Basic compilation using input files of type VBFile -->
<VBC
Sources = "@(VBFile)"
OutputAssembly= "$(appname).exe">
<!-- Set the OutputAssembly attribute of the VBC task
to the name of the executable file that is created -->
<Output
TaskParameter = "OutputAssembly"
ItemName = "EXEFile" />
</VBC>
<!-- Log the file name of the output file -->
<Message Text="The output file is @(EXEFile)"/>
</Target>
</Project>
Дальнейшие действия
Visual Studio может выполнять большую часть работы, описанной в этом пошаговом руководстве, автоматически. Сведения об использовании Visual Studio для создания, изменения, сборки и тестирования файлов проекта MSBuild см. в разделе Пошаговое руководство. Использование MSBuild.