BuildAMation
Utvecklare | Markera final |
---|---|
Initial release | 7 januari 2018 |
Stabil frisättning | v2.0.0 / 9 september 2019
|
Skrivet i | C# |
Operativ system | Windows , macOS , Linux |
Typ | Verktyg för mjukvaruutveckling |
Licens | Ny BSD-licens |
Hemsida |
BuildAMation (Bam) var ett gratis och öppen källkodssystem för flera plattformar för att skriva en enda beskrivning av hur man bygger programvara för stationära datorer. Den definierar en utökningsbar arkitektur baserad på C# , och exponerar en deklarativ syntax för att beskriva beroenden mellan byggbara moduler. Kärnsammansättningen avslöjar ett generiskt beroendesystem, medan paket med C#-skript utökar stödet till flertrådiga kommandoradsbyggnationer, Microsoft Visual Studio- projekt- och lösningsgenerering, Apple Xcode- projekt- och arbetsytagenerering och Makefile -generering.
Funktioner
BuildAMation stöder byggkod för C / C++ och Objective C- derivat. Den skriver byggutdata till en mapp som heter byggroten. Denna out-of-place build säkerställer att källträd inte modifieras av en build, och att utföra en ren build är lika enkelt som att ta bort en katalog.
BuildAMation kan utökas genom att definiera paket. Paket är vilken katalog som helst som innehåller en speciell bam-mapp, som innehåller filer som BuildAMation använder. Filerna som krävs är en XML- fil, kallad paketdefinitionsfilen, som finns direkt i bam-mappen, som beskriver paketberoendena. Dessutom, i en Scripts-underkatalog av bam, finns det C#-filer som visar vad det aktuella paketet gör. Paket kan logiskt grupperas i arkiv.
Exempel på BuildAMation-paket som tillhandahålls erbjuder stöd för olika kompilatorverktygskedjor och bygglägen. Sådana verktygskedjor är Microsoft Visual Studio , Clang för Apple, GCC för Linux och flera versioner av varje. Bygglägen definierar hur BuildAMation genererar sin utdata. Inbyggt byggläge kör en (fletrådad) kommandoradsbyggnad, medan byggläget VSSolution genererar en Microsoft Visual Studio-lösning och projekt.
Paket definierar moduler. Moduler är antingen konkreta byggbara enheter eller tillhandahåller en abstrakt basklass för att kunna bygga en klass av entitet. Varje modul kan referera till ett verktyg, vilket är det som används för att bygga på den modulen. Ett verktyg är en annan modul som gör att verktyg antingen kan förbyggas (t.ex. en kompilator), eller kan byggas som en del av den aktuella builden. Verktyg definierar inställningar genom en samling gränssnitt, som exponerar namngivna egenskaper för varje alternativ för verktyget. Inställningarna har standardvärden, men varje modul kan individuellt åsidosätta dessa inställningar genom att använda patchar. Patchar kan antingen vara privata (endast appliceras på den aktuella modulen) eller offentliga (tillämpas på den aktuella modulen och de moduler som är beroende av den). Offentliga patchar tillåter att sådana tillstånd som header inkluderar sökvägar exponeras, till exempel från en modul som representerar ett statiskt bibliotek.
Sökvägar i BuildAMation-skript använder makron för att upprätthålla en viss nivå av abstraktion och återanvändning. Makron är inneslutna i $(makronamn) uppmärkning. Fördefinierade strängfunktioner kan också användas i sökvägar och är inneslutna i @funcname(...)-uppmärkning. Kombinationen av makron och funktioner tillåter moduler att återanvända och kombinera delar av källvägar för att generera utdatavägar.
Åkallan
BuildAMation tillhandahåller ett kommandoradsverktyg som heter bam. Den här körbara filen bör anropas i vilken paketkatalog som helst för att bygga det paketet.
Exempel manus
Nedan är ett exempel på BuildAMation-skript från sviten av testpaket som medföljer utgåvan. Den genererar två dynamiska bibliotek skrivna i C, en körbar fil som använder båda biblioteken, och sammanställer sedan de tre binärerna till en katalog så att de är körbara.
använder Bam.Core ; namnutrymme Test13 ; offentlig förseglad klass DynamicLibraryA : C. _ DynamicLibrary { protected override void Init ( Bam . Core . Module parent ) { bas . Init ( förälder ); detta . CreateHeaderContainer ( "$(packagedir)/include/dynamicLibraryA.h" ) ; detta . CreateCSourceContainer ( "$(packagedir)/source/dynamicLibraryA.c" ) ; detta . PublicPatch (( settings , applyedTo ) => { var compiler = settings as C . ICommonCompilerSettings ; if ( null != compiler ) { compiler . IncludePaths . AddUnique ( this . CreateTokenizedString ( "$(packagedir)/include" )); } } ); if ( denna . BuildEnvironment . Platform . Inkluderar ( Bam . Core . EPlatform . Windows ) && denna . Linker är VisualCCommon . LinkerBase ) { this . LinkAgainst < WindowsSDK . WindowsSDK >(); } } } offentlig förseglad klass DynamicLibraryB : C . DynamicLibrary { protected override void Init ( Bam . Core . Module parent ) { bas . Init ( förälder ); detta . CreateHeaderContainer ( "$(packagedir)/include/dynamicLibraryB.h" ) ; detta . CreateCSourceContainer ( "$(packagedir)/source/dynamicLibraryB.c" ) ; detta . PublicPatch (( settings , applyedTo ) => { var compiler = settings as C . ICommonCompilerSettings ; if ( null != compiler ) { compiler . IncludePaths . AddUnique ( this . CreateTokenizedString ( "$(packagedir)/include" )); } } ); detta . LinkAgainst < DynamicLibraryA >(); if ( denna . BuildEnvironment . Platform . Inkluderar ( Bam . Core . EPlatform . Windows ) && denna . Linker är VisualCCommon . LinkerBase ) { this . LinkAgainst < WindowsSDK . WindowsSDK >(); } } } offentlig förseglad klass Tillämpning : C . ConsoleApplication { protected override void Init ( Bam . Core . Module parent ) { bas . Init ( förälder ); var källa = detta . CreateCSourceContainer ( "$(packagedir)/source/main.c" ) ; detta . PrivatePatch ( settings => { var gccLinker = inställningar som GccCommon . ICommonLinkerSettings ; if ( null != gccLinker ) { gccLinker . CanUseOrigin = true ; gccLinker . RPath . AddUnique ( "$ORIGIN" ); } }); detta . CompileAndLinkAgainst < DynamicLibraryA >( källa ); detta . CompileAndLinkAgainst < DynamicLibraryB >( källa ); if ( denna . BuildEnvironment . Platform . Inkluderar ( Bam . Core . EPlatform . Windows ) && denna . Linker är VisualCCommon . LinkerBase ) { this . LinkAgainst < WindowsSDK . WindowsSDK >(); } } } offentlig förseglad klass RuntimePackage : Publisher . Collation { protected override void Init ( Bam . Core . Module parent ) { base . Init ( förälder ); var app = detta . Inkludera < Application > ( C . ConsoleApplication . Key , EPublishingType . ConsoleApplication ); detta . Inkludera < DynamicLibraryA >( C . DynamicLibrary . Key , "." , app ); detta . Inkludera < DynamicLibraryB >( C . DynamicLibrary . Key , "." , app ); } }
Historia
Det som skulle bli BuildAMation började utvecklas 2010, men hette då Opus och lagrades i Google Code . Namnet ändrades 2014 till BuildAMation för att undvika förväxling med det befintliga Opus Make, och flyttades till ett GitHub- projekt. Ett antal mycket tidiga pre-releases gjordes.
Incitamentet för BuildAMation var att övervinna flera hinder som observerats av Mark Final i sin karriär inom mjukvaruteknik; att skriva en enda definition av hur man bygger mjukvara men använda sig av en mängd olika byggmetoder; att använda ett riktigt programmeringsspråk så att felsökning och profilering av byggsystemet kan utnyttja befintlig teknik, utvecklarkunskap och verktyg; för att exponera vanliga kompilator-/länkfunktioner med namn, snarare än att behöva återkalla syntaxen för varje verktygskedja.
Tidigt under 2015 genomgick den deklarativa syntaxen en fullständig omdesign efter att ha märkt att den ursprungliga syntaxen hade vissa begränsningar. En renare, mer utbyggbar syntax används nu och har hjälpt till att förenkla och förbättra befintliga paketskript.