11using System ;
22using System . Collections . Generic ;
33using System . IO ;
4+ using System . Linq ;
45using System . Reflection . Metadata ;
56using System . Reflection . PortableExecutable ;
67using System . Runtime . CompilerServices ;
@@ -86,8 +87,8 @@ public void It_creates_readytorun_images_for_all_assemblies_except_excluded_ones
8687 NuGetFramework framework = NuGetFramework . Parse ( targetFramework ) ;
8788
8889 publishDirectory . Should ( ) . NotHaveFiles ( new [ ] {
89- GetPDBFileName ( mainProjectDll , framework ) ,
90- GetPDBFileName ( classLibDll , framework ) ,
90+ GetPDBFileName ( mainProjectDll , framework , testProject . RuntimeIdentifier ) ,
91+ GetPDBFileName ( classLibDll , framework , testProject . RuntimeIdentifier ) ,
9192 } ) ;
9293 }
9394
@@ -112,7 +113,7 @@ public void It_creates_readytorun_symbols_when_switch_is_used(string targetFrame
112113 [ InlineData ( "net6.0" ) ]
113114 public void It_supports_framework_dependent_publishing ( string targetFramework )
114115 {
115- TestProjectPublishing_Internal ( "FrameworkDependent" , targetFramework , isSelfContained : false , emitNativeSymbols : true , identifier : targetFramework ) ;
116+ TestProjectPublishing_Internal ( "FrameworkDependent" , targetFramework , isSelfContained : false , composite : false , emitNativeSymbols : true , identifier : targetFramework ) ;
116117 }
117118
118119 [ Theory ]
@@ -199,7 +200,7 @@ public void It_warns_when_targetting_netcoreapp_2_x_readytorun()
199200 [ InlineData ( "net6.0" ) ]
200201 public void It_can_publish_readytorun_for_library_projects ( string targetFramework )
201202 {
202- TestProjectPublishing_Internal ( "LibraryProject1" , targetFramework , isSelfContained : false , makeExeProject : false , identifier : targetFramework ) ;
203+ TestProjectPublishing_Internal ( "LibraryProject1" , targetFramework , isSelfContained : false , composite : false , makeExeProject : false , identifier : targetFramework ) ;
203204 }
204205
205206 [ RequiresMSBuildVersionTheory ( "17.0.0.32901" ) ]
@@ -208,7 +209,7 @@ public void It_can_publish_readytorun_for_library_projects(string targetFramewor
208209 [ InlineData ( "net6.0" ) ]
209210 public void It_can_publish_readytorun_for_selfcontained_library_projects ( string targetFramework )
210211 {
211- TestProjectPublishing_Internal ( "LibraryProject2" , targetFramework , isSelfContained : true , makeExeProject : false , identifier : targetFramework ) ;
212+ TestProjectPublishing_Internal ( "LibraryProject2" , targetFramework , isSelfContained : true , composite : true , makeExeProject : false , identifier : targetFramework ) ;
212213 }
213214
214215 [ RequiresMSBuildVersionTheory ( "17.0.0.32901" ) ]
@@ -264,6 +265,103 @@ public void It_supports_libraries_when_using_crossgen2(string targetFramework)
264265 publishCommand . Execute ( ) . Should ( ) . Pass ( ) ;
265266 }
266267
268+ [ RequiresMSBuildVersionTheory ( "17.0.0.32901" ) ]
269+ [ InlineData ( "net6.0" , "linux-x64" , "windows,linux,osx" , "X64,Arm64" , "_" , "_" ) ]
270+ [ InlineData ( "net6.0" , "linux-x64" , "windows,linux,osx" , "X64,Arm64" , "composite" , "selfcontained" ) ] // Composite in .NET 6.0 is only supported for self-contained builds
271+ // In .NET 6.0 building targetting Windows on linux or osx doesn't support emitting native symbols.
272+ [ InlineData ( "net6.0" , "win-x64" , "windows" , "X64,Arm64" , "composite" , "selfcontained" ) ] // Composite in .NET 6.0 is only supported for self-contained builds
273+ [ InlineData ( "net6.0" , "osx-arm64" , "windows,linux,osx" , "X64,Arm64" , "_" , "_" ) ]
274+ // In .NET 6.0 building targetting Windows on linux or osx doesn't support emitting native symbols.
275+ [ InlineData ( "net6.0" , "win-x86" , "windows" , "X86,X64,Arm64,Arm" , "_" , "_" ) ]
276+ public void It_supports_crossos_arch_compilation ( string targetFramework , string runtimeIdentifier , string sdkSupportedOs , string sdkSupportedArch , string composite , string selfcontained )
277+ {
278+ var projectName = $ "CrossArchOs{ targetFramework } { runtimeIdentifier . Replace ( "-" , "." ) } { composite } { selfcontained } ";
279+ string sdkOs = "NOTHING" ;
280+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) )
281+ {
282+ sdkOs = "linux" ;
283+ }
284+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
285+ {
286+ sdkOs = "windows" ;
287+ }
288+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . OSX ) )
289+ {
290+ sdkOs = "osx" ;
291+ }
292+
293+ Assert . NotEqual ( "NOTHING" , sdkOs ) ; // We should know which OS we are running on
294+ Log . WriteLine ( $ "sdkOs = { sdkOs } ") ;
295+ if ( ! sdkSupportedOs . Contains ( sdkOs ) )
296+ {
297+ Log . WriteLine ( "Running test on OS that doesn't support this cross platform build" ) ;
298+ return ;
299+ }
300+
301+ string sdkArch = RuntimeInformation . ProcessArchitecture . ToString ( ) ;
302+ Log . WriteLine ( $ "sdkArch = { sdkArch } ") ;
303+ Assert . Contains ( sdkArch , new string [ ] { "Arm" , "Arm64" , "X64" , "X86" } ) ; // Assert that the Architecture in use is a known architecture
304+ if ( ! sdkSupportedArch . Split ( ',' ) . Contains ( sdkArch ) )
305+ {
306+ Log . WriteLine ( "Running test on processor architecture that doesn't support this cross platform build" ) ;
307+ return ;
308+ }
309+
310+ TestProjectPublishing_Internal ( projectName , targetFramework , isSelfContained : selfcontained == "selfcontained" , emitNativeSymbols : true , useCrossgen2 : true , composite : composite == "composite" , identifier : targetFramework , runtimeIdentifier : runtimeIdentifier ) ;
311+ }
312+
313+ private enum TargetOSEnum
314+ {
315+ Windows ,
316+ Linux ,
317+ OsX
318+ }
319+
320+ private static TargetOSEnum GetTargetOS ( string runtimeIdentifier )
321+ {
322+ if ( runtimeIdentifier . Contains ( "osx" ) )
323+ {
324+ return TargetOSEnum . OsX ;
325+ }
326+ else if ( runtimeIdentifier . Contains ( "win" ) )
327+ {
328+ return TargetOSEnum . Windows ;
329+ }
330+ else if ( runtimeIdentifier . Contains ( "linux" ) ||
331+ runtimeIdentifier . Contains ( "ubuntu" ) ||
332+ runtimeIdentifier . Contains ( "alpine" ) ||
333+ runtimeIdentifier . Contains ( "android" ) ||
334+ runtimeIdentifier . Contains ( "centos" ) ||
335+ runtimeIdentifier . Contains ( "debian" ) ||
336+ runtimeIdentifier . Contains ( "fedora" ) ||
337+ runtimeIdentifier . Contains ( "gentoo" ) ||
338+ runtimeIdentifier . Contains ( "suse" ) ||
339+ runtimeIdentifier . Contains ( "rhel" ) ||
340+ runtimeIdentifier . Contains ( "sles" ) ||
341+ runtimeIdentifier . Contains ( "tizen" ) )
342+ {
343+ return TargetOSEnum . Linux ;
344+ }
345+
346+ Assert . True ( false , $ "{ runtimeIdentifier } could not be converted into a known OS type. Adjust the if statement above until this does not happen") ;
347+ return TargetOSEnum . Windows ;
348+ }
349+
350+ private static bool IsTargetOsOsX ( string runtimeIdentifier )
351+ {
352+ return GetTargetOS ( runtimeIdentifier ) == TargetOSEnum . OsX ;
353+ }
354+
355+ private static bool IsTargetOsWindows ( string runtimeIdentifier )
356+ {
357+ return GetTargetOS ( runtimeIdentifier ) == TargetOSEnum . Windows ;
358+ }
359+
360+ private static bool IsTargetOsLinux ( string runtimeIdentifier )
361+ {
362+ return GetTargetOS ( runtimeIdentifier ) == TargetOSEnum . Linux ;
363+ }
364+
267365 private void TestProjectPublishing_Internal ( string projectName ,
268366 string targetFramework ,
269367 bool makeExeProject = true ,
@@ -272,13 +370,15 @@ private void TestProjectPublishing_Internal(string projectName,
272370 bool useCrossgen2 = false ,
273371 bool composite = true ,
274372 [ CallerMemberName ] string callingMethod = "" ,
275- string identifier = null )
373+ string identifier = null ,
374+ string runtimeIdentifier = null )
276375 {
277376 var testProject = CreateTestProjectForR2RTesting (
278377 targetFramework ,
279378 projectName ,
280379 "ClassLib" ,
281- isExeProject : makeExeProject ) ;
380+ isExeProject : makeExeProject ,
381+ runtimeIdentifier : runtimeIdentifier ) ;
282382
283383 testProject . AdditionalProperties [ "PublishReadyToRun" ] = "True" ;
284384 testProject . AdditionalProperties [ "PublishReadyToRunEmitSymbols" ] = emitNativeSymbols ? "True" : "False" ;
@@ -307,18 +407,34 @@ private void TestProjectPublishing_Internal(string projectName,
307407 else
308408 publishDirectory . Should ( ) . NotHaveFile ( "System.Private.CoreLib.dll" ) ;
309409
310- if ( emitNativeSymbols && ! RuntimeInformation . IsOSPlatform ( OSPlatform . OSX ) )
410+ if ( emitNativeSymbols && ! IsTargetOsOsX ( testProject . RuntimeIdentifier ) )
311411 {
312412 NuGetFramework framework = NuGetFramework . Parse ( targetFramework ) ;
413+ Log . WriteLine ( "Checking for symbol files" ) ;
414+ IEnumerable < string > pdbFiles ;
313415
314- publishDirectory . Should ( ) . HaveFiles ( new [ ] {
315- GetPDBFileName ( mainProjectDll , framework ) ,
316- GetPDBFileName ( classLibDll , framework ) ,
317- } ) ;
416+ if ( composite )
417+ {
418+ pdbFiles = new [ ] { GetPDBFileName ( Path . ChangeExtension ( mainProjectDll , "r2r.dll" ) , framework , testProject . RuntimeIdentifier ) } ;
419+ }
420+ else
421+ {
422+ pdbFiles = new [ ] {
423+ GetPDBFileName ( mainProjectDll , framework , testProject . RuntimeIdentifier ) ,
424+ GetPDBFileName ( classLibDll , framework , testProject . RuntimeIdentifier ) ,
425+ } ;
426+ }
427+
428+ foreach ( string s in pdbFiles )
429+ {
430+ Log . WriteLine ( $ "{ publishDirectory . FullName } { s } ") ;
431+ }
432+
433+ publishDirectory . Should ( ) . HaveFiles ( pdbFiles ) ;
318434 }
319435 }
320436
321- private TestProject CreateTestProjectForR2RTesting ( string targetFramework , string mainProjectName , string referenceProjectName , bool isExeProject = true )
437+ private TestProject CreateTestProjectForR2RTesting ( string targetFramework , string mainProjectName , string referenceProjectName , bool isExeProject = true , string runtimeIdentifier = null )
322438 {
323439 var referenceProject = new TestProject ( )
324440 {
@@ -340,7 +456,7 @@ public string Func()
340456 Name = mainProjectName ,
341457 TargetFrameworks = targetFramework ,
342458 IsExe = isExeProject ,
343- RuntimeIdentifier = EnvironmentInfo . GetCompatibleRid ( targetFramework ) ,
459+ RuntimeIdentifier = runtimeIdentifier ?? EnvironmentInfo . GetCompatibleRid ( targetFramework ) ,
344460 ReferencedProjects = { referenceProject } ,
345461 } ;
346462 testProject . SourceFiles [ $ "{ mainProjectName } .cs"] = @"
@@ -356,14 +472,14 @@ public static void Main()
356472 return testProject ;
357473 }
358474
359- public static string GetPDBFileName ( string assemblyFile , NuGetFramework framework )
475+ public static string GetPDBFileName ( string assemblyFile , NuGetFramework framework , string runtimeIdentifier )
360476 {
361- if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
477+ if ( IsTargetOsWindows ( runtimeIdentifier ) )
362478 {
363479 return Path . GetFileName ( Path . ChangeExtension ( assemblyFile , "ni.pdb" ) ) ;
364480 }
365481
366- if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) )
482+ if ( IsTargetOsLinux ( runtimeIdentifier ) )
367483 {
368484 if ( framework . Version . Major >= 6 )
369485 {
0 commit comments