'Windows_NT':'Windows_NT',
'CentOS7.1': 'Linux',
'OpenSUSE13.2': 'Linux',
- 'RHEL7.2': 'Linux']
+ 'RHEL7.2': 'Linux',
+ 'LinuxARMEmulator': 'Linux']
// Map of os -> nuget runtime
def targetNugetRuntimeMap = ['OSX' : 'osx.10.10-x64',
}
}
+// **************************
+// Define Linux ARM Emulator testing. This creates a per PR job which
+// cross builds native binaries for the Emulator rootfs.
+// NOTE: To add Ubuntu-ARM cross build jobs to this code, add the Ubuntu OS to the
+// OS array, branch the steps to be performed by Ubuntu and the Linux ARM emulator
+// based on the OS being handled, and handle the triggers accordingly
+// (the machine affinity of the new job remains the same)
+// **************************
+[true].each { isPR ->
+ ['Debug', 'Release'].each { configurationGroup ->
+ ['LinuxARMEmulator'].each { os ->
+ def osGroup = osGroupMap[os]
+ def newJobName = "${os.toLowerCase()}_cross_${configurationGroup.toLowerCase()}"
+ def arch = "arm-softfp"
+
+ // Setup variables to hold emulator folder path and the rootfs mount path
+ def armemul_path = '/opt/linux-arm-emulator'
+ def armrootfs_mountpath = '/opt/linux-arm-emulator-root'
+
+ def newJob = job(Utilities.getFullJobName(project, newJobName, isPR)) {
+ steps {
+ // Call the arm32_ci_script.sh script to perform the cross build of native corefx
+ shell("./scripts/arm32_ci_script.sh --emulatorPath=${armemul_path} --mountPath=${armrootfs_mountpath} --buildConfig=${configurationGroup.toLowerCase()} --verbose")
+ }
+ }
+
+ // The cross build jobs run on Ubuntu. The arm-cross-latest version
+ // contains the packages needed for cross building corefx
+ Utilities.setMachineAffinity(newJob, 'Ubuntu14.04', 'arm-cross-latest')
+
+ // Set up standard options.
+ Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
+
+ // Add archival for the built binaries
+ def archiveContents = "bin/Linux.${arch}.${configurationGroup}/**"
+ Utilities.addArchival(newJob, archiveContents)
+
+ // Set up triggers
+ if (os == 'LinuxARMEmulator') {
+ Utilities.addGithubPRTriggerForBranch(newJob, branch, "Innerloop Linux ARM Emulator ${configurationGroup} Cross Build", "(?i).*test\\W+Innerloop\\W+Linux\\W+ARM\\W+Emulator\\W+${configurationGroup}\\W+Cross\\W+Build.*")
+ }
+ }
+ }
+}
+
JobReport.Report.generateJobReport(out)
--- /dev/null
+#!/bin/bash
+
+#Usage message
+function usage {
+ echo 'ARM Emulator Cross Build Script'
+ echo 'This script cross builds corefx source'
+ echo ''
+ echo 'Typical usage:'
+ echo ' corefx source is at ~/cfx'
+ echo '$ cd ~/cfx'
+ echo '$ ./scripts/arm32_ci_script.sh'
+ echo ' --emulatorPath=/opt/linux-arm-emulator'
+ echo ' --mountPath=/opt/linux-arm-emulator-root'
+ echo ' --buildConfig=Release'
+ echo ' --verbose'
+ echo ''
+ echo 'Required Arguments:'
+ echo ' --emulatorPath=<path> : Path of the emulator folder (without ending /)'
+ echo ' <path>/platform/rootfs-t30.ext4 should exist'
+ echo ' --mountPath=<path> : The desired path for mounting the emulator rootfs (without ending /)'
+ echo ' This path is created if not already present'
+ echo ' --buildConfig=<config> : The value of config should be either Debug or Release'
+ echo ' Any other value is not accepted'
+ echo 'Optional Arguments:'
+ echo ' -v --verbose : Build made verbose'
+ echo ' -h --help : Prints this usage message and exits'
+ echo ''
+ echo 'Any other argument triggers an error and this usage message is displayed'
+ exit 1
+}
+
+#Display error message and exit
+function exit_with_error {
+ set +x
+
+ local errorMessage="$1"
+ local printUsage=$2
+
+ echo "ERROR: $errorMessage"
+ if [ "$printUsage" == "true" ]; then
+ echo ''
+ usage
+ fi
+ exit 1
+}
+
+#Exit if input string is empty
+function exit_if_empty {
+ local inputString="$1"
+ local errorMessage="$2"
+ local printUsage=$3
+
+ if [ -z "$inputString" ]; then
+ exit_with_error "$errorMessage" $printUsage
+ fi
+}
+
+#Exit if the input path does not exist
+function exit_if_path_absent {
+ local path="$1"
+ local errorMessage="$2"
+ local printUsage=$3
+
+ if [ ! -f "$path" -a ! -d "$path" ]; then
+ exit_with_error "$errorMessage" $printUsage
+ fi
+}
+
+#Check if the git changes were reverted completely
+function check_git_head {
+ local currentGitHead=`git rev-parse --verify HEAD`
+
+ if [[ "$__initialGitHead" != "$currentGitHead" ]]; then
+ exit_with_error "Some changes made to the code history were not completely reverted. Intial Git HEAD: $__initialGitHead, current Git HEAD: $currentGitHead" false
+ fi
+}
+
+function unmount_rootfs {
+ local rootfsFolder="$1"
+
+ if grep -qs "$rootfsFolder" /proc/mounts; then
+ sudo umount "$rootfsFolder"
+ fi
+}
+
+#Unmount the emulator file systems
+function unmount_emulator {
+ (set +x; echo 'Unmounting emulator...')
+
+ #Unmount all the mounted emulator file systems
+ unmount_rootfs "$__ARMRootfsMountPath/proc"
+ unmount_rootfs "$__ARMRootfsMountPath/dev/pts"
+ unmount_rootfs "$__ARMRootfsMountPath/dev"
+ unmount_rootfs "$__ARMRootfsMountPath/run/shm"
+ unmount_rootfs "$__ARMRootfsMountPath/sys"
+ unmount_rootfs "$__ARMRootfsMountPath"
+}
+
+#Clean the changes made to the environment by the script
+function clean_env {
+ #Unmount the emulator
+ unmount_emulator
+
+ #Check for revert of git changes
+ check_git_head
+}
+
+#Trap Ctrl-C and handle it
+function handle_ctrl_c {
+ set +x
+
+ echo 'ERROR: Ctrl-C handled. Script aborted before complete execution.'
+
+ clean_env
+
+ exit 1
+}
+trap handle_ctrl_c INT
+
+#Mount emulator to the target mount path
+function mount_emulator {
+ #Check if the mount path exists and create if neccessary
+ if [ ! -d "$__ARMRootfsMountPath" ]; then
+ sudo mkdir "$__ARMRootfsMountPath"
+ fi
+
+ #Unmount the emulator if already mounted at the mount path and mount again
+ unmount_emulator
+
+ sudo mount "$__ARMEmulPath"/platform/rootfs-t30.ext4 "$__ARMRootfsMountPath"
+ sudo mount -t proc /proc "$__ARMRootfsMountPath"/proc
+ sudo mount -o bind /dev/ "$__ARMRootfsMountPath"/dev
+ sudo mount -o bind /dev/pts "$__ARMRootfsMountPath"/dev/pts
+ sudo mount -t tmpfs shm "$__ARMRootfsMountPath"/run/shm
+ sudo mount -o bind /sys "$__ARMRootfsMountPath"/sys
+}
+
+#Cross builds corefx
+function cross_build_corefx {
+#Export the needed environment variables
+ (set +x; echo 'Exporting LINUX_ARM_* environment variable')
+ source "$__ARMRootfsMountPath"/dotnet/setenv/setenv_incpath.sh "$__ARMRootfsMountPath"
+
+ #Apply the changes needed to build for the emulator rootfs
+ (set +x; echo 'Applying cross build patch to suit Linux ARM emulator rootfs')
+ git am < "$__ARMRootfsMountPath"/dotnet/setenv/corefx_cross.patch
+
+ #Cross building for emulator rootfs
+ ROOTFS_DIR="$__ARMRootfsMountPath" CPLUS_INCLUDE_PATH=$LINUX_ARM_INCPATH CXXFLAGS=$LINUX_ARM_CXXFLAGS ./build.sh $__buildArch clean cross native $__verboseFlag $__buildConfig
+
+ #Reset the code to the upstream version
+ (set +x; echo 'Rewinding HEAD to master code')
+ git reset --hard HEAD^
+}
+
+#Define script variables
+__ARMEmulPath=
+__ARMRootfsMountPath=
+__buildConfig=
+__verboseFlag=
+__buildArch="arm-softfp"
+__initialGitHead=`git rev-parse --verify HEAD`
+
+#Parse command line arguments
+for arg in "$@"
+do
+ case $arg in
+ --emulatorPath=*)
+ __ARMEmulPath=${arg#*=}
+ ;;
+ --mountPath=*)
+ __ARMRootfsMountPath=${arg#*=}
+ ;;
+ --buildConfig=*)
+ __buildConfig="$(echo ${arg#*=} | awk '{print tolower($0)}')"
+ if [[ "$__buildConfig" != "debug" && "$__buildConfig" != "release" ]]; then
+ exit_with_error "--buildConfig can be only Debug or Release" true
+ fi
+ ;;
+ -v|--verbose)
+ __verboseFlag="verbose"
+ ;;
+ -h|--help)
+ usage
+ ;;
+ *)
+ exit_with_error "$arg not a recognized argument" true
+ ;;
+ esac
+done
+
+#Check if there are any uncommited changes in the source directory as git adds and removes patches
+if [[ $(git status -s) != "" ]]; then
+ echo 'ERROR: There are some uncommited changes. To avoid losing these changes commit them and try again.'
+ echo ''
+ git status
+ exit 1
+fi
+
+#Check if the compulsory arguments have been presented to the script and if the input paths exist
+exit_if_empty "$__ARMEmulPath" "--emulatorPath is a mandatory argument, not provided" true
+exit_if_empty "$__ARMRootfsMountPath" "--mountPath is a mandatory argument, not provided" true
+exit_if_empty "$__buildConfig" "--buildConfig is a mandatory argument, not provided" true
+exit_if_path_absent "$__ARMEmulPath/platform/rootfs-t30.ext4" "Path specified in --emulatorPath does not have the rootfs" false
+
+set -x
+set -e
+
+## Begin cross build
+(set +x; echo "Git HEAD @ $__initialGitHead")
+
+#Mount the emulator
+(set +x; echo 'Mounting emulator...')
+mount_emulator
+
+#Complete the cross build
+(set +x; echo 'Building corefx...')
+cross_build_corefx
+
+#Clean the environment
+(set +x; echo 'Cleaning environment...')
+clean_env
+
+(set +x; echo 'Build complete')