Enable Windows ARM64 corefx jobs
authorBruce Forstall <brucefo@microsoft.com>
Wed, 11 Jul 2018 18:32:41 +0000 (11:32 -0700)
committerBruce Forstall <brucefo@microsoft.com>
Fri, 13 Jul 2018 22:57:01 +0000 (15:57 -0700)
Disable various tests that currently fail, tagged with issues
describing the failures.

Commit migrated from https://github.com/dotnet/coreclr/commit/827b5f15e2fd9d642491ebb21bce8013d9937083

src/coreclr/netci.groovy
src/coreclr/tests/arm64/corefx_test_exclusions.txt
src/coreclr/tests/scripts/run-corefx-tests.bat
src/coreclr/tests/scripts/run-corefx-tests.py

index db99a28..34fa6d9 100755 (executable)
@@ -1567,10 +1567,9 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
                         Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} via ILLink", "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
                         break
                     }
-
-                    else  if (scenario == 'corefx_innerloop') {
+                    else if (scenario == 'corefx_innerloop') {
                         if (configuration == 'Checked') {
-                            Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} CoreFX Tests")                                
+                            Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} CoreFX Tests")
                         }
                         else {
                             Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} CoreFX Tests", "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+CoreFX Tests.*")
@@ -1641,7 +1640,7 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
 
                         case 'corefx_innerloop':
                             if (configuration == 'Checked') {
-                                Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} CoreFX Tests")                                
+                                Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} CoreFX Tests")
                             }
                             break
 
@@ -1763,7 +1762,7 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
                             break
                         case 'corefx_innerloop':
                             if (configuration == 'Checked') {
-                                Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} CoreFX Tests")                                
+                                Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} CoreFX Tests")
                             }
                             break
 
@@ -2237,22 +2236,21 @@ def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR
                                 // Archive and process (only) the test results
                                 Utilities.addArchival(newJob, "bin/Logs/**/testResults.xml")
                                 Utilities.addXUnitDotNETResults(newJob, "bin/Logs/**/testResults.xml")
