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