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