-
                             }
                             else {
-                              def workspaceRelativeFxRoot = "_/fx"
-                              def absoluteFxRoot = "%WORKSPACE%\\_\\fx"
-                              def fxBranch = getFxBranch(branch)
+                                def workspaceRelativeFxRoot = "_/fx"
+                                def absoluteFxRoot = "%WORKSPACE%\\_\\fx"
+                                def fxBranch = getFxBranch(branch)
 
-                              buildCommands += "python -u %WORKSPACE%\\tests\\scripts\\run-corefx-tests.py -arch ${arch} -ci_arch ${architecture} -build_type ${configuration} -fx_root ${absoluteFxRoot} -fx_branch ${fxBranch} -env_script ${envScriptPath}"
+                                buildCommands += "python -u %WORKSPACE%\\tests\\scripts\\run-corefx-tests.py -arch ${arch} -ci_arch ${architecture} -build_type ${configuration} -fx_root ${absoluteFxRoot} -fx_branch ${fxBranch} -env_script ${envScriptPath}"
 
-                              // Archive and process (only) the test results
-                              Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
-                              Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
+                                // Archive and process (only) the test results
+                                Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
+                                Utilities.addXUnitDotNETResults(newJob, "${workspaceRelativeFxRoot}/bin/**/testResults.xml")
 
-                              //Archive additional build stuff to diagnose why my attempt at fault injection isn't causing CI to fail
-                              Utilities.addArchival(newJob, "SetStressModes.bat", "", true, false)
-                              Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/testhost/**", "", true, false)
+                                //Archive additional build stuff to diagnose why my attempt at fault injection isn't causing CI to fail
+                                Utilities.addArchival(newJob, "SetStressModes.bat", "", true, false)
+                                Utilities.addArchival(newJob, "${workspaceRelativeFxRoot}/bin/testhost/**", "", true, false)
                             }
                         }
                         else if (isGcReliabilityFramework(scenario)) {
@@ -2298,32 +2296,26 @@ def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR
                     }
                     break
                 case 'arm':
+                case 'arm64':
                     assert isArmWindowsScenario(scenario)
 
-                    def buildArchitecture = 'arm'
                     def buildOpts = ''
 
+                    if (architecture == 'arm64') {
+                        buildOpts += " toolset_dir C:\\ats2"
+                    }
+
                     if (doCoreFxTesting) {
-                        // We shouldn't need to build the tests. However, run-corefx-tests.py currently depends on having the restored corefx
-                        // package available, to determine the correct corefx version git commit hash, and we need to build the tests before
-                        // running "tests\\runtest.cmd GenerateLayoutOnly". So build the pri-0 tests to make this happen.
-                        //
-                        // buildOpts += ' skiptests';
-                        buildOpts += " -priority=0"
+                        buildOpts += ' skiptests'
                     } else {
                         buildOpts += " -priority=${priority}"
                     }
 
                     // This is now a build only job. Do not run tests. Use the flow job.
-                    buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${buildArchitecture} ${buildOpts}"
+                    buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${architecture} ${buildOpts}"
 
                     if (doCoreFxTesting) {
                         assert isBuildOnly
-                        assert architecture == 'arm'
-
-                        // Generate the test layout because it restores the corefx package which allows run-corefx-tests.py
-                        // to determine the correct matching corefx version git commit hash.
-                        buildCommands += "tests\\runtest.cmd ${lowerConfiguration} ${architecture} GenerateLayoutOnly"
 
                         // Set the stress mode variables; this is incorporated into the generated CoreFx RunTests.cmd files.
                         def envScriptPath = ''
@@ -2339,10 +2331,15 @@ def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR
                         def absoluteFxRoot = "%WORKSPACE%\\_\\fx"
                         def fxBranch = getFxBranch(branch)
 
-                        buildCommands += "python -u %WORKSPACE%\\tests\\scripts\\run-corefx-tests.py -arch ${architecture} -ci_arch ${architecture} -build_type ${configuration} -fx_root ${absoluteFxRoot} -fx_branch ${fxBranch} -env_script ${envScriptPath} -no_run_tests"
+                        def toolsetDirOpt = ''
+                        if (architecture == 'arm64') {
+                            toolsetDirOpt = "-toolset_dir C:\\ats2"
+                        }
+
+                        buildCommands += "python -u %WORKSPACE%\\tests\\scripts\\run-corefx-tests.py -arch ${architecture} -ci_arch ${architecture} -build_type ${configuration} -fx_root ${absoluteFxRoot} -fx_branch ${fxBranch} -env_script ${envScriptPath} -no_run_tests ${toolsetDirOpt}"
 
                         // Zip up the CoreFx runtime and tests. We don't need the CoreCLR binaries; they have been copied to the CoreFX tree.
-                        buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('${workspaceRelativeFxRootWin}\\bin\\testhost\\netcoreapp-Windows_NT-Release-arm', '${workspaceRelativeFxRootWin}\\fxruntime.zip')\"";
+                        buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('${workspaceRelativeFxRootWin}\\bin\\testhost\\netcoreapp-Windows_NT-Release-${architecture}', '${workspaceRelativeFxRootWin}\\fxruntime.zip')\"";
                         buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('${workspaceRelativeFxRootWin}\\bin\\tests', '${workspaceRelativeFxRootWin}\\fxtests.zip')\"";
 
                         Utilities.addArchival(newJob, "${workspaceRelativeFxRootLinux}/fxruntime.zip")
@@ -2350,25 +2347,12 @@ def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR
                     } else {
                         // Zip up the tests directory so that we don't use so much space/time copying
                         // 10s of thousands of files around.
-                        buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('.\\bin\\tests\\${osGroup}.${buildArchitecture}.${configuration}', '.\\bin\\tests\\tests.zip')\"";
+                        buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('.\\bin\\tests\\${osGroup}.${architecture}.${configuration}', '.\\bin\\tests\\tests.zip')\"";
 
                         // Add archival.
                         Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip", "bin/Product/**/.nuget/**")
                     }
                     break
-                case 'arm64':
-                    assert isArmWindowsScenario(scenario)
-
-                    // This is now a build only job. Do not run tests. Use the flow job.
-                    buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${architecture} toolset_dir C:\\ats2 -priority=${priority}"
-
-                    // Zip up the tests directory so that we don't use so much space/time copying
-                    // 10s of thousands of files around.
-                    buildCommands += "powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('.\\bin\\tests\\${osGroup}.${architecture}.${configuration}', '.\\bin\\tests\\tests.zip')\"";
-
-                    // Add archival.
-                    Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip", "bin/Product/**/.nuget/**")
-                    break
                 default:
                     println("Unknown architecture: ${architecture}");
                     assert false
@@ -2425,7 +2409,7 @@ def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR
                         Utilities.addXUnitDotNETResults(newJob, '**/pal_tests.xml')
                     }
                     else {
-                        if(scenario == 'corefx_innerloop') {
+                        if (scenario == 'corefx_innerloop') {
                             assert os == 'Ubuntu' || 'OSX10.12'
                             assert architecture == 'x64'
 
@@ -2651,7 +2635,8 @@ def static shouldGenerateJob(def scenario, def isPR, def architecture, def confi
     if (isBuildOnly) {
         switch (architecture) {
             case 'arm':
-                // We use build only jobs for Windows arm cross-compilation corefx testing, so we need to generate builds for that.
+            case 'arm64':
+                // We use build only jobs for Windows arm/arm64 cross-compilation corefx testing, so we need to generate builds for that.
                 if (!isCoreFxScenario(scenario)) {
                     return false
                 }
@@ -2693,7 +2678,7 @@ def static shouldGenerateJob(def scenario, def isPR, def architecture, def confi
                 break
 
             case 'arm':
-                // We use build only jobs for Windows arm cross-compilation corefx testing, so we need to generate builds for that.
+                // We use build only jobs for Windows arm/arm64 cross-compilation corefx testing, so we need to generate builds for that.
                 // No "regular" Windows arm corefx jobs, e.g.
                 // For Ubuntu arm corefx testing, we use regular jobs (not "build only" since only Windows has "build only", and
                 // the Ubuntu arm "regular" jobs don't run tests anyway).
@@ -2711,7 +2696,9 @@ def static shouldGenerateJob(def scenario, def isPR, def architecture, def confi
 
             case 'arm64':
                 if (os == 'Windows_NT') {
-                    return false
+                    if (! (isBuildOnly && isCoreFxScenario(scenario)) ) {
+                        return false
+                    }
                 }
                 else {
                     if (!isCoreFxScenario(scenario)) {
@@ -3001,20 +2988,20 @@ def static CreateWindowsArmTestJob(def dslFactory, def project, def architecture
 
             if (isCoreFxScenario(scenario)) {
 
-                // Only arm supported for corefx testing now.
-                assert architecture == 'arm'
+                // Only arm/arm64 supported for corefx testing now.
+                assert architecture == 'arm' || architecture == 'arm64'
 
                 // Unzip CoreFx runtime
-                batchFile("powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('_\\fx\\fxruntime.zip', '_\\fx\\bin\\testhost\\netcoreapp-Windows_NT-Release-arm')\"")
+                batchFile("powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('_\\fx\\fxruntime.zip', '_\\fx\\bin\\testhost\\netcoreapp-Windows_NT-Release-${architecture}')\"")
 
                 // Unzip CoreFx tests.
                 batchFile("powershell -NoProfile -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('_\\fx\\fxtests.zip', '_\\fx\\bin\\tests')\"")
 
                 // Add the script to run the corefx tests
-                def corefx_runtime_path   = "%WORKSPACE%\\_\\fx\\bin\\testhost\\netcoreapp-Windows_NT-Release-arm"
+                def corefx_runtime_path   = "%WORKSPACE%\\_\\fx\\bin\\testhost\\netcoreapp-Windows_NT-Release-${architecture}"
                 def corefx_tests_dir      = "%WORKSPACE%\\_\\fx\\bin\\tests"
-                def corefx_exclusion_file = "%WORKSPACE%\\tests\\arm\\corefx_test_exclusions.txt"
-                batchFile("call %WORKSPACE%\\tests\\scripts\\run-corefx-tests.bat ${corefx_runtime_path} ${corefx_tests_dir} ${corefx_exclusion_file}")
+                def corefx_exclusion_file = "%WORKSPACE%\\tests\\${architecture}\\corefx_test_exclusions.txt"
+                batchFile("call %WORKSPACE%\\tests\\scripts\\run-corefx-tests.bat ${corefx_runtime_path} ${corefx_tests_dir} ${corefx_exclusion_file} ${architecture}")
 
             } else { // !isCoreFxScenario(scenario)
 
@@ -3633,11 +3620,6 @@ def static shouldGenerateFlowJob(def scenario, def isPR, def architecture, def c
         if (configuration != 'Checked') {
             return false
         }
-
-        // On Windows, CoreFx tests currently not implemented for ARM64.
-        if (isCoreFxScenario(scenario) && (os == 'Windows_NT') && (architecture == 'arm64')) {
-            return false
-        }
     }
     else if (isR2RBaselineScenario(scenario)) {
         if (configuration != 'Checked' && configuration != 'Release') {
index 6b00a58..660069e 100644 (file)
@@ -1,3 +1,13 @@
 Invariant.Tests
-System.Diagnostics.Process.Tests
+System.ComponentModel.Composition.Tests                 # https://github.com/dotnet/coreclr/issues/18913
+System.Diagnostics.Process.Tests                        # https://github.com/dotnet/coreclr/issues/16001
+System.Drawing.Common.Tests                             # https://github.com/dotnet/coreclr/issues/18886
+System.Linq.Expressions.Tests                           # JitStress=1 JitStress=2 https://github.com/dotnet/coreclr/issues/18886
+System.Management.Tests                                 # https://github.com/dotnet/coreclr/issues/18886
+System.Net.HttpListener.Tests                           # https://github.com/dotnet/coreclr/issues/17584
+System.Numerics.Vectors.Tests                           # https://github.com/dotnet/coreclr/issues/18886
+System.Runtime.InteropServices.RuntimeInformation.Tests # VM assert -- https://github.com/dotnet/coreclr/issues/18886
+System.Runtime.Serialization.Formatters.Tests           # long running? https://github.com/dotnet/coreclr/issues/18886
+System.Runtime.Tests                                    # https://github.com/dotnet/coreclr/issues/18914
+System.Text.RegularExpressions.Tests                    # https://github.com/dotnet/coreclr/issues/18912 -- timeout -- JitMinOpts only
 System.ValueTuple.Tests
index 32103f2..b77644f 100644 (file)
@@ -5,17 +5,19 @@ goto start
 :usage
 echo Usage: run-corefx-tests.bat ^<runtime path^> ^<tests dir^> ^<test exclusion file^>
 echo.
-echo Runs the corefx tests on a Windows ARM device, by searching for all relevant corefx
+echo Runs the corefx tests on a Windows ARM/ARM64 device, by searching for all relevant corefx
 echo RunTests.cmd files in the ^<tests dir^> tree, and running each one in turn. This
-echo script is typically run on a Windows ARM machine after the run-corefx-test.py script
+echo script is typically run on a Windows ARM/ARM64 machine after the run-corefx-test.py script
 echo is run on a Windows x64 machine with the `-no_run_tests` argument, to build the
 echo corefx tree, including tests, and then copying the built runtime layout and tests
-echo to the ARM machine.
+echo to the ARM/ARM64 machine.
 echo.
 echo Arguments:
-echo ^<runtime path^> -- Path to corefx-built runtime "layout", e.g. _\fx\bin\testhost\netcoreapp-Windows_NT-Release-arm
-echo ^<tests dir^> -- Path to corefx test tree, e.g., _\fx\bin\tests
+echo ^<runtime path^>        -- Path to corefx-built runtime "layout", e.g. _\fx\bin\testhost\netcoreapp-Windows_NT-Release-arm
+echo ^<tests dir^>           -- Path to corefx test tree, e.g., _\fx\bin\tests
 echo ^<test exclusion file^> -- Path to test exclusion file, e.g., C:\coreclr\tests\arm\corefx_test_exclusions.txt
+echo ^<architecture^>        -- Architecture to run, either ARM or ARM64. (We can't depend on PROCESSOR_ARCHITECTURE because
+echo                            the batch script might be invoked with an ARM64 CMD but we need to run ARM.)
 echo.
 echo The ^<test exclusion file^> is a file with a list of assemblies for which the
 echo tests should not be run. This allows excluding failing tests by excluding the
@@ -26,23 +28,22 @@ echo.
 echo     System.Console.Tests
 echo     System.Data.SqlClient.Tests
 echo     System.Diagnostics.Process.Tests
-echo.
-echo This script only works for Windows ARM, but perhaps should be extended to work
-echo for Windows ARM64 as well.
 goto :eof
 
 :start
-if "%3"=="" goto usage
-if not "%4"=="" goto usage
+if "%4"=="" goto usage
+if not "%5"=="" goto usage
 
 set _runtime_path=%1
 set _tests_dir=%2
 set _exclusion_file=%3
+set _architecture=%4
 
 echo Running CoreFX tests
 echo Using runtime: %_runtime_path%
 echo Using tests: %_tests_dir%
 echo Using test exclusion file: %_exclusion_file%
+echo Using architecture: %_architecture%
 
 set _pass=0
 set _fail=0
@@ -50,7 +51,7 @@ set _skipped=0
 set _total=0
 
 pushd %_tests_dir%
-for /F %%i in ('dir /s /b /A:D netcoreapp-Windows_NT-Release-arm') do (
+for /F %%i in ('dir /s /b /A:D netcoreapp-Windows_NT-Release-%_architecture%') do (
     if exist %%i\RunTests.cmd call :one %%i
 )
 popd
@@ -69,7 +70,11 @@ REM From this, we want System.Management.Tests to compare against the exclusion
 REM of test names to skip.
 
 set _t1=%1
-set _t2=%_t1:\netcoreapp-Windows_NT-Release-arm=%
+if /i %_architecture%==arm (
+    set _t2=%_t1:\netcoreapp-Windows_NT-Release-arm=%
+) else (
+    set _t2=%_t1:\netcoreapp-Windows_NT-Release-arm64=%
+)
 for /F %%j in ("%_t2%") do set _t3=%%~nxj
 findstr /i %_t3% %_exclusion_file% >nul
 if %errorlevel% EQU 0 (
index 4acd5d2..a45f5d6 100644 (file)
@@ -70,6 +70,7 @@ parser.add_argument('-fx_branch', dest='fx_branch', default='master')
 parser.add_argument('-fx_commit', dest='fx_commit', default=None)
 parser.add_argument('-env_script', dest='env_script', default=None)
 parser.add_argument('-no_run_tests', dest='no_run_tests', action="store_true", default=False)
+parser.add_argument('-toolset_dir', dest='toolset_dir', default='c:\\ats2')
 
 
 ##########################################################################
@@ -81,8 +82,8 @@ def validate_args(args):
     Args:
         args (argparser.ArgumentParser): Args parsed by the argument parser.
     Returns:
-        (arch, ci_arch, build_type, clr_root, fx_root, fx_branch, fx_commit, env_script, no_run_tests)
-            (str, str, str, str, str, str, str, str)
+        (arch, ci_arch, build_type, clr_root, fx_root, fx_branch, fx_commit, env_script, no_run_tests, toolset_dir)
+            (str, str, str, str, str, str, str, str, str)
     Notes:
     If the arguments are valid then return them all in a tuple. If not, raise
     an exception stating x argument is incorrect.
@@ -97,6 +98,7 @@ def validate_args(args):
     fx_commit = args.fx_commit
     env_script = args.env_script
     no_run_tests = args.no_run_tests
+    toolset_dir = args.toolset_dir
 
     def validate_arg(arg, check):
         """ Validate an individual arg
@@ -142,7 +144,7 @@ def validate_args(args):
         validate_arg(env_script, lambda item: os.path.isfile(env_script))
         env_script = os.path.abspath(env_script)
 
-    args = (arch, ci_arch, build_type, clr_root, fx_root, fx_branch, fx_commit, env_script, no_run_tests)
+    args = (arch, ci_arch, build_type, clr_root, fx_root, fx_branch, fx_commit, env_script, no_run_tests, toolset_dir)
 
     log('Configuration:')
     log(' arch: %s' % arch)
@@ -154,6 +156,7 @@ def validate_args(args):
     log(' fx_commit: %s' % fx_commit)
     log(' env_script: %s' % env_script)
     log(' no_run_tests: %s' % no_run_tests)
+    log(' toolset_dir: %s' % toolset_dir)
 
     return args
 
@@ -215,7 +218,7 @@ def main(args):
     global Unix_name_map
     global testing
 
-    arch, ci_arch, build_type, clr_root, fx_root, fx_branch, fx_commit, env_script, no_run_tests = validate_args(
+    arch, ci_arch, build_type, clr_root, fx_root, fx_branch, fx_commit, env_script, no_run_tests, toolset_dir = validate_args(
         args)
 
     clr_os = 'Windows_NT' if Is_windows else Unix_name_map[os.uname()[0]]
@@ -276,11 +279,8 @@ def main(args):
             os.makedirs(fx_home)
         os.putenv('HOME', fx_home)
         log('HOME=' + fx_home)
-
-    # Determine the RID to specify the to corefix build scripts.  This seems to
-    # be way harder than it ought to be.
  
-    # Gather up some arguments to pass to both build and build-tests.
+    # Gather up some arguments to pass to build-managed, build-native, and build-tests scripts.
 
     config_args = '-Release -os:%s -buildArch:%s' % (clr_os, arch)
 
@@ -300,17 +300,23 @@ def main(args):
     # Cross build corefx for arm32 on x86.
 
     build_native_args = ''
+
     if not Is_windows and arch == 'arm' :
         # We need to force clang5.0; we are building in a docker container that doesn't have
         # clang3.9, which is currently the default used by build-native.sh. We need to pass
         # "-cross", but we also pass "-portable", which build-native.sh normally passes
         # (there doesn't appear to be a way to pass these individually).
-        build_native_args = '-AdditionalArgs:"-portable -cross" -Clang:clang5.0'
+        build_native_args += ' -AdditionalArgs:"-portable -cross" -Clang:clang5.0'
 
     if not Is_windows and arch == 'arm64' :
         # We need to pass "-cross", but we also pass "-portable", which build-native.sh normally
         # passes (there doesn't appear to be a way to pass these individually).
-        build_native_args = '-AdditionalArgs:"-portable -cross"'
+        build_native_args += ' -AdditionalArgs:"-portable -cross"'
+
+    if Is_windows and arch == 'arm64' :
+        # We need to pass toolsetDir to specify the arm64 private toolset.
+        # This is temporary, until private toolset is no longer used. So hard-code the CI toolset dir.
+        build_native_args += ' -ToolSetDir:"toolsetDir=%s"' % toolset_dir
 
     command = ' '.join(('build-native.cmd' if Is_windows else './build-native.sh',
                         config_args,
@@ -318,12 +324,14 @@ def main(args):
     log(command)
     returncode = 0 if testing else os.system(command)
     if returncode != 0:
+        log('Error: exit code %s' % returncode)
         sys.exit(1)
 
     command = ' '.join(('build-managed.cmd' if Is_windows else './build-managed.sh', config_args))
     log(command)
     returncode = 0 if testing else os.system(command)
     if returncode != 0:
+        log('Error: exit code %s' % returncode)
         sys.exit(1)
 
     # Override the built corefx runtime (which it picked up by copying from packages determined
@@ -381,6 +389,7 @@ def main(args):
     log(command)
     returncode = 0 if testing else os.system(command)
     if returncode != 0:
+        log('Error: exit code %s' % returncode)
         sys.exit(1)
 
     sys.exit(0)