Kompilacja Automatyczna: MSBuild Wrocławska Grupa .NET Paweł Hofman Wrocławska Grupa .NET http://www.wrocnet.org Software Engineer Silicon & Software Systems (S3) www.s3group.com TechEd 2002
Agenda Historia – pliki .makefile MSBuild Wymagania Właściwości, elementy, scenariusze… Sposób działania Rozszerzalność Wykorzystanie Wsparcie ze strony oprogramowania innych firm Przykład rozwiązania praktycznego problemu Pytania TechEd 2002
Odrobina historii – make program make / nmake stworzony przez Stuarta Feldmana w 1977 roku (Bell Labs) pliki .makefile składające się z szeregu reguł: <CEL>: <SKŁADNIKI> <KOMENDA>
Odrobina historii – make (2) Przykład pliku .makefile składającego się z trzech reguł: hello: hello.o aux.o gcc hello.o aux.o -o hello hello.o: hello.c gcc -c hello.c -o hello.o aux.o: aux.c gcc -c aux.c -o aux.o źródło: http://www.programuj.com
Odrobina historii – make (3) Przykład pliku .makefile ze zmiennymi: CC=gcc CFLAGS=-g OBJS=hello.o aux.o hello: $(OBJS) $(CC) $(LFLAGS) $^ -o $@ źródło: http://www.programuj.com
MS Build
MSBuild - Postawowy Wprowadza pojęcia: właściwości (properties) elementów podlegających przetwarzaniu (items) zadań (tasks) scenariuszy (targets) projekt MSBuild właściwości elementy scenariusz zadania zadania
MS Build zwyczajne pliki XML dostępny za darmo w wersjach SDK: .NET 2.0 .NET 3.0 i 3.5 Mono – własna implementacja - xbuild pliki projektów *.csproj, *.vbproj, *.vcproj (VS 2008) oraz *.sln pliki *.targets i *.proj
Przykład (1) <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <OutputType>EXE</OutputType> <RootNamespace>VisualEditor.Registry</RootNamespace> <AssemblyName>VisualEditor.Registry</AssemblyName> <StartupObject>VisualEditor.Registry.Program</StartupObject> <Optimize>true</Optimize> <OutputPath>..\..\..\output\</OutputPath> <DefineConstants>TRACE</DefineConstants> <WarningLevel>4</WarningLevel> </PropertyGroup> ...
Przykład (2) Sekcje: PropertyGroup ItemGroup ... <ItemGroup> <Reference Include="System" /> <Reference Include="System.Xml" /> </ItemGroup> <Compile Include="Program.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> </Project> Sekcje: PropertyGroup właściwości (również warunkowe) o dowolnych nazwach ItemGroup elementy kompilacji (również zależne rekurencyjnie) zależności (referencje do innych modułów i metadanych) import innych projektów
Znaki specjalne źródło - MSDN Znak Opis i znaczenie % znak procenta – odwołania do metadanych (np. pełna ścieżka do pliku) $ znak dolara – odwołanie do właściwości @ znak małpy – odwołanie do elementów listy ( nawias otwierający – użycie w listach ) nawias zamykający – użycie w listach ` apostrof – wyrażenia w warunkach ; średnik – separator elementów listy ? znak zapytania – maska pojedynczego znaku przy nazwie pliku w elementach sekcji Include/Exclude * gwiazdka – maska znaku przy nazwie pliku i rekurencyjnym przeglądaniu katalogów w elementach sekcji Include/Exclude źródło - MSDN
MSBuild – Scenariusze (1) zależności wywołań definiowanie własnych uruchamianie z poziomu VisualStudio uruchamianie z poziomu konsoli MSBuild.exe SuperApp.sln /t:Rebuild /p:Configuration=Release
MSBuild – Scenariusze (2) <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <OutputType>EXE</OutputType> <AssemblyName>VisualProject.Registry</AssemblyName> </PropertyGroup> <ItemGroup> <Compile Include=".\**\*.cs" /> </ItemGroup> <ProjectReference Include="ReferencedProject.proj"/> <Target Name="default" DependsOnTargets="BuildProjectReferences"> <Message Text="Building project..."/> </Target> <Target Name="BuildProjectReferences"> <MSBuild Projects="@(ProjectReference)" /> </Project>
MSBuild – Zadania zadania (tasks) warunkowe – if, switch, ale i każdy element posiada atrybuty: Condition="'$(CONFIG)'=='DEBUG'" Condition="!Exists('$(builtdir)')" wbudowane Compile / RegisterAssembly / MSBuild / Exec Copy / Delete / WriteLinesToFile / ReadLinesFromFile Message / Warning / Error… własne zadania napisane w .NET assembly (referencja do klasy w projekcie MSBuild) implementuje interfejs (Microsoft.Build.Framework.ITask)
MSBuild – Własne zadania Wywołanie i zapamiętanie wyniku zadania: ... <UsingTask AssemblyFile="C:\...\Community.Tasks.DLL" TaskName="MSBuild.Community.Tasks.Mail" /> <Target Name="SendEmail"> <Mail SendTo="build@company.com"> <Output TaskParameter="Content" PropertyName="MailContent"/> </Mail> <Message Text="Content: $(MailContent)” /> </Target>
MSBuild – Zadania (2) metadane: źródło - MSDN Element Opis i znaczenie ... <ItemGroup> <MyItem Include="Source\Program.cs" /> </ItemGroup> <MyItem Include="C:\**\Source\Program.cs" /> metadane: źródło - MSDN Element Opis i znaczenie %(FullPath) pełna ścieżka dokumentu; C:\MyProject\Source\Program.cs %(RootDir) dysk; C:\ %(Filename) nazwa pliku; Program %(Extension) rozszerzenie; .cs %(RelativeDir) folder względny; Source\ %(Directory) folder pliku; MyProject\Source\ %(RecursiveDir) folder przy rekurencyjnym przeglądaniu w poszukiwaniu pliku; MyProject\Source\
MSBuild – Zadania (3) Przykład kopiowania wszystkich plików dołączonych do projektu jako ‘ItemToCopy’: ... // property <ItemToCopyDestDir>C:/dest/</ItemToCopyDestDir> ... // item <ItemToCopy Include="C:/src/**/*.txt" /> ... // target <Copy SourceFiles="@(ItemToCopy->‘%(FullPath)')" DestinationFiles= "@(ItemToCopy->‘$(ItemToCopyDestDir)%(Filename)%(Extension)')" /> ...
Przykład (3) Przebieg procesu kompilacji (CSharp.targets): <PropertyGroup> <CoreBuildDependsOn> BuildOnlySettings; PrepareForBuild; PreBuildEvent; UnmanagedUnregistration; ResolveReferences; PrepareResources; ResolveKeySource; Compile; GenerateSerializationAssemblies; CreateSatelliteAssemblies; GenerateManifests; GetTargetPath; PrepareForRun; UnmanagedRegistration; IncrementalClean; PostBuildEvent </CoreBuildDependsOn> </PropertyGroup>
Dodatkowe wsparcie ze strony JetBrains CruiseControl.NET R# 3.1 i 4.0 (*.proj) TeamCity 3.1 CruiseControl.NET poprzez <execute> MSBuild Sidekick dodatkowe zadania od społeczności .NET pakowanie wysyłanie na serwer ftp wysyłanie wiadomości pocztowych uruchamianie testów NUnit http://msbuildtasks.tigris.org/
JetBrains - TeamCity
JetBrains – TeamCity (2)
ZADANIE
Problem do rozwiązania istniejący projekt różna wersja programu przy kompilacji (zaangażowani programiści (build system – kolejny numer wersja 0.0.0.0) zgodny ze własnymi regułami) 0.0.0.0 x.y.z.b
Demo
MSBuild – Przed i po kompilacji Niebezpieczny przykład wykonania własnych zadań przed i po kompilacji projektu: te scenariusze mogą już istnieć w załączanym (importowanym) projekcie !!! ... <Target Name="BeforeBuild"> <Message Text="Applied before build." Importance="high" /> </Target> <Target Name="AfterBuild"> <Message Text="Applied after build." Importance="high" />
MSBuild – Przed i po kompilacji Bezpieczne wykonanie własnych zadań przed i po kompilacji projektu: ... <PropertyGroup> <CoreBuildDependsOn> CreateVersionFile; $(CoreBuildDependsOn); DeleteVersionFile; </CoreBuildDependsOn> </PropertyGroup> <Target Name="CreateVersionFile"> <Message Text="Applied before compile." Importance="high" /> </Target> <Target Name="DeleteVersionFile"> <Message Text="Applied after compile." Importance="high" />
Podsumowanie podstawowe zasady działania poprzez rozszerzenia stworzone przez entuzjastów zyskały ‘bardzo dużo’ funkcjonalności MSBuild umożliwia: rozszerzanie o własne zadania definiowanie wielu scenariuszy warunkowe łączenie scenariuszy
Pytania ? Przykładowe pytania, które mogą paść:
google + „visual studio videos 2008 extensibility” Źródła Filmy instruktarzowe: google + „visual studio videos 2008 extensibility” Kody źródłowe: http://msbuildtasks.tigris.org/ Strona domowa: google + „msbuild”