55using System . IO ;
66using System . Linq ;
77using System . Reflection ;
8+ using System . Text ;
89using System . Threading ;
910using Microsoft . Build . Framework ;
1011using Microsoft . Build . Utilities ;
@@ -173,19 +174,11 @@ static string GetNdkToolchainLibraryDir (string binDir, AndroidTargetArch arch)
173174 return GetNdkToolchainLibraryDir ( binDir , NdkUtil . GetArchDirName ( arch ) ) ;
174175 }
175176
176- static string GetShortPath ( string path )
177- {
178- if ( Environment . OSVersion . Platform != PlatformID . Win32NT )
179- return QuoteFileName ( path ) ;
180- var shortPath = KernelEx . GetShortPathName ( Path . GetDirectoryName ( path ) ) ;
181- return Path . Combine ( shortPath , Path . GetFileName ( path ) ) ;
182- }
183-
184177 static string QuoteFileName ( string fileName )
185178 {
186179 var builder = new CommandLineBuilder ( ) ;
187180 builder . AppendFileNameIfNotNull ( fileName ) ;
188- return builder . ToString ( ) ;
181+ return builder . ToString ( ) . Replace ( @"\" , @"\\" ) . Normalize ( NormalizationForm . FormC ) ;
189182 }
190183
191184 static bool ValidateAotConfiguration ( TaskLoggingHelper log , AndroidTargetArch arch , bool enableLLVM )
@@ -379,7 +372,6 @@ IEnumerable<Config> GetAotConfigs ()
379372 } catch ( InvalidOperationException ex ) {
380373 Diagnostic . Error ( 5101 , ex . Message ) ;
381374 }
382-
383375 string toolchainLibDir ;
384376 if ( NdkUtil . UsingClangNDK )
385377 toolchainLibDir = GetNdkToolchainLibraryDir ( toolchainPath , arch ) ;
@@ -388,19 +380,19 @@ IEnumerable<Config> GetAotConfigs ()
388380
389381 var libs = new List < string > ( ) ;
390382 if ( NdkUtil . UsingClangNDK ) {
391- libs . Add ( $ "-L{ GetShortPath ( toolchainLibDir ) } ") ;
392- libs . Add ( $ "-L{ GetShortPath ( androidLibPath ) } ") ;
383+ libs . Add ( $ "-L{ QuoteFileName ( toolchainLibDir ) } ") ;
384+ libs . Add ( $ "-L{ QuoteFileName ( androidLibPath ) } ") ;
393385
394386 if ( arch == AndroidTargetArch . Arm ) {
395387 // Needed for -lunwind to work
396388 string compilerLibDir = Path . Combine ( toolchainPath , ".." , "sysroot" , "usr" , "lib" , NdkUtil . GetArchDirName ( arch ) ) ;
397- libs . Add ( $ "-L{ GetShortPath ( compilerLibDir ) } ") ;
389+ libs . Add ( $ "-L{ QuoteFileName ( compilerLibDir ) } ") ;
398390 }
399391 }
400392
401- libs . Add ( GetShortPath ( Path . Combine ( toolchainLibDir , "libgcc.a" ) ) ) ;
402- libs . Add ( GetShortPath ( Path . Combine ( androidLibPath , "libc.so" ) ) ) ;
403- libs . Add ( GetShortPath ( Path . Combine ( androidLibPath , "libm.so" ) ) ) ;
393+ libs . Add ( QuoteFileName ( Path . Combine ( toolchainLibDir , "libgcc.a" ) ) ) ;
394+ libs . Add ( QuoteFileName ( Path . Combine ( androidLibPath , "libc.so" ) ) ) ;
395+ libs . Add ( QuoteFileName ( Path . Combine ( androidLibPath , "libm.so" ) ) ) ;
404396
405397 ldFlags = string . Join ( ";" , libs ) ;
406398 }
@@ -422,23 +414,23 @@ IEnumerable<Config> GetAotConfigs ()
422414 aotOptions . Add ( "profile-only" ) ;
423415 foreach ( var p in Profiles ) {
424416 var fp = Path . GetFullPath ( p . ItemSpec ) ;
425- aotOptions . Add ( $ "profile={ GetShortPath ( fp ) } ") ;
417+ aotOptions . Add ( $ "profile={ QuoteFileName ( fp ) } ") ;
426418 }
427419 }
428420 if ( ! string . IsNullOrEmpty ( AotAdditionalArguments ) )
429421 aotOptions . Add ( AotAdditionalArguments ) ;
430422 if ( sequencePointsMode == SequencePointsMode . Offline )
431- aotOptions . Add ( "msym-dir=" + GetShortPath ( outdir ) ) ;
423+ aotOptions . Add ( "msym-dir=" + QuoteFileName ( outdir ) ) ;
432424 if ( AotMode != AotMode . Normal )
433425 aotOptions . Add ( AotMode . ToString ( ) . ToLowerInvariant ( ) ) ;
434426
435- aotOptions . Add ( "outfile=" + GetShortPath ( outputFile ) ) ;
427+ aotOptions . Add ( "outfile=" + QuoteFileName ( outputFile ) ) ;
436428 aotOptions . Add ( "asmwriter" ) ;
437429 aotOptions . Add ( "mtriple=" + mtriple ) ;
438- aotOptions . Add ( "tool-prefix=" + GetShortPath ( toolPrefix ) ) ;
430+ aotOptions . Add ( "tool-prefix=" + QuoteFileName ( toolPrefix ) ) ;
439431 aotOptions . Add ( "ld-flags=" + ldFlags ) ;
440- aotOptions . Add ( "llvm-path=" + GetShortPath ( sdkBinDirectory ) ) ;
441- aotOptions . Add ( "temp-path=" + GetShortPath ( tempDir ) ) ;
432+ aotOptions . Add ( "llvm-path=" + QuoteFileName ( sdkBinDirectory ) ) ;
433+ aotOptions . Add ( "temp-path=" + QuoteFileName ( tempDir ) ) ;
442434
443435 string aotOptionsStr = ( EnableLLVM ? "--llvm " : "" ) + "--aot=" + string . Join ( "," , aotOptions ) ;
444436
@@ -471,50 +463,63 @@ bool RunAotCompiler (string assembliesPath, string aotCompiler, string aotOption
471463 {
472464 var stdout_completed = new ManualResetEvent ( false ) ;
473465 var stderr_completed = new ManualResetEvent ( false ) ;
474- var psi = new ProcessStartInfo ( ) {
475- FileName = aotCompiler ,
476- Arguments = aotOptions + " " + assembly ,
477- UseShellExecute = false ,
478- RedirectStandardOutput = true ,
479- RedirectStandardError = true ,
480- CreateNoWindow = true ,
481- WindowStyle = ProcessWindowStyle . Hidden ,
482- WorkingDirectory = WorkingDirectory ,
483- } ;
484-
485- // we do not want options to be provided out of band to the cross compilers
486- psi . EnvironmentVariables [ "MONO_ENV_OPTIONS" ] = String . Empty ;
487- // the C code cannot parse all the license details, including the activation code that tell us which license level is allowed
488- // so we provide this out-of-band to the cross-compilers - this can be extended to communicate a few others bits as well
489- psi . EnvironmentVariables [ "MONO_PATH" ] = assembliesPath ;
490-
491- LogDebugMessage ( "[AOT] MONO_PATH=\" {0}\" MONO_ENV_OPTIONS=\" {1}\" {2} {3}" ,
492- psi . EnvironmentVariables [ "MONO_PATH" ] , psi . EnvironmentVariables [ "MONO_ENV_OPTIONS" ] , psi . FileName , psi . Arguments ) ;
493-
494- using ( var proc = new Process ( ) ) {
495- proc . OutputDataReceived += ( s , e ) => {
496- if ( e . Data != null )
497- OnAotOutputData ( s , e ) ;
498- else
499- stdout_completed . Set ( ) ;
500- } ;
501- proc . ErrorDataReceived += ( s , e ) => {
502- if ( e . Data != null )
503- OnAotErrorData ( s , e ) ;
504- else
505- stderr_completed . Set ( ) ;
466+ var responseFile = Path . GetTempFileName ( ) ;
467+ try {
468+ using ( var sw = new StreamWriter ( path : responseFile , append : false ,
469+ encoding : new UTF8Encoding ( encoderShouldEmitUTF8Identifier : false ) ) ) {
470+ sw . WriteLine ( aotOptions + " " + assembly ) ;
471+ }
472+
473+ var psi = new ProcessStartInfo ( ) {
474+ FileName = aotCompiler ,
475+ Arguments = $ "--response=\" { responseFile } \" ",
476+ UseShellExecute = false ,
477+ RedirectStandardOutput = true ,
478+ RedirectStandardError = true ,
479+ CreateNoWindow = true ,
480+ WindowStyle = ProcessWindowStyle . Hidden ,
481+ WorkingDirectory = WorkingDirectory ,
506482 } ;
507- proc . StartInfo = psi ;
508- proc . Start ( ) ;
509- proc . BeginOutputReadLine ( ) ;
510- proc . BeginErrorReadLine ( ) ;
511- CancellationToken . Register ( ( ) => { try { proc . Kill ( ) ; } catch ( Exception ) { } } ) ;
512- proc . WaitForExit ( ) ;
513- if ( psi . RedirectStandardError )
514- stderr_completed . WaitOne ( TimeSpan . FromSeconds ( 30 ) ) ;
515- if ( psi . RedirectStandardOutput )
516- stdout_completed . WaitOne ( TimeSpan . FromSeconds ( 30 ) ) ;
517- return proc . ExitCode == 0 ;
483+
484+ psi . EnvironmentVariables [ "MONO_LOG_LEVEL" ] = "debug" ;
485+ // we do not want options to be provided out of band to the cross compilers
486+ psi . EnvironmentVariables [ "MONO_ENV_OPTIONS" ] = String . Empty ;
487+ // the C code cannot parse all the license details, including the activation code that tell us which license level is allowed
488+ // so we provide this out-of-band to the cross-compilers - this can be extended to communicate a few others bits as well
489+ psi . EnvironmentVariables [ "MONO_PATH" ] = assembliesPath . Normalize ( NormalizationForm . FormC ) ;
490+
491+ LogDebugMessage ( $ "[AOT] { aotOptions } { assembly } ") ;
492+ LogDebugMessage ( "[AOT] MONO_PATH=\" {0}\" MONO_ENV_OPTIONS=\" {1}\" {2} {3}" ,
493+ psi . EnvironmentVariables [ "MONO_PATH" ] , psi . EnvironmentVariables [ "MONO_ENV_OPTIONS" ] , psi . FileName , psi . Arguments ) ;
494+
495+ using ( var proc = new Process ( ) ) {
496+ proc . OutputDataReceived += ( s , e ) => {
497+ if ( e . Data != null )
498+ OnAotOutputData ( s , e ) ;
499+ else
500+ stdout_completed . Set ( ) ;
501+ } ;
502+ proc . ErrorDataReceived += ( s , e ) => {
503+ if ( e . Data != null )
504+ OnAotErrorData ( s , e ) ;
505+ else
506+ stderr_completed . Set ( ) ;
507+ } ;
508+ proc . StartInfo = psi ;
509+ proc . Start ( ) ;
510+ proc . BeginOutputReadLine ( ) ;
511+ proc . BeginErrorReadLine ( ) ;
512+ CancellationToken . Register ( ( ) => { try { proc . Kill ( ) ; } catch ( Exception ) { } } ) ;
513+ proc . WaitForExit ( ) ;
514+ if ( psi . RedirectStandardError )
515+ stderr_completed . WaitOne ( TimeSpan . FromSeconds ( 30 ) ) ;
516+ if ( psi . RedirectStandardOutput )
517+ stdout_completed . WaitOne ( TimeSpan . FromSeconds ( 30 ) ) ;
518+ return proc . ExitCode == 0 ;
519+ }
520+ } finally {
521+ if ( File . Exists ( responseFile ) )
522+ File . Delete ( responseFile ) ;
518523 }
519524 }
520525
0 commit comments