Merge pull request #15640 from tannergooding/hwintrin-lower
[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 $__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 -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 -MsBuildLog="/flp:Verbosity=normal;LogFile=$__LogsDir/Nuget_$__BuildOS__$__BuildArch__$__BuildType.log" -BuildTarget -__IntermediatesDir=$__IntermediatesDir -__RootBinDir=$__RootBinDir -BuildNugetPackage=false -UseSharedCompilation=false $__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         ninja|-ninja)
729             __UseNinja=1
730             ;;
731
732         pgoinstrument|-pgoinstrument)
733             __PgoInstrument=1
734             ;;
735
736         nopgooptimize|-nopgooptimize)
737             __PgoOptimize=0
738             __SkipRestoreOptData=1
739             ;;
740
741         ibcinstrument|-ibcinstrument)
742             __IbcTuning="/Tuning"
743             ;;
744
745         configureonly|-configureonly)
746             __ConfigureOnly=1
747             __SkipMSCorLib=1
748             __SkipNuget=1
749             ;;
750
751         skipconfigure|-skipconfigure)
752             __SkipConfigure=1
753             ;;
754
755         skipnative|-skipnative)
756             # Use "skipnative" to use the same option name as build.cmd.
757             __SkipCoreCLR=1
758             ;;
759
760         skipcoreclr|-skipcoreclr)
761             # Accept "skipcoreclr" for backwards-compatibility.
762             __SkipCoreCLR=1
763             ;;
764
765         crosscomponent|-crosscomponent)
766             __DoCrossArchBuild=1
767             ;;
768
769         skipmscorlib|-skipmscorlib)
770             __SkipMSCorLib=1
771             ;;
772
773         skipgenerateversion|-skipgenerateversion)
774             __SkipGenerateVersion=1
775             ;;
776
777         skiprestoreoptdata|-skiprestoreoptdata)
778             __SkipRestoreOptData=1
779             ;;
780
781         skipcrossgen|-skipcrossgen)
782             __SkipCrossgen=1
783             ;;
784
785         includetests|-includetests)
786             ;;
787
788         skiptests|-skiptests)
789             __IncludeTests=
790             ;;
791
792         skipnuget|-skipnuget)
793             __SkipNuget=1
794             ;;
795
796         ignorewarnings|-ignorewarnings)
797             __IgnoreWarnings=1
798             __cmakeargs="$__cmakeargs -DCLR_CMAKE_WARNINGS_ARE_ERRORS=OFF"
799             ;;
800
801         cmakeargs|-cmakeargs)
802             if [ -n "$2" ]; then
803                 __cmakeargs="$__cmakeargs $2"
804                 shift
805             else
806                 echo "ERROR: 'cmakeargs' requires a non-empty option argument"
807                 exit 1
808             fi
809             ;;
810
811         bindir|-bindir)
812             if [ -n "$2" ]; then
813                 __RootBinDir="$2"
814                 if [ ! -d $__RootBinDir ]; then
815                     mkdir $__RootBinDir
816                 fi
817                 __RootBinParent=$(dirname $__RootBinDir)
818                 __RootBinName=${__RootBinDir##*/}
819                 __RootBinDir="$(cd $__RootBinParent &>/dev/null && printf %s/%s $PWD $__RootBinName)"
820                 shift
821             else
822                 echo "ERROR: 'bindir' requires a non-empty option argument"
823                 exit 1
824             fi
825             ;;
826         msbuildonunsupportedplatform|-msbuildonunsupportedplatform)
827             __msbuildonunsupportedplatform=1
828             ;;
829         numproc|-numproc)
830             if [ -n "$2" ]; then
831               __NumProc="$2"
832               shift
833             else
834               echo "ERROR: 'numproc' requires a non-empty option argument"
835               exit 1
836             fi
837             ;;
838         osgroup|-osgroup)
839             if [ -n "$2" ]; then
840               __BuildOS="$2"
841               shift
842             else
843               echo "ERROR: 'osgroup' requires a non-empty option argument"
844               exit 1
845             fi
846             ;;
847
848         *)
849             __UnprocessedBuildArgs="$__UnprocessedBuildArgs $1"
850             ;;
851     esac
852
853     shift
854 done
855
856 __RunArgs="-BuildArch=$__BuildArch -BuildType=$__BuildType -BuildOS=$__BuildOS"
857
858 # Configure environment if we are doing a verbose build
859 if [ $__VerboseBuild == 1 ]; then
860     export VERBOSE=1
861         __RunArgs="$__RunArgs -verbose"
862 fi
863
864 # Set default clang version
865 if [[ $__ClangMajorVersion == 0 && $__ClangMinorVersion == 0 ]]; then
866     __ClangMajorVersion=3
867     __ClangMinorVersion=9
868 fi
869
870 if [[ "$__BuildArch" == "armel" ]]; then
871     # Armel cross build is Tizen specific and does not support Portable RID build
872     __PortableBuild=0
873 fi
874
875 if [ $__PortableBuild == 0 ]; then
876         __RunArgs="$__RunArgs -PortableBuild=false"
877 fi
878
879 # Set dependent variables
880 __LogsDir="$__RootBinDir/Logs"
881
882 # init the host distro name
883 initHostDistroRid
884
885 # Set the remaining variables based upon the determined build configuration
886 __BinDir="$__RootBinDir/Product/$__BuildOS.$__BuildArch.$__BuildType"
887 __PackagesBinDir="$__BinDir/.nuget"
888 __ToolsDir="$__RootBinDir/tools"
889 __TestWorkingDir="$__RootBinDir/tests/$__BuildOS.$__BuildArch.$__BuildType"
890 export __IntermediatesDir="$__RootBinDir/obj/$__BuildOS.$__BuildArch.$__BuildType"
891 __TestIntermediatesDir="$__RootBinDir/tests/obj/$__BuildOS.$__BuildArch.$__BuildType"
892 __isMSBuildOnNETCoreSupported=0
893 __CrossComponentBinDir="$__BinDir"
894 __CrossCompIntermediatesDir="$__IntermediatesDir/crossgen"
895
896 __CrossArch="$__HostArch"
897 if [[ "$__HostArch" == "x64" && ("$__BuildArch" == "arm" || "$__BuildArch" == "armel") ]]; then
898     __CrossArch="x86"
899 fi
900 if [ $__CrossBuild == 1 ]; then
901     __CrossComponentBinDir="$__CrossComponentBinDir/$__CrossArch"
902 fi
903 __CrossgenCoreLibLog="$__LogsDir/CrossgenCoreLib_$__BuildOS.$BuildArch.$__BuildType.log"
904 __CrossgenExe="$__CrossComponentBinDir/crossgen"
905
906 # Init if MSBuild for .NET Core is supported for this platform
907 isMSBuildOnNETCoreSupported
908
909 # CI_SPECIFIC - On CI machines, $HOME may not be set. In such a case, create a subfolder and set the variable to set.
910 # This is needed by CLI to function.
911 if [ -z "$HOME" ]; then
912     if [ ! -d "$__ProjectDir/temp_home" ]; then
913         mkdir temp_home
914     fi
915     export HOME=$__ProjectDir/temp_home
916     echo "HOME not defined; setting it to $HOME"
917 fi
918
919 # Specify path to be set for CMAKE_INSTALL_PREFIX.
920 # This is where all built CoreClr libraries will copied to.
921 export __CMakeBinDir="$__BinDir"
922
923 # Configure environment if we are doing a cross compile.
924 if [ $__CrossBuild == 1 ]; then
925     export CROSSCOMPILE=1
926     if ! [[ -n "$ROOTFS_DIR" ]]; then
927         export ROOTFS_DIR="$__ProjectRoot/cross/rootfs/$__BuildArch"
928     fi
929 fi
930
931 # init the target distro name
932 initTargetDistroRid
933
934 # Make the directories necessary for build if they don't exist
935 setup_dirs
936
937 # Check prereqs.
938 check_prereqs
939
940 # Restore the package containing profile counts for profile-guided optimizations
941 restore_optdata
942
943 # Generate event logging infrastructure sources
944 generate_event_logging_sources
945
946 # Build the coreclr (native) components.
947 __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"
948 build_native $__SkipCoreCLR "$__BuildArch" "$__IntermediatesDir" "$__ExtraCmakeArgs" "CoreCLR component"
949
950 # Build cross-architecture components
951 if [[ $__CrossBuild == 1 && $__DoCrossArchBuild == 1 ]]; then
952     build_cross_arch_component
953 fi
954
955 # Build System.Private.CoreLib.
956
957 build_CoreLib
958
959 # Generate nuget packages
960 if [ $__SkipNuget != 1 ]; then
961     generate_NugetPackages
962 fi
963
964
965 # Build complete
966
967 echo "Repo successfully built."
968 echo "Product binaries are available at $__BinDir"
969 exit 0