2011-05-23 10 views
7

मैं अपने निर्माण को गति देने की कोशिश कर रहा हूं (csharp, msbuild, .NET 3.5)। Fsutil हार्डलिंक बनाने के साथ प्रतिलिपि बदलें।धीमी प्रतिलिपि कार्यों के बजाय fsutil हार्डलिंक के साथ msbuild को गति दें

पहले, मुझे लगभग एसएलएन फाइलों पर एक स्क्रिप्ट चलाने और डीएल संदर्भ निजी = झूठी बनाने के साथ मिल गया, फिर एक पोस्ट बिल्ड इवेंट हार्डलिंक बनाते हैं। समस्या ट्रांजिटिव निर्भरता शामिल नहीं है। इसलिए, मुझे लगता है कि मुझे msbuild में ResolveAssemblyReference कार्य को संदर्भित करने की आवश्यकता है ताकि मुझे ट्रांजिटिव निर्भरता प्राप्त हो सके जो मुझे हार्डलिंक करने की आवश्यकता है।

कोई विचार?

This व्यक्ति ने एक ही चीज़ की कोशिश की, लेकिन अंतिम समाधान पोस्ट नहीं किया।

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

+1

क्यों अपने सभी बिन करने के लिए एक DEVPATH सेट अप नहीं बजाय फ़ोल्डर। फिर आपको कॉपीलोकल को बंद करने के अलावा कुछ भी करने की आवश्यकता नहीं है। http://blogs.msdn.com/b/junfeng/archive/2005/12/13/503059.aspx – adrianm

उत्तर

6

यह वीएस 2010 में समर्थित है। लेकिन 2008 नहीं। _CopyFilesMarkedCopyLocal में कॉपी करने के लिए UseHardLinksIfPossible विकल्प देखें।

संदर्भ के लिए http://social.msdn.microsoft.com/Forums/en/tfsbuild/thread/9382a3d8-4632-4826-ad15-d5e845080981, http://msdn.microsoft.com/en-us/library/ms171466(v=VS.90).aspx देखें।

_CopyFilesMarkedCopyLocal लक्ष्य को ओवरराइड करें। हम इस तरह से csproj फ़ाइलों को इस तरह कुछ जोड़ते हैं: <Import Project="..\..\..\..\..\\CommonBuild\TW.Override.Microsoft.Common.targets" /> (यह प्रत्येक पूर्ण नैन निर्माण पर एक नैन कार्य के साथ फ़ाइल में स्वतः जोड़ा गया है, इसलिए प्रत्येक परियोजना लाभ)।

हमारे नए लक्ष्य फ़ाइल है:

 
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <UsingTask TaskName="CopyWithHardlinkOption" AssemblyFile="..\lib\TWBuildOptimization\TW.Hardlinker.dll" /> 
    <!-- 
    ============================================================ 
             _CopyFilesMarkedCopyLocal 
    Overridden in order to allow hardlinking with our custom Copy Task.           

    Hardlinking is a major performance improvement. Sometimes 50% of the time compared to copying. 

    Copy references that are marked as "CopyLocal" and their dependencies, including .pdbs, .xmls and satellites. 
    ============================================================ 
    --> 
    <Target 
     Name="_CopyFilesMarkedCopyLocal"> 
     <CopyWithHardlinkOption 
      SourceFiles="@(ReferenceCopyLocalPaths)" 
      DestinationFiles="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" 
      SkipUnchangedFiles="true" 
       UseHardlinksIfPossible="true" 
      OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"> 
      <Output TaskParameter="DestinationFiles" ItemName="FileWritesShareable"/> 
     </CopyWithHardlinkOption> 
    </Target> 
</Project> 

