Nullable: String (#23450)
[platform/upstream/coreclr.git] / build-test.sh
1 #!/usr/bin/env bash
2
3 __PortableBuild=1
4
5 initTargetDistroRid()
6 {
7     source init-distro-rid.sh
8
9     # Only pass ROOTFS_DIR if cross is specified.
10     if (( ${__CrossBuild} == 1 )); then
11         passedRootfsDir=${ROOTFS_DIR}
12     fi
13
14     initDistroRidGlobal ${__BuildOS} ${__BuildArch} ${__PortableBuild} ${passedRootfsDir}
15 }
16
17 isMSBuildOnNETCoreSupported()
18 {
19     __isMSBuildOnNETCoreSupported=$__msbuildonunsupportedplatform
20
21     if [ $__isMSBuildOnNETCoreSupported == 1 ]; then
22         return
23     fi
24
25     if [ "$__HostArch" == "x64" ]; then
26         if [ "$__HostOS" == "Linux" ]; then
27             __isMSBuildOnNETCoreSupported=1
28             UNSUPPORTED_RIDS=("debian.9-x64" "ubuntu.17.04-x64")
29             for UNSUPPORTED_RID in "${UNSUPPORTED_RIDS[@]}"
30             do
31                 if [ "${__DistroRid}" == "$UNSUPPORTED_RID" ]; then
32                     __isMSBuildOnNETCoreSupported=0
33                     break
34                 fi
35             done
36         elif [ "$__HostOS" == "OSX" ]; then
37             __isMSBuildOnNETCoreSupported=1
38         fi
39     fi
40 }
41
42 build_test_wrappers()
43 {
44     if [ $__BuildTestWrappers -ne -0 ]; then
45         echo "${__MsgPrefix}Creating test wrappers..."
46
47         export __Exclude="${__ProjectDir}/tests/issues.targets"
48         export __BuildLogRootName="Tests_XunitWrapper"
49
50         buildVerbosity="Summary"
51
52         if [ $__VerboseBuild == 1 ]; then
53             buildVerbosity="Diag"
54         fi
55
56         # Set up directories and file names
57         __BuildLogRootName=$subDirectoryName
58         __BuildLog="$__LogsDir/${__BuildLogRootName}.${__BuildOS}.${__BuildArch}.${__BuildType}.log"
59         __BuildWrn="$__LogsDir/${__BuildLogRootName}.${__BuildOS}.${__BuildArch}.${__BuildType}.wrn"
60         __BuildErr="$__LogsDir/${__BuildLogRootName}.${__BuildOS}.${__BuildArch}.${__BuildType}.err"
61         __MsbuildLog="/fileloggerparameters:\"Verbosity=normal;LogFile=${__BuildLog}\""
62         __MsbuildWrn="/fileloggerparameters1:\"WarningsOnly;LogFile=${__BuildWrn}\""
63         __MsbuildErr="/fileloggerparameters2:\"ErrorsOnly;LogFile=${__BuildErr}\""
64         __Logging="$__MsbuildLog $__MsbuildWrn $__MsbuildErr /consoleloggerparameters:$buildVerbosity"
65
66         nextCommand="\"${__DotNetCli}\" msbuild \"${__ProjectDir}/tests/runtest.proj\" /p:RestoreAdditionalProjectSources=https://dotnet.myget.org/F/dotnet-core/ /p:BuildWrappers=true /p:TargetsWindows=false $__Logging /p:__BuildOS=$__BuildOS /p:__BuildType=$__BuildType /p:__BuildArch=$__BuildArch"
67         eval $nextCommand
68
69         if [ $? -ne 0 ]; then
70             echo "${__MsgPrefix}Error: build failed. Refer to the build log files for details (above)"
71             exit 1
72         else
73             echo "XUnit Wrappers have been built."
74             echo { "\"build_os\"": "\"${__BuildOS}\"", "\"build_arch\"": "\"${__BuildArch}\"", "\"build_type\"": "\"${__BuildType}\"" } > "${__TestWorkingDir}/build_info.json"
75
76         fi
77     fi
78 }
79
80 generate_layout()
81 {
82     echo "${__MsgPrefix}Creating test overlay..."
83
84     __TestDir=$__ProjectDir/tests
85     __ProjectFilesDir=$__TestDir
86     __TestBinDir=$__TestWorkingDir
87
88     if [ $__RebuildTests -ne 0 ]; then
89         if [ -d "${__TestBinDir}" ]; then
90             echo "Removing tests build dir: ${__TestBinDir}"
91             rm -rf $__TestBinDir
92         fi
93     fi
94
95     __CMakeBinDir="${__TestBinDir}"
96
97     if [ -z "$__TestIntermediateDir" ]; then
98         __TestIntermediateDir="tests/obj/${__BuildOS}.${__BuildArch}.${__BuildType}"
99     fi
100
101     echo "__BuildOS: ${__BuildOS}"
102     echo "__BuildArch: ${__BuildArch}"
103     echo "__BuildType: ${__BuildType}"
104     echo "__TestIntermediateDir: ${__TestIntermediateDir}"
105
106     if [ ! -f "$__TestBinDir" ]; then
107         echo "Creating TestBinDir: ${__TestBinDir}"
108         mkdir -p $__TestBinDir
109     fi
110     if [ ! -f "$__LogsDir" ]; then
111         echo "Creating LogsDir: ${__LogsDir}"
112         mkdir -p $__LogsDir
113     fi
114     if [ ! -f "$__MsbuildDebugLogsDir" ]; then
115         echo "Creating MsbuildDebugLogsDir: ${__MsbuildDebugLogsDir}"
116         mkdir -p $__MsbuildDebugLogsDir
117     fi
118
119     # Set up the directory for MSBuild debug logs.
120     export MSBUILDDEBUGPATH="${__MsbuildDebugLogsDir}"
121
122     __BuildProperties="-p:OSGroup=${__BuildOS} -p:BuildOS=${__BuildOS} -p:BuildArch=${__BuildArch} -p:BuildType=${__BuildType}"
123
124     # =========================================================================================
125     # ===
126     # === Restore product binaries from packages
127     # ===
128     # =========================================================================================
129
130     build_MSBuild_projects "Restore_Packages" "${__ProjectDir}/tests/build.proj" "Restore product binaries (build tests)" "/t:BatchRestorePackages"
131
132     if [ -n "$__UpdateInvalidPackagesArg" ]; then
133         __up="/t:UpdateInvalidPackageVersions"
134     fi
135
136     echo "${__MsgPrefix}Creating test overlay..."
137
138     if [ -z "$xUnitTestBinBase" ]; then
139         xUnitTestBinBase=$__TestWorkingDir
140     fi
141
142     export CORE_ROOT=$xUnitTestBinBase/Tests/Core_Root
143
144     if [ -d "${CORE_ROOT}" ]; then
145         rm -rf $CORE_ROOT
146     fi
147
148     mkdir -p $CORE_ROOT
149
150     build_MSBuild_projects "Tests_Overlay_Managed" "${__ProjectDir}/tests/runtest.proj" "Creating test overlay" "/t:CreateTestOverlay"
151
152     chmod +x $__BinDir/corerun
153     chmod +x $__BinDir/crossgen
154
155     # Make sure to copy over the pulled down packages
156     cp -r $__BinDir/* $CORE_ROOT/ > /dev/null
157
158     if [ "$__BuildOS" != "OSX" ]; then
159         nextCommand="\"$__TestDir/setup-stress-dependencies.sh\" --outputDir=$CORE_ROOT"
160         echo "Resolve runtime dependences via $nextCommand"
161         eval $nextCommand
162     fi
163 }
164
165 generate_testhost()
166 {
167     echo "${__MsgPrefix}Generating test host..."
168
169     export TEST_HOST=$xUnitTestBinBase/testhost
170
171     if [ -d "${TEST_HOST}" ]; then
172         rm -rf $TEST_HOST
173     fi
174
175     mkdir -p $TEST_HOST
176
177     build_MSBuild_projects "Tests_Generate_TestHost" "${__ProjectDir}/tests/runtest.proj" "Creating test host" "/t:CreateTestHost"
178 }
179
180
181 build_Tests()
182 {
183     echo "${__MsgPrefix}Building Tests..."
184
185     __TestDir=$__ProjectDir/tests
186     __ProjectFilesDir=$__TestDir
187     __TestBinDir=$__TestWorkingDir
188
189     if [ -f  "${__TestWorkingDir}/build_info.json" ]; then
190         rm  "${__TestWorkingDir}/build_info.json"
191     fi
192
193     if [ $__RebuildTests -ne 0 ]; then
194         if [ -d "${__TestBinDir}" ]; then
195             echo "Removing tests build dir: ${__TestBinDir}"
196             rm -rf $__TestBinDir
197         fi
198     fi
199
200     export __CMakeBinDir="${__TestBinDir}"
201     if [ ! -d "${__TestIntermediatesDir}" ]; then
202         mkdir -p ${__TestIntermediatesDir}
203     fi
204
205     __NativeTestIntermediatesDir="${__TestIntermediatesDir}/Native"
206     if [  ! -d "${__NativeTestIntermediatesDir}" ]; then
207         mkdir -p ${__NativeTestIntermediatesDir}
208     fi
209
210     __ManagedTestIntermediatesDir="${__TestIntermediatesDir}/Managed"
211     if [ ! -d "${__ManagedTestIntermediatesDir}" ]; then
212         mkdir -p ${__ManagedTestIntermediatesDir}
213     fi
214
215     echo "__BuildOS: ${__BuildOS}"
216     echo "__BuildArch: ${__BuildArch}"
217     echo "__BuildType: ${__BuildType}"
218     echo "__TestIntermediatesDir: ${__TestIntermediatesDir}"
219     echo "__NativeTestIntermediatesDir: ${__NativeTestIntermediatesDir}"
220     echo "__ManagedTestIntermediatesDir: ${__ManagedTestIntermediatesDir}"
221
222     if [ ! -f "$__TestBinDir" ]; then
223         echo "Creating TestBinDir: ${__TestBinDir}"
224         mkdir -p $__TestBinDir
225     fi
226     if [ ! -f "$__LogsDir" ]; then
227         echo "Creating LogsDir: ${__LogsDir}"
228         mkdir -p $__LogsDir
229     fi
230     if [ ! -f "$__MsbuildDebugLogsDir" ]; then
231         echo "Creating MsbuildDebugLogsDir: ${__MsbuildDebugLogsDir}"
232         mkdir -p $__MsbuildDebugLogsDir
233     fi
234
235     # Set up the directory for MSBuild debug logs.
236     export MSBUILDDEBUGPATH="${__MsbuildDebugLogsDir}"
237
238     __BuildProperties="-p:OSGroup=${__BuildOS} -p:BuildOS=${__BuildOS} -p:BuildArch=${__BuildArch} -p:BuildType=${__BuildType}"
239
240     # =========================================================================================
241     # ===
242     # === Restore product binaries from packages
243     # ===
244     # =========================================================================================
245
246     if [ ${__SkipRestorePackages} != 1 ]; then
247         build_MSBuild_projects "Restore_Product" "${__ProjectDir}/tests/build.proj" "Restore product binaries (build tests)" "/t:BatchRestorePackages"
248     fi
249
250     if [ $__SkipNative != 1 ]; then
251         build_native_projects "$__BuildArch" "${__NativeTestIntermediatesDir}"
252
253         if [ $? -ne 0 ]; then
254             echo "${__MsgPrefix}Error: build failed. Refer to the build log files for details (above)"
255             exit 1
256         fi
257     fi
258
259     if [ $__SkipManaged != 1 ]; then
260         echo "Starting the Managed Tests Build..."
261
262         build_MSBuild_projects "Tests_Managed" "$__ProjectDir/tests/build.proj" "Managed tests build (build tests)" "$__up"
263
264         if [ $? -ne 0 ]; then
265             echo "${__MsgPrefix}Error: build failed. Refer to the build log files for details (above)"
266             exit 1
267         else
268             echo "Checking the Managed Tests Build..."
269
270             build_MSBuild_projects "Check_Test_Build" "${__ProjectDir}/tests/runtest.proj" "Check Test Build" "/t:CheckTestBuild"
271
272             if [ $? -ne 0 ]; then
273                 echo "${__MsgPrefix}Error: Check Test Build failed."
274                 exit 1
275             fi
276         fi
277
278         echo "Managed tests build success!"
279     fi
280
281     build_test_wrappers
282
283     if [ -n "$__UpdateInvalidPackagesArg" ]; then
284         __up="/t:UpdateInvalidPackageVersions"
285     fi
286
287     generate_layout
288 }
289
290 build_MSBuild_projects()
291 {
292     subDirectoryName=$1
293     shift
294     projectName=$1
295     shift
296     stepName="$1"
297     shift
298     extraBuildParameters=("$@")
299
300     # Set up directories and file names
301     __BuildLogRootName=$subDirectoryName
302     __BuildLog="$__LogsDir/${__BuildLogRootName}.${__BuildOS}.${__BuildArch}.${__BuildType}.log"
303     __BuildWrn="$__LogsDir/${__BuildLogRootName}.${__BuildOS}.${__BuildArch}.${__BuildType}.wrn"
304     __BuildErr="$__LogsDir/${__BuildLogRootName}.${__BuildOS}.${__BuildArch}.${__BuildType}.err"
305
306     # Use binclashlogger by default if no other logger is specified
307     if [[ "${extraBuildParameters[*]}" == *"/l:"* ]]; then
308         __msbuildEventLogging=
309     else
310         __msbuildEventLogging="/l:BinClashLogger,Tools/Microsoft.DotNet.Build.Tasks.dll\;LogFile=binclash.log"
311     fi
312
313     if [[ "$subDirectoryName" == "Tests_Managed" ]]; then
314         # Execute msbuild managed test build in stages - workaround for excessive data retention in MSBuild ConfigCache
315         # See https://github.com/Microsoft/msbuild/issues/2993
316
317         # __SkipPackageRestore and __SkipTargetingPackBuild used  to control build by tests/src/dirs.proj
318         export __SkipPackageRestore=false
319         export __SkipTargetingPackBuild=false
320         export __NumberOfTestGroups=3
321
322         __AppendToLog=false
323
324         if [ -n "$__priority1" ]; then
325             export __NumberOfTestGroups=10
326         fi
327
328         for (( testGroupToBuild=1 ; testGroupToBuild <= __NumberOfTestGroups; testGroupToBuild = testGroupToBuild + 1 ))
329         do
330             __msbuildLog="\"/flp:Verbosity=normal;LogFile=${__BuildLog};Append=${__AppendToLog}\""
331             __msbuildWrn="\"/flp1:WarningsOnly;LogFile=${__BuildWrn};Append=${__AppendToLog}\""
332             __msbuildErr="\"/flp2:ErrorsOnly;LogFile=${__BuildErr};Append=${__AppendToLog}\""
333
334             export __TestGroupToBuild=$testGroupToBuild
335
336             # Generate build command
337             buildArgs=("/nologo" "/verbosity:minimal" "/clp:Summary")
338             buildArgs+=("/p:RestoreDefaultOptimizationDataPackage=false" "/p:PortableBuild=true")
339             buildArgs+=("/p:UsePartialNGENOptimization=false" "/maxcpucount")
340
341             buildArgs+=("$projectName" "${__msbuildLog}" "${__msbuildWrn}" "${__msbuildErr}")
342             buildArgs+=("$__msbuildEventLogging")
343             buildArgs+=("${extraBuildParameters[@]}")
344             buildArgs+=("${__CommonMSBuildArgs[@]}")
345             buildArgs+=("${__UnprocessedBuildArgs[@]}")
346
347             nextCommand="\"$__ProjectRoot/dotnet.sh\" msbuild ${buildArgs[@]}"
348             echo "Building step '$stepName' testGroupToBuild=$testGroupToBuild via $nextCommand"
349             eval $nextCommand
350
351             # Make sure everything is OK
352             if [ $? -ne 0 ]; then
353                 echo "${__MsgPrefix}Failed to build $stepName. See the build logs:"
354                 echo "    $__BuildLog"
355                 echo "    $__BuildWrn"
356                 echo "    $__BuildErr"
357                 exit 1
358             fi
359             export __SkipPackageRestore=true
360             export __SkipTargetingPackBuild=true
361             __AppendToLog=true
362         done
363     else
364         __msbuildLog="\"/flp:Verbosity=normal;LogFile=${__BuildLog}\""
365         __msbuildWrn="\"/flp1:WarningsOnly;LogFile=${__BuildWrn}\""
366         __msbuildErr="\"/flp2:ErrorsOnly;LogFile=${__BuildErr}\""
367
368         # Generate build command
369         buildArgs=("/nologo" "/verbosity:minimal" "/clp:Summary")
370         buildArgs+=("/p:RestoreDefaultOptimizationDataPackage=false" "/p:PortableBuild=true")
371         buildArgs+=("/p:UsePartialNGENOptimization=false" "/maxcpucount")
372
373         buildArgs+=("$projectName" "${__msbuildLog}" "${__msbuildWrn}" "${__msbuildErr}")
374         buildArgs+=("$__msbuildEventLogging")
375         buildArgs+=("${extraBuildParameters[@]}")
376         buildArgs+=("${__CommonMSBuildArgs[@]}")
377         buildArgs+=("${__UnprocessedBuildArgs[@]}")
378
379         nextCommand="\"$__ProjectRoot/dotnet.sh\" msbuild ${buildArgs[@]}"
380         echo "Building step '$stepName' via $nextCommand"
381         eval $nextCommand
382
383         # Make sure everything is OK
384         if [ $? -ne 0 ]; then
385             echo "${__MsgPrefix}Failed to build $stepName. See the build logs:"
386             echo "    $__BuildLog"
387             echo "    $__BuildWrn"
388             echo "    $__BuildErr"
389             exit 1
390         fi
391     fi
392 }
393
394 build_native_projects()
395 {
396     platformArch="$1"
397     intermediatesForBuild="$2"
398
399     extraCmakeArguments="-DCLR_CMAKE_TARGET_OS=${__BuildOS} -DCLR_CMAKE_HOST_ARCH=${platformArch}"
400     message="native tests assets"
401
402     # All set to commence the build
403     echo "Commencing build of $message for $__BuildOS.$__BuildArch.$__BuildType in $intermediatesForBuild"
404
405     generator=""
406     buildFile="Makefile"
407     buildTool="make"
408     if [ $__UseNinja == 1 ]; then
409         generator="ninja"
410         buildFile="build.ninja"
411         if ! buildTool=$(command -v ninja || command -v ninja-build); then
412            echo "Unable to locate ninja!" 1>&2
413            exit 1
414         fi
415     fi
416
417     if [ $__SkipConfigure == 0 ]; then
418         # if msbuild is not supported, then set __SkipGenerateVersion to 1
419         if [ $__isMSBuildOnNETCoreSupported == 0 ]; then __SkipGenerateVersion=1; fi
420         # Drop version.c file
421         __versionSourceFile="$intermediatesForBuild/version.c"
422         if [ $__SkipGenerateVersion == 0 ]; then
423             pwd
424             $__ProjectRoot/dotnet.sh msbuild /nologo /verbosity:minimal /clp:Summary \
425                                      /p:RestoreDefaultOptimizationDataPackage=false /p:PortableBuild=true \
426                                      /p:UsePartialNGENOptimization=false /maxcpucount \
427                                      $__ProjectDir/build.proj /t:GenerateVersionHeader \
428                                      /p:GenerateVersionHeader=true /p:NativeVersionSourceFile=$__versionSourceFile \
429                                      /l:BinClashLogger,Tools/Microsoft.DotNet.Build.Tasks.dll\;LogFile=binclash.log \
430                                      $__CommonMSBuildArgs $__UnprocessedBuildArgs
431         else
432             # Generate the dummy version.c, but only if it didn't exist to make sure we don't trigger unnecessary rebuild
433             __versionSourceLine="static char sccsid[] __attribute__((used)) = \"@(#)No version information produced\";"
434             if [ -e $__versionSourceFile ]; then
435                 read existingVersionSourceLine < $__versionSourceFile
436             fi
437             if [ "$__versionSourceLine" != "$existingVersionSourceLine" ]; then
438                 echo $__versionSourceLine > $__versionSourceFile
439             fi
440         fi
441
442         pushd "$intermediatesForBuild"
443         # Regenerate the CMake solution
444         # Force cross dir to point to project root cross dir, in case there is a cross build.
445         scriptDir="$__ProjectRoot/src/pal/tools"
446         if [[ $__GccBuild == 0 ]]; then
447             nextCommand="CONFIG_DIR=\"$__ProjectRoot/cross\" \"$scriptDir/gen-buildsys-clang.sh\" \"$__TestDir\" $__ClangMajorVersion $__ClangMinorVersion $platformArch $scriptDir $__BuildType $__CodeCoverage $generator $extraCmakeArguments $__cmakeargs"
448         else
449             nextCommand="CONFIG_DIR=\"$__ProjectRoot/cross\" \"$scriptDir/gen-buildsys-gcc.sh\" \"$__TestDir\" \"$__GccMajorVersion\" \"$__GccMinorVersion\" $platformArch $scriptDir $__BuildType $__CodeCoverage $generator $extraCmakeArguments $__cmakeargs"
450         fi
451         echo "Invoking $nextCommand"
452         eval $nextCommand
453         popd
454     fi
455
456     if [ ! -f "$intermediatesForBuild/$buildFile" ]; then
457         echo "Failed to generate $message build project!"
458         exit 1
459     fi
460
461     # Build
462     if [ $__ConfigureOnly == 1 ]; then
463         echo "Finish configuration & skipping $message build."
464         return
465     fi
466
467     pushd "$intermediatesForBuild"
468
469     echo "Executing $buildTool install -j $__NumProc"
470
471     $buildTool install -j $__NumProc
472     if [ $? != 0 ]; then
473         echo "Failed to build $message."
474         exit 1
475     fi
476
477     popd
478     echo "Native tests build success!"
479 }
480
481 usage()
482 {
483     echo "Usage: $0 [BuildArch] [BuildType] [verbose] [coverage] [cross] [clangx.y] [ninja] [runtests] [bindir]"
484     echo "BuildArch can be: x64, x86, arm, armel, arm64"
485     echo "BuildType can be: debug, checked, release"
486     echo "coverage - optional argument to enable code coverage build (currently supported only for Linux and OSX)."
487     echo "ninja - target ninja instead of GNU make"
488     echo "clangx.y - optional argument to build using clang version x.y - supported version 3.5 - 6.0"
489     echo "gccx.y - optional argument to build using gcc version x.y."
490     echo "cross - optional argument to signify cross compilation,"
491     echo "      - will use ROOTFS_DIR environment variable if set."
492     echo "portableLinux - build for Portable Linux Distribution"
493     echo "portablebuild - Use portable build."
494     echo "verbose - optional argument to enable verbose build output."
495     echo "rebuild - if tests have already been built - rebuild them"
496     echo "skipnative: skip the native tests build"
497     echo "skipmanaged: skip the managed section of the test build"
498     echo "buildtestwrappersonly - only build the test wrappers"
499     echo "generatelayoutonly - only pull down dependencies and build coreroot"
500     echo "generatetesthostonly - only pull down dependencies and build coreroot and the CoreFX testhost"
501     echo "skiprestorepackages - skip package restore"
502     echo "runtests - run tests after building them"
503     echo "bindir - output directory (defaults to $__ProjectRoot/bin)"
504     echo "msbuildonunsupportedplatform - build managed binaries even if distro is not officially supported."
505     echo "priority1 - include priority=1 tests in the build"
506     exit 1
507 }
508
509
510 # Obtain the location of the bash script to figure out where the root of the repo is.
511 __ProjectRoot="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
512
513 # Use uname to determine what the CPU is.
514 CPUName=$(uname -p)
515
516 # Some Linux platforms report unknown for platform, but the arch for machine.
517 if [ "$CPUName" == "unknown" ]; then
518     CPUName=$(uname -m)
519 fi
520
521 case $CPUName in
522     i686)
523         echo "Unsupported CPU $CPUName detected, build might not succeed!"
524         __BuildArch=x86
525         __HostArch=x86
526         ;;
527
528     x86_64)
529         __BuildArch=x64
530         __HostArch=x64
531         ;;
532
533     armv7l)
534         echo "Unsupported CPU $CPUName detected, build might not succeed!"
535         __BuildArch=arm
536         __HostArch=arm
537         ;;
538
539     aarch64)
540         __BuildArch=arm64
541         __HostArch=arm64
542         ;;
543
544     *)
545         echo "Unknown CPU $CPUName detected, configuring as if for x64"
546         __BuildArch=x64
547         __HostArch=x64
548         ;;
549 esac
550
551 # Use uname to determine what the OS is.
552 OSName=$(uname -s)
553 case $OSName in
554     Linux)
555         __BuildOS=Linux
556         __HostOS=Linux
557         ;;
558
559     Darwin)
560         __BuildOS=OSX
561         __HostOS=OSX
562         ;;
563
564     FreeBSD)
565         __BuildOS=FreeBSD
566         __HostOS=FreeBSD
567         ;;
568
569     OpenBSD)
570         __BuildOS=OpenBSD
571         __HostOS=OpenBSD
572         ;;
573
574     NetBSD)
575         __BuildOS=NetBSD
576         __HostOS=NetBSD
577         ;;
578
579     SunOS)
580         __BuildOS=SunOS
581         __HostOS=SunOS
582         ;;
583
584     *)
585         echo "Unsupported OS $OSName detected, configuring as if for Linux"
586         __BuildOS=Linux
587         __HostOS=Linux
588         ;;
589 esac
590
591 __BuildType=Debug
592 __CodeCoverage=
593 __IncludeTests=INCLUDE_TESTS
594
595 # Set the various build properties here so that CMake and MSBuild can pick them up
596 export __ProjectDir="$__ProjectRoot"
597 __SourceDir="$__ProjectDir/src"
598 __PackagesDir="$__ProjectDir/packages"
599 __RootBinDir="$__ProjectDir/bin"
600 __BuildToolsDir="$__ProjectDir/Tools"
601 __DotNetCli="$__ProjectDir/dotnet.sh"
602 __UnprocessedBuildArgs=
603 __CommonMSBuildArgs=
604 __MSBCleanBuildArgs=
605 __UseNinja=0
606 __VerboseBuild=0
607 __SkipRestore=""
608 __SkipNative=0
609 __SkipManaged=0
610 __SkipConfigure=0
611 __SkipGenerateVersion=0
612 __ConfigureOnly=0
613 __CrossBuild=0
614 __ClangMajorVersion=0
615 __ClangMinorVersion=0
616 __GccBuild=0
617 __GccMajorVersion=0
618 __GccMinorVersion=0
619 __NuGetPath="$__PackagesDir/NuGet.exe"
620 __SkipRestorePackages=0
621 __DistroRid=""
622 __cmakeargs=""
623 __PortableLinux=0
624 __msbuildonunsupportedplatform=0
625 __NativeTestIntermediatesDir=
626 __RunTests=0
627 __RebuildTests=0
628 __BuildTestWrappers=1
629 __GenerateLayoutOnly=
630 __GenerateTestHostOnly=
631 __priority1=
632 __BuildTestWrappersOnly=
633 CORE_ROOT=
634
635 while :; do
636     if [ $# -le 0 ]; then
637         break
638     fi
639
640     lowerI="$(echo $1 | awk '{print tolower($0)}')"
641     case $lowerI in
642         -\?|-h|--help)
643             usage
644             exit 1
645             ;;
646
647         x86)
648             __BuildArch=x86
649             ;;
650
651         x64)
652             __BuildArch=x64
653             ;;
654
655         arm)
656             __BuildArch=arm
657             ;;
658
659         armel)
660             __BuildArch=armel
661             ;;
662
663         arm64)
664             __BuildArch=arm64
665             ;;
666
667         debug)
668             __BuildType=Debug
669             ;;
670
671         checked)
672             __BuildType=Checked
673             ;;
674
675         release)
676             __BuildType=Release
677             ;;
678
679         coverage)
680             __CodeCoverage=Coverage
681             ;;
682
683         cross)
684             __CrossBuild=1
685             ;;
686
687         portablebuild=false)
688             __PortableBuild=0
689             ;;
690
691         portablelinux)
692             if [ "$__BuildOS" == "Linux" ]; then
693                 __PortableLinux=1
694             else
695                 echo "ERROR: portableLinux not supported for non-Linux platforms."
696                 exit 1
697             fi
698             ;;
699
700         verbose)
701             __VerboseBuild=1
702             ;;
703
704         clang3.5|-clang3.5)
705             __ClangMajorVersion=3
706             __ClangMinorVersion=5
707             ;;
708
709         clang3.6|-clang3.6)
710             __ClangMajorVersion=3
711             __ClangMinorVersion=6
712             ;;
713
714         clang3.7|-clang3.7)
715             __ClangMajorVersion=3
716             __ClangMinorVersion=7
717             ;;
718
719         clang3.8|-clang3.8)
720             __ClangMajorVersion=3
721             __ClangMinorVersion=8
722             ;;
723
724         clang3.9|-clang3.9)
725             __ClangMajorVersion=3
726             __ClangMinorVersion=9
727             ;;
728
729         clang4.0|-clang4.0)
730             __ClangMajorVersion=4
731             __ClangMinorVersion=0
732             ;;
733
734         clang5.0|-clang5.0)
735             __ClangMajorVersion=5
736             __ClangMinorVersion=0
737             ;;
738
739         clang6.0|-clang6.0)
740             __ClangMajorVersion=6
741             __ClangMinorVersion=0
742             ;;
743
744         gcc5|-gcc5)
745             __GccMajorVersion=5
746             __GccMinorVersion=
747             __GccBuild=1
748             ;;
749
750         gcc6|-gcc6)
751             __GccMajorVersion=6
752             __GccMinorVersion=
753             __GccBuild=1
754             ;;
755
756         gcc7|-gcc7)
757             __GccMajorVersion=7
758             __GccMinorVersion=
759             __GccBuild=1
760             ;;
761
762         gcc8|-gcc8)
763             __GccMajorVersion=8
764             __GccMinorVersion=
765             __GccBuild=1
766             ;;
767
768         gcc|-gcc)
769             __GccMajorVersion=
770             __GccMinorVersion=
771             __GccBuild=1
772             ;;
773
774         ninja)
775             __UseNinja=1
776             ;;
777
778         runtests)
779             __RunTests=1
780             ;;
781
782         rebuild)
783             __RebuildTests=1
784             ;;
785
786         skipnative|-skipnative)
787             __SkipNative=1
788             ;;
789
790         skipmanaged|-skipmanaged)
791             __SkipManaged=1
792             __BuildTestWrappers=0
793             ;;
794
795         buildtestwrappersonly)
796             __BuildTestWrappersOnly=1
797             ;;
798
799         generatelayoutonly)
800             __GenerateLayoutOnly=1
801             ;;
802
803         generatetesthostonly)
804             __GenerateTestHostOnly=1
805             ;;
806
807         skiprestorepackages)
808             __SkipRestorePackages=1
809             ;;
810
811         bindir)
812             if [ -n "$2" ]; then
813                 __RootBinDir="$2"
814                 if [ ! -d $__RootBinDir ]; then
815                     mkdir $__RootBinDir
816                 fi
817                 __RootBinParent=$(dirname $__RootBinDir)
818                 __RootBinName=${__RootBinDir##*/}
819                 __RootBinDir="$(cd $__RootBinParent &>/dev/null && printf %s/%s $PWD $__RootBinName)"
820                 shift
821             else
822                 echo "ERROR: 'bindir' requires a non-empty option argument"
823                 exit 1
824             fi
825             ;;
826
827         msbuildonunsupportedplatform)
828             __msbuildonunsupportedplatform=1
829             ;;
830
831         priority1)
832             __priority1=1
833             __UnprocessedBuildArgs+=("/p:CLRTestPriorityToBuild=1")
834             ;;
835
836         *)
837             __UnprocessedBuildArgs+=("$1")
838             ;;
839     esac
840
841     shift
842 done
843
844 # Get the number of processors available to the scheduler
845 # Other techniques such as `nproc` only get the number of
846 # processors available to a single process.
847 if [ `uname` = "FreeBSD" ]; then
848   __NumProc=`sysctl hw.ncpu | awk '{ print $2+1 }'`
849 elif [ `uname` = "NetBSD" ]; then
850   __NumProc=$(($(getconf NPROCESSORS_ONLN)+1))
851 elif [ `uname` = "Darwin" ]; then
852   __NumProc=$(($(getconf _NPROCESSORS_ONLN)+1))
853 else
854   __NumProc=$(nproc --all)
855 fi
856
857 __CommonMSBuildArgs=("/p:__BuildArch=$__BuildArch" "/p:__BuildType=$__BuildType" "/p:__BuildOS=$__BuildOS")
858
859 # Configure environment if we are doing a verbose build
860 if [ $__VerboseBuild == 1 ]; then
861     export VERBOSE=1
862     __CommonMSBuildArgs+=("/v:detailed")
863 fi
864
865 # Set default clang version
866 if [[ $__ClangMajorVersion == 0 && $__ClangMinorVersion == 0 ]]; then
867     if [[ "$__BuildArch" == "arm" || "$__BuildArch" == "armel" ]]; then
868         __ClangMajorVersion=5
869         __ClangMinorVersion=0
870     else
871         __ClangMajorVersion=3
872         __ClangMinorVersion=9
873     fi
874 fi
875
876 # Set dependent variables
877 __LogsDir="$__RootBinDir/Logs"
878 __MsbuildDebugLogsDir="$__LogsDir/MsbuildDebugLogs"
879
880 # Set the remaining variables based upon the determined build configuration
881 __BinDir="$__RootBinDir/Product/$__BuildOS.$__BuildArch.$__BuildType"
882 __PackagesBinDir="$__BinDir/.nuget"
883 __TestDir="$__ProjectDir/tests"
884 __TestWorkingDir="$__RootBinDir/tests/$__BuildOS.$__BuildArch.$__BuildType"
885 __IntermediatesDir="$__RootBinDir/obj/$__BuildOS.$__BuildArch.$__BuildType"
886 __TestIntermediatesDir="$__RootBinDir/tests/obj/$__BuildOS.$__BuildArch.$__BuildType"
887 __isMSBuildOnNETCoreSupported=0
888 __CrossComponentBinDir="$__BinDir"
889 __CrossCompIntermediatesDir="$__IntermediatesDir/crossgen"
890
891 __CrossArch="$__HostArch"
892 if [[ "$__HostArch" == "x64" && "$__BuildArch" == "arm" ]]; then
893     __CrossArch="x86"
894 fi
895 if [ $__CrossBuild == 1 ]; then
896     __CrossComponentBinDir="$__CrossComponentBinDir/$__CrossArch"
897 fi
898 __CrossgenCoreLibLog="$__LogsDir/CrossgenCoreLib_$__BuildOS.$BuildArch.$__BuildType.log"
899 __CrossgenExe="$__CrossComponentBinDir/crossgen"
900
901 isMSBuildOnNETCoreSupported
902
903 # CI_SPECIFIC - On CI machines, $HOME may not be set. In such a case, create a subfolder and set the variable to it.
904 # This is needed by CLI to function.
905 if [ -z "$HOME" ]; then
906     if [ ! -d "$__ProjectDir/temp_home" ]; then
907         mkdir temp_home
908     fi
909     export HOME=$__ProjectDir/temp_home
910     echo "HOME not defined; setting it to $HOME"
911 fi
912
913 # Configure environment if we are doing a cross compile.
914 if [ $__CrossBuild == 1 ]; then
915     export CROSSCOMPILE=1
916     if ! [[ -n "$ROOTFS_DIR" ]]; then
917         export ROOTFS_DIR="$__ProjectRoot/cross/rootfs/$__BuildArch"
918     fi
919 fi
920
921 # init the target distro name
922 initTargetDistroRid
923
924 # Override tool directory
925
926 if [[ (-z "$__GenerateLayoutOnly") && (-z "$__GenerateTestHostOnly") && (-z "$__BuildTestWrappersOnly") ]]; then
927     build_Tests
928 elif [ ! -z "$__BuildTestWrappersOnly" ]; then
929     build_test_wrappers
930 else
931     generate_layout
932     if [ ! -z "$__GenerateTestHostOnly" ]; then
933         generate_testhost
934     fi
935 fi
936
937 if [ $? -ne 0 ]; then
938     echo "Failed to build tests"
939     exit 1
940 fi
941
942 echo "${__MsgPrefix}Test build successful."
943 echo "${__MsgPrefix}Test binaries are available at ${__TestBinDir}"
944
945 __testNativeBinDir=$__IntermediatesDir/tests
946
947 if [ $__RunTests -ne 0 ]; then
948
949     echo "Run Tests..."
950
951     nextCommand="$__TestDir/runtest.sh --testRootDir=$__TestBinDir --coreClrBinDir=$__BinDir --coreFxBinDir=$CORE_ROOT --testNativeBinDir=$__testNativeBinDir"
952     echo "$nextCommand"
953     eval $nextCommand
954
955     echo "Tests run successful."
956 else
957     echo "To run all tests use 'tests/runtests.sh' where:"
958     echo "    testRootDir      = $__TestBinDir"
959     echo "    coreClrBinDir    = $__BinDir"
960     echo "    coreFxBinDir     = $CORE_ROOT"
961     echo "    testNativeBinDir = $__testNativeBinDir"
962     echo " -------------------------------------------------- "
963     echo " Example runtest.sh command"
964     echo ""
965     echo " ./tests/runtest.sh --coreOverlayDir=$CORE_ROOT --testNativeBinDir=$__testNativeBinDir --testRootDir=$__TestBinDir --copyNativeTestBin"
966     echo " -------------------------------------------------- "
967     echo "To run single test use the following command:"
968     echo "    bash ${__TestBinDir}/__TEST_PATH__/__TEST_NAME__.sh -coreroot=${CORE_ROOT}"
969 fi
970