2012-10-20 10 views
17

मेरे पास बारह समाधान कॉन्फ़िगरेशन के साथ एक विजुअल स्टूडियो 2012 समाधान है। प्रत्येक समाधान कॉन्फ़िगरेशन स्वतंत्र है (यानी, प्रत्येक कॉन्फ़िगरेशन के आउटपुट पूरी तरह से असंबंधित हैं)।मैं समानांतर में एकाधिक कॉन्फ़िगरेशन कैसे बना सकता हूं?

प्रश्न: मैं कैसे एक ही चरण में सभी बारह विन्यास का निर्माण कर सकते हैं, जैसे कि कमांड लाइन पर एक भी MSBuild आदेश चलाकर, और मैं विन्यास समानांतर में निर्मित किया जाना कैसे प्राप्त कर सकते हैं द्वारा?

उदाहरण के तौर पर, अगर केवल दो कॉन्फ़िगरेशन थे, रिलीज/एएनसीपीयू और डीबग/एएनसीपीयूयू, मैं चाहता हूं कि इनमें से दोनों एक ही समय में समानांतर में निर्माण करें।

पूर्णता के लिए, मैंने जो कोशिश की है, वह निम्नलिखित है; मेरे पास अभी तक इस समस्या का समाधान नहीं है।


एक ही बार में सभी परियोजनाओं का निर्माण करने के लिए, मुझे लगता है कि प्रत्येक विन्यास के लिए समाधान फ़ाइल पर MSBuild कार्य चलाता लक्ष्य बिल्ड के साथ एक नई परियोजना फ़ाइल बनाई:

<Target Name="Build"> 
    <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release;Platform=Win32"  Targets="$(BuildCommand)" /> 
    <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release;Platform=x64"  Targets="$(BuildCommand)" /> 
    <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release;Platform=ARM"  Targets="$(BuildCommand)" /> 
    <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release(ZW);Platform=Win32" Targets="$(BuildCommand)" /> 
    <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release(ZW);Platform=x64" Targets="$(BuildCommand)" /> 
    <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release(ZW);Platform=ARM" Targets="$(BuildCommand)" /> 

    <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug;Platform=Win32"  Targets="$(BuildCommand)" /> 
    <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug;Platform=x64"   Targets="$(BuildCommand)" /> 
    <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug;Platform=ARM"   Targets="$(BuildCommand)" /> 
    <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug(ZW);Platform=Win32" Targets="$(BuildCommand)" /> 
    <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug(ZW);Platform=x64"  Targets="$(BuildCommand)" /> 
    <MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug(ZW);Platform=ARM"  Targets="$(BuildCommand)" /> 
</Target> 

यह महान काम करता है, सिवाय इसके कि प्रत्येक एमएसबिल्ड कार्य अनुक्रम में लागू होता है, इसलिए कोई समांतरता नहीं है (हां, समांतरता प्रत्येक कॉन्फ़िगरेशन बिल्ड के भीतर है, लेकिन मैं वास्तव में कॉन्फ़िगरेशन बिल्डों में समांतरता प्राप्त करना चाहता हूं)।

समानांतर में कॉन्फ़िगरेशन प्राप्त करने के प्रयास में, मैंने MSBuild कार्य की BuildInParallel संपत्ति का उपयोग करने का प्रयास किया। मैं एक पूर्व निर्माण कार्य है कि प्रत्येक विन्यास के लिए प्रोजेक्ट फ़ाइलें उत्पन्न लिखा था, तो समानांतर में इन उत्पन्न सभी परियोजनाओं का निर्माण करने का प्रयास किया:

<Target Name="PreBuild" Outputs="%(ProjectConfiguration.Identity)" Returns="%(BuildProject.Identity)"> 
    <Message Text="Cloning Solution for Configuration: %(ProjectConfiguration.Identity)" /> 
    <PropertyGroup> 
    <BuildProjectPath>$(IntPath)\%(ProjectConfiguration.Platform)\%(ProjectConfiguration.Configuration)\build.proj</BuildProjectPath> 
    </PropertyGroup> 
    <ItemGroup> 
    <BuildProject Include="$(BuildProjectPath)" /> 
    </ItemGroup> 
    <MakeDir Directories="$(IntPath)\%(ProjectConfiguration.Platform)\%(ProjectConfiguration.Configuration)" /> 
    <WriteLinesToFile 
    File="$(BuildProjectPath)" 
    Lines="&lt;?xml version='1.0' encoding='utf-8'?&gt; 
