diff options
-rw-r--r-- | build.sh | 340 | ||||
-rw-r--r-- | src/Native/CMakeLists.txt | 43 | ||||
-rw-r--r-- | src/Native/configure.cmake | 15 | ||||
-rw-r--r-- | src/Native/gen-buildsys-clang.sh | 112 |
4 files changed, 510 insertions, 0 deletions
diff --git a/build.sh b/build.sh new file mode 100644 index 000000000..71bd808ee --- /dev/null +++ b/build.sh @@ -0,0 +1,340 @@ +#!/usr/bin/env bash + +usage() +{ + echo "Usage: $0 [managed] [native] [BuildArch] [BuildType] [clean] [verbose] [clangx.y]" + echo "managed - optional argument to build the managed code" + echo "native - optional argument to build the native code" + echo "The following arguments affect native builds only:" + echo "BuildArch can be: x64, arm" + echo "BuildType can be: Debug, Release" + echo "clean - optional argument to force a clean build." + echo "verbose - optional argument to enable verbose build output." + echo "clangx.y - optional argument to build using clang version x.y." + + exit 1 +} + +setup_dirs() +{ + echo Setting up directories for build + + mkdir -p "$__BinDir" + mkdir -p "$__IntermediatesDir" +} + +# Performs "clean build" type actions (deleting and remaking directories) + +clean() +{ + echo "Cleaning previous output for the selected configuration" + rm -rf "$__BinDir" + rm -rf "$__IntermediatesDir" +} + +# Check the system to ensure the right pre-reqs are in place + +check_managed_prereqs() +{ + __monoversion=$(mono --version | grep "version 4.[1-9]") + + if [ $? -ne 0 ]; then + # if built from tarball, mono only identifies itself as 4.0.1 + __monoversion=$(mono --version | egrep "version 4.0.[1-9]+(.[0-9]+)?") + if [ $? -ne 0 ]; then + echo "Mono 4.0.1.44 or later is required to build corert." + exit 1 + else + echo "WARNING: Mono 4.0.1.44 or later is required to build corert. Unable to assess if current version is supported." + fi + fi +} + +check_native_prereqs() +{ + echo "Checking pre-requisites..." + + # Check presence of CMake on the path + hash cmake 2>/dev/null || { echo >&2 "Please install cmake before running this script"; exit 1; } + + # Check for clang + hash clang-$__ClangMajorVersion.$__ClangMinorVersion 2>/dev/null || hash clang$__ClangMajorVersion$__ClangMinorVersion 2>/dev/null || hash clang 2>/dev/null || { echo >&2 "Please install clang before running this script"; exit 1; } +} + +# Prepare the system for building + +prepare_managed_build() +{ + # Pull NuGet.exe down if we don't have it already + if [ ! -e "$__nugetpath" ]; then + which curl wget > /dev/null 2> /dev/null + if [ $? -ne 0 -a $? -ne 1 ]; then + echo "cURL or wget is required to build corert." + exit 1 + fi + echo "Restoring NuGet.exe..." + + # curl has HTTPS CA trust-issues less often than wget, so lets try that first. + which curl > /dev/null 2> /dev/null + if [ $? -ne 0 ]; then + mkdir -p $__packageroot + wget -q -O $__nugetpath https://api.nuget.org/downloads/nuget.exe + else + curl -sSL --create-dirs -o $__nugetpath https://api.nuget.org/downloads/nuget.exe + fi + + if [ $? -ne 0 ]; then + echo "Failed to restore NuGet.exe." + exit 1 + fi + fi + + # Grab the MSBuild package if we don't have it already + if [ ! -e "$__msbuildpath" ]; then + echo "Restoring MSBuild..." + mono "$__nugetpath" install $__msbuildpackageid -Version $__msbuildpackageversion -source "https://www.myget.org/F/dotnet-buildtools/" -OutputDirectory "$__packageroot" + if [ $? -ne 0 ]; then + echo "Failed to restore MSBuild." + exit 1 + fi + fi +} + +prepare_native_build() +{ + # Specify path to be set for CMAKE_INSTALL_PREFIX. + # This is where all built CoreClr libraries will copied to. + export __CMakeBinDir="$__BinDir" + + # Configure environment if we are doing a clean build. + if [ $__CleanBuild == 1 ]; then + clean + fi + + # Configure environment if we are doing a verbose build + if [ $__VerboseBuild == 1 ]; then + export VERBOSE=1 + fi +} + +build_managed_corert() +{ + __buildproj=$__scriptpath/build.proj + __buildlog=$__scriptpath/msbuild.log + + MONO29679=1 ReferenceAssemblyRoot=$__referenceassemblyroot mono $__msbuildpath "$__buildproj" /nologo /verbosity:minimal "/fileloggerparameters:Verbosity=normal;LogFile=$__buildlog" /t:Build /p:OSGroup=$__BuildOS /p:UseRoslynCompiler=true /p:COMPUTERNAME=$(hostname) /p:USERNAME=$(id -un) "$@" + BUILDERRORLEVEL=$? + + echo + + # Pull the build summary from the log file + tail -n 4 "$__buildlog" + echo Build Exit Code = $BUILDERRORLEVEL +} + +build_native_corert() +{ + # All set to commence the build + + echo "Commencing build of corert native components for $__BuildOS.$__BuildArch.$__BuildType" + cd "$__IntermediatesDir" + + # Regenerate the CMake solution + echo "Invoking cmake with arguments: \"$__nativeroot\" $__CMakeArgs" + "$__nativeroot/gen-buildsys-clang.sh" "$__nativeroot" $__ClangMajorVersion $__ClangMinorVersion $__CMakeArgs + + # Check that the makefiles were created. + + if [ ! -f "$__IntermediatesDir/Makefile" ]; then + echo "Failed to generate native component build project!" + exit 1 + fi + + # Get the number of processors available to the scheduler + # Other techniques such as `nproc` only get the number of + # processors available to a single process. + if [ `uname` = "FreeBSD" ]; then + NumProc=`sysctl hw.ncpu | awk '{ print $2+1 }'` + else + NumProc=$(($(getconf _NPROCESSORS_ONLN)+1)) + fi + + # Build + + echo "Executing make install -j $NumProc $__UnprocessedBuildArgs" + + make install -j $NumProc $__UnprocessedBuildArgs + if [ $? != 0 ]; then + echo "Failed to build corert native components." + exit 1 + fi + + echo "CoreRT native components successfully built." + echo "Product binaries are available at $__BinDir" +} + +__scriptpath=$(cd "$(dirname "$0")"; pwd -P) +__nativeroot=$__scriptpath/src/Native +__packageroot=$__scriptpath/packages +__sourceroot=$__scriptpath/src +__nugetpath=$__packageroot/NuGet.exe +__nugetconfig=$__sourceroot/NuGet.Config +__rootbinpath="$__scriptpath/bin" +__msbuildpackageid="Microsoft.Build.Mono.Debug" +__msbuildpackageversion="14.1.0.0-prerelease" +__msbuildpath=$__packageroot/$__msbuildpackageid.$__msbuildpackageversion/lib/MSBuild.exe +__BuildArch=x64 +__buildmanaged=false +__buildnative=false +# Use uname to determine what the OS is. +OSName=$(uname -s) +case $OSName in + Linux) + __BuildOS=Linux + ;; + + Darwin) + __BuildOS=OSX + ;; + + FreeBSD) + __BuildOS=FreeBSD + ;; + + *) + echo "Unsupported OS $OSName detected, configuring as if for Linux" + __BuildOS=Linux + ;; +esac +__BuildType=Debug +__CMakeArgs=DEBUG + +case $__BuildOS in + FreeBSD) + __monoroot=/usr/local + ;; + OSX) + __monoroot=/Library/Frameworks/Mono.framework/Versions/Current + ;; + *) + __monoroot=/usr + ;; +esac + +__referenceassemblyroot=$__monoroot/lib/mono/xbuild-frameworks +BUILDERRORLEVEL=0 + +# Set the various build properties here so that CMake and MSBuild can pick them up +__UnprocessedBuildArgs= +__CleanBuild=false +__VerboseBuild=false +__ClangMajorVersion=3 +__ClangMinorVersion=5 + +for i in "$@" + do + lowerI="$(echo $i | awk '{print tolower($0)}')" + case $lowerI in + -?|-h|--help) + usage + exit 1 + ;; + managed) + __buildmanaged=true + ;; + native) + __buildnative=true + ;; + x64) + __BuildArch=x64 + __MSBuildBuildArch=x64 + ;; + arm) + __BuildArch=arm + __MSBuildBuildArch=arm + ;; + debug) + __BuildType=Debug + ;; + release) + __BuildType=Release + __CMakeArgs=RELEASE + ;; + clean) + __CleanBuild=1 + ;; + verbose) + __VerboseBuild=1 + ;; + clang3.5) + __ClangMajorVersion=3 + __ClangMinorVersion=5 + ;; + clang3.6) + __ClangMajorVersion=3 + __ClangMinorVersion=6 + ;; + clang3.7) + __ClangMajorVersion=3 + __ClangMinorVersion=7 + ;; + *) + __UnprocessedBuildArgs="$__UnprocessedBuildArgs $i" + esac +done + +# If neither managed nor native are passed as arguments, default to building native only + +if [ "$__buildmanaged" = false -a "$__buildnative" = false ]; then + __buildmanaged=false + __buildnative=true +fi + +# Set the remaining variables based upon the determined build configuration +__IntermediatesDir="$__rootbinpath/obj/$__BuildOS.$__BuildArch.$__BuildType/Native" +__BinDir="$__rootbinpath/$__BuildOS.$__BuildArch.$__BuildType/Native" + +# Make the directories necessary for build if they don't exist + +setup_dirs + +if $__buildmanaged; then + + # Check prereqs. + + check_managed_prereqs + + # Prepare the system + + prepare_managed_build + + # Build the corert native components. + + build_managed_corert + + # Build complete +fi + +# If managed build failed, exit with the status code of the managed build +if [ $BUILDERRORLEVEL != 0 ]; then + exit $BUILDERRORLEVEL +fi + +if $__buildnative; then + + # Check prereqs. + + check_native_prereqs + + # Prepare the system + + prepare_native_build + + # Build the corert native components. + + build_native_corert + + # Build complete +fi + +exit $BUILDERRORLEVEL diff --git a/src/Native/CMakeLists.txt b/src/Native/CMakeLists.txt new file mode 100644 index 000000000..7d26d88fe --- /dev/null +++ b/src/Native/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 2.8.12) +project(CoreRT) + +set(CMAKE_MACOSX_RPATH ON) +set(CMAKE_INSTALL_PREFIX $ENV{__CMakeBinDir}) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_C_FLAGS "-std=c11") +set(CMAKE_CXX_FLAGS "-std=c++11") +set(CMAKE_SHARED_LIBRARY_PREFIX "") + +add_compile_options(-Weverything) +add_compile_options(-Wno-format-nonliteral) +add_compile_options(-Wno-missing-prototypes) +add_compile_options(-Wno-disabled-macro-expansion) +add_compile_options(-Wno-c++98-compat) +add_compile_options(-Wno-c++98-compat-pedantic) +add_compile_options(-Werror) +add_compile_options(-fPIC) + +if (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL amd64) + add_definitions(-DBIT64=1) +elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l) + add_definitions(-DBIT32=1) + # Because we don't use CMAKE_C_COMPILER/CMAKE_CXX_COMPILER to use clang + # we have to set the triple by adding a compiler argument + add_compile_options(-target armv7-linux-gnueabihf) + add_compile_options(-mthumb) + add_compile_options(-mfpu=vfpv3) +endif () + +string(TOUPPER ${CMAKE_BUILD_TYPE} UPPERCASE_CMAKE_BUILD_TYPE) +if (UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG) + add_compile_options(-g -O0) + add_definitions(-DDEBUG) +elseif (UPPERCASE_CMAKE_BUILD_TYPE STREQUAL RELEASE) + add_compile_options (-O3) + add_definitions(-DNDEBUG) +else () + message(FATAL_ERROR "Unknown build type. Set CMAKE_BUILD_TYPE to DEBUG or RELEASE.") +endif () + +include(configure.cmake) + diff --git a/src/Native/configure.cmake b/src/Native/configure.cmake new file mode 100644 index 000000000..b50f03196 --- /dev/null +++ b/src/Native/configure.cmake @@ -0,0 +1,15 @@ +include(CheckFunctionExists) +include(CheckStructHasMember) +include(CheckCXXSourceCompiles) +include(CheckCXXSourceRuns) + +#CMake does not include /usr/local/include into the include search path +#thus add it manually. This is required on FreeBSD. +include_directories(/usr/local/include) + +if (CMAKE_SYSTEM_NAME STREQUAL Linux) + set (CMAKE_REQUIRED_LIBRARIES rt) +endif () + +set (CMAKE_REQUIRED_LIBRARIES) + diff --git a/src/Native/gen-buildsys-clang.sh b/src/Native/gen-buildsys-clang.sh new file mode 100644 index 000000000..9367c3201 --- /dev/null +++ b/src/Native/gen-buildsys-clang.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +# +# This file invokes cmake and generates the build system for gcc. +# + +if [ $# -lt 3 -o $# -gt 4 ] +then + echo "Usage..." + echo "gen-buildsys-clang.sh <path to top level CMakeLists.txt> <ClangMajorVersion> <ClangMinorVersion> [build flavor]" + echo "Specify the path to the top level CMake file - <corert>/src/Native" + echo "Specify the clang version to use, split into major and minor version" + echo "Optionally specify the build configuration (flavor.) Defaults to DEBUG." + exit 1 +fi + +# Set up the environment to be used for building with clang. +if which "clang-$2.$3" > /dev/null 2>&1 + then + export CC="$(which clang-$2.$3)" + export CXX="$(which clang++-$2.$3)" +elif which "clang$2$3" > /dev/null 2>&1 + then + export CC="$(which clang$2$3)" + export CXX="$(which clang++$2$3)" +elif which clang > /dev/null 2>&1 + then + export CC="$(which clang)" + export CXX="$(which clang++)" +else + echo "Unable to find Clang Compiler" + exit 1 +fi + +# Possible build types are DEBUG, RELEASE, RELWITHDEBINFO, MINSIZEREL. +# Default to DEBUG +if [ -z "$4" ] +then + echo "Defaulting to DEBUG build." + buildtype="DEBUG" +else + buildtype="$4" +fi + +OS=`uname` + +# Locate llvm +# This can be a little complicated, because the common use-case of Ubuntu with +# llvm-3.5 installed uses a rather unusual llvm installation with the version +# number postfixed (i.e. llvm-ar-3.5), so we check for that first. +# On FreeBSD the version number is appended without point and dash (i.e. +# llvm-ar35). +# Additionally, OSX doesn't use the llvm- prefix. +if [ $OS = "Linux" -o $OS = "FreeBSD" -o $OS = "OpenBSD" -o $OS = "NetBSD" ]; then + llvm_prefix="llvm-" +elif [ $OS = "Darwin" ]; then + llvm_prefix="" +else + echo "Unable to determine build platform" + exit 1 +fi + +desired_llvm_major_version=$2 +desired_llvm_minor_version=$3 +if [ $OS = "FreeBSD" ]; then + desired_llvm_version="$desired_llvm_major_version$desired_llvm_minor_version" +elif [ $OS = "OpenBSD" ]; then + desired_llvm_version="" +elif [ $OS = "NetBSD" ]; then + desired_llvm_version="" +else + desired_llvm_version="-$desired_llvm_major_version.$desired_llvm_minor_version" +fi +locate_llvm_exec() { + if which "$llvm_prefix$1$desired_llvm_version" > /dev/null 2>&1 + then + echo "$(which $llvm_prefix$1$desired_llvm_version)" + elif which "$llvm_prefix$1" > /dev/null 2>&1 + then + echo "$(which $llvm_prefix$1)" + else + exit 1 + fi +} + +llvm_ar="$(locate_llvm_exec ar)" +[[ $? -eq 0 ]] || { echo "Unable to locate llvm-ar"; exit 1; } +llvm_link="$(locate_llvm_exec link)" +[[ $? -eq 0 ]] || { echo "Unable to locate llvm-link"; exit 1; } +llvm_nm="$(locate_llvm_exec nm)" +[[ $? -eq 0 ]] || { echo "Unable to locate llvm-nm"; exit 1; } +if [ $OS = "Linux" -o $OS = "FreeBSD" -o $OS = "OpenBSD" -o $OS = "NetBSD" ]; then + llvm_objdump="$(locate_llvm_exec objdump)" + [[ $? -eq 0 ]] || { echo "Unable to locate llvm-objdump"; exit 1; } +fi + +cmake_extra_defines= +if [[ -n "$LLDB_LIB_DIR" ]]; then + cmake_extra_defines="$cmake_extra_defines -DWITH_LLDB_LIBS=$LLDB_LIB_DIR" +fi +if [[ -n "$LLDB_INCLUDE_DIR" ]]; then + cmake_extra_defines="$cmake_extra_defines -DWITH_LLDB_INCLUDES=$LLDB_INCLUDE_DIR" +fi + +cmake \ + "-DCMAKE_AR=$llvm_ar" \ + "-DCMAKE_LINKER=$llvm_link" \ + "-DCMAKE_NM=$llvm_nm" \ + "-DCMAKE_OBJDUMP=$llvm_objdump" \ + "-DCMAKE_RANLIB=$llvm_ranlib" \ + "-DCMAKE_BUILD_TYPE=$buildtype" \ + $cmake_extra_defines \ + "$1" |