Merge pull request #23307 from franksinankaya/gcc_cleanup_13
[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
159 generate_testhost()
160 {
161     echo "${__MsgPrefix}Generating test host..."
162
163     export TEST_HOST=$xUnitTestBinBase/testhost
164
165     if [ -d "${TEST_HOST}" ]; then
166         rm -rf $TEST_HOST
167     fi
168
169     mkdir -p $TEST_HOST
170
171     build_MSBuild_projects "Tests_Generate_TestHost" "${__ProjectDir}/tests/runtest.proj" "Creating test host" "/t:CreateTestHost"
172 }
173
174
175 build_Tests()
176 {
177     echo "${__MsgPrefix}Building Tests..."
178
179     __TestDir=$__ProjectDir/tests
180     __ProjectFilesDir=$__TestDir
181     __TestBinDir=$__TestWorkingDir
182
183     if [ -f  "${__TestWorkingDir}/build_info.json" ]; then
184         rm  "${__TestWorkingDir}/build_info.json"
185     fi
186
187     if [ $__RebuildTests -ne 0 ]; then
188         if [ -d "${__TestBinDir}" ]; then
189             echo "Removing tests build dir: ${__TestBinDir}"
190             rm -rf $__TestBinDir
191         fi
192     fi
193
194     export __CMakeBinDir="${__TestBinDir}"
195     if [ ! -d "${__TestIntermediatesDir}" ]; then
196         mkdir -p ${__TestIntermediatesDir}
197     fi
198
199     __NativeTestIntermediatesDir="${__TestIntermediatesDir}/Native"
200     if [  ! -d "${__NativeTestIntermediatesDir}" ]; then
201         mkdir -p ${__NativeTestIntermediatesDir}
202     fi
203
204     __ManagedTestIntermediatesDir="${__TestIntermediatesDir}/Managed"
205     if [ ! -d "${__ManagedTestIntermediatesDir}" ]; then
206         mkdir -p ${__ManagedTestIntermediatesDir}
207     fi
208
209     echo "__BuildOS: ${__BuildOS}"
210     echo "__BuildArch: ${__BuildArch}"
211     echo "__BuildType: ${__BuildType}"
212     echo "__TestIntermediatesDir: ${__TestIntermediatesDir}"
213     echo "__NativeTestIntermediatesDir: ${__NativeTestIntermediatesDir}"
214     echo "__ManagedTestIntermediatesDir: ${__ManagedTestIntermediatesDir}"
215
216     if [ ! -f "$__TestBinDir" ]; then
217         echo "Creating TestBinDir: ${__TestBinDir}"
218         mkdir -p $__TestBinDir
219     fi
220     if [ ! -f "$__LogsDir" ]; then
221         echo "Creating LogsDir: ${__LogsDir}"
222         mkdir -p $__LogsDir
223     fi
224     if [ ! -f "$__MsbuildDebugLogsDir" ]; then
225         echo "Creating MsbuildDebugLogsDir: ${__MsbuildDebugLogsDir}"
226         mkdir -p $__MsbuildDebugLogsDir
227     fi
228
229     # Set up the directory for MSBuild debug logs.
230     export MSBUILDDEBUGPATH="${__MsbuildDebugLogsDir}"
231
232     __BuildProperties="-p:OSGroup=${__BuildOS} -p:BuildOS=${__BuildOS} -p:BuildArch=${__BuildArch} -p:BuildType=${__BuildType}"
233
234     # =========================================================================================
235     # ===
236     # === Restore product binaries from packages
237     # ===
238     # =========================================================================================
239
240     if [ ${__SkipRestorePackages} != 1 ]; then
241         build_MSBuild_projects "Restore_Product" "${__ProjectDir}/tests/build.proj" "Restore product binaries (build tests)" "/t:BatchRestorePackages"
242     fi
243
244     if [ $__SkipNative != 1 ]; then
245         build_native_projects "$__BuildArch" "${__NativeTestIntermediatesDir}"
246
247         if [ $? -ne 0 ]; then
248             echo "${__MsgPrefix}Error: build failed. Refer to the build log files for details (above)"
249             exit 1
250         fi
251     fi
252
253     if [ $__SkipManaged != 1 ]; then
254         echo "Starting the Managed Tests Build..."
255
256         build_MSBuild_projects "Tests_Managed" "$__ProjectDir/tests/build.proj" "Managed tests build (build tests)" "$__up"
257
258         if [ $? -ne 0 ]; then
259             echo "${__MsgPrefix}Error: build failed. Refer to the build log files for details (above)"
260             exit 1
261         else
262             echo "Checking the Managed Tests Build..."
263
264             build_MSBuild_projects "Check_Test_Build" "${__ProjectDir}/tests/runtest.proj" "Check Test Build" "/t:CheckTestBuild"
265
266             if [ $? -ne 0 ]; then
267                 echo "${__MsgPrefix}Error: Check Test Build failed."
268                 exit 1
269             fi
270         fi
271
272         echo "Managed tests build success!"
273     fi
274
275     build_test_wrappers
276
277     if [ -n "$__UpdateInvalidPackagesArg" ]; then
278         __up="/t:UpdateInvalidPackageVersions"
279     fi
280
281     generate_layout
282 }
283
284 build_MSBuild_projects()
285 {
286     subDirectoryName=$1
287     shift
288     projectName=$1
289     shift
290     stepName="$1"
291     shift
292     extraBuildParameters=("$@")
293
294     # Set up directories and file names
295     __BuildLogRootName=$subDirectoryName
296     __BuildLog="$__LogsDir/${__BuildLogRootName}.${__BuildOS}.${__BuildArch}.${__BuildType}.log"
297     __BuildWrn="$__LogsDir/${__BuildLogRootName}.${__BuildOS}.${__BuildArch}.${__BuildType}.wrn"
298     __BuildErr="$__LogsDir/${__BuildLogRootName}.${__BuildOS}.${__BuildArch}.${__BuildType}.err"
299
300     # Use binclashlogger by default if no other logger is specified
301     if [[ "${extraBuildParameters[*]}" == *"/l:"* ]]; then
302         __msbuildEventLogging=
303     else
304         __msbuildEventLogging="/l:BinClashLogger,Tools/Microsoft.DotNet.Build.Tasks.dll\;LogFile=binclash.log"
305     fi
306
307     if [[ "$subDirectoryName" == "Tests_Managed" ]]; then
308         # Execute msbuild managed test build in stages - workaround for excessive data retention in MSBuild ConfigCache
309         # See https://github.com/Microsoft/msbuild/issues/2993
310
311         # __SkipPackageRestore and __SkipTargetingPackBuild used  to control build by tests/src/dirs.proj
312         export __SkipPackageRestore=false
313         export __SkipTargetingPackBuild=false
314         export __NumberOfTestGroups=3
315
316         __AppendToLog=false
317
318         if [ -n "$__priority1" ]; then
319             export __NumberOfTestGroups=10
320         fi
321
322         for (( testGroupToBuild=1 ; testGroupToBuild <= __NumberOfTestGroups; testGroupToBuild = testGroupToBuild + 1 ))
323         do
324             __msbuildLog="\"/flp:Verbosity=normal;LogFile=${__BuildLog};Append=${__AppendToLog}\""
325             __msbuildWrn="\"/flp1:WarningsOnly;LogFile=${__BuildWrn};Append=${__AppendToLog}\""
326             __msbuildErr="\"/flp2:ErrorsOnly;LogFile=${__BuildErr};Append=${__AppendToLog}\""
327
328             export __TestGroupToBuild=$testGroupToBuild
329
330             # Generate build command
331             buildArgs=("/nologo" "/verbosity:minimal" "/clp:Summary")
332             buildArgs+=("/p:RestoreDefaultOptimizationDataPackage=false" "/p:PortableBuild=true")
333             buildArgs+=("/p:UsePartialNGENOptimization=false" "/maxcpucount")
334
335             buildArgs+=("$projectName" "${__msbuildLog}" "${__msbuildWrn}" "${__msbuildErr}")
336             buildArgs+=("$__msbuildEventLogging")
337             buildArgs+=("${extraBuildParameters[@]}")
338             buildArgs+=("${__CommonMSBuildArgs[@]}")
339             buildArgs+=("${__UnprocessedBuildArgs[@]}")
340
341             nextCommand="\"$__ProjectRoot/dotnet.sh\" msbuild ${buildArgs[@]}"
342             echo "Building step '$stepName' testGroupToBuild=$testGroupToBuild via $nextCommand"
343             eval $nextCommand
344
345             # Make sure everything is OK
346             if [ $? -ne 0 ]; then
347                 echo "${__MsgPrefix}Failed to build $stepName. See the build logs:"
348                 echo "    $__BuildLog"
349                 echo "    $__BuildWrn"
350                 echo "    $__BuildErr"
351                 exit 1
352             fi
353             export __SkipPackageRestore=true
354             export __SkipTargetingPackBuild=true
355             __AppendToLog=true
356         done
357     else
358         __msbuildLog="\"/flp:Verbosity=normal;LogFile=${__BuildLog}\""
359         __msbuildWrn="\"/flp1:WarningsOnly;LogFile=${__BuildWrn}\""
360         __msbuildErr="\"/flp2:ErrorsOnly;LogFile=${__BuildErr}\""
361
362         # Generate build command
363         buildArgs=("/nologo" "/verbosity:minimal" "/clp:Summary")
364         buildArgs+=("/p:RestoreDefaultOptimizationDataPackage=false" "/p:PortableBuild=true")
365         buildArgs+=("/p:UsePartialNGENOptimization=false" "/maxcpucount")
366
367         buildArgs+=("$projectName" "${__msbuildLog}" "${__msbuildWrn}" "${__msbuildErr}")
368         buildArgs+=("$__msbuildEventLogging")
369         buildArgs+=("${extraBuildParameters[@]}")
370         buildArgs+=("${__CommonMSBuildArgs[@]}")
371         buildArgs+=("${__UnprocessedBuildArgs[@]}")
372
373         nextCommand="\"$__ProjectRoot/dotnet.sh\" msbuild ${buildArgs[@]}"
374         echo "Building step '$stepName' via $nextCommand"
375         eval $nextCommand
376
377         # Make sure everything is OK
378         if [ $? -ne 0 ]; then
379             echo "${__MsgPrefix}Failed to build $stepName. See the build logs:"
380             echo "    $__BuildLog"
381             echo "    $__BuildWrn"
382             echo "    $__BuildErr"
383             exit 1
384         fi
385     fi
386 }
387
388 build_native_projects()
389 {
390     platformArch="$1"
391     intermediatesForBuild="$2"
392
393     extraCmakeArguments="-DCLR_CMAKE_TARGET_OS=${__BuildOS} -DCLR_CMAKE_HOST_ARCH=${platformArch}"
394     message="native tests assets"
395
396     # All set to commence the build
397     echo "Commencing build of $message for $__BuildOS.$__BuildArch.$__BuildType in $intermediatesForBuild"
398
399     generator=""
400     buildFile="Makefile"
401     buildTool="make"
402     if [ $__UseNinja == 1 ]; then
403         generator="ninja"
404         buildFile="build.ninja"
405         if ! buildTool=$(command -v ninja || command -v ninja-build); then
406            echo "Unable to locate ninja!" 1>&2
407            exit 1
408         fi
409     fi
410
411     if [ $__SkipConfigure == 0 ]; then
412         # if msbuild is not supported, then set __SkipGenerateVersion to 1
413         if [ $__isMSBuildOnNETCoreSupported == 0 ]; then __SkipGenerateVersion=1; fi
414         # Drop version.c file
415         __versionSourceFile="$intermediatesForBuild/version.c"
416         if [ $__SkipGenerateVersion == 0 ]; then
417             pwd
418             $__ProjectRoot/dotnet.sh msbuild /nologo /verbosity:minimal /clp:Summary \
419                                      /p:RestoreDefaultOptimizationDataPackage=false /p:PortableBuild=true \
420                                      /p:UsePartialNGENOptimization=false /maxcpucount \
421                                      $__ProjectDir/build.proj /t:GenerateVersionHeader \
422                                      /p:GenerateVersionHeader=true /p:NativeVersionSourceFile=$__versionSourceFile \
423                                      /l:BinClashLogger,Tools/Microsoft.DotNet.Build.Tasks.dll\;LogFile=binclash.log \
424                                      $__CommonMSBuildArgs $__UnprocessedBuildArgs
425         else
426             # Generate the dummy version.c, but only if it didn't exist to make sure we don't trigger unnecessary rebuild
427             __versionSourceLine="static char sccsid[] __attribute__((used)) = \"@(#)No version information produced\";"
428             if [ -e $__versionSourceFile ]; then
429                 read existingVersionSourceLine < $__versionSourceFile
430             fi
431             if [ "$__versionSourceLine" != "$existingVersionSourceLine" ]; then
432                 echo $__versionSourceLine > $__versionSourceFile
433             fi
434         fi
435
436         pushd "$intermediatesForBuild"
437         # Regenerate the CMake solution
438         # Force cross dir to point to project root cross dir, in case there is a cross build.
439         scriptDir="$__ProjectRoot/src/pal/tools"
440         if [[ $__GccBuild == 0 ]]; then
441             nextCommand="CONFIG_DIR=\"$__ProjectRoot/cross\" \"$scriptDir/gen-buildsys-clang.sh\" \"$__TestDir\" $__ClangMajorVersion $__ClangMinorVersion $platformArch $scriptDir $__BuildType $__CodeCoverage $generator $extraCmakeArguments $__cmakeargs"
442         else
443             nextCommand="CONFIG_DIR=\"$__ProjectRoot/cross\" \"$scriptDir/gen-buildsys-gcc.sh\" \"$__TestDir\" \"$__GccMajorVersion\" \"$__GccMinorVersion\" $platformArch $scriptDir $__BuildType $__CodeCoverage $generator $extraCmakeArguments $__cmakeargs"
444         fi
445         echo "Invoking $nextCommand"
446         eval $nextCommand
447         popd
448     fi
449
450     if [ ! -f "$intermediatesForBuild/$buildFile" ]; then
451         echo "Failed to generate $message build project!"
452         exit 1
453     fi
454
455     # Build
456     if [ $__ConfigureOnly == 1 ]; then
457         echo "Finish configuration & skipping $message build."
458         return
459     fi
460
461     pushd "$intermediatesForBuild"
462
463     echo "Executing $buildTool install -j $__NumProc"
464
465     $buildTool install -j $__NumProc
466     if [ $? != 0 ]; then
467         echo "Failed to build $message."
468         exit 1
469     fi
470
471     popd
472     echo "Native tests build success!"
473 }
474
475 usage()
476 {
477     echo "Usage: $0 [BuildArch] [BuildType] [verbose] [coverage] [cross] [clangx.y] [ninja] [runtests] [bindir]"
478     echo "BuildArch can be: x64, x86, arm, armel, arm64"
479     echo "BuildType can be: debug, checked, release"
480     echo "coverage - optional argument to enable code coverage build (currently supported only for Linux and OSX)."
481     echo "ninja - target ninja instead of GNU make"
482     echo "clangx.y - optional argument to build using clang version x.y - supported version 3.5 - 6.0"
483     echo "gccx.y - optional argument to build using gcc version x.y."
484     echo "cross - optional argument to signify cross compilation,"
485     echo "      - will use ROOTFS_DIR environment variable if set."
486     echo "portableLinux - build for Portable Linux Distribution"
487     echo "portablebuild - Use portable build."
488     echo "verbose - optional argument to enable verbose build output."
489     echo "rebuild - if tests have already been built - rebuild them"
490     echo "skipnative: skip the native tests build"
491     echo "skipmanaged: skip the managed section of the test build"
492     echo "buildtestwrappersonly - only build the test wrappers"
493     echo "generatelayoutonly - only pull down dependencies and build coreroot"
494     echo "generatetesthostonly - only pull down dependencies and build coreroot and the CoreFX testhost"
495     echo "skiprestorepackages - skip package restore"
496     echo "runtests - run tests after building them"
497     echo "bindir - output directory (defaults to $__ProjectRoot/bin)"
498     echo "msbuildonunsupportedplatform - build managed binaries even if distro is not officially supported."
499     echo "priority1 - include priority=1 tests in the build"
500     exit 1
501 }
502
503
504 # Obtain the location of the bash script to figure out where the root of the repo is.
505 __ProjectRoot="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
506
507 # Use uname to determine what the CPU is.
508 CPUName=$(uname -p)
509
510 # Some Linux platforms report unknown for platform, but the arch for machine.
511 if [ "$CPUName" == "unknown" ]; then
512     CPUName=$(uname -m)
513 fi
514
515 case $CPUName in
516     i686)
517         echo "Unsupported CPU $CPUName detected, build might not succeed!"
518         __BuildArch=x86
519         __HostArch=x86
520         ;;
521
522     x86_64)
523         __BuildArch=x64
524         __HostArch=x64
525         ;;
526
527     armv7l)
528         echo "Unsupported CPU $CPUName detected, build might not succeed!"
529         __BuildArch=arm
530         __HostArch=arm
531         ;;
532
533     aarch64)
534         __BuildArch=arm64
535         __HostArch=arm64
536         ;;
537
538     *)
539         echo "Unknown CPU $CPUName detected, configuring as if for x64"
540         __BuildArch=x64
541         __HostArch=x64
542         ;;
543 esac
544
545 # Use uname to determine what the OS is.
546 OSName=$(uname -s)
547 case $OSName in
548     Linux)
549         __BuildOS=Linux
550         __HostOS=Linux
551         ;;
552
553     Darwin)
554         __BuildOS=OSX
555         __HostOS=OSX
556         ;;
557
558     FreeBSD)
559         __BuildOS=FreeBSD
560         __HostOS=FreeBSD
561         ;;
562
563     OpenBSD)
564         __BuildOS=OpenBSD
565         __HostOS=OpenBSD
566         ;;
567
568     NetBSD)
569         __BuildOS=NetBSD
570         __HostOS=NetBSD
571         ;;
572
573     SunOS)
574         __BuildOS=SunOS
575         __HostOS=SunOS
576         ;;
577
578     *)
579         echo "Unsupported OS $OSName detected, configuring as if for Linux"
580         __BuildOS=Linux
581         __HostOS=Linux
582         ;;
583 esac
584
585 __BuildType=Debug
586 __CodeCoverage=
587 __IncludeTests=INCLUDE_TESTS
588
589 # Set the various build properties here so that CMake and MSBuild can pick them up
590 export __ProjectDir="$__ProjectRoot"
591 __SourceDir="$__ProjectDir/src"
592 __PackagesDir="$__ProjectDir/packages"
593 __RootBinDir="$__ProjectDir/bin"
594 __BuildToolsDir="$__ProjectDir/Tools"
595 __DotNetCli="$__ProjectDir/dotnet.sh"
596 __UnprocessedBuildArgs=
597 __CommonMSBuildArgs=
598 __MSBCleanBuildArgs=
599 __UseNinja=0
600 __VerboseBuild=0
601 __SkipRestore=""
602 __SkipNative=0
603 __SkipManaged=0
604 __SkipConfigure=0
605 __SkipGenerateVersion=0
606 __ConfigureOnly=0
607 __CrossBuild=0
608 __ClangMajorVersion=0
609 __ClangMinorVersion=0
610 __GccBuild=0
611 __GccMajorVersion=0
612 __GccMinorVersion=0
613 __NuGetPath="$__PackagesDir/NuGet.exe"
614 __SkipRestorePackages=0
615 __DistroRid=""
616 __cmakeargs=""
617 __PortableLinux=0
618 __msbuildonunsupportedplatform=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         gcc5|-gcc5)
739             __GccMajorVersion=5
740             __GccMinorVersion=
741             __GccBuild=1
742             ;;
743
744         gcc6|-gcc6)
745             __GccMajorVersion=6
746             __GccMinorVersion=
747             __GccBuild=1
748             ;;
749
750         gcc7|-gcc7)
751             __GccMajorVersion=7
752             __GccMinorVersion=
753             __GccBuild=1
754             ;;
755
756         gcc8|-gcc8)
757             __GccMajorVersion=8
758             __GccMinorVersion=
759             __GccBuild=1
760             ;;
761
762         gcc|-gcc)
763             __GccMajorVersion=
764             __GccMinorVersion=
765             __GccBuild=1
766             ;;
767
768         ninja)
769             __UseNinja=1
770             ;;
771
772         runtests)
773             __RunTests=1
774             ;;
775
776         rebuild)
777             __RebuildTests=1
778             ;;
779
780         skipnative|-skipnative)
781             __SkipNative=1
782             ;;
783
784         skipmanaged|-skipmanaged)
785             __SkipManaged=1
786             __BuildTestWrappers=0
787             ;;
788
789         buildtestwrappersonly)
790             __BuildTestWrappersOnly=1
791             ;;
792
793         generatelayoutonly)
794             __GenerateLayoutOnly=1
795             ;;
796
797         generatetesthostonly)
798             __GenerateTestHostOnly=1
799             ;;
800
801         skiprestorepackages)
802             __SkipRestorePackages=1
803             ;;
804
805         bindir)
806             if [ -n "$2" ]; then
807                 __RootBinDir="$2"
808                 if [ ! -d $__RootBinDir ]; then
809                     mkdir $__RootBinDir
810                 fi
811                 __RootBinParent=$(dirname $__RootBinDir)
812                 __RootBinName=${__RootBinDir##*/}
813                 __RootBinDir="$(cd $__RootBinParent &>/dev/null && printf %s/%s $PWD $__RootBinName)"
814                 shift
815             else
816                 echo "ERROR: 'bindir' requires a non-empty option argument"
817                 exit 1
818             fi
819             ;;
820
821         msbuildonunsupportedplatform)
822             __msbuildonunsupportedplatform=1
823             ;;
824
825         priority1)
826             __priority1=1
827             __UnprocessedBuildArgs+=("/p:CLRTestPriorityToBuild=1")
828             ;;
829
830         *)
831             __UnprocessedBuildArgs+=("$1")
832             ;;
833     esac
834
835     shift
836 done
837
838 # Get the number of processors available to the scheduler
839 # Other techniques such as `nproc` only get the number of
840 # processors available to a single process.
841 if [ `uname` = "FreeBSD" ]; then
842   __NumProc=`sysctl hw.ncpu | awk '{ print $2+1 }'`
843 elif [ `uname` = "NetBSD" ]; then
844   __NumProc=$(($(getconf NPROCESSORS_ONLN)+1))
845 elif [ `uname` = "Darwin" ]; then
846   __NumProc=$(($(getconf _NPROCESSORS_ONLN)+1))
847 else
848   __NumProc=$(nproc --all)
849 fi
850
851 __CommonMSBuildArgs=("/p:__BuildArch=$__BuildArch" "/p:__BuildType=$__BuildType" "/p:__BuildOS=$__BuildOS")
852
853 # Configure environment if we are doing a verbose build
854 if [ $__VerboseBuild == 1 ]; then
855     export VERBOSE=1
856     __CommonMSBuildArgs+=("/v:detailed")
857 fi
858
859 # Set default clang version
860 if [[ $__ClangMajorVersion == 0 && $__ClangMinorVersion == 0 ]]; then
861     if [[ "$__BuildArch" == "arm" || "$__BuildArch" == "armel" ]]; then
862         __ClangMajorVersion=5
863         __ClangMinorVersion=0
864     else
865         __ClangMajorVersion=3
866         __ClangMinorVersion=9
867     fi
868 fi
869
870 # Set dependent variables
871 __LogsDir="$__RootBinDir/Logs"
872 __MsbuildDebugLogsDir="$__LogsDir/MsbuildDebugLogs"
873
874 # Set the remaining variables based upon the determined build configuration
875 __BinDir="$__RootBinDir/Product/$__BuildOS.$__BuildArch.$__BuildType"
876 __PackagesBinDir="$__BinDir/.nuget"
877 __TestDir="$__ProjectDir/tests"
878 __TestWorkingDir="$__RootBinDir/tests/$__BuildOS.$__BuildArch.$__BuildType"
879 __IntermediatesDir="$__RootBinDir/obj/$__BuildOS.$__BuildArch.$__BuildType"
880 __TestIntermediatesDir="$__RootBinDir/tests/obj/$__BuildOS.$__BuildArch.$__BuildType"
881 __isMSBuildOnNETCoreSupported=0
882 __CrossComponentBinDir="$__BinDir"
883 __CrossCompIntermediatesDir="$__IntermediatesDir/crossgen"
884
885 __CrossArch="$__HostArch"
886 if [[ "$__HostArch" == "x64" && "$__BuildArch" == "arm" ]]; then
887     __CrossArch="x86"
888 fi
889 if [ $__CrossBuild == 1 ]; then
890     __CrossComponentBinDir="$__CrossComponentBinDir/$__CrossArch"
891 fi
892 __CrossgenCoreLibLog="$__LogsDir/CrossgenCoreLib_$__BuildOS.$BuildArch.$__BuildType.log"
893 __CrossgenExe="$__CrossComponentBinDir/crossgen"
894
895 isMSBuildOnNETCoreSupported
896
897 # CI_SPECIFIC - On CI machines, $HOME may not be set. In such a case, create a subfolder and set the variable to it.
898 # This is needed by CLI to function.
899 if [ -z "$HOME" ]; then
900     if [ ! -d "$__ProjectDir/temp_home" ]; then
901         mkdir temp_home
902     fi
903     export HOME=$__ProjectDir/temp_home
904     echo "HOME not defined; setting it to $HOME"
905 fi
906
907 # Configure environment if we are doing a cross compile.
908 if [ $__CrossBuild == 1 ]; then
909     export CROSSCOMPILE=1
910     if ! [[ -n "$ROOTFS_DIR" ]]; then
911         export ROOTFS_DIR="$__ProjectRoot/cross/rootfs/$__BuildArch"
912     fi
913 fi
914
915 # init the target distro name
916 initTargetDistroRid
917
918 # Override tool directory
919
920 if [[ (-z "$__GenerateLayoutOnly") && (-z "$__GenerateTestHostOnly") && (-z "$__BuildTestWrappersOnly") ]]; then
921     build_Tests
922 elif [ ! -z "$__BuildTestWrappersOnly" ]; then
923     build_test_wrappers
924 else
925     generate_layout
926     if [ ! -z "$__GenerateTestHostOnly" ]; then
927         generate_testhost
928     fi
929 fi
930
931 if [ $? -ne 0 ]; then
932     echo "Failed to build tests"
933     exit 1
934 fi
935
936 echo "${__MsgPrefix}Test build successful."
937 echo "${__MsgPrefix}Test binaries are available at ${__TestBinDir}"
938
939 __testNativeBinDir=$__IntermediatesDir/tests
940
941 if [ $__RunTests -ne 0 ]; then
942
943     echo "Run Tests..."
944
945     nextCommand="$__TestDir/runtest.sh --testRootDir=$__TestBinDir --coreClrBinDir=$__BinDir --coreFxBinDir=$CORE_ROOT --testNativeBinDir=$__testNativeBinDir"
946     echo "$nextCommand"
947     eval $nextCommand
948
949     echo "Tests run successful."
950 else
951     echo "To run all tests use 'tests/runtests.sh' where:"
952     echo "    testRootDir      = $__TestBinDir"
953     echo "    coreClrBinDir    = $__BinDir"
954     echo "    coreFxBinDir     = $CORE_ROOT"
955     echo "    testNativeBinDir = $__testNativeBinDir"
956     echo " -------------------------------------------------- "
957     echo " Example runtest.sh command"
958     echo ""
959     echo " ./tests/runtest.sh --coreOverlayDir=$CORE_ROOT --testNativeBinDir=$__testNativeBinDir --testRootDir=$__TestBinDir --copyNativeTestBin"
960     echo " -------------------------------------------------- "
961     echo "To run single test use the following command:"
962     echo "    bash ${__TestBinDir}/__TEST_PATH__/__TEST_NAME__.sh -coreroot=${CORE_ROOT}"
963 fi
964