&lt;Project DefaultTargets='Build' ToolsVersion='4.0' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'> 
    &lt;Target Name='Build'&gt; 
    &lt;MSBuild 
     Projects='$(SlnPath)' 
     Properties=' 
     SolutionDir=$(MSBuildProjectDirectory)\%3b 
     Configuration=%(ProjectConfiguration.Configuration)%3b 
     Platform=%(ProjectConfiguration.Platform) 
     ' 
     Targets='$(BuildCommand)' 
    /&gt; 
    &lt;/Target&gt; 
&lt;/Project&gt;" 
    Overwrite="true" /> 

</Target> 
<Target Name="Build" DependsOnTargets="PreBuild"> 
    <Message Text="%(BuildProject.Identity)" /> 
    <MSBuild Projects="%(BuildProject.Identity)" Properties="BuildCommand=$(BuildCommand)" BuildInParallel="true" /> 
</Target> 

दुर्भाग्य से, जबकि यह सब बारह विन्यास का निर्माण करता है, यह उन्हें क्रमानुसार बनाता है। मेरा अनुमान है कि जब एमएसबिल्ड परियोजनाओं के सेट पर निर्भरता विश्लेषण करता है, तो यह पहचानता है कि वे सभी एक ही समाधान फ़ाइल पर निर्भर करते हैं, इसलिए यह तय करता है कि उन्हें समानांतर में नहीं बनाया जा सकता है। (यह सिर्फ एक अनुमान है; मैं पूरी तरह गलत हो सकता हूं। मुझे एमएसबिल्ड के बारे में बहुत कम पता है।)

मैं इमारत के दौरान/एम स्विच का भी उपयोग कर रहा हूं।

+1

_why_ के लिए यह महत्वपूर्ण है के रूप में:: उदाहरण बुनियादी दृष्टिकोण दे here मैं अपने निर्माण के समय से कम से कम 37% कटौती कर सकते हैं अगर मैं समानांतर में चलाने के लिए बनाता है प्राप्त कर सकते हैं। (मैंने कमांड लाइन से एमएसबिल्ड के 12 उदाहरण चलाकर इसका परीक्षण किया, और बिल्ड प्रदर्शन में 37% की वृद्धि देखी - 4: 09 बनाम 6:40। इसका नकारात्मक पक्ष यह है कि यह बिल्डों के एकीकृत लॉगिंग को तोड़ देता है ; प्रत्येक बिल्ड अपने स्वयं के लॉग उत्सर्जित करता है।) –

उत्तर

20

एमएसबिल्ड टास्क के BuildInParallel विकल्प का लाभ उठाएं, और सभी परियोजनाओं को एक ही कॉल में पास करें।

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <ItemGroup> 
     <ProjectToBuild Include="a1.sln"> 
      <Properties>Configuration=Debug</Properties> 
     </ProjectToBuild> 
     <ProjectToBuild Include="a1.sln"> 
      <Properties>Configuration=Release</Properties> 
     </ProjectToBuild> 
    </ItemGroup> 
    <Target Name="Build"> 
     <MSBuild Projects="@(ProjectToBuild)" BuildInParallel="true" /> 
    </Target> 
</Project> 
+0

हां, यह शानदार काम करता है। धन्यवाद, जेसन। –

+0

यदि दोनों कॉन्फ़िगरेशन फिर एक और कार्य करने के लिए जाते हैं, तो क्या प्रत्येक कॉन्फ़िगरेशन के तहत इसे घोंसला करना संभव है जैसे प्रत्येक कॉन्फ़िगरेशन के लिए अगले कार्य समानांतर में निष्पादित किए जाते हैं? जैसे यह रिलीज और डिबग करने के लिए इंतजार नहीं करेगा, फिर रिलीज के लिए कार्य ए करें, और डीबग के लिए कार्य ए करें, लेकिन जैसे ही डीबग किया जाता है, डीबग के लिए ए शुरू होता है, और जैसे ही रिलीज़ हो जाता है रिलीज के लिए ए शुरू होता है ? – paulm

+1

यदि मैं आपका प्रश्न सही ढंग से समझता हूं: यह दृष्टिकोण दो पूरी तरह से स्वतंत्र संचालन के रूप में बंद हो जाता है। प्रत्येक जितना तेज़ हो सके उतना पूरा करेगा, दोनों के बीच कोई सिंक्रनाइज़ेशन नहीं होगा। कल्पना कीजिए कि आपने अभी दो कंसोल विंडो लॉन्च की हैं, और प्रत्येक में एमएसबिल्ड टाइप किया है। –