A növekményes projektösszeépítő egy objektum, amely egy adott módon kezeli a projekt erőforrásait. A növekményes projektösszeépítők gyakran alkalmaznak egy átalakítást az erőforráson egy erőforrás vagy más típusú termék előállításához.
A bedolgozók növekményes projektösszeépítőket biztosítanak a platformhoz a speciális erőforrás-átalakítások megvalósításához. A Java fejlesztőeszközök (JDT) például megadnak egy növekményes projektösszeépítőt, amely lefordítja a Java forrásfájlt az osztályfájlra, amikor a fájl hozzáadásra vagy módosításra kerül a Java projektben. Nyomonköveti a függő fájlokat és szükség esetén lefordítja őket.
Az API szemszögéből a platform két alaptípusú összeépítést ad meg:
A növekményes összeépítések az erőforrás-változásra épül. A változás tükrözi az összes erőforrás-módosítás hálózati hatását, mióta az összeépítő utoljára létrehozta a projektet. A delta hasonlít az erőforrásmódosítási eseményekben használttal.
A felhasználók a projekteket rendszeres időközönként kiüríthetik a projekt következő növekményes összeépítésekor a teljes projekt újraépítésének érdekében. A projekt kiürítése eltávolítja az összeépítési információkat, mint például a problémajelzők vagy osztályfájlok.
Az összeépítők legjobban egy példán keresztül érthetők meg. A JDT Java fordítót egy Java növekményes projektösszeépítő vezérli, amely lefordítja a módosított projektfájlokat. Teljes összeépítés aktiválásakor (vagy kiürítés utáni növekményes összeépítéskor) a projekt összes .java fájlja lefordításra kerül. A fordítási problémák problémajelzőként kerülnek hozzáadásra a .java fájlokhoz. Növekményes összeépítés aktiválásakor az összeépítő szelektíven lefordítja a hozzáadott, módosított vagy másképpen befolyásolt .java fájlokat, amelyek leírásra kerülnek az erőforrásváltozásokban és szükség szerint frissíti a problémajelzőket. A már nem megfelelő .class fájlok vagy jelzők eltávolításra kerülnek.
A növekményes összeépítésnek nyilvánvaló teljesítményelőnyei vannak a többszáz vagy többezer erőforrással rendelkező projekt esetén, amelyek nagy része nincs módosítva egy tetszőleges időpontban.
A növekményes összeépítés technikai problémája annak meghatározása, hogy pontosan mit kell újból összeépíteni. A Java összeépítő által karbantartott belső állapot például olyan dolgokat tartalmaz, mint a függőségi gráf és a jelentett fordítási problémák. Ezt az információt a növekményes összeépítés használja annak azonosításához, hogy mely osztályokat kell újrafordítani a Java erőforrás módosításakor.
Az összeépítés alap struktúrája a platformban van megadva, a valós munka pedig az összeépítőkódban történik. Az összetett növekményes összeépítők megvalósításának mintái túlmutatnak ezen a leíráson, mivel a megvalósítás független az adott összeépítő-kialakítástól.
Az összeépítő explicit módon meghívható az alábbiak szerint:
Gyakorlatban a munkaterület-felhasználó aktivál egy összeépítést az erőforrásnavigátor-menü megfelelő parancsainak kiválasztásával.
A növekményes projektösszeépítőket a platform implicit módon is meghívja az automatikus összeépítés során. Ha engedélyezve van, akkor az automatikus összeépítések a munkaterület módosításakor futnak.
Az org.eclipse.core.resources.builders kiterjesztési pont egy növekményes projektösszeépítőt biztosít a platformhoz. Az alábbi leírónyelv megjeleníti, hogy az elképzelt com.example.builders bedolgozó hogyan hoz létre egy növekményes projektösszeépítőt.
<extension
id="mybuilder" name="My Sample Builder" point="org.eclipse.core.resources.builders">
<builder
<run
class="com.example.builders.BuilderExample">
<parameter name="optimize" value="true" />
<parameter name="comment" value="Builder comment" />
</run>
</builder>
</extension>
A kiterjesztési pontban azonosított osztálynak ki kell terjesztenie az IncrementalProjectBuilder platformosztályt.
public class BuilderExample extends IncrementalProjectBuilder {
IProject[] build(int kind, Map args, IProgressMonitor monitor)
throws CoreException {
// logika megadása
return null;
}
protected void startupOnInitialize() {
// inicializálás
}
protected void clean(IProgressMonitor monitor) {
// összeépítő kiürítési logika megadása
}
}
Az összeépítés-feldolgozás a build() metódussal kezdődik, amely a kért összeépítés típusáról tartalmaz információkat. Az összeépítés az alábbi értékek egyikével rendelkezhet:
Egy növekményes összeépítés kérésekor a rendszer egy erőforrás-változást biztosít az erőforrásban az utolsó összeépítés óta történt módosítások leírása érdekében. Az alábbi részlet tovább finomítja a build() metódust.
protected IProject[] build(int kind, Map args, IProgressMonitor monitor
throws CoreException {
if (kind == IncrementalProjectBuilder.FULL_BUILD) {
fullBuild(monitor);
} else {
IResourceDelta delta = getDelta(getProject());
if (delta == null) {
fullBuild(monitor);
} else {
incrementalBuild(delta, monitor);
}
}
return null;
}
Néha előfordul, hogy az "X" projekt összeépítésekor az összeépítőnek egy másik "Y" projekt módosításaival kapcsolatos információkra van szüksége. (Ha az X Java osztálya például az Y által biztosított felületet valósítja meg.) X összeépítésekor az Y deltája a getDelta(Y) meghívásával áll rendelkezésre. Annak biztosításához, hogy a platform szolgáltathasson ilyen változásokat, az X összeépítőjének deklarálnia kell az X és Y közötti függőségeket az Y-t tartalmazó tömb build() hívásból visszaadásával. Ha az összeépítő nem rendelkezik függőségekkel, akkor egyszerűen nullát ad vissza. További információkat az IncrementalProjectBuilder tartalmaz.
A teljes összeépítés kérés feldolgozásához szükséges logika bedolgozó-specifikus. Ez magában foglalja a projekt összes erőforrásának meglátogatását, vagy akár egyéb projektek megvizsgálását, ha függőségek vannak a projektek között. Az alábbi részlet bemutatja a teljes összeépítés egy lehetséges megvalósítását.
protected void fullBuild(final IProgressMonitor monitor) throws CoreException {
try {
getProject().accept(new MyBuildVisitor());
} catch (CoreException e) { }
}
Az összeépítés-látogató végrehajtja az adott erőforrás összeépítését (és igaz választ ad az összes leszármazott erőforrás meglátogatására).
class MyBuildVisitor implements IResourceVisitor {
public boolean visit(IResource res) {
//összeépíti a megadott erőforrást.
//igaz értékkel tér vissza a leszármazott látogatásának folytatására.
return true;
}
}
A látogatás folyamat addig folytatódik, amíg a teljes erőforrásfa be nincs járva.
Növekményes összeépítés végrehajtásakor az összeépítő egy erőforrásmódosító-változást használ egy teljes erőforrásfa helyett.
protected void incrementalBuild(IResourceDelta delta,
IProgressMonitor monitor) throws CoreException {
// a látogató nem működik.
delta.accept(new MyBuildDeltaVisitor());
}
A látogatási folyamat addig folytatódik, amíg a teljes erőforrás-különbségfa be nincs járva. A módosítások természete hasonlít az Erőforrásmódosítás-figyelő részben leírthoz. Egy fontos különbség, hogy növekményes projektösszeépítők esetén egy adott projektre, nem a teljes munkaterületre épülő erőforrásváltozást kezel.
A munkaterület lehetővé teszi a felhasználók számára, hogy egy összeépítés kezdeményezése előtt kiürítsenek egy projektet vagy projektek halmazát. Ezen szolgáltatás segítségével a felhasználó adott projektek esetén kényszeríthet egy újraépítést teljesen elölről. Az összeépítőknek meg kell valósítaniuk ezt a metódust a problémajelzők vagy származtatott erőforrások kiürítéséhez a projektben.
Ahhoz, hogy egy összeépítő rendelkezésre álljon egy adott projekthez, meg kell adni a projekt összeépítés-specifikációjában. A projekt összeépítési specifikációja a futtatandó parancsok listája sorrendben a projekt összeépítésekor. Minden parancs megnevez egy növekményes projektösszeépítőt.
MEGJEGYZÉS: Az összeépítés parancsban az összeépítő neve az összeépítő kiterjesztés teljes képzésű azonosítója. Egy kiterjesztés teljes képzésű azonosítója a bedolgozó azonosítójának és a plugin.xml fájlban lévő egyszerű kiterjesztési azonosítónak az egyesítésével kerül létrehozásra. Például a "com.pelda.osszeepitok" bedolgozóban lévő "sajat_osszeepito" egyszerű névvel rendelkező összeépítő neve "com.pelda.osszeepitok.sajat_osszeepito" lenne.
Az alábbi részlet hozzáad egy új összeépítőt elsődleges összeépítőként az összeépítők meglévő listájában.
final String BUILDER_ID = "com.pelda.osszeepitok.sajat_osszeepito";
IProjectDescription desc = project.getDescription();
ICommand[] commands = desc.getBuildSpec();
boolean found = false;
for (int i = 0; i < commands.length; ++i) {
if (commands[i].getBuilderName().equals(BUILDER_ID)) {
found = true;
break;
}
}
if (!found) {
//összeépítő projekthez adása
ICommand command = desc.newCommand();
command.setBuilderName(BUILDER_ID);
ICommand[] newCommands = new ICommand[commands.length + 1];
// Hozzáadás más összeépítők előtt.
System.arraycopy(commands, 0, newCommands, 1, commands.length);
newCommands[0] = command;
desc.setBuildSpec(newCommands);
project.setDescription(desc, null);
}
A projekt összeépítőjének beállítása csak egyszer történik meg, általában a projekt létrehozásakor.