Skip to content

Latest commit

 

History

History
155 lines (122 loc) · 7.65 KB

cross-building.md

File metadata and controls

155 lines (122 loc) · 7.65 KB

Cross Compilation for ARM on Linux

Through cross compilation, on Linux it is possible to build CoreRT for arm or arm64.

Requirements

You need a Debian based host and the following packages needs to be installed:

$ sudo apt-get install qemu qemu-user-static binfmt-support debootstrap

In addition, to cross compile CoreCLR the binutils for the target are required. So for arm you need:

$ sudo apt-get install binutils-arm-linux-gnueabihf

and conversely for arm64:

$ sudo apt-get install binutils-aarch64-linux-gnu

Generating the rootfs

The cross\build-rootfs.sh script can be used to download the files needed for cross compilation. It will generate an Ubuntu 14.04 rootfs as this is what CoreRT targets.

Usage: build-rootfs.sh [BuildArch]
BuildArch can be: arm, arm64

The build-rootfs.sh script must be run as root as it has to make some symlinks to the system, it will by default generate the rootfs in cross\rootfs\<BuildArch> however this can be changed by setting the ROOTFS_DIR environment variable.

For example, to generate an arm rootfs:

$ sudo ./cross/build-rootfs.sh arm

and if you wanted to generate the rootfs elsewhere:

$ sudo ROOTFS_DIR=~/coreclr-cross/arm ./build-rootfs.sh arm

Cross compiling CoreCLR

Once the rootfs has been generated, it will be possible to cross compile CoreRT. If ROOTFS_DIR was set when generating the rootfs, then it must also be set when running build.sh.

So, without ROOTFS_DIR:

$ ./build.sh arm debug verbose clean cross

And with:

$ ROOTFS_DIR=~/coreclr-cross/arm ./build.sh arm debug verbose clean cross

As usual the resulting binaries will be found in bin/Product/BuildOS.BuildArch.BuildType/

Using CoreRT for cross compiling under arm on x86 host

It's possible to use CoreRT for compiling under arm/armel on x86 host (or on x64 machine using rootfs). You can build Debug or Release version. For example Release means: release CoreRT/CoreCLR/CoreFX builds + CoreRT(ILC) release enabled optimizations. For better components compatibility, if you want to build Debug version, you must compile ALL projects as Debug version. Otherwise, ALL as Release version.

  1. Build CoreCLR for x86
sudo ./cross/build-rootfs.sh x86 xenial
./build.sh x86 debug verbose cross
  1. Build CoreFX
sudo ./cross/build-rootfs.sh x86 xenial
./build-native.sh -debug -buildArch=x86 -- verbose cross
./build-managed.sh -debug -verbose
  1. Build CoreRT for x86 and armel
sudo ./cross/build-rootfs.sh armel tizen
sudo ./cross/build-rootfs.sh x86 xenial
./build.sh armel debug verbose cross
./build.sh x86 debug verbose cross crosstarget skiptests
  1. Copy necessary binaries to working directory in x86 rootfs. Or in any host directory, if you have 32-bit multiarch-support on your x64 host.
# 1) Copy CoreCLR(with CoreRun) part
cp ${CORECLR}/bin/Product/Linux.x86.Debug/* ${WORKING_DIR}

# 2) Copy CoreRT part
cp ${CORERT}/bin/Linux.armel.Debug/tools/ilc.dll ${WORKING_DIR}
cp ${CORERT}/bin/Linux.armel.Debug/tools/ILCompiler.* ${WORKING_DIR}
cp ${CORERT}/bin/Linux.armel.Debug/tools/System.CommandLine.dll ${WORKING_DIR}
cp ${CORERT}/bin/Linux.armel.Debug/tools/Microsoft.DiaSymReader.dll ${WORKING_DIR}
cp -r ${CORERT}/bin/Linux.armel.Debug/framework ${WORKING_DIR}
cp -r ${CORERT}/bin/Linux.armel.Debug/sdk ${WORKING_DIR}

# 3) Copy CoreRT x86 jitinterface with target armel version
cp ${CORERT}/bin/Linux.x86.Debug/tools/armeljitinterface.so ${WORKING_DIR}/jitinterface.so

# 4) Copy CoreFX part
# Copy native architecture dependence libs
cp ${COREFX}/bin/Linux.x86.Debug/native/* ${WORKING_DIR}
# Copy arch independence libs
# This part varies depending on the application, these dependencies for HelloWorld only
NETCORE_PATH=netcoreapp-Linux-Debug-x64
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Runtime.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Runtime.Extensions.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Collections.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Reflection.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Reflection.Metadata.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Collections.Immutable.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Console.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.IO.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Runtime.InteropServices.RuntimeInformation.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Runtime.InteropServices.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Threading.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Diagnostics.Debug.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Linq.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.IO.FileSystem.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.IO.MemoryMappedFiles.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.IO.UnmanagedMemoryStream.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.IO.FileSystem.Primitives.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Runtime.Handles.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Text.Encoding.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Text.Encoding.Extensions.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Reflection.Primitives.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Collections.Concurrent.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Security.Cryptography.Algorithms.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Security.Cryptography.Primitives.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Runtime.CompilerServices.Unsafe.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Globalization.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Private.Xml.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Diagnostics.Tracing.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Buffers.dll ${WORKING_DIR}
cp ${COREFX}/bin/runtime/${NETCORE_PATH}/System.Memory.dll ${WORKING_DIR}
  1. Rename RyuJIT compiler library
# Use cross-compiler library as default for ILC
# libclrjit.so is used by the CoreCLR that compiler runs on,
# and libclrjitilc.so is used for the actual compilation.
cp ${WORKING_DIR}/libarmelnonjit.so ${WORKING_DIR}/libclrjitilc.so
  1. Build ObjectWriter library. You have to compile it on x86 chroot.

  2. And to execute use:

# Hello.ilc.rsp is in CoreRT armel build. It's necessary to edit the paths on the relatively our working directory.
./corerun ilc.dll --codegenopt "AltJitNgen=*" --verbose @Hello.ilc.rsp

# Any other options to RyuJIT could be passed via --codegenopt argument, e.g.:
# ./corerun ilc.dll --codegenopt "AltJitNgen=*" --codegenopt "NgenDisasm=*" --verbose @Hello.ilc.rsp

# For linking
clang -target arm-linux-gnueabi --sysroot=corert/cross/rootfs/armel -Bcorert/cross/rootfs/armel/usr/lib/gcc/armv7l-tizen-linux-gnueabi/6.2.1 -Lcorert/cross/rootfs/armel/usr/lib/gcc/armv7l-tizen-linux-gnueabi/6.2.1 Hello.o -o Hello corert/bin/Linux.armel.Debug/sdk/libbootstrapper.a corert/bin/Linux.armel.Debug/sdk/libRuntime.a corert/bin/Linux.armel.Debug/sdk/libSystem.Private.CoreLib.Native.a corert/bin/Linux.armel.Debug/framework/System.Native.a corert/bin/Linux.armel.Debug/framework/System.Globalization.Native.a -g -Wl,-rpath,'$ORIGIN' -pthread -lstdc++ -ldl -lm -luuid -lrt -fPIC