MSBuild 4 कॉपी UseHardlinksIfPossible विकल्प देखें। मैंने डिकंपलिंग और पुनर्मूल्यांकन के माध्यम से 3.5 तक इसका समर्थन किया। CopyFileWithLogging में प्रासंगिक तर्क था:

 // The port from 4.0's task that allows hardlinking 
     bool hardlinkSucceeded = false; 
     if (UseHardlinksIfPossible) 
     { 
      if (File.Exists(destinationFile)) 
      { 
       FileUtilities.DeleteNoThrow(destinationFile); 
      } 
      if (!TwNativeMethods.CreateHardLink(destinationFile, sourceFile, IntPtr.Zero)) 
      { 
       var win32Exception = new Win32Exception(Marshal.GetLastWin32Error()); 
       Log.LogMessage(MessageImportance.High, "Hardlinking had a problem {0}, will retry copying. {1}", new object[] {win32Exception.Message, win32Exception}); 
      } 
      hardlinkSucceeded = true; 
     } 
     if (!hardlinkSucceeded) 
     { 
      Log.LogMessageFromResources(MessageImportance.Normal, "Copy.FileComment", new object[] { sourceFile, destinationFile }); 
      Log.LogMessageFromResources(MessageImportance.Low, "Shared.ExecCommand", new object[0]); 
      Log.LogCommandLine(MessageImportance.Low, "copy /y \"" + sourceFile + "\" \"" + destinationFile + "\""); 
      File.Copy(sourceFile, destinationFile, true); 
     } 
     // end port 

इसके अलावा इन्हें जोड़ने के लिए किया था:

// decompiled from 4.0 
internal static class TwNativeMethods 
{ 
    [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)] 
    internal static extern bool CreateHardLink(string newFileName, string exitingFileName, IntPtr securityAttributes); 
} 

// decompiled from 4.0 
internal static class FileUtilities 
{ 
    internal static void DeleteNoThrow(string path) 
    { 
     try 
     { 
      File.Delete(path); 
     } 
     catch (Exception exception) 
     { 
      if (ExceptionHandling.NotExpectedException(exception)) 
      { 
       throw; 
      } 
     } 
    } 
} 

// decompiled from 4.0 
internal static class ExceptionHandling 
{ 
    // Methods 
    internal static bool IsCriticalException(Exception e) 
    { 
     return (((e is StackOverflowException) || (e is OutOfMemoryException)) || ((e is ExecutionEngineException) || (e is AccessViolationException))); 
    } 

    internal static bool NotExpectedException(Exception e) 
    { 
     return (((!(e is UnauthorizedAccessException) && !(e is ArgumentNullException)) && (!(e is PathTooLongException) && !(e is DirectoryNotFoundException))) && ((!(e is NotSupportedException) && !(e is ArgumentException)) && (!(e is SecurityException) && !(e is IOException)))); 
    } 

    internal static bool NotExpectedReflectionException(Exception e) 
    { 
     return ((((!(e is TypeLoadException) && !(e is MethodAccessException)) && (!(e is MissingMethodException) && !(e is MemberAccessException))) && ((!(e is BadImageFormatException) && !(e is ReflectionTypeLoadException)) && (!(e is CustomAttributeFormatException) && !(e is TargetParameterCountException)))) && (((!(e is InvalidCastException) && !(e is AmbiguousMatchException)) && (!(e is InvalidFilterCriteriaException) && !(e is TargetException))) && (!(e is MissingFieldException) && NotExpectedException(e)))); 
    } 
} 
+0

क्या प्रतिलिपि बनाने के बजाय \ binj \ debug \ bin \ debug से फ़ाइलों को स्थानांतरित करने के लिए msbuild को मजबूर करने के लिए कोई तरीका है (या उस मामले के लिए कठिन लिंक बनाएं) \ obj \ debug से? – ya23

+0

@ ya23 मुझे लगता है कि \ obj के तहत मौजूद dll/exe मौजूद \ bin के समान नहीं हैं। – Ankush

0

क्या आपने अपने स्वयं के लक्ष्य को परिभाषित करने का प्रयास किया है जो ResolveAssemblyReferences लक्ष्य के बाद चलता है? ResolveAssembly संदर्भों के चलने के बाद, आप अपने लिंक निर्माण को चलाने के लिए @ (संदर्भपैथ) आइटम का उपयोग करने में सक्षम होना चाहिए। AfterResolveReferences को कार्यान्वित करने पर विचार करें, जो Microsoft.Common.targets में आपके लिए ओवरराइड करने के लिए केवल एक खाली प्लेसहोल्डर है।

+0

धन्यवाद, अंत में, मैं संदर्भों के संक्रमणीय बंद करने की बजाय हार्डलिंक बनाने के लिए एमएसबिल्ड की प्रति स्थानीय कार्य को ओवरव्रो करता हूं। अगर मैं अन्य लोगों की मदद करता हूं तो मुझे स्रोत खोलने की उम्मीद है। और अधिक विस्तृत प्रतिक्रिया पोस्ट करने और प्रश्न के उत्तर देने की योजना का उत्तर दिया। – JAWspeak

संबंधित मुद्दे