Quanto segue si applica a RAD Studio XE4, ma può valere anche per versioni precedenti o successive. Inoltre, le dipendenze definite in .groupproj non saranno onorate con questo metodo. Il .groupproj che stavo cercando di parallelizzare non aveva dipendenze tra i progetti, quindi non ho capito come gestirlo.
Quando si costruisce a.file groupproj con MSBuild utilizzando il target , Clean
o Make
, la build non viene eseguita in parallelo poiché queste destinazioni utilizzano l'attività CallTarget
per eseguire altri target, ma CallTarget
non esegue le sue destinazioni in parallelo.
Per creare progetti separati in parallelo, il progetto MSBuild deve utilizzare un singolo MSBuild
task per creare più progetti contemporaneamente. Gli obiettivi devono essere definiti in questo modo:
<Target Name="Build">
<MSBuild Projects="@(Projects)" BuildInParallel="true"/>
</Target>
<Target Name="Clean">
<MSBuild Targets="Clean" Projects="@(Projects)" BuildInParallel="true"/>
</Target>
<Target Name="Make">
<MSBuild Targets="Make" Projects="@(Projects)" BuildInParallel="true"/>
</Target>
aggiungere questi al .groupproj, quindi rimuovere gli altri <Target>
direttive, nonché la direttiva <Import>
. (CodeGear.Group.Targets
definisce alcuni obiettivi per creare i progetti nell'ordine corretto e per creare dipendenze quando si chiede di creare solo un sottoinsieme dei progetti, ma sostituisce gli obiettivi , definiti nel file .groupproj.) Si noti che questo solo ti permette di costruire tutti i progetti, non solo un sottoinsieme.
BuildInParallel
was added in MSBuild 3.5. Tuttavia, dal momento che .groupproj file non specificano l'attributo ToolsVersion
, MSBuild utilizzerà il compito MSBuild
come definito nella versione 2.0, che non supporta BuildInParallel
. Ci sono due opzioni per risolvere questo:
- Aggiungi
ToolsVersion="3.5"
(o una versione successiva) per l'elemento principale <Project>
del file .groupproj.
- Eseguire MSBuild con il parametro della riga di comando
/toolsversion:3.5
(o /tv:3.5
in breve) (/toolsversion
ignora la ToolsVersion
specificato in tutti i file di progetto.)
Dopo questa operazione, eseguire MSBuild con la /maxcpucount
(o /m
) e i tuoi progetti dovrebbero costruire in parallelo. Tuttavia, RAD Studio non gestisce correttamente il gruppo di progetto, quindi è consigliabile assegnare al file un'estensione diversa per chiarire che non si tratta di un gruppo di progetti RAD Studio standard (qualsiasi estensione che termina con proj
).
Il seguente foglio di stile XSLT esegue la trasformazione descritto in precedenza:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
exclude-result-prefixes="msbuild"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
xmlns:msbuild="http://schemas.microsoft.com/developer/msbuild/2003"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="//msbuild:Project">
<xsl:copy>
<xsl:attribute name="ToolsVersion">3.5</xsl:attribute>
<xsl:apply-templates select="@* | node()"/>
<Target Name="Build">
<MSBuild Projects="@(Projects)" BuildInParallel="true"/>
</Target>
<Target Name="Clean">
<MSBuild Targets="Clean" Projects="@(Projects)" BuildInParallel="true"/>
</Target>
<Target Name="Make">
<MSBuild Targets="Make" Projects="@(Projects)" BuildInParallel="true"/>
</Target>
</xsl:copy>
</xsl:template>
<xsl:template match="//msbuild:Target">
<!-- Do not copy -->
</xsl:template>
<xsl:template match="//msbuild:Import">
<!-- Do not copy -->
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
È possibile applicare questo foglio di stile con MSBuild (4.0 o versione successiva: XslTransformation
è stato aggiunto in MSBuild 4.0) utilizzando questo file di progetto (dove groupproj2parallel.xslt
è il XSLT file di cui sopra):
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Build" Inputs="$(InputPaths)" Outputs="$(OutputPaths)">
<XslTransformation
XmlInputPaths="$(InputPaths)"
XslInputPath="groupproj2parallel.xslt"
OutputPaths="$(OutputPaths)" />
</Target>
</Project>
è necessario specificare InputPaths
e OutputPaths
esplicitamente sulla riga di comando con /p:InputPaths="..." /p:OutputPaths="..."
, o da loro specificando sulla 0.123.071,618 mila Parametrodi un'attività MSBuild
. (In alternativa, si può semplicemente hardcode i nomi dei file nel file di progetto.)
Le definizioni di destinazione forniti con MSBuild per C# e progetti di Visual Basic gestire le dipendenze utilizzando i <ProjectReference>
elementi di cui i file di progetto, invece di definire dipendenze nel file di soluzione. I file .dproj di Delphi e i file .cbproj di C++ Builder non supportano questo, in quanto il sottostante CodeGear.Common.Targets
non riutilizza la macchina definita in Microsoft.Common.Targets
per <ProjectReference>
.
Dimenticato di menzionare, sto utilizzando Embarcadero delphi XE6 – tabasko
L'ho sempre fatto da solo quando avevo bisogno di script della compilazione utilizzando, ad esempio, Python –
Sarebbe una soluzione sì, ma preferirei non fai questo se c'è un meccanismo "built-in" in msbuild per realizzarlo. – tabasko