@@ -11,144 +11,82 @@ public class ILRepackHelper
1111 _context = context ;
1212 }
1313
14- public void MergeJsonNet ( DirectoryPath sourcePath , DirectoryPath outputPath )
14+ public void MergeDLLs ( FilePath primaryDll , FilePath [ ] dllsToMerge , FilePath outputDll )
1515 {
16- var targetDll = sourcePath . CombineWithFilePath ( "IO.Ably.dll" ) ;
17- var docsFile = sourcePath . CombineWithFilePath ( "IO.Ably.xml" ) ;
18- var outputDll = outputPath . CombineWithFilePath ( "IO.Ably.dll" ) ;
19- var jsonNetDll = sourcePath . CombineWithFilePath ( "Newtonsoft.Json.dll" ) ;
20-
21- _context . EnsureDirectoryExists ( outputPath ) ;
22-
23- _context . Information ( $ "Merging { jsonNetDll . GetFilename ( ) } into { targetDll . GetFilename ( ) } ...") ;
24-
25- // Get the root directory (parent of cake-build)
26- var rootDir = _context . MakeAbsolute ( _context . Directory ( "../" ) ) ;
27- var ilRepackPath = rootDir . CombineWithFilePath ( "tools/ilrepack.exe" ) ;
28-
29- // Use ILRepack directly like FAKE does
30- var exitCode = _context . StartProcess ( ilRepackPath . FullPath , new ProcessSettings
31- {
32- Arguments = new ProcessArgumentBuilder ( )
33- . Append ( $ "/lib:\" { sourcePath . FullPath } \" ")
34- . Append ( "/targetplatform:v4" )
35- . Append ( "/internalize" )
36- . Append ( $ "/attr:\" { targetDll . FullPath } \" ")
37- . Append ( $ "/keyfile:\" { rootDir . CombineWithFilePath ( "IO.Ably.snk" ) . FullPath } \" ")
38- . Append ( "/parallel" )
39- . Append ( $ "/out:\" { outputDll . FullPath } \" ")
40- . Append ( $ "\" { targetDll . FullPath } \" ")
41- . Append ( $ "\" { jsonNetDll . FullPath } \" ")
42- } ) ;
43-
44- if ( exitCode != 0 )
45- {
46- throw new Exception ( $ "ILRepack failed with exit code { exitCode } ") ;
47- }
48-
49- // Copy XML documentation
50- if ( _context . FileExists ( docsFile ) )
51- {
52- _context . CopyFile ( docsFile , outputPath . CombineWithFilePath ( "IO.Ably.xml" ) ) ;
53- }
54-
55- _context . Information ( $ "✓ Merged assembly created at { outputDll } ") ;
56- }
57-
58- public void MergeDeltaCodec ( DirectoryPath sourcePath , DirectoryPath outputPath )
59- {
60- var targetDll = outputPath . CombineWithFilePath ( "IO.Ably.dll" ) ;
61- var docsFile = outputPath . CombineWithFilePath ( "IO.Ably.xml" ) ;
62- var deltaCodecDll = sourcePath . CombineWithFilePath ( "IO.Ably.DeltaCodec.dll" ) ;
63- var tempInputDll = outputPath . CombineWithFilePath ( "IO.Ably.temp.dll" ) ;
64-
65- if ( ! _context . FileExists ( deltaCodecDll ) )
16+ if ( ! _context . FileExists ( primaryDll ) )
6617 {
67- _context . Warning ( $ "DeltaCodec DLL not found at { deltaCodecDll } , skipping merge...") ;
68- return ;
18+ throw new Exception ( $ "Primary DLL not found: { primaryDll } ") ;
6919 }
7020
71- if ( ! _context . FileExists ( targetDll ) )
21+ if ( dllsToMerge == null || dllsToMerge . Length == 0 )
7222 {
73- _context . Warning ( $ "Target DLL not found at { targetDll } , skipping merge...") ;
74- return ;
23+ throw new ArgumentException ( "At least one DLL must be specified to merge" ) ;
7524 }
7625
77- _context . Information ( $ "Merging { deltaCodecDll . GetFilename ( ) } into { targetDll . GetFilename ( ) } ...") ;
78-
7926 // Get the root directory (parent of cake-build)
8027 var rootDir = _context . MakeAbsolute ( _context . Directory ( "../" ) ) ;
8128 var ilRepackPath = rootDir . CombineWithFilePath ( "tools/ilrepack.exe" ) ;
8229
83- // Copy target DLL to temp location to avoid input/output conflict
84- _context . CopyFile ( targetDll , tempInputDll ) ;
85-
86- // Backup PDB and config files
87- var targetPdb = outputPath . CombineWithFilePath ( "IO.Ably.pdb" ) ;
88- var tempInputPdb = outputPath . CombineWithFilePath ( "IO.Ably.temp.pdb" ) ;
89- if ( _context . FileExists ( targetPdb ) )
90- {
91- _context . CopyFile ( targetPdb , tempInputPdb ) ;
92- }
93-
94- var targetConfig = outputPath . CombineWithFilePath ( "IO.Ably.dll.config" ) ;
95- var tempInputConfig = outputPath . CombineWithFilePath ( "IO.Ably.temp.dll.config" ) ;
96- if ( _context . FileExists ( targetConfig ) )
97- {
98- _context . CopyFile ( targetConfig , tempInputConfig ) ;
99- }
30+ // Build list of DLL paths - primary first, then merging DLLs
31+ var dllPaths = new List < string > { $ "\" { primaryDll . FullPath } \" " } ;
32+ var mergingDllNames = new List < string > ( ) ;
10033
101- try
34+ foreach ( var dllPath in dllsToMerge )
10235 {
103- // Merge DeltaCodec into IO.Ably.dll (output directly with correct name)
104- var exitCode = _context . StartProcess ( ilRepackPath . FullPath , new ProcessSettings
36+ if ( _context . FileExists ( dllPath ) )
10537 {
106- Arguments = new ProcessArgumentBuilder ( )
107- . Append ( $ "/lib:\" { sourcePath . FullPath } \" ")
108- . Append ( $ "/lib:\" { outputPath . FullPath } \" ")
109- . Append ( "/targetplatform:v4" )
110- . Append ( "/internalize" )
111- . Append ( $ "/attr:\" { tempInputDll . FullPath } \" ")
112- . Append ( $ "/keyfile:\" { rootDir . CombineWithFilePath ( "IO.Ably.snk" ) . FullPath } \" ")
113- . Append ( "/parallel" )
114- . Append ( $ "/out:\" { targetDll . FullPath } \" ")
115- . Append ( $ "\" { tempInputDll . FullPath } \" ")
116- . Append ( $ "\" { deltaCodecDll . FullPath } \" ")
117- } ) ;
118-
119- if ( exitCode != 0 )
38+ dllPaths . Add ( $ "\" { dllPath . FullPath } \" ") ;
39+ mergingDllNames . Add ( dllPath . GetFilename ( ) . ToString ( ) ) ;
40+ }
41+ else
12042 {
121- throw new Exception ( $ "ILRepack failed with exit code { exitCode } ") ;
43+ throw new Exception ( $ "Merge dll not found at path \" { dllPath . FullPath } \" ") ;
12244 }
12345 }
124- finally
46+
47+ _context . Information ( $ "Merging { string . Join ( ", " , mergingDllNames ) } into { primaryDll . GetFilename ( ) } ...") ;
48+
49+ // Ensure output directory exists
50+ var outputDir = outputDll . GetDirectory ( ) ;
51+ _context . EnsureDirectoryExists ( outputDir ) ;
52+
53+ // Get the directory containing the primary DLL for assembly resolution
54+ var binDir = primaryDll . GetDirectory ( ) ;
55+
56+ // Build ILRepack arguments - explicitly merge only the DLLs we specify
57+ var args = new ProcessArgumentBuilder ( )
58+ . Append ( "/targetplatform:v4" )
59+ . Append ( "/internalize" )
60+ // /lib: Specifies where ILRepack should search for referenced assemblies when loading the primary DLL.
61+ // This is needed because Mono.Cecil (used by ILRepack) must resolve all type references while reading
62+ // the assembly metadata, even before the merge begins. Without this, it fails to resolve types from
63+ // dependencies like Newtonsoft.Json that are referenced in custom attributes or type signatures.
64+ . Append ( $ "/lib:\" { binDir . FullPath } \" ")
65+ . Append ( $ "/attr:\" { primaryDll . FullPath } \" ")
66+ . Append ( $ "/keyfile:\" { rootDir . CombineWithFilePath ( "IO.Ably.snk" ) . FullPath } \" ")
67+ . Append ( "/parallel" )
68+ . Append ( $ "/out:\" { outputDll . FullPath } \" ") ;
69+
70+ // Add all DLL paths explicitly (primary + merging DLLs)
71+ foreach ( var dllPath in dllPaths )
12572 {
126- // Clean up temp files
127- if ( _context . FileExists ( tempInputDll ) )
128- {
129- _context . DeleteFile ( tempInputDll ) ;
130- }
131- if ( _context . FileExists ( tempInputPdb ) )
132- {
133- _context . DeleteFile ( tempInputPdb ) ;
134- }
135- if ( _context . FileExists ( tempInputConfig ) )
136- {
137- _context . DeleteFile ( tempInputConfig ) ;
138- }
73+ args . Append ( dllPath ) ;
13974 }
14075
141- // Clean up DeltaCodec files from output path since they're now merged
142- var deltaCodecFiles = _context . GetFiles ( outputPath . Combine ( "IO.Ably.DeltaCodec.*" ) . FullPath ) ;
143-
144- foreach ( var file in deltaCodecFiles )
76+ // Use ILRepack to merge all DLLs in one go
77+ var exitCode = _context . StartProcess ( ilRepackPath . FullPath , new ProcessSettings
78+ {
79+ Arguments = args
80+ } ) ;
81+
82+ if ( exitCode != 0 )
14583 {
146- _context . DeleteFile ( file ) ;
147- _context . Information ( $ "Cleaned up: { file . GetFilename ( ) } ") ;
84+ throw new Exception ( $ "ILRepack failed with exit code { exitCode } ") ;
14885 }
14986
150- _context . Information ( $ "✓ DeltaCodec merged into { targetDll } ") ;
87+ _context . Information ( $ "✓ Merged assembly created at { outputDll } ") ;
15188 }
15289}
15390
15491var ilRepackHelper = new ILRepackHelper ( Context ) ;
92+
0 commit comments