2017-04-10 11:41:01 +00:00
#!/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 ' --buildConfig=Release'
echo ' --armel'
echo ' --verbose'
echo ''
echo 'Required Arguments:'
echo ' --buildConfig=<config> : The value of config should be either Debug or Release'
echo ' Any other value is not accepted'
echo 'Optional Arguments:'
2017-06-07 13:16:24 +00:00
echo ' --mode=<mode> : docker (default) or emulator'
echo ' --arm : Build as arm (default)'
2017-04-10 11:41:01 +00:00
echo ' --armel : Build as armel'
2017-06-07 13:16:24 +00:00
echo ' --linuxCodeName=<name> : Code name for Linux: For arm, trusty (default) and xenial. For armel, tizen'
echo ' --skipRootFS : Skip building rootfs'
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'
2017-04-10 11:41:01 +00:00
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 "
#Check if there are any open files in this directory.
if [ -d $rootfsFolder ] ; then
#If we find information about the file
if sudo lsof +D $rootfsFolder ; then
( set +x; echo 'See above for lsof information. Continuing with the build.' )
fi
fi
if mountpoint -q -- " $rootfsFolder " ; 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 {
#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.'
exit 1
}
trap handle_ctrl_c INT
#Trap Exit and handle it
function handle_exit {
set +x
echo 'The script is exited. Cleaning environment..'
clean_env
}
trap handle_exit EXIT
#Mount with checking to be already existed
function mount_with_checking {
set +x
local options = " $1 "
local from = " $2 "
local rootfsFolder = " $3 "
if mountpoint -q -- " $rootfsFolder " ; then
( set +x; echo " $rootfsFolder is already mounted. " )
else {
( set -x; sudo mount $options " $from " " $rootfsFolder " )
}
fi
}
#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 -p " $__ARMRootfsMountPath "
fi
set +x
mount_with_checking "" " $__ARMEmulPath /platform/ $__ARMRootfsImageBase " " $__ARMRootfsMountPath "
mount_with_checking "-t proc" "/proc" " $__ARMRootfsMountPath /proc "
mount_with_checking "-o bind" "/dev/" " $__ARMRootfsMountPath /dev "
mount_with_checking "-o bind" "/dev/pts" " $__ARMRootfsMountPath /dev/pts "
mount_with_checking "-t tmpfs" "shm" " $__ARMRootfsMountPath /run/shm "
mount_with_checking "-o bind" "/sys" " $__ARMRootfsMountPath /sys "
}
#Cross builds corefx
function cross_build_corefx {
#Apply fixes for armel
if [ " $__buildArch " = = "armel" ] ; then
#Export the needed environment variables
( set +x; echo 'Exporting LINUX_ARM_* environment variable' )
source " $__ARMRootfsMountPath " /dotnet/setenv/setenv_incpath.sh " $__ARMRootfsMountPath "
fi
#Cross building for emulator rootfs
ROOTFS_DIR = " $__ARMRootfsMountPath " CPLUS_INCLUDE_PATH = $LINUX_ARM_INCPATH CXXFLAGS = $LINUX_ARM_CXXFLAGS ./build-native.sh -buildArch= $__buildArch -$__buildConfig -- cross $__verboseFlag
ROOTFS_DIR = " $__ARMRootfsMountPath " CPLUS_INCLUDE_PATH = $LINUX_ARM_INCPATH CXXFLAGS = $LINUX_ARM_CXXFLAGS ./build-managed.sh -$__buildConfig -skipTests -BuildPackages= false
}
2017-06-07 13:16:24 +00:00
# Cross builds corefx using Docker image
function cross_build_corefx_with_docker {
__currentWorkingDirectory = ` pwd `
# Check build configuration and choose Docker image
if [ " $__buildArch " = = "arm" ] ; then
# TODO: For arm, we are going to embed RootFS inside Docker image.
case $__linuxCodeName in
trusty)
2017-08-21 15:34:15 +00:00
__dockerImage = " microsoft/dotnet-buildtools-prereqs:ubuntu-14.04-cross-0cd4667-20172211042239"
2017-06-07 13:16:24 +00:00
__skipRootFS = 1
__dockerEnvironmentVariables = "-e ROOTFS_DIR=/crossrootfs/arm"
__runtimeOS = "ubuntu.14.04"
; ;
xenial)
2017-08-21 15:34:15 +00:00
__dockerImage = " microsoft/dotnet-buildtools-prereqs:ubuntu-16.04-cross-ef0ac75-20175511035548"
2017-06-07 13:16:24 +00:00
__skipRootFS = 1
__dockerEnvironmentVariables = "-e ROOTFS_DIR=/crossrootfs/arm"
__runtimeOS = "ubuntu.16.04"
; ;
*)
exit_with_error " ERROR: $__linuxCodeName is not a supported linux name for $__buildArch " false
; ;
esac
elif [ " $__buildArch " = = "armel" ] ; then
# For armel Tizen, we are going to construct RootFS on the fly.
case $__linuxCodeName in
tizen)
2017-08-21 15:34:15 +00:00
__dockerImage = " hqueue/dotnetcore:ubuntu1404_cross_prereqs_v4-tizen_rootfs"
__skipRootFS = 1
__dockerEnvironmentVariables += " -e ROOTFS_DIR=/crossrootfs/armel.tizen.build"
2017-06-07 13:16:24 +00:00
__runtimeOS = "tizen.4.0.0"
; ;
*)
echo " ERROR: $__linuxCodeName is not a supported linux name for $__buildArch "
exit_with_error " ERROR: $__linuxCodeName is not a supported linux name for $__buildArch " false
; ;
esac
else
exit_with_error " ERROR: unknown buildArch $__buildArch " false
fi
__dockerCmd = " sudo docker run ${ __dockerEnvironmentVariables } --privileged -i --rm -v $__currentWorkingDirectory :/opt/corefx -w /opt/corefx $__dockerImage "
if [ $__skipRootFS = = 0 ] ; then
# Build rootfs
__buildRootfsCmd = " ./cross/build-rootfs.sh $__buildArch $__linuxCodeName --skipunmount "
( set +x; echo " Build RootFS for $__buildArch $__linuxCodeName " )
$__dockerCmd $__buildRootfsCmd
sudo chown -R $( id -u -n) cross/rootfs
fi
# Cross building corefx with rootfs in Docker
if [ " $__buildArch " = = "armel" ] ; then
2017-08-21 15:34:15 +00:00
__extraCmd = "/p:OverridePackageSource=https://tizen.myget.org/F/dotnet-core/api/v3/index.json"
2017-10-19 20:04:20 +00:00
__portableLinux = "-PortableBuild=false"
2017-08-21 15:34:15 +00:00
fi
2017-06-07 13:16:24 +00:00
2017-10-19 20:04:20 +00:00
__buildCmd = " ./build.sh -buildArch= $__buildArch - $__buildConfig -RuntimeOS= $__runtimeOS $__portableLinux -- $__extraCmd "
2017-08-21 15:34:15 +00:00
$__dockerCmd $__buildCmd
sudo chown -R $( id -u -n) ./bin
2017-06-07 13:16:24 +00:00
}
2017-04-10 11:41:01 +00:00
#Define script variables
2017-06-07 13:16:24 +00:00
__ciMode = "docker"
2017-04-10 11:41:01 +00:00
__ARMEmulPath =
__ARMRootfsImageBase = "rootfs-u1404.ext4"
__ARMRootfsMountPath =
__buildConfig =
__verboseFlag =
__buildArch = "arm"
2017-06-07 13:16:24 +00:00
__linuxCodeName = "trusty"
__skipRootFS = 0
2017-04-10 11:41:01 +00:00
__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
; ;
2017-06-07 13:16:24 +00:00
--mode= *)
__ciMode = ${ arg #*= }
; ;
--arm)
__ARMRootfsImageBase = "rootfs-u1404.ext4"
__buildArch = "arm"
; ;
2017-04-10 11:41:01 +00:00
--armel)
__ARMRootfsImageBase = "rootfs-t30.ext4"
__buildArch = "armel"
2017-06-07 13:16:24 +00:00
__linuxCodeName = "tizen"
; ;
--linuxCodeName= *)
__linuxCodeName = ${ arg #*= }
; ;
--skipRootFS)
__skipRootFS = 1
2017-04-10 11:41:01 +00:00
; ;
-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
exit_if_empty " $__buildConfig " "--buildConfig is a mandatory argument, not provided" true
2017-06-07 13:16:24 +00:00
if [ " $__ciMode " = = "emulator" ] ; then
#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_path_absent " $__ARMEmulPath /platform/ $__ARMRootfsImageBase " "Path specified in --emulatorPath does not have the rootfs" false
2017-04-10 11:41:01 +00:00
2017-06-07 13:16:24 +00:00
__ARMRootfsMountPath = " ${ __ARMRootfsMountPath } _ ${ __buildArch } "
fi
2017-04-10 11:41:01 +00:00
set -x
set -e
## Begin cross build
( set +x; echo " Git HEAD @ $__initialGitHead " )
#Complete the cross build
( set +x; echo 'Building corefx...' )
2017-06-07 13:16:24 +00:00
if [ " $__ciMode " = = "docker" ] ; then
cross_build_corefx_with_docker
else
cross_build_corefx
fi
2017-04-10 11:41:01 +00:00
#Clean the environment
( set +x; echo 'Cleaning environment...' )
clean_env
( set +x; echo 'Build complete' )