Merge pull request #16813 from CarolEidt/FixDD544983
[platform/upstream/coreclr.git] / build.sh
1 #!/usr/bin/env bash
2
3 # resolve python-version to use
4 if [ "$PYTHON" == "" ] ; then
5     if ! PYTHON=$(command -v python2.7 || command -v python2 || command -v python)
6     then
7        echo "Unable to locate build-dependency python2.x!" 1>&2
8        exit 1
9     fi
10 fi
11
12 # validate python-dependency
13 # useful in case of explicitly set option.
14 if ! command -v $PYTHON > /dev/null
15 then
16    echo "Unable to locate build-dependency python2.x ($PYTHON)!" 1>&2
17    exit 1
18 fi
19
20 usage()
21 {
22     echo "Usage: $0 [BuildArch] [BuildType] [-verbose] [-coverage] [-cross] [-clangx.y] [-ninja] [-configureonly] [-skipconfigure] [-skipnative] [-skipmscorlib] [-skiptests] [-stripsymbols] [-ignorewarnings] [-cmakeargs] [-bindir]"
23     echo "BuildArch can be: -x64, -x86, -arm, -armel, -arm64"
24     echo "BuildType can be: -debug, -checked, -release"
25     echo "-coverage - optional argument to enable code coverage build (currently supported only for Linux and OSX)."
26     echo "-ninja - target ninja instead of GNU make"
27     echo "-clangx.y - optional argument to build using clang version x.y."
28     echo "-cross - optional argument to signify cross compilation,"
29     echo "       - will use ROOTFS_DIR environment variable if set."
30     echo "-crosscomponent - optional argument to build cross-architecture component,"
31     echo "                - will use CAC_ROOTFS_DIR environment variable if set."
32     echo "-nopgooptimize - do not use profile guided optimizations."
33     echo "-pgoinstrument - generate instrumented code for profile guided optimization enabled binaries."
34     echo "-ibcinstrument - generate IBC-tuning-enabled native images when invoking crossgen."
35     echo "-configureonly - do not perform any builds; just configure the build."
36     echo "-skipconfigure - skip build configuration."
37     echo "-skipnative - do not build native components."
38     echo "-skipmscorlib - do not build mscorlib.dll."
39     echo "-skiptests - skip the tests in the 'tests' subdirectory."
40     echo "-skipnuget - skip building nuget packages."
41     echo "-skiprestoreoptdata - skip restoring optimization data used by profile-based optimizations."
42     echo "-skipcrossgen - skip native image generation"
43     echo "-verbose - optional argument to enable verbose build output."
44     echo "-skiprestore: skip restoring packages ^(default: packages are restored during build^)."
45     echo "-disableoss: Disable Open Source Signing for System.Private.CoreLib."
46     echo "-officialbuildid=^<ID^>: specify the official build ID to be used by this build."
47     echo "-Rebuild: passes /t:rebuild to the build projects."
48     echo "-stripSymbols - Optional argument to strip native symbols during the build."
49     echo "-skipgenerateversion - disable version generation even if MSBuild is supported."
50     echo "-ignorewarnings - do not treat warnings as errors"
51     echo "-cmakeargs - user-settable additional arguments passed to CMake."
52     echo "-bindir - output directory (defaults to $__ProjectRoot/bin)"
53     echo "-msbuildonunsupportedplatform - build managed binaries even if distro is not officially supported."
54     echo "-numproc - set the number of build processes."
55     exit 1
56 }
57
58 initHostDistroRid()
59 {
60     __HostDistroRid=""
61     if [ "$__HostOS" == "Linux" ]; then
62         if [ -e /etc/os-release ]; then
63             source /etc/os-release
64             if [[ $ID == "alpine" || $ID == "rhel" ]]; then
65                 # remove the last version digit
66                 VERSION_ID=${VERSION_ID%.*}
67             fi
68             __HostDistroRid="$ID.$VERSION_ID-$__HostArch"
69         elif [ -e /etc/redhat-release ]; then
70             local redhatRelease=$(</etc/redhat-release)
71             if [[ $redhatRelease == "CentOS release 6."* || $redhatRelease == "Red Hat Enterprise Linux Server release 6."* ]]; then
72                __HostDistroRid="rhel.6-$__HostArch"
73             fi
74         fi
75     fi
76     if [ "$__HostOS" == "FreeBSD" ]; then
77         __freebsd_version=`sysctl -n kern.osrelease | cut -f1 -d'.'`
78         __HostDistroRid="freebsd.$__freebsd_version-$__HostArch"
79     fi
80
81     if [ "$__HostDistroRid" == "" ]; then
82         echo "WARNING: Can not determine runtime id for current distro."
83     fi
84 }
85
86 initTargetDistroRid()
87 {
88     if [ $__CrossBuild == 1 ]; then
89         if [ "$__BuildOS" == "Linux" ]; then
90             if [ ! -e $ROOTFS_DIR/etc/os-release ]; then
91                 if [ -e $ROOTFS_DIR/android_platform ]; then
92                     source $ROOTFS_DIR/android_platform
93                     export __DistroRid="$RID"
94                 else
95                     echo "WARNING: Can not determine runtime id for current distro."
96                     export __DistroRid=""
97                 fi
98             else
99                 source $ROOTFS_DIR/etc/os-release
100                 export __DistroRid="$ID.$VERSION_ID-$__BuildArch"
101             fi
102         fi
103     else
104         export __DistroRid="$__HostDistroRid"
105     fi
106
107     if [ "$__BuildOS" == "OSX" ]; then
108         __PortableBuild=1
109     fi
110
111     # Portable builds target the base RID
112     if [ $__PortableBuild == 1 ]; then
113         if [ "$__BuildOS" == "Linux" ]; then
114             export __DistroRid="linux-$__BuildArch"
115         elif [ "$__BuildOS" == "OSX" ]; then
116             export __DistroRid="osx-$__BuildArch"
117         elif [ "$__BuildOS" == "FreeBSD" ]; then
118             export __DistroRid="freebsd-$__BuildArch"
119         fi
120     fi
121 }
122
123 setup_dirs()
124 {
125     echo Setting up directories for build
126
127     mkdir -p "$__RootBinDir"
128     mkdir -p "$__BinDir"
129     mkdir -p "$__LogsDir"
130     mkdir -p "$__IntermediatesDir"
131
132     if [ $__CrossBuild == 1 ]; then
133         mkdir -p "$__CrossComponentBinDir"
134         mkdir -p "$__CrossCompIntermediatesDir"
135     fi
136 }
137
138 # Check the system to ensure the right prereqs are in place
139
140 check_prereqs()
141 {
142     echo "Checking prerequisites..."
143
144     # Check presence of CMake on the path
145     hash cmake 2>/dev/null || { echo >&2 "Please install cmake before running this script"; exit 1; }
146
147
148     # Minimum required version of clang is version 3.9 for arm/armel cross build
149     if [[ $__CrossBuild == 1 && ("$__BuildArch" == "arm" || "$__BuildArch" == "armel") ]]; then
150         if ! [[ "$__ClangMajorVersion" -gt "3" || ( $__ClangMajorVersion == 3 && $__ClangMinorVersion == 9 ) ]]; then
151             echo "Please install clang3.9 or latest for arm/armel cross build"; exit 1;
152         fi
153     fi
154
155     # Check for clang
156     hash clang-$__ClangMajorVersion.$__ClangMinorVersion 2>/dev/null ||  hash clang$__ClangMajorVersion$__ClangMinorVersion 2>/dev/null ||  hash clang 2>/dev/null || { echo >&2 "Please install clang-$__ClangMajorVersion.$__ClangMinorVersion before running this script"; exit 1; }
157
158 }
159
160 restore_optdata()
161 {
162     # we only need optdata on a Release build
163     if [[ "$__BuildType" != "Release" ]]; then __SkipRestoreOptData=1; fi
164
165     if [[ ( $__SkipRestoreOptData == 0 ) && ( $__isMSBuildOnNETCoreSupported == 1 ) ]]; then
166         echo "Restoring the OptimizationData package"
167         "$__ProjectRoot/run.sh" sync -optdata
168         if [ $? != 0 ]; then
169             echo "Failed to restore the optimization data package."
170             exit 1
171         fi
172     fi
173
174     if [ $__isMSBuildOnNETCoreSupported == 1 ]; then
175         # Parse the optdata package versions out of msbuild so that we can pass them on to CMake
176         local DotNetCli="$__ProjectRoot/Tools/dotnetcli/dotnet"
177         if [ ! -f $DotNetCli ]; then
178             source "$__ProjectRoot/init-tools.sh"
179             if [ $? != 0 ]; then
180                 echo "Failed to restore buildtools."
181                 exit 1
182             fi
183         fi
184         local OptDataProjectFilePath="$__ProjectRoot/src/.nuget/optdata/optdata.csproj"
185         __PgoOptDataVersion=$(DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 $DotNetCli msbuild $OptDataProjectFilePath /t:DumpPgoDataPackageVersion /nologo | sed 's/^\s*//')
186         __IbcOptDataVersion=$(DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 $DotNetCli msbuild $OptDataProjectFilePath /t:DumpIbcDataPackageVersion /nologo | sed 's/^\s*//')
187     fi
188 }
189
190 generate_event_logging_sources()
191 {
192     if [ $__SkipCoreCLR == 1 ]; then
193         return
194     fi
195
196 # Event Logging Infrastructure
197     __GeneratedIntermediate="$__IntermediatesDir/eventing"
198     __GeneratedIntermediateEventProvider="$__GeneratedIntermediate/eventprovider"
199     __GeneratedIntermediateEventPipe="$__GeneratedIntermediate/eventpipe"
200
201     __PythonWarningFlags="-Wall"
202     if [[ $__IgnoreWarnings == 0 ]]; then
203         __PythonWarningFlags="$__PythonWarningFlags -Werror"
204     fi
205
206
207     if [[ $__SkipCoreCLR == 0 || $__ConfigureOnly == 1 ]]; then
208         echo "Laying out dynamically generated files consumed by the build system "
209         echo "Laying out dynamically generated Event test files, etmdummy stub functions, and external linkages"
210         $PYTHON -B $__PythonWarningFlags "$__ProjectRoot/src/scripts/genEventing.py" --inc $__IntermediatesDir/src/inc --dummy $__IntermediatesDir/src/inc/etmdummy.h --man "$__ProjectRoot/src/vm/ClrEtwAll.man" --testdir "$__GeneratedIntermediateEventProvider/tests"
211
212         if  [[ $? != 0 ]]; then
213             exit
214         fi
215
216         echo "Laying out dynamically generated EventPipe Implementation"
217         $PYTHON -B $__PythonWarningFlags "$__ProjectRoot/src/scripts/genEventPipe.py" --man "$__ProjectRoot/src/vm/ClrEtwAll.man" --intermediate "$__GeneratedIntermediateEventPipe"
218
219         #determine the logging system
220         case $__BuildOS in
221             Linux|FreeBSD)
222                 echo "Laying out dynamically generated Event Logging Implementation of Lttng"
223                 $PYTHON -B $__PythonWarningFlags "$__ProjectRoot/src/scripts/genLttngProvider.py" --man "$__ProjectRoot/src/vm/ClrEtwAll.man" --intermediate "$__GeneratedIntermediateEventProvider"
224                 if  [[ $? != 0 ]]; then
225                     exit
226                 fi
227                 ;;
228             *)
229                 echo "Laying out dummy event logging provider"
230                 $PYTHON -B $__PythonWarningFlags "$__ProjectRoot/src/scripts/genDummyProvider.py" --man "$__ProjectRoot/src/vm/ClrEtwAll.man" --intermediate "$__GeneratedIntermediateEventProvider"
231                 if  [[ $? != 0 ]]; then
232                     exit
233                 fi
234                 ;;
235         esac
236
237         if [[ $__CrossBuild == 1 ]]; then
238             cp -r $__GeneratedIntermediate $__CrossCompIntermediatesDir
239         fi
240     fi
241 }
242
243 build_native()
244 {
245     skipCondition=$1
246     platformArch="$2"
247     intermediatesForBuild="$3"
248     extraCmakeArguments="$4"
249     message="$5"
250
251     if [ $skipCondition == 1 ]; then
252         echo "Skipping $message build."
253         return
254     fi
255
256     # All set to commence the build
257     echo "Commencing build of $message for $__BuildOS.$__BuildArch.$__BuildType in $intermediatesForBuild"
258
259     generator=""
260     buildFile="Makefile"
261     buildTool="make"
262     if [ $__UseNinja == 1 ]; then
263         generator="ninja"
264         buildFile="build.ninja"
265         if ! buildTool=$(command -v ninja || command -v ninja-build); then
266            echo "Unable to locate ninja!" 1>&2
267            exit 1
268         fi
269     fi
270
271     if [ $__SkipConfigure == 0 ]; then
272         # if msbuild is not supported, then set __SkipGenerateVersion to 1
273         if [ $__isMSBuildOnNETCoreSupported == 0 ]; then __SkipGenerateVersion=1; fi
274         # Drop version.cpp file
275         __versionSourceFile="$intermediatesForBuild/version.cpp"
276         if [ $__SkipGenerateVersion == 0 ]; then
277             pwd
278             "$__ProjectRoot/run.sh" build -Project=$__ProjectDir/build.proj -generateHeaderUnix -NativeVersionSourceFile=$__versionSourceFile -MsBuildEventLogging="/l:BinClashLogger,Tools/Microsoft.DotNet.Build.Tasks.dll;LogFile=binclash.log"  $__RunArgs $__UnprocessedBuildArgs
279         else
280             # Generate the dummy version.cpp, but only if it didn't exist to make sure we don't trigger unnecessary rebuild
281             __versionSourceLine="static char sccsid[] __attribute__((used)) = \"@(#)No version information produced\";"
282             if [ -e $__versionSourceFile ]; then
283                 read existingVersionSourceLine < $__versionSourceFile
284             fi
285             if [ "$__versionSourceLine" != "$existingVersionSourceLine" ]; then
286                 echo $__versionSourceLine > $__versionSourceFile
287             fi
288         fi
289
290
291         pushd "$intermediatesForBuild"
292         # Regenerate the CMake solution
293         echo "Invoking \"$__ProjectRoot/src/pal/tools/gen-buildsys-clang.sh\" \"$__ProjectRoot\" $__ClangMajorVersion $__ClangMinorVersion $platformArch $__BuildType $__CodeCoverage $__IncludeTests $generator $extraCmakeArguments $__cmakeargs"
294         "$__ProjectRoot/src/pal/tools/gen-buildsys-clang.sh" "$__ProjectRoot" $__ClangMajorVersion $__ClangMinorVersion $platformArch $__BuildType $__CodeCoverage $__IncludeTests $generator "$extraCmakeArguments" "$__cmakeargs"
295         popd
296     fi
297
298     if [ ! -f "$intermediatesForBuild/$buildFile" ]; then
299         echo "Failed to generate $message build project!"
300         exit 1
301     fi
302
303     # Build
304     if [ $__ConfigureOnly == 1 ]; then
305         echo "Finish configuration & skipping $message build."
306         return
307     fi
308
309     # Check that the makefiles were created.
310     pushd "$intermediatesForBuild"
311
312     echo "Executing $buildTool install -j $__NumProc"
313
314     $buildTool install -j $__NumProc
315     if [ $? != 0 ]; then
316         echo "Failed to build $message."
317         exit 1
318     fi
319
320     popd
321 }
322
323 build_cross_arch_component()
324 {
325     __SkipCrossArchBuild=1
326     TARGET_ROOTFS=""
327     # check supported cross-architecture components host(__HostArch)/target(__BuildArch) pair
328     if [[ ("$__BuildArch" == "arm" || "$__BuildArch" == "armel") && "$__CrossArch" == "x86" ]]; then
329         export CROSSCOMPILE=0
330         __SkipCrossArchBuild=0
331
332         # building x64-host/arm-target cross-architecture component need to use cross toolchain of x86
333         if [ "$__HostArch" == "x64" ]; then
334             export CROSSCOMPILE=1
335         fi
336     else
337         # not supported
338         return
339     fi
340
341     export __CMakeBinDir="$__CrossComponentBinDir"
342     export CROSSCOMPONENT=1
343     __IncludeTests=
344
345     if [ $CROSSCOMPILE == 1 ]; then
346         TARGET_ROOTFS="$ROOTFS_DIR"
347         if [ -n "$CAC_ROOTFS_DIR" ]; then
348             export ROOTFS_DIR="$CAC_ROOTFS_DIR"
349         else
350             export ROOTFS_DIR="$__ProjectRoot/cross/rootfs/$__CrossArch"
351         fi
352     fi
353
354     __ExtraCmakeArgs="-DCLR_CMAKE_TARGET_ARCH=$__BuildArch -DCLR_CMAKE_TARGET_OS=$__BuildOS -DCLR_CMAKE_PACKAGES_DIR=$__PackagesDir -DCLR_CMAKE_PGO_INSTRUMENT=$__PgoInstrument -DCLR_CMAKE_OPTDATA_VERSION=$__PgoOptDataVersion -DCLR_CMAKE_PGO_OPTIMIZE=$__PgoOptimize"
355     build_native $__SkipCrossArchBuild "$__CrossArch" "$__CrossCompIntermediatesDir" "$__ExtraCmakeArgs" "cross-architecture component"
356
357     # restore ROOTFS_DIR, CROSSCOMPONENT, and CROSSCOMPILE
358     if [ -n "$TARGET_ROOTFS" ]; then
359         export ROOTFS_DIR="$TARGET_ROOTFS"
360     fi
361     export CROSSCOMPONENT=
362     export CROSSCOMPILE=1
363 }
364
365 isMSBuildOnNETCoreSupported()
366 {
367     __isMSBuildOnNETCoreSupported=$__msbuildonunsupportedplatform
368
369     if [ $__isMSBuildOnNETCoreSupported == 1 ]; then
370         return
371     fi
372
373     if [ "$__HostArch" == "x64" ]; then
374         if [ "$__HostOS" == "Linux" ]; then
375             __isMSBuildOnNETCoreSupported=1
376             # note: the RIDs below can use globbing patterns
377             UNSUPPORTED_RIDS=("debian.9-x64" "ubuntu.17.04-x64")
378             for UNSUPPORTED_RID in "${UNSUPPORTED_RIDS[@]}"
379             do
380                 if [[ $__HostDistroRid == $UNSUPPORTED_RID ]]; then
381                     __isMSBuildOnNETCoreSupported=0
382                     break
383                 fi
384             done
385         elif [ "$__HostOS" == "OSX" ]; then
386             __isMSBuildOnNETCoreSupported=1
387         fi
388     fi
389 }
390
391
392 build_CoreLib_ni()
393 {
394     if [ $__SkipCrossgen == 1 ]; then
395         echo "Skipping generating native image"
396         return
397     fi
398
399     if [ $__SkipCoreCLR == 0 -a -e $__BinDir/crossgen ]; then
400         echo "Generating native image for System.Private.CoreLib."
401         echo "$__BinDir/crossgen /Platform_Assemblies_Paths $__BinDir/IL $__IbcTuning /out $__BinDir/System.Private.CoreLib.dll $__BinDir/IL/System.Private.CoreLib.dll"
402         $__BinDir/crossgen /Platform_Assemblies_Paths $__BinDir/IL $__IbcTuning /out $__BinDir/System.Private.CoreLib.dll $__BinDir/IL/System.Private.CoreLib.dll
403         if [ $? -ne 0 ]; then
404             echo "Failed to generate native image for System.Private.CoreLib."
405             exit 1
406         fi
407
408         if [ "$__BuildOS" == "Linux" ]; then
409             echo "Generating symbol file for System.Private.CoreLib."
410             $__BinDir/crossgen /CreatePerfMap $__BinDir $__BinDir/System.Private.CoreLib.dll
411             if [ $? -ne 0 ]; then
412                 echo "Failed to generate symbol file for System.Private.CoreLib."
413                 exit 1
414             fi
415         fi
416     fi
417 }
418
419 build_CoreLib()
420 {
421
422     if [ $__isMSBuildOnNETCoreSupported == 0 ]; then
423         echo "System.Private.CoreLib.dll build unsupported."
424         return
425     fi
426
427     if [ $__SkipMSCorLib == 1 ]; then
428        echo "Skipping building System.Private.CoreLib."
429        return
430     fi
431
432     echo "Commencing build of managed components for $__BuildOS.$__BuildArch.$__BuildType"
433
434     # Invoke MSBuild
435     __ExtraBuildArgs=""
436     if [[ "$__IbcTuning" -eq "" ]]; then
437         __ExtraBuildArgs="$__ExtraBuildArgs -OptimizationDataDir=\"$__PackagesDir/optimization.$__BuildOS-$__BuildArch.IBC.CoreCLR/$__IbcOptDataVersion/data/\""
438         __ExtraBuildArgs="$__ExtraBuildArgs -EnableProfileGuidedOptimization=true"
439     fi
440     $__ProjectRoot/run.sh build -Project=$__ProjectDir/build.proj -MsBuildEventLogging="/l:BinClashLogger,Tools/Microsoft.DotNet.Build.Tasks.dll;LogFile=binclash.log" -MsBuildLog="/flp:Verbosity=normal;LogFile=$__LogsDir/System.Private.CoreLib_$__BuildOS__$__BuildArch__$__BuildType.log" -BuildTarget -__IntermediatesDir=$__IntermediatesDir -__RootBinDir=$__RootBinDir -BuildNugetPackage=false -UseSharedCompilation=false $__RunArgs $__ExtraBuildArgs $__UnprocessedBuildArgs
441
442     if [ $? -ne 0 ]; then
443         echo "Failed to build managed components."
444         exit 1
445     fi
446
447     # The cross build generates a crossgen with the target architecture.
448     if [ $__CrossBuild != 1 ]; then
449        # The architecture of host pc must be same architecture with target.
450        if [[ ( "$__HostArch" == "$__BuildArch" ) ]]; then
451            build_CoreLib_ni
452        elif [[ ( "$__HostArch" == "x64" ) && ( "$__BuildArch" == "x86" ) ]]; then
453            build_CoreLib_ni
454        elif [[ ( "$__HostArch" == "arm64" ) && ( "$__BuildArch" == "arm" ) ]]; then
455            build_CoreLib_ni
456        else
457            exit 1
458        fi
459     fi
460 }
461
462 generate_NugetPackages()
463 {
464     # We can only generate nuget package if we also support building mscorlib as part of this build.
465     if [ $__isMSBuildOnNETCoreSupported == 0 ]; then
466         echo "Nuget package generation unsupported."
467         return
468     fi
469
470     # Since we can build mscorlib for this OS, did we build the native components as well?
471     if [ $__SkipCoreCLR == 1 ]; then
472         echo "Unable to generate nuget packages since native components were not built."
473         return
474     fi
475
476     echo "Generating nuget packages for "$__BuildOS
477     echo "DistroRid is "$__DistroRid
478     echo "ROOTFS_DIR is "$ROOTFS_DIR
479     # Build the packages
480     $__ProjectRoot/run.sh build -Project=$__SourceDir/.nuget/packages.builds -MsBuildEventLogging="/l:BinClashLogger,Tools/Microsoft.DotNet.Build.Tasks.dll;LogFile=binclash.log" -MsBuildLog="/flp:Verbosity=normal;LogFile=$__LogsDir/Nuget_$__BuildOS__$__BuildArch__$__BuildType.log" -BuildTarget -__IntermediatesDir=$__IntermediatesDir -__RootBinDir=$__RootBinDir -BuildNugetPackage=false -UseSharedCompilation=false -__DoCrossArchBuild=$__DoCrossArchBuild $__RunArgs $__UnprocessedBuildArgs
481
482     if [ $? -ne 0 ]; then
483         echo "Failed to generate Nuget packages."
484         exit 1
485     fi
486 }
487
488 echo "Commencing CoreCLR Repo build"
489
490 # Argument types supported by this script:
491 #
492 # Build architecture - valid values are: x64, ARM.
493 # Build Type         - valid values are: Debug, Checked, Release
494 #
495 # Set the default arguments for build
496
497 # Obtain the location of the bash script to figure out where the root of the repo is.
498 __ProjectRoot="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
499
500 # Use uname to determine what the CPU is.
501 CPUName=$(uname -p)
502 # Some Linux platforms report unknown for platform, but the arch for machine.
503 if [ "$CPUName" == "unknown" ]; then
504     CPUName=$(uname -m)
505 fi
506
507 case $CPUName in
508     i686)
509         echo "Unsupported CPU $CPUName detected, build might not succeed!"
510         __BuildArch=x86
511         __HostArch=x86
512         ;;
513
514     x86_64)
515         __BuildArch=x64
516         __HostArch=x64
517         ;;
518
519     armv7l)
520         echo "Unsupported CPU $CPUName detected, build might not succeed!"
521         __BuildArch=arm
522         __HostArch=arm
523         ;;
524
525     aarch64)
526         __BuildArch=arm64
527         __HostArch=arm64
528         ;;
529
530     amd64)
531         __BuildArch=x64
532         __HostArch=x64
533         ;;
534     *)
535         echo "Unknown CPU $CPUName detected, configuring as if for x64"
536         __BuildArch=x64
537         __HostArch=x64
538         ;;
539 esac
540
541 # Use uname to determine what the OS is.
542 OSName=$(uname -s)
543 case $OSName in
544     Linux)
545         __BuildOS=Linux
546         __HostOS=Linux
547         ;;
548
549     Darwin)
550         __BuildOS=OSX
551         __HostOS=OSX
552         ;;
553
554     FreeBSD)
555         __BuildOS=FreeBSD
556         __HostOS=FreeBSD
557         ;;
558
559     OpenBSD)
560         __BuildOS=OpenBSD
561         __HostOS=OpenBSD
562         ;;
563
564     NetBSD)
565         __BuildOS=NetBSD
566         __HostOS=NetBSD
567         ;;
568
569     SunOS)
570         __BuildOS=SunOS
571         __HostOS=SunOS
572         ;;
573
574     *)
575         echo "Unsupported OS $OSName detected, configuring as if for Linux"
576         __BuildOS=Linux
577         __HostOS=Linux
578         ;;
579 esac
580
581 __BuildType=Debug
582 __CodeCoverage=
583 __IncludeTests=Include_Tests
584 __IgnoreWarnings=0
585
586 # Set the various build properties here so that CMake and MSBuild can pick them up
587 __ProjectDir="$__ProjectRoot"
588 __SourceDir="$__ProjectDir/src"
589 __PackagesDir="${DotNetRestorePackagesPath:-${__ProjectDir}/packages}"
590 __RootBinDir="$__ProjectDir/bin"
591 __UnprocessedBuildArgs=
592 __RunArgs=
593 __MSBCleanBuildArgs=
594 __UseNinja=0
595 __VerboseBuild=0
596 __PgoInstrument=0
597 __PgoOptimize=1
598 __IbcTuning=""
599 __ConfigureOnly=0
600 __SkipConfigure=0
601 __SkipRestore=""
602 __SkipNuget=0
603 __SkipCoreCLR=0
604 __SkipMSCorLib=0
605 __SkipRestoreOptData=0
606 __SkipCrossgen=0
607 __CrossBuild=0
608 __ClangMajorVersion=0
609 __ClangMinorVersion=0
610 __NuGetPath="$__PackagesDir/NuGet.exe"
611 __HostDistroRid=""
612 __DistroRid=""
613 __cmakeargs=""
614 __SkipGenerateVersion=0
615 __DoCrossArchBuild=0
616 __PortableBuild=1
617 __msbuildonunsupportedplatform=0
618 __PgoOptDataVersion=""
619 __IbcOptDataVersion=""
620
621 # Get the number of processors available to the scheduler
622 # Other techniques such as `nproc` only get the number of
623 # processors available to a single process.
624 if [ `uname` = "FreeBSD" ]; then
625   __NumProc=`sysctl hw.ncpu | awk '{ print $2+1 }'`
626 elif [ `uname` = "NetBSD" ]; then
627   __NumProc=$(($(getconf NPROCESSORS_ONLN)+1))
628 elif [ `uname` = "Darwin" ]; then
629   __NumProc=$(($(getconf _NPROCESSORS_ONLN)+1))
630 else
631   __NumProc=$(nproc --all)
632 fi
633
634 while :; do
635     if [ $# -le 0 ]; then
636         break
637     fi
638
639     lowerI="$(echo $1 | awk '{print tolower($0)}')"
640     case $lowerI in
641         -\?|-h|--help)
642             usage
643             exit 1
644             ;;
645
646         x86|-x86)
647             __BuildArch=x86
648             ;;
649
650         x64|-x64)
651             __BuildArch=x64
652             ;;
653
654         arm|-arm)
655             __BuildArch=arm
656             ;;
657
658         armel|-armel)
659             __BuildArch=armel
660             ;;
661
662         arm64|-arm64)
663             __BuildArch=arm64
664             ;;
665
666         debug|-debug)
667             __BuildType=Debug
668             ;;
669
670         checked|-checked)
671             __BuildType=Checked
672             ;;
673
674         release|-release)
675             __BuildType=Release
676             ;;
677
678         coverage|-coverage)
679             __CodeCoverage=Coverage
680             ;;
681
682         cross|-cross)
683             __CrossBuild=1
684             ;;
685
686         -portablebuild=false)
687             __PortableBuild=0
688             ;;
689
690         verbose|-verbose)
691             __VerboseBuild=1
692             ;;
693
694         stripsymbols|-stripsymbols)
695             __cmakeargs="$__cmakeargs -DSTRIP_SYMBOLS=true"
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|-ninja)
739             __UseNinja=1
740             ;;
741
742         pgoinstrument|-pgoinstrument)
743             __PgoInstrument=1
744             ;;
745
746         nopgooptimize|-nopgooptimize)
747             __PgoOptimize=0
748             __SkipRestoreOptData=1
749             ;;
750
751         ibcinstrument|-ibcinstrument)
752             __IbcTuning="/Tuning"
753             ;;
754
755         configureonly|-configureonly)
756             __ConfigureOnly=1
757             __SkipMSCorLib=1
758             __SkipNuget=1
759             ;;
760
761         skipconfigure|-skipconfigure)
762             __SkipConfigure=1
763             ;;
764
765         skipnative|-skipnative)
766             # Use "skipnative" to use the same option name as build.cmd.
767             __SkipCoreCLR=1
768             ;;
769
770         skipcoreclr|-skipcoreclr)
771             # Accept "skipcoreclr" for backwards-compatibility.
772             __SkipCoreCLR=1
773             ;;
774
775         crosscomponent|-crosscomponent)
776             __DoCrossArchBuild=1
777             ;;
778
779         skipmscorlib|-skipmscorlib)
780             __SkipMSCorLib=1
781             ;;
782
783         skipgenerateversion|-skipgenerateversion)
784             __SkipGenerateVersion=1
785             ;;
786
787         skiprestoreoptdata|-skiprestoreoptdata)
788             __SkipRestoreOptData=1
789             ;;
790
791         skipcrossgen|-skipcrossgen)
792             __SkipCrossgen=1
793             ;;
794
795         includetests|-includetests)
796             ;;
797
798         skiptests|-skiptests)
799             __IncludeTests=
800             ;;
801
802         skipnuget|-skipnuget)
803             __SkipNuget=1
804             ;;
805
806         ignorewarnings|-ignorewarnings)
807             __IgnoreWarnings=1
808             __cmakeargs="$__cmakeargs -DCLR_CMAKE_WARNINGS_ARE_ERRORS=OFF"
809             ;;
810
811         cmakeargs|-cmakeargs)
812             if [ -n "$2" ]; then
813                 __cmakeargs="$__cmakeargs $2"
814                 shift
815             else
816                 echo "ERROR: 'cmakeargs' requires a non-empty option argument"
817                 exit 1
818             fi
819             ;;
820
821         bindir|-bindir)
822             if [ -n "$2" ]; then
823                 __RootBinDir="$2"
824                 if [ ! -d $__RootBinDir ]; then
825                     mkdir $__RootBinDir
826                 fi
827                 __RootBinParent=$(dirname $__RootBinDir)
828                 __RootBinName=${__RootBinDir##*/}
829                 __RootBinDir="$(cd $__RootBinParent &>/dev/null && printf %s/%s $PWD $__RootBinName)"
830                 shift
831             else
832                 echo "ERROR: 'bindir' requires a non-empty option argument"
833                 exit 1
834             fi
835             ;;
836         msbuildonunsupportedplatform|-msbuildonunsupportedplatform)
837             __msbuildonunsupportedplatform=1
838             ;;
839         numproc|-numproc)
840             if [ -n "$2" ]; then
841               __NumProc="$2"
842               shift
843             else
844               echo "ERROR: 'numproc' requires a non-empty option argument"
845               exit 1
846             fi
847             ;;
848         osgroup|-osgroup)
849             if [ -n "$2" ]; then
850               __BuildOS="$2"
851               shift
852             else
853               echo "ERROR: 'osgroup' requires a non-empty option argument"
854               exit 1
855             fi
856             ;;
857
858         *)
859             __UnprocessedBuildArgs="$__UnprocessedBuildArgs $1"
860             ;;
861     esac
862
863     shift
864 done
865
866 __RunArgs="-BuildArch=$__BuildArch -BuildType=$__BuildType -BuildOS=$__BuildOS"
867
868 # Configure environment if we are doing a verbose build
869 if [ $__VerboseBuild == 1 ]; then
870     export VERBOSE=1
871         __RunArgs="$__RunArgs -verbose"
872 fi
873
874 # Set default clang version
875 if [[ $__ClangMajorVersion == 0 && $__ClangMinorVersion == 0 ]]; then
876     __ClangMajorVersion=3
877     __ClangMinorVersion=9
878 fi
879
880 if [[ "$__BuildArch" == "armel" ]]; then
881     # Armel cross build is Tizen specific and does not support Portable RID build
882     __PortableBuild=0
883 fi
884
885 if [ $__PortableBuild == 0 ]; then
886         __RunArgs="$__RunArgs -PortableBuild=false"
887 fi
888
889 # Set dependent variables
890 __LogsDir="$__RootBinDir/Logs"
891
892 # init the host distro name
893 initHostDistroRid
894
895 # Set the remaining variables based upon the determined build configuration
896 __BinDir="$__RootBinDir/Product/$__BuildOS.$__BuildArch.$__BuildType"
897 __PackagesBinDir="$__BinDir/.nuget"
898 __ToolsDir="$__RootBinDir/tools"
899 __TestWorkingDir="$__RootBinDir/tests/$__BuildOS.$__BuildArch.$__BuildType"
900 export __IntermediatesDir="$__RootBinDir/obj/$__BuildOS.$__BuildArch.$__BuildType"
901 __TestIntermediatesDir="$__RootBinDir/tests/obj/$__BuildOS.$__BuildArch.$__BuildType"
902 __isMSBuildOnNETCoreSupported=0
903 __CrossComponentBinDir="$__BinDir"
904 __CrossCompIntermediatesDir="$__IntermediatesDir/crossgen"
905
906 __CrossArch="$__HostArch"
907 if [[ "$__HostArch" == "x64" && ("$__BuildArch" == "arm" || "$__BuildArch" == "armel") ]]; then
908     __CrossArch="x86"
909 fi
910 if [ $__CrossBuild == 1 ]; then
911     __CrossComponentBinDir="$__CrossComponentBinDir/$__CrossArch"
912 fi
913 __CrossgenCoreLibLog="$__LogsDir/CrossgenCoreLib_$__BuildOS.$BuildArch.$__BuildType.log"
914 __CrossgenExe="$__CrossComponentBinDir/crossgen"
915
916 # Init if MSBuild for .NET Core is supported for this platform
917 isMSBuildOnNETCoreSupported
918
919 # CI_SPECIFIC - On CI machines, $HOME may not be set. In such a case, create a subfolder and set the variable to set.
920 # This is needed by CLI to function.
921 if [ -z "$HOME" ]; then
922     if [ ! -d "$__ProjectDir/temp_home" ]; then
923         mkdir temp_home
924     fi
925     export HOME=$__ProjectDir/temp_home
926     echo "HOME not defined; setting it to $HOME"
927 fi
928
929 # Specify path to be set for CMAKE_INSTALL_PREFIX.
930 # This is where all built CoreClr libraries will copied to.
931 export __CMakeBinDir="$__BinDir"
932
933 # Configure environment if we are doing a cross compile.
934 if [ $__CrossBuild == 1 ]; then
935     export CROSSCOMPILE=1
936     if ! [[ -n "$ROOTFS_DIR" ]]; then
937         export ROOTFS_DIR="$__ProjectRoot/cross/rootfs/$__BuildArch"
938     fi
939 fi
940
941 # init the target distro name
942 initTargetDistroRid
943
944 # Make the directories necessary for build if they don't exist
945 setup_dirs
946
947 # Check prereqs.
948 check_prereqs
949
950 # Restore the package containing profile counts for profile-guided optimizations
951 restore_optdata
952
953 # Generate event logging infrastructure sources
954 generate_event_logging_sources
955
956 # Build the coreclr (native) components.
957 __ExtraCmakeArgs="-DCLR_CMAKE_TARGET_OS=$__BuildOS -DCLR_CMAKE_PACKAGES_DIR=$__PackagesDir -DCLR_CMAKE_PGO_INSTRUMENT=$__PgoInstrument -DCLR_CMAKE_OPTDATA_VERSION=$__PgoOptDataVersion -DCLR_CMAKE_PGO_OPTIMIZE=$__PgoOptimize"
958 build_native $__SkipCoreCLR "$__BuildArch" "$__IntermediatesDir" "$__ExtraCmakeArgs" "CoreCLR component"
959
960 # Build cross-architecture components
961 if [[ $__CrossBuild == 1 && $__DoCrossArchBuild == 1 ]]; then
962     build_cross_arch_component
963 fi
964
965 # Build System.Private.CoreLib.
966
967 build_CoreLib
968
969 # Generate nuget packages
970 if [ $__SkipNuget != 1 ]; then
971     generate_NugetPackages
972 fi
973
974
975 # Build complete
976
977 echo "Repo successfully built."
978 echo "Product binaries are available at $__BinDir"
979 exit 0