Copy infra files from runtime
authorAdeel <3840695+am11@users.noreply.github.com>
Thu, 28 Oct 2021 09:54:38 +0000 (12:54 +0300)
committerAdeel <3840695+am11@users.noreply.github.com>
Fri, 29 Oct 2021 01:02:33 +0000 (04:02 +0300)
27 files changed:
eng/native/build-commons.sh [new file with mode: 0755]
eng/native/configurecompiler.cmake [new file with mode: 0644]
eng/native/configureoptimization.cmake [new file with mode: 0644]
eng/native/configurepaths.cmake [new file with mode: 0644]
eng/native/configureplatform.cmake [new file with mode: 0644]
eng/native/configuretools.cmake [new file with mode: 0644]
eng/native/functions.cmake [new file with mode: 0644]
eng/native/gen-buildsys.cmd [new file with mode: 0644]
eng/native/gen-buildsys.sh [new file with mode: 0755]
eng/native/generateexportedsymbols.sh [new file with mode: 0755]
eng/native/generateversionscript.sh [new file with mode: 0755]
eng/native/genmoduleindex.cmd [new file with mode: 0644]
eng/native/genmoduleindex.sh [new file with mode: 0755]
eng/native/init-distro-rid.sh [new file with mode: 0644]
eng/native/init-os-and-arch.sh [new file with mode: 0644]
eng/native/init-vs-env.cmd [new file with mode: 0644]
eng/native/naming.props [new file with mode: 0644]
eng/native/output-toolchain-info.cmake [new file with mode: 0644]
eng/native/sanitizerblacklist.txt [new file with mode: 0644]
eng/native/set-cmake-path.ps1 [new file with mode: 0644]
eng/native/tryrun.cmake [new file with mode: 0644]
eng/native/version/NativeVersion.rc [new file with mode: 0644]
eng/native/version/_version.c [new file with mode: 0644]
eng/native/version/_version.h [new file with mode: 0644]
eng/native/version/copy_version_files.cmd [new file with mode: 0644]
eng/native/version/copy_version_files.sh [new file with mode: 0755]
eng/native/version/runtime_version.h [new file with mode: 0644]

diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh
new file mode 100755 (executable)
index 0000000..93afd4a
--- /dev/null
@@ -0,0 +1,462 @@
+#!/usr/bin/env bash
+
+initTargetDistroRid()
+{
+    source "$__RepoRootDir/eng/native/init-distro-rid.sh"
+
+    local passedRootfsDir=""
+
+    # Only pass ROOTFS_DIR if cross is specified and the target platform is not Darwin that doesn't use rootfs
+    if [[ "$__CrossBuild" == 1 && "$platform" != "Darwin" ]]; then
+        passedRootfsDir="$ROOTFS_DIR"
+    fi
+
+    initDistroRidGlobal "$__TargetOS" "$__BuildArch" "$__PortableBuild" "$passedRootfsDir"
+}
+
+setup_dirs()
+{
+    echo Setting up directories for build
+
+    mkdir -p "$__RootBinDir"
+    mkdir -p "$__BinDir"
+    mkdir -p "$__IntermediatesDir"
+}
+
+# Check the system to ensure the right prereqs are in place
+check_prereqs()
+{
+    echo "Checking prerequisites..."
+
+    if [[ "$__HostOS" == "OSX" ]]; then
+        # Check presence of pkg-config on the path
+        command -v pkg-config 2>/dev/null || { echo >&2 "Please install pkg-config before running this script, see https://github.com/dotnet/runtime/blob/main/docs/workflow/requirements/macos-requirements.md"; exit 1; }
+
+        if ! pkg-config openssl ; then
+            # We export the proper PKG_CONFIG_PATH where openssl was installed by Homebrew
+            # It's important to _export_ it since build-commons.sh is sourced by other scripts such as build-native.sh
+            export PKG_CONFIG_PATH=$(brew --prefix)/opt/openssl@1.1/lib/pkgconfig:$(brew --prefix)/opt/openssl/lib/pkgconfig
+            # We try again with the PKG_CONFIG_PATH in place, if pkg-config still can't find OpenSSL, exit with an error, cmake won't find OpenSSL either
+            pkg-config openssl || { echo >&2 "Please install openssl before running this script, see https://github.com/dotnet/runtime/blob/main/docs/workflow/requirements/macos-requirements.md"; exit 1; }
+        fi
+    fi
+
+    if [[ "$__UseNinja" == 1 ]]; then
+        command -v ninja 2>/dev/null || command -v ninja-build 2>/dev/null || { echo "Unable to locate ninja!"; exit 1; }
+    fi
+}
+
+build_native()
+{
+    eval "$__RepoRootDir/eng/native/version/copy_version_files.sh"
+
+    targetOS="$1"
+    platformArch="$2"
+    cmakeDir="$3"
+    intermediatesDir="$4"
+    target="$5"
+    cmakeArgs="$6"
+    message="$7"
+
+    # All set to commence the build
+    echo "Commencing build of \"$target\" target in \"$message\" for $__TargetOS.$__BuildArch.$__BuildType in $intermediatesDir"
+
+    if [[ "$targetOS" == OSX || "$targetOS" == MacCatalyst ]]; then
+        if [[ "$platformArch" == x64 ]]; then
+            cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"x86_64\" $cmakeArgs"
+        elif [[ "$platformArch" == arm64 ]]; then
+            cmakeArgs="-DCMAKE_OSX_ARCHITECTURES=\"arm64\" $cmakeArgs"
+        else
+            echo "Error: Unknown OSX architecture $platformArch."
+            exit 1
+        fi
+    fi
+
+    if [[ "$targetOS" == MacCatalyst ]]; then
+        cmakeArgs="-DCMAKE_SYSTEM_VARIANT=MacCatalyst $cmakeArgs"
+    fi
+
+    if [[ "$targetOS" == Android && -z "$ROOTFS_DIR" ]]; then
+        if [[ -z "$ANDROID_NDK_ROOT" ]]; then
+            echo "Error: You need to set the ANDROID_NDK_ROOT environment variable pointing to the Android NDK root."
+            exit 1
+        fi
+
+        # keep ANDROID_NATIVE_API_LEVEL in sync with src/mono/Directory.Build.props
+        cmakeArgs="-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake -DANDROID_NATIVE_API_LEVEL=21 $cmakeArgs"
+
+        # Don't try to set CC/CXX in init-compiler.sh - it's handled in android.toolchain.cmake already
+        __Compiler="default"
+
+        if [[ "$platformArch" == x64 ]]; then
+            cmakeArgs="-DANDROID_ABI=x86_64 $cmakeArgs"
+        elif [[ "$platformArch" == x86 ]]; then
+            cmakeArgs="-DANDROID_ABI=x86 $cmakeArgs"
+        elif [[ "$platformArch" == arm64 ]]; then
+            cmakeArgs="-DANDROID_ABI=arm64-v8a $cmakeArgs"
+        elif [[ "$platformArch" == arm ]]; then
+            cmakeArgs="-DANDROID_ABI=armeabi-v7a $cmakeArgs"
+        else
+            echo "Error: Unknown Android architecture $platformArch."
+            exit 1
+        fi
+    fi
+
+    if [[ "$__UseNinja" == 1 ]]; then
+        generator="ninja"
+        buildTool="$(command -v ninja || command -v ninja-build)"
+    else
+        buildTool="make"
+    fi
+
+    if [[ "$__SkipConfigure" == 0 ]]; then
+
+        if [[ "$__StaticAnalyzer" == 1 ]]; then
+            scan_build=scan-build
+        fi
+
+        nextCommand="\"$__RepoRootDir/eng/native/gen-buildsys.sh\" \"$cmakeDir\" \"$intermediatesDir\" $platformArch $__Compiler \"$__CompilerMajorVersion\" \"$__CompilerMinorVersion\" $__BuildType \"$generator\" $scan_build $cmakeArgs"
+        echo "Invoking $nextCommand"
+        eval $nextCommand
+
+        local exit_code="$?"
+        if [[ "$exit_code" != 0  ]]; then
+            echo "${__ErrMsgPrefix}Failed to generate \"$message\" build project!"
+            exit "$exit_code"
+        fi
+    fi
+
+    # Check that the makefiles were created.
+    if [[ ! -f "$intermediatesDir/CMakeCache.txt" ]]; then
+        echo "${__ErrMsgPrefix}Unable to find generated build files for \"$message\" project!"
+        exit 1
+    fi
+
+    # Build
+    if [[ "$__ConfigureOnly" == 1 ]]; then
+        echo "Finish configuration & skipping \"$message\" build."
+        return
+    fi
+
+    SAVED_CFLAGS="${CFLAGS}"
+    SAVED_CXXFLAGS="${CXXFLAGS}"
+    SAVED_LDFLAGS="${LDFLAGS}"
+
+    # Let users provide additional compiler/linker flags via EXTRA_CFLAGS/EXTRA_CXXFLAGS/EXTRA_LDFLAGS.
+    # If users directly override CFLAG/CXXFLAGS/LDFLAGS, that may lead to some configure tests working incorrectly.
+    # See https://github.com/dotnet/runtime/issues/35727 for more information.
+    export CFLAGS="${CFLAGS} ${EXTRA_CFLAGS}"
+    export CXXFLAGS="${CXXFLAGS} ${EXTRA_CXXFLAGS}"
+    export LDFLAGS="${LDFLAGS} ${EXTRA_LDFLAGS}"
+
+    local exit_code
+    if [[ "$__StaticAnalyzer" == 1 ]]; then
+        pushd "$intermediatesDir"
+
+        buildTool="$SCAN_BUILD_COMMAND -o $__BinDir/scan-build-log $buildTool"
+        echo "Executing $buildTool $target -j $__NumProc"
+        "$buildTool" $target -j "$__NumProc"
+        exit_code="$?"
+
+        popd
+    else
+        cmake_command=cmake
+        if [[ "$build_arch" == "wasm" ]]; then
+            cmake_command="emcmake cmake"
+            echo "Executing $cmake_command --build \"$intermediatesDir\" --target $target -- -j $__NumProc"
+            $cmake_command --build "$intermediatesDir" --target $target -- -j "$__NumProc"
+            exit_code="$?"
+        else
+            # For non-wasm Unix scenarios, we may have to use an old version of CMake that doesn't support
+            # multiple targets. Instead, directly invoke the build tool to build multiple targets in one invocation.
+            pushd "$intermediatesDir"
+
+            echo "Executing $buildTool $target -j $__NumProc"
+            "$buildTool" $target -j "$__NumProc"
+            exit_code="$?"
+
+            popd
+        fi
+    fi
+
+    CFLAGS="${SAVED_CFLAGS}"
+    CXXFLAGS="${SAVED_CXXFLAGS}"
+    LDFLAGS="${SAVED_LDFLAGS}"
+
+    if [[ "$exit_code" != 0 ]]; then
+        echo "${__ErrMsgPrefix}Failed to build \"$message\"."
+        exit "$exit_code"
+    fi
+}
+
+usage()
+{
+    echo "Usage: $0 <options>"
+    echo ""
+    echo "Common Options:"
+    echo ""
+    echo "BuildArch can be: -arm, -armel, -arm64, -s390x, x64, x86, -wasm"
+    echo "BuildType can be: -debug, -checked, -release"
+    echo "-os: target OS (defaults to running OS)"
+    echo "-bindir: output directory (defaults to $__ProjectRoot/artifacts)"
+    echo "-ci: indicates if this is a CI build."
+    echo "-clang: optional argument to build using clang in PATH (default)."
+    echo "-clangx.y: optional argument to build using clang version x.y."
+    echo "-cmakeargs: user-settable additional arguments passed to CMake."
+    echo "-configureonly: do not perform any builds; just configure the build."
+    echo "-cross: optional argument to signify cross compilation,"
+    echo "        will use ROOTFS_DIR environment variable if set."
+    echo "-gcc: optional argument to build using gcc in PATH."
+    echo "-gccx.y: optional argument to build using gcc version x.y."
+    echo "-ninja: target ninja instead of GNU make"
+    echo "-numproc: set the number of build processes."
+    echo "-portablebuild: pass -portablebuild=false to force a non-portable build."
+    echo "-skipconfigure: skip build configuration."
+    echo "-keepnativesymbols: keep native/unmanaged debug symbols."
+    echo "-verbose: optional argument to enable verbose build output."
+    echo ""
+    echo "Additional Options:"
+    echo ""
+    for i in "${!usage_list[@]}"; do
+        echo "${usage_list[${i}]}"
+    done
+    echo ""
+    exit 1
+}
+
+source "$__RepoRootDir/eng/native/init-os-and-arch.sh"
+
+__BuildArch=$arch
+__HostArch=$arch
+__TargetOS=$os
+__HostOS=$os
+__BuildOS=$os
+
+# 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.
+platform="$(uname)"
+if [[ "$platform" == "FreeBSD" ]]; then
+  __NumProc=$(($(sysctl -n hw.ncpu)+1))
+elif [[ "$platform" == "NetBSD" || "$platform" == "SunOS" ]]; then
+  __NumProc=$(($(getconf NPROCESSORS_ONLN)+1))
+elif [[ "$platform" == "Darwin" ]]; then
+  __NumProc=$(($(getconf _NPROCESSORS_ONLN)+1))
+else
+  if command -v nproc > /dev/null 2>&1; then
+    __NumProc=$(nproc --all)
+  elif (NAME=""; . /etc/os-release; test "$NAME" = "Tizen"); then
+    __NumProc=$(getconf _NPROCESSORS_ONLN)
+  else
+    __NumProc=1
+  fi
+fi
+
+while :; do
+    if [[ "$#" -le 0 ]]; then
+        break
+    fi
+
+    lowerI="$(echo "$1" | tr "[:upper:]" "[:lower:]")"
+    case "$lowerI" in
+        -\?|-h|--help)
+            usage
+            exit 1
+            ;;
+
+        arm|-arm)
+            __BuildArch=arm
+            ;;
+
+        arm64|-arm64)
+            __BuildArch=arm64
+            ;;
+
+        armel|-armel)
+            __BuildArch=armel
+            ;;
+
+        bindir|-bindir)
+            if [[ -n "$2" ]]; then
+                __RootBinDir="$2"
+                if [[ ! -d "$__RootBinDir" ]]; then
+                    mkdir "$__RootBinDir"
+                fi
+                __RootBinParent=$(dirname "$__RootBinDir")
+                __RootBinName="${__RootBinDir##*/}"
+                __RootBinDir="$(cd "$__RootBinParent" &>/dev/null && printf %s/%s "$PWD" "$__RootBinName")"
+                shift
+            else
+                echo "ERROR: 'bindir' requires a non-empty option argument"
+                exit 1
+            fi
+            ;;
+
+        checked|-checked)
+            __BuildType=Checked
+            ;;
+
+        ci|-ci)
+            __ArcadeScriptArgs="--ci"
+            __ErrMsgPrefix="##vso[task.logissue type=error]"
+            ;;
+
+        clang*|-clang*)
+                __Compiler=clang
+                # clangx.y or clang-x.y
+                version="$(echo "$lowerI" | tr -d '[:alpha:]-=')"
+                parts=(${version//./ })
+                __CompilerMajorVersion="${parts[0]}"
+                __CompilerMinorVersion="${parts[1]}"
+                if [[ -z "$__CompilerMinorVersion" && "$__CompilerMajorVersion" -le 6 ]]; then
+                    __CompilerMinorVersion=0;
+                fi
+            ;;
+
+        cmakeargs|-cmakeargs)
+            if [[ -n "$2" ]]; then
+                __CMakeArgs="$2 $__CMakeArgs"
+                shift
+            else
+                echo "ERROR: 'cmakeargs' requires a non-empty option argument"
+                exit 1
+            fi
+            ;;
+
+        configureonly|-configureonly)
+            __ConfigureOnly=1
+            __SkipMSCorLib=1
+            __SkipNuget=1
+            ;;
+
+        cross|-cross)
+            __CrossBuild=1
+            ;;
+
+        debug|-debug)
+            __BuildType=Debug
+            ;;
+
+        gcc*|-gcc*)
+                __Compiler=gcc
+                # gccx.y or gcc-x.y
+                version="$(echo "$lowerI" | tr -d '[:alpha:]-=')"
+                parts=(${version//./ })
+                __CompilerMajorVersion="${parts[0]}"
+                __CompilerMinorVersion="${parts[1]}"
+            ;;
+
+        keepnativesymbols|-keepnativesymbols)
+            __CMakeArgs="$__CMakeArgs -DCLR_CMAKE_KEEP_NATIVE_SYMBOLS=true"
+            ;;
+
+        ninja|-ninja)
+            __UseNinja=1
+            ;;
+
+        numproc|-numproc)
+            if [[ -n "$2" ]]; then
+              __NumProc="$2"
+              shift
+            else
+              echo "ERROR: 'numproc' requires a non-empty option argument"
+              exit 1
+            fi
+            ;;
+
+        portablebuild=false|-portablebuild=false)
+            __PortableBuild=0
+            ;;
+
+        release|-release)
+            __BuildType=Release
+            ;;
+
+        skipconfigure|-skipconfigure)
+            __SkipConfigure=1
+            ;;
+
+        verbose|-verbose)
+            __VerboseBuild=1
+            ;;
+
+        x86|-x86)
+            __BuildArch=x86
+            ;;
+
+        x64|-x64)
+            __BuildArch=x64
+            ;;
+
+        s390x|-s390x)
+            __BuildArch=s390x
+            ;;
+
+        wasm|-wasm)
+            __BuildArch=wasm
+            ;;
+
+        os|-os)
+            if [[ -n "$2" ]]; then
+                __TargetOS="$2"
+                shift
+            else
+                echo "ERROR: 'os' requires a non-empty option argument"
+                exit 1
+            fi
+            ;;
+
+        *)
+            handle_arguments "$1" "$2"
+            if [[ "$__ShiftArgs" == 1 ]]; then
+                shift
+                __ShiftArgs=0
+            fi
+            ;;
+    esac
+
+    shift
+done
+
+__CommonMSBuildArgs="/p:TargetArchitecture=$__BuildArch /p:Configuration=$__BuildType /p:TargetOS=$__TargetOS /nodeReuse:false $__OfficialBuildIdArg $__SignTypeArg $__SkipRestoreArg"
+
+# Configure environment if we are doing a verbose build
+if [[ "$__VerboseBuild" == 1 ]]; then
+    VERBOSE=1
+    export VERBOSE
+    __CommonMSBuildArgs="$__CommonMSBuildArgs /v:detailed"
+fi
+
+if [[ "$__PortableBuild" == 0 ]]; then
+    __CommonMSBuildArgs="$__CommonMSBuildArgs /p:PortableBuild=false"
+fi
+
+if [[ "$__BuildArch" == wasm ]]; then
+    # nothing to do here
+    true
+elif [[ "$__TargetOS" == iOS || "$__TargetOS" == iOSSimulator ]]; then
+    # nothing to do here
+    true
+elif [[ "$__TargetOS" == tvOS || "$__TargetOS" == tvOSSimulator ]]; then
+    # nothing to do here
+    true
+elif [[ "$__TargetOS" == Android ]]; then
+    # nothing to do here
+    true
+else
+    __CMakeArgs="-DFEATURE_DISTRO_AGNOSTIC_SSL=$__PortableBuild $__CMakeArgs"
+fi
+
+# Configure environment if we are doing a cross compile.
+if [[ "$__CrossBuild" == 1 ]]; then
+    CROSSCOMPILE=1
+    export CROSSCOMPILE
+    # Darwin that doesn't use rootfs
+    if [[ ! -n "$ROOTFS_DIR" && "$platform" != "Darwin" ]]; then
+        ROOTFS_DIR="$__RepoRootDir/.tools/rootfs/$__BuildArch"
+        export ROOTFS_DIR
+    fi
+fi
+
+# init the target distro name
+initTargetDistroRid
diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake
new file mode 100644 (file)
index 0000000..a298574
--- /dev/null
@@ -0,0 +1,701 @@
+include(${CMAKE_CURRENT_LIST_DIR}/configuretools.cmake)
+
+# Set initial flags for each configuration
+
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+set(CMAKE_C_STANDARD 11)
+set(CMAKE_C_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+include(CheckCCompilerFlag)
+include(CheckCXXCompilerFlag)
+
+# "configureoptimization.cmake" must be included after CLR_CMAKE_HOST_UNIX has been set.
+include(${CMAKE_CURRENT_LIST_DIR}/configureoptimization.cmake)
+
+#-----------------------------------------------------
+# Initialize Cmake compiler flags and other variables
+#-----------------------------------------------------
+
+if (CLR_CMAKE_HOST_UNIX)
+    add_compile_options(-g)
+    add_compile_options(-Wall)
+    if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+        add_compile_options(-Wno-null-conversion)
+    else()
+        add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Werror=conversion-null>)
+    endif()
+endif()
+
+if (CMAKE_CONFIGURATION_TYPES) # multi-configuration generator?
+    set(CMAKE_CONFIGURATION_TYPES "Debug;Checked;Release;RelWithDebInfo" CACHE STRING "" FORCE)
+endif (CMAKE_CONFIGURATION_TYPES)
+
+set(CMAKE_C_FLAGS_CHECKED "")
+set(CMAKE_CXX_FLAGS_CHECKED "")
+set(CMAKE_EXE_LINKER_FLAGS_CHECKED "")
+set(CMAKE_SHARED_LINKER_FLAGS_CHECKED "")
+
+set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "")
+set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "")
+set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "")
+set(CMAKE_EXE_LINKER_FLAGS_DEBUG "")
+set(CMAKE_EXE_LINKER_FLAGS_DEBUG "")
+set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "")
+
+add_compile_definitions("$<$<CONFIG:DEBUG>:DEBUG;_DEBUG;_DBG;URTBLDENV_FRIENDLY=Debug;BUILDENV_DEBUG=1>")
+add_compile_definitions("$<$<CONFIG:CHECKED>:DEBUG;_DEBUG;_DBG;URTBLDENV_FRIENDLY=Checked;BUILDENV_CHECKED=1>")
+add_compile_definitions("$<$<OR:$<CONFIG:RELEASE>,$<CONFIG:RELWITHDEBINFO>>:NDEBUG;URTBLDENV_FRIENDLY=Retail>")
+
+if (MSVC)
+  add_linker_flag(/guard:cf)
+
+  # Linker flags
+  #
+  set (WINDOWS_SUBSYSTEM_VERSION 6.01)
+
+  if (CLR_CMAKE_HOST_ARCH_ARM)
+    set(WINDOWS_SUBSYSTEM_VERSION 6.02) #windows subsystem - arm minimum is 6.02
+  elseif(CLR_CMAKE_HOST_ARCH_ARM64)
+    set(WINDOWS_SUBSYSTEM_VERSION 6.03) #windows subsystem - arm64 minimum is 6.03
+  endif ()
+
+  #Do not create Side-by-Side Assembly Manifest
+  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /MANIFEST:NO")
+  # can handle addresses larger than 2 gigabytes
+  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /LARGEADDRESSAWARE")
+  #shrink pdb size
+  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /PDBCOMPRESS")
+
+  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DEBUG")
+  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNORE:4197,4013,4254,4070,4221")
+  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,${WINDOWS_SUBSYSTEM_VERSION}")
+
+  set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /IGNORE:4221")
+
+  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG")
+  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /PDBCOMPRESS")
+  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:1572864")
+
+  # Checked build specific flags
+  add_linker_flag(/INCREMENTAL:NO CHECKED) # prevent "warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:REF' specification"
+  add_linker_flag(/OPT:REF CHECKED)
+  add_linker_flag(/OPT:NOICF CHECKED)
+
+  # Release build specific flags
+  add_linker_flag(/LTCG RELEASE)
+  add_linker_flag(/OPT:REF RELEASE)
+  add_linker_flag(/OPT:ICF RELEASE)
+  add_linker_flag(/INCREMENTAL:NO RELEASE)
+  set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")
+
+  # ReleaseWithDebugInfo build specific flags
+  add_linker_flag(/LTCG RELWITHDEBINFO)
+  add_linker_flag(/OPT:REF RELWITHDEBINFO)
+  add_linker_flag(/OPT:ICF RELWITHDEBINFO)
+  set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")
+
+  # Force uCRT to be dynamically linked for Release build
+  add_linker_flag(/NODEFAULTLIB:libucrt.lib RELEASE)
+  add_linker_flag(/DEFAULTLIB:ucrt.lib RELEASE)
+
+elseif (CLR_CMAKE_HOST_UNIX)
+  # Set the values to display when interactively configuring CMAKE_BUILD_TYPE
+  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "DEBUG;CHECKED;RELEASE;RELWITHDEBINFO")
+
+  # Use uppercase CMAKE_BUILD_TYPE for the string comparisons below
+  string(TOUPPER ${CMAKE_BUILD_TYPE} UPPERCASE_CMAKE_BUILD_TYPE)
+
+  set(CLR_SANITIZE_CXX_OPTIONS "")
+  set(CLR_SANITIZE_LINK_OPTIONS "")
+
+  # set the CLANG sanitizer flags for debug build
+  if(UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL CHECKED)
+    # obtain settings from running enablesanitizers.sh
+    string(FIND "$ENV{DEBUG_SANITIZERS}" "asan" __ASAN_POS)
+    string(FIND "$ENV{DEBUG_SANITIZERS}" "ubsan" __UBSAN_POS)
+    if ((${__ASAN_POS} GREATER -1) OR (${__UBSAN_POS} GREATER -1))
+      list(APPEND CLR_SANITIZE_CXX_OPTIONS -fsanitize-blacklist=${CMAKE_CURRENT_SOURCE_DIR}/sanitizerblacklist.txt)
+      set (CLR_CXX_SANITIZERS "")
+      set (CLR_LINK_SANITIZERS "")
+      if (${__ASAN_POS} GREATER -1)
+        list(APPEND CLR_CXX_SANITIZERS address)
+        list(APPEND CLR_LINK_SANITIZERS address)
+        set(CLR_SANITIZE_CXX_FLAGS "${CLR_SANITIZE_CXX_FLAGS}address,")
+        set(CLR_SANITIZE_LINK_FLAGS "${CLR_SANITIZE_LINK_FLAGS}address,")
+        add_definitions(-DHAS_ASAN)
+        message("Address Sanitizer (asan) enabled")
+      endif ()
+      if (${__UBSAN_POS} GREATER -1)
+        # all sanitizier flags are enabled except alignment (due to heavy use of __unaligned modifier)
+        list(APPEND CLR_CXX_SANITIZERS
+          "bool"
+          bounds
+          enum
+          float-cast-overflow
+          float-divide-by-zero
+          "function"
+          integer
+          nonnull-attribute
+          null
+          object-size
+          "return"
+          returns-nonnull-attribute
+          shift
+          unreachable
+          vla-bound
+          vptr)
+        list(APPEND CLR_LINK_SANITIZERS
+          undefined)
+        message("Undefined Behavior Sanitizer (ubsan) enabled")
+      endif ()
+      list(JOIN CLR_CXX_SANITIZERS "," CLR_CXX_SANITIZERS_OPTIONS)
+      list(APPEND CLR_SANITIZE_CXX_OPTIONS "-fsanitize=${CLR_CXX_SANITIZERS_OPTIONS}")
+      list(JOIN CLR_LINK_SANITIZERS "," CLR_LINK_SANITIZERS_OPTIONS)
+      list(APPEND CLR_SANITIZE_LINK_OPTIONS "-fsanitize=${CLR_LINK_SANITIZERS_OPTIONS}")
+
+      # -fdata-sections -ffunction-sections: each function has own section instead of one per .o file (needed for --gc-sections)
+      # -O1: optimization level used instead of -O0 to avoid compile error "invalid operand for inline asm constraint"
+      add_compile_options("$<$<OR:$<CONFIG:DEBUG>,$<CONFIG:CHECKED>>:${CLR_SANITIZE_CXX_OPTIONS};-fdata-sections;--ffunction-sections;-O1>")
+      add_linker_flag("${CLR_SANITIZE_LINK_OPTIONS}" DEBUG CHECKED)
+      # -Wl and --gc-sections: drop unused sections\functions (similar to Windows /Gy function-level-linking)
+      add_linker_flag("-Wl,--gc-sections" DEBUG CHECKED)
+    endif ()
+  endif(UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL CHECKED)
+
+  if(CLR_CMAKE_HOST_BROWSER)
+    # The emscripten build has additional warnings so -Werror breaks
+    add_compile_options(-Wno-unused-parameter)
+    add_compile_options(-Wno-alloca)
+    add_compile_options(-Wno-implicit-int-float-conversion)
+  endif()
+endif(MSVC)
+
+# CLR_ADDITIONAL_LINKER_FLAGS - used for passing additional arguments to linker
+# CLR_ADDITIONAL_COMPILER_OPTIONS - used for passing additional arguments to compiler
+#
+# For example:
+#       ./build-native.sh cmakeargs "-DCLR_ADDITIONAL_COMPILER_OPTIONS=<...>" cmakeargs "-DCLR_ADDITIONAL_LINKER_FLAGS=<...>"
+#
+if(CLR_CMAKE_HOST_UNIX)
+  foreach(ADDTL_LINKER_FLAG ${CLR_ADDITIONAL_LINKER_FLAGS})
+    add_linker_flag(${ADDTL_LINKER_FLAG})
+  endforeach()
+endif(CLR_CMAKE_HOST_UNIX)
+
+if(CLR_CMAKE_HOST_LINUX)
+  add_compile_options($<$<COMPILE_LANGUAGE:ASM>:-Wa,--noexecstack>)
+  add_linker_flag(-Wl,--build-id=sha1)
+  add_linker_flag(-Wl,-z,relro,-z,now)
+elseif(CLR_CMAKE_HOST_FREEBSD)
+  add_compile_options($<$<COMPILE_LANGUAGE:ASM>:-Wa,--noexecstack>)
+  add_linker_flag("-Wl,--build-id=sha1")
+elseif(CLR_CMAKE_HOST_SUNOS)
+  add_compile_options($<$<COMPILE_LANGUAGE:ASM>:-Wa,--noexecstack>)
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector")
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector")
+  add_definitions(-D__EXTENSIONS__ -D_XPG4_2 -D_POSIX_PTHREAD_SEMANTICS)
+elseif(CLR_CMAKE_HOST_OSX AND NOT CLR_CMAKE_HOST_IOS AND NOT CLR_CMAKE_HOST_TVOS)
+  add_definitions(-D_XOPEN_SOURCE)
+  add_linker_flag("-Wl,-bind_at_load")
+endif()
+
+#------------------------------------
+# Definitions (for platform)
+#-----------------------------------
+if (CLR_CMAKE_HOST_ARCH_AMD64)
+  set(ARCH_HOST_NAME x64)
+  add_definitions(-DHOST_AMD64 -DHOST_64BIT)
+elseif (CLR_CMAKE_HOST_ARCH_I386)
+  set(ARCH_HOST_NAME x86)
+  add_definitions(-DHOST_X86)
+elseif (CLR_CMAKE_HOST_ARCH_ARM)
+  set(ARCH_HOST_NAME arm)
+  add_definitions(-DHOST_ARM)
+elseif (CLR_CMAKE_HOST_ARCH_ARM64)
+  set(ARCH_HOST_NAME arm64)
+  add_definitions(-DHOST_ARM64 -DHOST_64BIT)
+elseif (CLR_CMAKE_HOST_ARCH_S390X)
+  set(ARCH_HOST_NAME s390x)
+  add_definitions(-DHOST_S390X -DHOST_64BIT -DBIGENDIAN)
+elseif (CLR_CMAKE_HOST_ARCH_WASM)
+  set(ARCH_HOST_NAME wasm)
+  add_definitions(-DHOST_WASM -DHOST_32BIT=1)
+elseif (CLR_CMAKE_HOST_ARCH_MIPS64)
+  set(ARCH_HOST_NAME mips64)
+  add_definitions(-DHOST_MIPS64 -DHOST_64BIT=1)
+else ()
+  clr_unknown_arch()
+endif ()
+
+if (CLR_CMAKE_HOST_UNIX)
+  if(CLR_CMAKE_HOST_LINUX)
+    if(CLR_CMAKE_HOST_UNIX_AMD64)
+      message("Detected Linux x86_64")
+    elseif(CLR_CMAKE_HOST_UNIX_ARM)
+      message("Detected Linux ARM")
+    elseif(CLR_CMAKE_HOST_UNIX_ARM64)
+      message("Detected Linux ARM64")
+    elseif(CLR_CMAKE_HOST_UNIX_X86)
+      message("Detected Linux i686")
+    elseif(CLR_CMAKE_HOST_UNIX_S390X)
+      message("Detected Linux s390x")
+    else()
+      clr_unknown_arch()
+    endif()
+  endif(CLR_CMAKE_HOST_LINUX)
+endif(CLR_CMAKE_HOST_UNIX)
+
+if (CLR_CMAKE_HOST_UNIX)
+  add_definitions(-DHOST_UNIX)
+
+  if(CLR_CMAKE_HOST_OSX OR CLR_CMAKE_HOST_MACCATALYST)
+    add_definitions(-DHOST_OSX)
+    if(CLR_CMAKE_HOST_UNIX_AMD64)
+      message("Detected OSX x86_64")
+    elseif(CLR_CMAKE_HOST_UNIX_ARM64)
+      message("Detected OSX ARM64")
+    else()
+      clr_unknown_arch()
+    endif()
+  elseif(CLR_CMAKE_HOST_FREEBSD)
+    message("Detected FreeBSD amd64")
+  elseif(CLR_CMAKE_HOST_NETBSD)
+    message("Detected NetBSD amd64")
+  elseif(CLR_CMAKE_HOST_SUNOS)
+    message("Detected SunOS amd64")
+  endif(CLR_CMAKE_HOST_OSX OR CLR_CMAKE_HOST_MACCATALYST)
+endif(CLR_CMAKE_HOST_UNIX)
+
+if (CLR_CMAKE_HOST_WIN32)
+  add_definitions(-DHOST_WINDOWS)
+
+  # Define the CRT lib references that link into Desktop imports
+  set(STATIC_MT_CRT_LIB  "libcmt$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>.lib")
+  set(STATIC_MT_VCRT_LIB  "libvcruntime$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>.lib")
+  set(STATIC_MT_CPP_LIB  "libcpmt$<$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>:d>.lib")
+endif(CLR_CMAKE_HOST_WIN32)
+
+# Unconditionally define _FILE_OFFSET_BITS as 64 on all platforms.
+add_definitions(-D_FILE_OFFSET_BITS=64)
+
+# Architecture specific files folder name
+if (CLR_CMAKE_TARGET_ARCH_AMD64)
+    set(ARCH_SOURCES_DIR amd64)
+    set(ARCH_TARGET_NAME x64)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_AMD64>)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_64BIT>)
+elseif (CLR_CMAKE_TARGET_ARCH_ARM64)
+    set(ARCH_SOURCES_DIR arm64)
+    set(ARCH_TARGET_NAME arm64)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_ARM64>)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_64BIT>)
+elseif (CLR_CMAKE_TARGET_ARCH_ARM)
+    set(ARCH_SOURCES_DIR arm)
+    set(ARCH_TARGET_NAME arm)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_ARM>)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_32BIT>)
+elseif (CLR_CMAKE_TARGET_ARCH_I386)
+    set(ARCH_TARGET_NAME x86)
+    set(ARCH_SOURCES_DIR i386)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_X86>)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_32BIT>)
+elseif (CLR_CMAKE_TARGET_ARCH_S390X)
+    set(ARCH_TARGET_NAME s390x)
+    set(ARCH_SOURCES_DIR s390x)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_S390X>)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_64BIT>)
+elseif (CLR_CMAKE_TARGET_ARCH_WASM)
+    set(ARCH_TARGET_NAME wasm)
+    set(ARCH_SOURCES_DIR wasm)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_WASM>)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_32BIT>)
+elseif (CLR_CMAKE_TARGET_ARCH_MIPS64)
+    set(ARCH_TARGET_NAME mips64)
+    set(ARCH_SOURCES_DIR mips64)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_MIPS64>)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_ARCH>>>:TARGET_64BIT>)
+else ()
+    clr_unknown_arch()
+endif ()
+
+#--------------------------------------
+# Compile Options
+#--------------------------------------
+if (CLR_CMAKE_HOST_UNIX)
+  # Disable frame pointer optimizations so profilers can get better call stacks
+  add_compile_options(-fno-omit-frame-pointer)
+
+  # The -fms-extensions enable the stuff like __if_exists, __declspec(uuid()), etc.
+  add_compile_options(-fms-extensions)
+  #-fms-compatibility      Enable full Microsoft Visual C++ compatibility
+  #-fms-extensions         Accept some non-standard constructs supported by the Microsoft compiler
+
+  # Make signed arithmetic overflow of addition, subtraction, and multiplication wrap around
+  # using twos-complement representation (this is normally undefined according to the C++ spec).
+  add_compile_options(-fwrapv)
+
+  if(CLR_CMAKE_HOST_OSX OR CLR_CMAKE_HOST_MACCATALYST)
+    # We cannot enable "stack-protector-strong" on OS X due to a bug in clang compiler (current version 7.0.2)
+    add_compile_options(-fstack-protector)
+  elseif(NOT CLR_CMAKE_HOST_BROWSER)
+    check_c_compiler_flag(-fstack-protector-strong COMPILER_SUPPORTS_F_STACK_PROTECTOR_STRONG)
+    if (COMPILER_SUPPORTS_F_STACK_PROTECTOR_STRONG)
+      add_compile_options(-fstack-protector-strong)
+    endif()
+  endif(CLR_CMAKE_HOST_OSX OR CLR_CMAKE_HOST_MACCATALYST)
+
+  # Suppress warnings-as-errors in release branches to reduce servicing churn
+  if (PRERELEASE)
+    add_compile_options(-Werror)
+  endif(PRERELEASE)
+
+  # Disabled common warnings
+  add_compile_options(-Wno-unused-variable)
+  add_compile_options(-Wno-unused-value)
+  add_compile_options(-Wno-unused-function)
+  add_compile_options(-Wno-tautological-compare)
+  add_compile_options(-Wno-unknown-pragmas)
+
+  # Explicitly enabled warnings
+  check_c_compiler_flag(-Wimplicit-fallthrough COMPILER_SUPPORTS_W_IMPLICIT_FALLTHROUGH)
+  if (COMPILER_SUPPORTS_W_IMPLICIT_FALLTHROUGH)
+    add_compile_options(-Wimplicit-fallthrough)
+  endif()
+
+  #These seem to indicate real issues
+  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-invalid-offsetof>)
+
+  add_compile_options(-Wno-unused-but-set-variable)
+
+  if (CMAKE_C_COMPILER_ID MATCHES "Clang")
+    add_compile_options(-Wno-unknown-warning-option)
+
+    # The -ferror-limit is helpful during the porting, it makes sure the compiler doesn't stop
+    # after hitting just about 20 errors.
+    add_compile_options(-ferror-limit=4096)
+
+    # Disabled warnings
+    add_compile_options(-Wno-unused-private-field)
+    # There are constants of type BOOL used in a condition. But BOOL is defined as int
+    # and so the compiler thinks that there is a mistake.
+    add_compile_options(-Wno-constant-logical-operand)
+    # We use pshpack1/2/4/8.h and poppack.h headers to set and restore packing. However
+    # clang 6.0 complains when the packing change lifetime is not contained within
+    # a header file.
+    add_compile_options(-Wno-pragma-pack)
+
+    # The following warning indicates that an attribute __attribute__((__ms_struct__)) was applied
+    # to a struct or a class that has virtual members or a base class. In that case, clang
+    # may not generate the same object layout as MSVC.
+    add_compile_options(-Wno-incompatible-ms-struct)
+
+    add_compile_options(-Wno-reserved-identifier)
+  else()
+    add_compile_options(-Wno-uninitialized)
+    add_compile_options(-Wno-strict-aliasing)
+    add_compile_options(-Wno-array-bounds)
+    add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-class-memaccess>)
+    add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-misleading-indentation>)
+    add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-stringop-overflow>)
+    add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-stringop-truncation>)
+    add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-placement-new>)
+
+    if (CMAKE_CXX_COMPILER_ID)
+      check_cxx_compiler_flag(-faligned-new COMPILER_SUPPORTS_F_ALIGNED_NEW)
+      if (COMPILER_SUPPORTS_F_ALIGNED_NEW)
+        add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-faligned-new>)
+      endif()
+    endif()
+  endif()
+
+  # Some architectures (e.g., ARM) assume char type is unsigned while CoreCLR assumes char is signed
+  # as x64 does. It has been causing issues in ARM (https://github.com/dotnet/runtime/issues/5778)
+  add_compile_options(-fsigned-char)
+
+  # We mark the function which needs exporting with DLLEXPORT
+  add_compile_options(-fvisibility=hidden)
+
+  # Specify the minimum supported version of macOS
+  # Mac Catalyst needs a special CFLAG, exclusive with mmacosx-version-min
+  if(CLR_CMAKE_HOST_MACCATALYST)
+    # Somewhere between CMake 3.17 and 3.19.4, it became impossible to not pass
+    # a value for mmacosx-version-min (blank CMAKE_OSX_DEPLOYMENT_TARGET gets
+    # replaced with a default value, and always gets expanded to an OS version.
+    # https://gitlab.kitware.com/cmake/cmake/-/issues/20132
+    # We need to disable the warning that -tagret replaces -mmacosx-version-min
+    set(DISABLE_OVERRIDING_MIN_VERSION_ERROR -Wno-overriding-t-option)
+    add_link_options(-Wno-overriding-t-option)
+    if(CLR_CMAKE_HOST_ARCH_ARM64)
+      set(MACOS_VERSION_MIN_FLAGS "-target arm64-apple-ios14.2-macabi")
+      add_link_options(-target arm64-apple-ios14.2-macabi)
+    elseif(CLR_CMAKE_HOST_ARCH_AMD64)
+      set(MACOS_VERSION_MIN_FLAGS "-target x86_64-apple-ios13.5-macabi")
+      add_link_options(-target x86_64-apple-ios13.5-macabi)
+    else()
+      clr_unknown_arch()
+    endif()
+    # These options are intentionally set using the CMAKE_XXX_FLAGS instead of
+    # add_compile_options so that they take effect on the configuration functions
+    # in various configure.cmake files.
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MACOS_VERSION_MIN_FLAGS} ${DISABLE_OVERRIDING_MIN_VERSION_ERROR}")
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MACOS_VERSION_MIN_FLAGS} ${DISABLE_OVERRIDING_MIN_VERSION_ERROR}")
+    set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${MACOS_VERSION_MIN_FLAGS} ${DISABLE_OVERRIDING_MIN_VERSION_ERROR}")
+  elseif(CLR_CMAKE_HOST_OSX)
+    if(CLR_CMAKE_HOST_ARCH_ARM64)
+      set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0")
+      add_compile_options(-arch arm64)
+    elseif(CLR_CMAKE_HOST_ARCH_AMD64)
+      set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13")
+      add_compile_options(-arch x86_64)
+    else()
+      clr_unknown_arch()
+    endif()
+  endif(CLR_CMAKE_HOST_MACCATALYST)
+
+endif(CLR_CMAKE_HOST_UNIX)
+
+if(CLR_CMAKE_TARGET_UNIX)
+  add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_UNIX>)
+  # Contracts are disabled on UNIX.
+  add_definitions(-DDISABLE_CONTRACTS)
+  if(CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_OSX>)
+  elseif(CLR_CMAKE_TARGET_FREEBSD)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_FREEBSD>)
+  elseif(CLR_CMAKE_TARGET_ANDROID)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_ANDROID>)
+  elseif(CLR_CMAKE_TARGET_LINUX)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_LINUX>)
+  elseif(CLR_CMAKE_TARGET_NETBSD)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_NETBSD>)
+  elseif(CLR_CMAKE_TARGET_SUNOS)
+    add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_SUNOS>)
+  endif()
+else(CLR_CMAKE_TARGET_UNIX)
+  add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:IGNORE_DEFAULT_TARGET_OS>>>:TARGET_WINDOWS>)
+endif(CLR_CMAKE_TARGET_UNIX)
+
+if(CLR_CMAKE_HOST_UNIX_ARM)
+   if (NOT DEFINED CLR_ARM_FPU_TYPE)
+     set(CLR_ARM_FPU_TYPE vfpv3)
+   endif(NOT DEFINED CLR_ARM_FPU_TYPE)
+
+   # 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(-mthumb)
+   add_compile_options(-mfpu=${CLR_ARM_FPU_TYPE})
+   if (NOT DEFINED CLR_ARM_FPU_CAPABILITY)
+     set(CLR_ARM_FPU_CAPABILITY 0x7)
+   endif(NOT DEFINED CLR_ARM_FPU_CAPABILITY)
+   add_definitions(-DCLR_ARM_FPU_CAPABILITY=${CLR_ARM_FPU_CAPABILITY})
+   add_compile_options(-march=armv7-a)
+   if(ARM_SOFTFP)
+     add_definitions(-DARM_SOFTFP)
+     add_compile_options(-mfloat-abi=softfp)
+   endif(ARM_SOFTFP)
+endif(CLR_CMAKE_HOST_UNIX_ARM)
+
+if(CLR_CMAKE_HOST_UNIX_X86)
+  add_compile_options(-msse2)
+endif()
+
+if(CLR_CMAKE_HOST_UNIX)
+  add_compile_options(${CLR_ADDITIONAL_COMPILER_OPTIONS})
+endif(CLR_CMAKE_HOST_UNIX)
+
+if (MSVC)
+  # Compile options for targeting windows
+
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/nologo>) # Suppress Startup Banner
+  # /W3 is added by default by CMake, so remove it
+  string(REPLACE "/W3" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+  string(REPLACE "/W3" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+  # set default warning level to 3 but allow targets to override it.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/W$<GENEX_EVAL:$<IF:$<BOOL:$<TARGET_PROPERTY:MSVC_WARNING_LEVEL>>,$<TARGET_PROPERTY:MSVC_WARNING_LEVEL>,3>>>)
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/WX>) # treat warnings as errors
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Oi>) # enable intrinsics
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Oy->) # disable suppressing of the creation of frame pointers on the call stack for quicker function calls
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Gm->) # disable minimal rebuild
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Zp8>) # pack structs on 8-byte boundary
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Gy>) # separate functions for linker
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/GS>) # Explicitly enable the buffer security checks
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/fp:precise>) # Enable precise floating point
+
+  # disable C++ RTTI
+  # /GR is added by default by CMake, so remove it manually.
+  string(REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")
+
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/FC>) # use full pathnames in diagnostics
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/MP>) # Build with Multiple Processes (number of processes equal to the number of processors)
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Zm200>) # Specify Precompiled Header Memory Allocation Limit of 150MB
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Zc:strictStrings>) # Disable string-literal to char* or wchar_t* conversion
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Zc:wchar_t>) # wchar_t is a built-in type.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Zc:inline>) # All inline functions must have their definition available in the current translation unit.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Zc:forScope>) # Enforce standards-compliant for scope.
+
+  # Disable Warnings:
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4065>) # switch statement contains 'default' but no 'case' labels
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4100>) # 'identifier' : unreferenced formal parameter
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4127>) # conditional expression is constant
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4189>) # local variable is initialized but not referenced
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4200>) # nonstandard extension used : zero-sized array in struct/union
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4201>) # nonstandard extension used : nameless struct/union
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4245>) # conversion from 'type1' to 'type2', signed/unsigned mismatch
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4291>) # no matching operator delete found; memory will not be freed if initialization throws an exception
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4456>) # declaration of 'identifier' hides previous local declaration
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4457>) # declaration of 'identifier' hides function parameter
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4458>) # declaration of 'identifier' hides class member
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4733>) # Inline asm assigning to 'FS:0' : handler not registered as safe handler
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4838>) # conversion from 'type_1' to 'type_2' requires a narrowing conversion
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4960>) # 'function' is too big to be profiled
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd4961>) # No profile data was merged into '.pgd file', profile-guided optimizations disabled
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/wd5105>) # macro expansion producing 'defined' has undefined behavior
+
+  # Treat Warnings as Errors:
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4007>) # 'main' : must be __cdecl.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4013>) # 'function' undefined - assuming extern returning int.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4102>) # "'%$S' : unreferenced label".
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4551>) # Function call missing argument list.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4700>) # Local used w/o being initialized.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4640>) # 'instance' : construction of local static object is not thread-safe
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4806>) # Unsafe operation involving type 'bool'.
+
+  # Set Warning Level 3:
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w34092>) # Sizeof returns 'unsigned long'.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w34121>) # Structure is sensitive to alignment.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w34125>) # Decimal digit in octal sequence.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w34130>) # Logical operation on address of string constant.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w34132>) # Const object should be initialized.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w34212>) # Function declaration used ellipsis.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w34530>) # C++ exception handler used, but unwind semantics are not enabled. Specify -GX.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w35038>) # data member 'member1' will be initialized after data member 'member2'.
+
+  # Set Warning Level 4:
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/w44177>) # Pragma data_seg s/b at global scope.
+
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Zi>) # enable debugging information
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/ZH:SHA_256>) # use SHA256 for generating hashes of compiler processed source files.
+  add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/source-charset:utf-8>) # Force MSVC to compile source as UTF-8.
+
+  if (CLR_CMAKE_HOST_ARCH_I386)
+    add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/Gz>)
+  endif (CLR_CMAKE_HOST_ARCH_I386)
+
+  add_compile_options($<$<AND:$<COMPILE_LANGUAGE:C,CXX>,$<OR:$<CONFIG:Release>,$<CONFIG:Relwithdebinfo>>>:/GL>)
+
+  if (CLR_CMAKE_HOST_ARCH_AMD64)
+    # The generator expression in the following command means that the /homeparams option is added only for debug builds for C and C++ source files
+    add_compile_options($<$<AND:$<CONFIG:Debug>,$<COMPILE_LANGUAGE:C,CXX>>:/homeparams>) # Force parameters passed in registers to be written to the stack
+  endif (CLR_CMAKE_HOST_ARCH_AMD64)
+
+  # enable control-flow-guard support for native components for non-Arm64 builds
+  # Added using variables instead of add_compile_options to let individual projects override it
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /guard:cf")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /guard:cf")
+
+  # Enable EH-continuation table and CET-compatibility for native components for amd64 builds except for components of the Mono
+  # runtime. Added some switches using variables instead of add_compile_options to let individual projects override it.
+  if (CLR_CMAKE_HOST_ARCH_AMD64 AND NOT CLR_CMAKE_RUNTIME_MONO)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /guard:ehcont")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /guard:ehcont")
+    set(CMAKE_ASM_MASM_FLAGS "${CMAKE_ASM_MASM_FLAGS} /guard:ehcont")
+    add_linker_flag(/guard:ehcont)
+    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /CETCOMPAT")
+  endif (CLR_CMAKE_HOST_ARCH_AMD64 AND NOT CLR_CMAKE_RUNTIME_MONO)
+
+  # Statically linked CRT (libcmt[d].lib, libvcruntime[d].lib and libucrt[d].lib) by default. This is done to avoid
+  # linking in VCRUNTIME140.DLL for a simplified xcopy experience by reducing the dependency on VC REDIST.
+  #
+  # For Release builds, we shall dynamically link into uCRT [ucrtbase.dll] (which is pushed down as a Windows Update on downlevel OS) but
+  # wont do the same for debug/checked builds since ucrtbased.dll is not redistributable and Debug/Checked builds are not
+  # production-time scenarios.
+  set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$<AND:$<OR:$<CONFIG:Debug>,$<CONFIG:Checked>>,$<NOT:$<BOOL:$<TARGET_PROPERTY:DAC_COMPONENT>>>>:Debug>)
+
+  add_compile_options($<$<COMPILE_LANGUAGE:ASM_MASM>:/ZH:SHA_256>)
+
+  if (CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64)
+    # Contracts work too slow on ARM/ARM64 DEBUG/CHECKED.
+    add_definitions(-DDISABLE_CONTRACTS)
+  endif (CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64)
+
+  # Don't display the output header when building RC files.
+  add_compile_options($<$<COMPILE_LANGUAGE:RC>:/nologo>)
+endif (MSVC)
+
+if(CLR_CMAKE_ENABLE_CODE_COVERAGE)
+
+  if(CLR_CMAKE_HOST_UNIX)
+    string(TOUPPER ${CMAKE_BUILD_TYPE} UPPERCASE_CMAKE_BUILD_TYPE)
+    if(NOT UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG)
+      message( WARNING "Code coverage results with an optimised (non-Debug) build may be misleading" )
+    endif(NOT UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG)
+
+    add_compile_options(-fprofile-arcs)
+    add_compile_options(-ftest-coverage)
+    add_linker_flag(--coverage)
+  else()
+    message(FATAL_ERROR "Code coverage builds not supported on current platform")
+  endif(CLR_CMAKE_HOST_UNIX)
+
+endif(CLR_CMAKE_ENABLE_CODE_COVERAGE)
+
+if (CMAKE_GENERATOR MATCHES "(Makefile|Ninja)")
+  set(CMAKE_RC_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
+endif()
+
+# Ensure other tools are present
+if (CLR_CMAKE_HOST_WIN32)
+    if(CLR_CMAKE_HOST_ARCH_ARM)
+
+      # Explicitly specify the assembler to be used for Arm32 compile
+      file(TO_CMAKE_PATH "$ENV{VCToolsInstallDir}\\bin\\HostX86\\arm\\armasm.exe" CMAKE_ASM_COMPILER)
+
+      set(CMAKE_ASM_MASM_COMPILER ${CMAKE_ASM_COMPILER})
+      message("CMAKE_ASM_MASM_COMPILER explicitly set to: ${CMAKE_ASM_MASM_COMPILER}")
+
+      # Enable generic assembly compilation to avoid CMake generate VS proj files that explicitly
+      # use ml[64].exe as the assembler.
+      enable_language(ASM)
+      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded         "")
+      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL      "")
+      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug    "")
+      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
+      set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -g <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
+
+    elseif(CLR_CMAKE_HOST_ARCH_ARM64)
+
+      # Explicitly specify the assembler to be used for Arm64 compile
+      file(TO_CMAKE_PATH "$ENV{VCToolsInstallDir}\\bin\\HostX86\\arm64\\armasm64.exe" CMAKE_ASM_COMPILER)
+
+      set(CMAKE_ASM_MASM_COMPILER ${CMAKE_ASM_COMPILER})
+      message("CMAKE_ASM_MASM_COMPILER explicitly set to: ${CMAKE_ASM_MASM_COMPILER}")
+
+      # Enable generic assembly compilation to avoid CMake generate VS proj files that explicitly
+      # use ml[64].exe as the assembler.
+      enable_language(ASM)
+      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded         "")
+      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL      "")
+      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug    "")
+      set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
+      set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -g <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
+    else()
+      enable_language(ASM_MASM)
+      set(CMAKE_ASM_MASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded         "")
+      set(CMAKE_ASM_MASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL      "")
+      set(CMAKE_ASM_MASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug    "")
+      set(CMAKE_ASM_MASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
+    endif()
+
+    # Ensure that MC is present
+    find_program(MC mc)
+    if (MC STREQUAL "MC-NOTFOUND")
+        message(FATAL_ERROR "MC not found")
+    endif()
+
+elseif (NOT CLR_CMAKE_HOST_BROWSER)
+    enable_language(ASM)
+
+endif(CLR_CMAKE_HOST_WIN32)
diff --git a/eng/native/configureoptimization.cmake b/eng/native/configureoptimization.cmake
new file mode 100644 (file)
index 0000000..50c7b1c
--- /dev/null
@@ -0,0 +1,17 @@
+if(CLR_CMAKE_HOST_WIN32)
+    add_compile_options($<$<AND:$<COMPILE_LANGUAGE:C,CXX>,$<CONFIG:Debug>>:/Od>)
+    if (CLR_CMAKE_HOST_ARCH_I386)
+        # The Windows x86 Checked CLR has some kind of problem with exception handling
+        # when compiled with /O2. Issue: https://github.com/dotnet/runtime/issues/59845.
+        add_compile_options($<$<AND:$<COMPILE_LANGUAGE:C,CXX>,$<CONFIG:Checked>>:/O1>)
+    else()
+        add_compile_options($<$<AND:$<COMPILE_LANGUAGE:C,CXX>,$<CONFIG:Checked>>:/O2>)
+    endif()
+    add_compile_options($<$<AND:$<COMPILE_LANGUAGE:C,CXX>,$<CONFIG:Release>>:/Ox>)
+    add_compile_options($<$<AND:$<COMPILE_LANGUAGE:C,CXX>,$<CONFIG:RelWithDebInfo>>:/O2>)
+elseif(CLR_CMAKE_HOST_UNIX)
+    add_compile_options($<$<CONFIG:Debug>:-O0>)
+    add_compile_options($<$<CONFIG:Checked>:-O2>)
+    add_compile_options($<$<CONFIG:Release>:-O3>)
+    add_compile_options($<$<CONFIG:RelWithDebInfo>:-O2>)
+endif()
diff --git a/eng/native/configurepaths.cmake b/eng/native/configurepaths.cmake
new file mode 100644 (file)
index 0000000..19407a4
--- /dev/null
@@ -0,0 +1,9 @@
+get_filename_component(CLR_REPO_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../.. ABSOLUTE)
+set(CLR_ENG_NATIVE_DIR ${CMAKE_CURRENT_LIST_DIR})
+get_filename_component(CLR_SRC_NATIVE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../src/native ABSOLUTE)
+get_filename_component(CLR_SRC_LIBS_NATIVE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../src/libraries/Native ABSOLUTE)
+set (CLR_ARTIFACTS_OBJ_DIR "${CLR_REPO_ROOT_DIR}/artifacts/obj")
+set(VERSION_HEADER_PATH "${CLR_ARTIFACTS_OBJ_DIR}/_version.h")
+set(VERSION_FILE_PATH "${CLR_ARTIFACTS_OBJ_DIR}/_version.c")
+set(VERSION_FILE_RC_PATH "${CLR_ARTIFACTS_OBJ_DIR}/NativeVersion.rc")
+set(RUNTIME_VERSION_HEADER_PATH "${CLR_ARTIFACTS_OBJ_DIR}/runtime_version.h")
diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake
new file mode 100644 (file)
index 0000000..f5c8abe
--- /dev/null
@@ -0,0 +1,427 @@
+include(${CMAKE_CURRENT_LIST_DIR}/functions.cmake)
+
+# If set, indicates that this is not an officially supported release
+# Keep in sync with IsPrerelease in Directory.Build.props
+set(PRERELEASE 1)
+
+#----------------------------------------
+# Detect and set platform variable names
+#     - for non-windows build platform & architecture is detected using inbuilt CMAKE variables and cross target component configure
+#     - for windows we use the passed in parameter to CMAKE to determine build arch
+#----------------------------------------
+set(CLR_CMAKE_HOST_OS ${CMAKE_SYSTEM_NAME})
+if(CLR_CMAKE_HOST_OS STREQUAL Linux)
+    set(CLR_CMAKE_HOST_UNIX 1)
+    if(CLR_CROSS_COMPONENTS_BUILD)
+        # CMAKE_HOST_SYSTEM_PROCESSOR returns the value of `uname -p` on host.
+        if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL amd64)
+            if(CLR_CMAKE_TARGET_ARCH STREQUAL "arm" OR CLR_CMAKE_TARGET_ARCH STREQUAL "armel")
+                if(CMAKE_CROSSCOMPILING)
+                    set(CLR_CMAKE_HOST_UNIX_X86 1)
+                else()
+                    set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+                endif()
+            else()
+                set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+            endif()
+        elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL i686)
+            set(CLR_CMAKE_HOST_UNIX_X86 1)
+        else()
+            clr_unknown_arch()
+        endif()
+    else()
+        # CMAKE_SYSTEM_PROCESSOR returns the value of `uname -p` on target.
+        # For the AMD/Intel 64bit architecture two different strings are common.
+        # Linux and Darwin identify it as "x86_64" while FreeBSD and netbsd uses the
+        # "amd64" string. Accept either of the two here.
+        if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL amd64)
+            set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+        elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l)
+            set(CLR_CMAKE_HOST_UNIX_ARM 1)
+            set(CLR_CMAKE_HOST_UNIX_ARMV7L 1)
+        elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL arm OR CMAKE_SYSTEM_PROCESSOR STREQUAL armv7-a)
+            set(CLR_CMAKE_HOST_UNIX_ARM 1)
+        elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL arm64)
+            set(CLR_CMAKE_HOST_UNIX_ARM64 1)
+        elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL i686 OR CMAKE_SYSTEM_PROCESSOR STREQUAL x86)
+            set(CLR_CMAKE_HOST_UNIX_X86 1)
+        elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL s390x)
+            set(CLR_CMAKE_HOST_UNIX_S390X 1)
+        elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL mips64)
+            set(CLR_CMAKE_HOST_UNIX_MIPS64 1)
+        else()
+            clr_unknown_arch()
+        endif()
+    endif()
+    set(CLR_CMAKE_HOST_LINUX 1)
+
+    # Detect Linux ID
+    set(LINUX_ID_FILE "/etc/os-release")
+    if(CMAKE_CROSSCOMPILING)
+        set(LINUX_ID_FILE "${CMAKE_SYSROOT}${LINUX_ID_FILE}")
+    endif()
+
+    if(EXISTS ${LINUX_ID_FILE})
+        execute_process(
+            COMMAND bash -c "source ${LINUX_ID_FILE} && echo \$ID"
+            OUTPUT_VARIABLE CLR_CMAKE_LINUX_ID
+            OUTPUT_STRIP_TRAILING_WHITESPACE)
+    endif()
+
+    if(DEFINED CLR_CMAKE_LINUX_ID)
+        if(CLR_CMAKE_LINUX_ID STREQUAL tizen)
+            set(CLR_CMAKE_TARGET_TIZEN_LINUX 1)
+            set(CLR_CMAKE_HOST_OS ${CLR_CMAKE_LINUX_ID})
+        elseif(CLR_CMAKE_LINUX_ID STREQUAL alpine)
+            set(CLR_CMAKE_HOST_ALPINE_LINUX 1)
+            set(CLR_CMAKE_HOST_OS ${CLR_CMAKE_LINUX_ID})
+        endif()
+    endif(DEFINED CLR_CMAKE_LINUX_ID)
+endif(CLR_CMAKE_HOST_OS STREQUAL Linux)
+
+if(CLR_CMAKE_HOST_OS STREQUAL Darwin)
+    set(CLR_CMAKE_HOST_UNIX 1)
+
+    if(CMAKE_SYSTEM_VARIANT STREQUAL MacCatalyst)
+      set(CLR_CMAKE_HOST_MACCATALYST 1)
+    else()
+      set(CLR_CMAKE_HOST_OSX 1)
+    endif(CMAKE_SYSTEM_VARIANT STREQUAL MacCatalyst)
+
+    if(CMAKE_OSX_ARCHITECTURES STREQUAL x86_64)
+        set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+    elseif(CMAKE_OSX_ARCHITECTURES STREQUAL arm64)
+        set(CLR_CMAKE_HOST_UNIX_ARM64 1)
+    else()
+        clr_unknown_arch()
+    endif()
+    set(CMAKE_ASM_COMPILE_OBJECT "${CMAKE_C_COMPILER} <FLAGS> <DEFINES> <INCLUDES> -o <OBJECT> -c <SOURCE>")
+endif(CLR_CMAKE_HOST_OS STREQUAL Darwin)
+
+if(CLR_CMAKE_HOST_OS STREQUAL iOS OR CLR_CMAKE_HOST_OS STREQUAL iOSSimulator)
+    set(CLR_CMAKE_HOST_UNIX 1)
+    set(CLR_CMAKE_HOST_IOS 1)
+    if(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
+        set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+    elseif(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
+        set(CLR_CMAKE_HOST_UNIX_X86 1)
+    elseif(CMAKE_OSX_ARCHITECTURES MATCHES "armv7")
+        set(CLR_CMAKE_HOST_UNIX_ARM 1)
+    elseif(CMAKE_OSX_ARCHITECTURES MATCHES "arm64")
+        set(CLR_CMAKE_HOST_UNIX_ARM64 1)
+    else()
+        clr_unknown_arch()
+    endif()
+endif(CLR_CMAKE_HOST_OS STREQUAL iOS OR CLR_CMAKE_HOST_OS STREQUAL iOSSimulator)
+
+if(CLR_CMAKE_HOST_OS STREQUAL tvOS OR CLR_CMAKE_HOST_OS STREQUAL tvOSSimulator)
+    set(CLR_CMAKE_HOST_UNIX 1)
+    set(CLR_CMAKE_HOST_TVOS 1)
+    if(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
+        set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+    elseif(CMAKE_OSX_ARCHITECTURES MATCHES "arm64")
+        set(CLR_CMAKE_HOST_UNIX_ARM64 1)
+    else()
+        clr_unknown_arch()
+    endif()
+endif(CLR_CMAKE_HOST_OS STREQUAL tvOS OR CLR_CMAKE_HOST_OS STREQUAL tvOSSimulator)
+
+if(CLR_CMAKE_HOST_OS STREQUAL Android)
+    set(CLR_CMAKE_HOST_UNIX 1)
+    set(CLR_CMAKE_HOST_LINUX 1)
+    set(CLR_CMAKE_HOST_ANDROID 1)
+    if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
+        set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7-a)
+        set(CLR_CMAKE_HOST_UNIX_ARM 1)
+    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
+        set(CLR_CMAKE_HOST_UNIX_ARM64 1)
+    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL i686)
+        set(CLR_CMAKE_HOST_UNIX_X86 1)
+    else()
+        clr_unknown_arch()
+    endif()
+endif(CLR_CMAKE_HOST_OS STREQUAL Android)
+
+if(CLR_CMAKE_HOST_OS STREQUAL FreeBSD)
+    set(CLR_CMAKE_HOST_UNIX 1)
+    set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+    set(CLR_CMAKE_HOST_FREEBSD 1)
+endif(CLR_CMAKE_HOST_OS STREQUAL FreeBSD)
+
+if(CLR_CMAKE_HOST_OS STREQUAL OpenBSD)
+    set(CLR_CMAKE_HOST_UNIX 1)
+    set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+    set(CLR_CMAKE_HOST_OPENBSD 1)
+endif(CLR_CMAKE_HOST_OS STREQUAL OpenBSD)
+
+if(CLR_CMAKE_HOST_OS STREQUAL NetBSD)
+    set(CLR_CMAKE_HOST_UNIX 1)
+    set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+    set(CLR_CMAKE_HOST_NETBSD 1)
+endif(CLR_CMAKE_HOST_OS STREQUAL NetBSD)
+
+if(CLR_CMAKE_HOST_OS STREQUAL SunOS)
+    set(CLR_CMAKE_HOST_UNIX 1)
+    EXECUTE_PROCESS(
+        COMMAND isainfo -n
+        OUTPUT_VARIABLE SUNOS_NATIVE_INSTRUCTION_SET)
+
+    if(SUNOS_NATIVE_INSTRUCTION_SET MATCHES "amd64" OR CMAKE_CROSSCOMPILING)
+        set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+        set(CMAKE_SYSTEM_PROCESSOR "amd64")
+    else()
+        clr_unknown_arch()
+    endif()
+
+    EXECUTE_PROCESS(
+        COMMAND uname -o
+        OUTPUT_VARIABLE SUNOS_KERNEL_KIND
+        ERROR_QUIET)
+
+    set(CLR_CMAKE_HOST_SUNOS 1)
+    if(SUNOS_KERNEL_KIND STREQUAL illumos OR CMAKE_CROSSCOMPILING)
+        set(CLR_CMAKE_HOST_OS_ILLUMOS 1)
+    else(SUNOS_KERNEL_KIND STREQUAL illumos OR CMAKE_CROSSCOMPILING)
+        set(CLR_CMAKE_HOST_OS_SOLARIS 1)
+    endif(SUNOS_KERNEL_KIND STREQUAL illumos OR CMAKE_CROSSCOMPILING)
+endif(CLR_CMAKE_HOST_OS STREQUAL SunOS)
+
+if(CLR_CMAKE_HOST_OS STREQUAL Windows)
+    set(CLR_CMAKE_HOST_OS windows)
+    set(CLR_CMAKE_HOST_WIN32 1)
+endif(CLR_CMAKE_HOST_OS STREQUAL Windows)
+
+if(CLR_CMAKE_HOST_OS STREQUAL Emscripten)
+    set(CLR_CMAKE_HOST_UNIX 1)
+    set(CLR_CMAKE_HOST_BROWSER 1)
+endif(CLR_CMAKE_HOST_OS STREQUAL Emscripten)
+
+#--------------------------------------------
+# This repo builds two set of binaries
+# 1. binaries which execute on target arch machine
+#        - for such binaries host architecture & target architecture are same
+#        - eg. coreclr.dll
+# 2. binaries which execute on host machine but target another architecture
+#        - host architecture is different from target architecture
+#        - eg. crossgen.exe - runs on x64 machine and generates nis targeting arm64
+#        - for complete list of such binaries refer to file crosscomponents.cmake
+#-------------------------------------------------------------
+# Set HOST architecture variables
+if(CLR_CMAKE_HOST_UNIX_ARM)
+    set(CLR_CMAKE_HOST_ARCH_ARM 1)
+    set(CLR_CMAKE_HOST_ARCH "arm")
+
+    if(CLR_CMAKE_HOST_UNIX_ARMV7L)
+        set(CLR_CMAKE_HOST_ARCH_ARMV7L 1)
+    endif()
+elseif(CLR_CMAKE_HOST_UNIX_ARM64)
+    set(CLR_CMAKE_HOST_ARCH_ARM64 1)
+    set(CLR_CMAKE_HOST_ARCH "arm64")
+elseif(CLR_CMAKE_HOST_UNIX_AMD64)
+    set(CLR_CMAKE_HOST_ARCH_AMD64 1)
+    set(CLR_CMAKE_HOST_ARCH "x64")
+elseif(CLR_CMAKE_HOST_UNIX_X86)
+    set(CLR_CMAKE_HOST_ARCH_I386 1)
+    set(CLR_CMAKE_HOST_ARCH "x86")
+elseif(CLR_CMAKE_HOST_UNIX_S390X)
+    set(CLR_CMAKE_HOST_ARCH_S390X 1)
+    set(CLR_CMAKE_HOST_ARCH "s390x")
+elseif(CLR_CMAKE_HOST_BROWSER)
+    set(CLR_CMAKE_HOST_ARCH_WASM 1)
+    set(CLR_CMAKE_HOST_ARCH "wasm")
+elseif(CLR_CMAKE_HOST_UNIX_MIPS64)
+    set(CLR_CMAKE_HOST_ARCH_MIPS64 1)
+    set(CLR_CMAKE_HOST_ARCH "mips64")
+elseif(WIN32)
+    # CLR_CMAKE_HOST_ARCH is passed in as param to cmake
+    if (CLR_CMAKE_HOST_ARCH STREQUAL x64)
+        set(CLR_CMAKE_HOST_ARCH_AMD64 1)
+    elseif(CLR_CMAKE_HOST_ARCH STREQUAL x86)
+        set(CLR_CMAKE_HOST_ARCH_I386 1)
+    elseif(CLR_CMAKE_HOST_ARCH STREQUAL arm)
+        set(CLR_CMAKE_HOST_ARCH_ARM 1)
+    elseif(CLR_CMAKE_HOST_ARCH STREQUAL arm64)
+        set(CLR_CMAKE_HOST_ARCH_ARM64 1)
+    else()
+        clr_unknown_arch()
+    endif()
+endif()
+
+# Set TARGET architecture variables
+# Target arch will be a cmake param (optional) for both windows as well as non-windows build
+# if target arch is not specified then host & target are same
+if(NOT DEFINED CLR_CMAKE_TARGET_ARCH OR CLR_CMAKE_TARGET_ARCH STREQUAL "" )
+  set(CLR_CMAKE_TARGET_ARCH ${CLR_CMAKE_HOST_ARCH})
+
+  # This is required for "arm" targets (CMAKE_SYSTEM_PROCESSOR "armv7l"),
+  # for which this flag otherwise won't be set up below
+  if (CLR_CMAKE_HOST_ARCH_ARMV7L)
+    set(CLR_CMAKE_TARGET_ARCH_ARMV7L 1)
+  endif()
+endif()
+
+# Set target architecture variables
+if (CLR_CMAKE_TARGET_ARCH STREQUAL x64)
+    set(CLR_CMAKE_TARGET_ARCH_AMD64 1)
+  elseif(CLR_CMAKE_TARGET_ARCH STREQUAL x86)
+    set(CLR_CMAKE_TARGET_ARCH_I386 1)
+  elseif(CLR_CMAKE_TARGET_ARCH STREQUAL arm64)
+    set(CLR_CMAKE_TARGET_ARCH_ARM64 1)
+  elseif(CLR_CMAKE_TARGET_ARCH STREQUAL arm)
+    set(CLR_CMAKE_TARGET_ARCH_ARM 1)
+  elseif(CLR_CMAKE_TARGET_ARCH STREQUAL armel)
+    set(CLR_CMAKE_TARGET_ARCH_ARM 1)
+    set(CLR_CMAKE_TARGET_ARCH_ARMV7L 1)
+    set(ARM_SOFTFP 1)
+  elseif(CLR_CMAKE_TARGET_ARCH STREQUAL s390x)
+    set(CLR_CMAKE_TARGET_ARCH_S390X 1)
+  elseif(CLR_CMAKE_TARGET_ARCH STREQUAL wasm)
+    set(CLR_CMAKE_TARGET_ARCH_WASM 1)
+  elseif(CLR_CMAKE_TARGET_ARCH STREQUAL mips64)
+    set(CLR_CMAKE_TARGET_ARCH_MIPS64 1)
+  else()
+    clr_unknown_arch()
+endif()
+
+# Set TARGET architecture variables
+# Target os will be a cmake param (optional) for both windows as well as non-windows build
+# if target os is not specified then host & target os are same
+if (NOT DEFINED CLR_CMAKE_TARGET_OS OR CLR_CMAKE_TARGET_OS STREQUAL "" )
+  set(CLR_CMAKE_TARGET_OS ${CLR_CMAKE_HOST_OS})
+endif()
+
+if(CLR_CMAKE_TARGET_OS STREQUAL Linux)
+    set(CLR_CMAKE_TARGET_UNIX 1)
+    set(CLR_CMAKE_TARGET_LINUX 1)
+endif(CLR_CMAKE_TARGET_OS STREQUAL Linux)
+
+if(CLR_CMAKE_TARGET_OS STREQUAL tizen)
+    set(CLR_CMAKE_TARGET_UNIX 1)
+    set(CLR_CMAKE_TARGET_LINUX 1)
+    set(CLR_CMAKE_TARGET_TIZEN_LINUX 1)
+endif(CLR_CMAKE_TARGET_OS STREQUAL tizen)
+
+if(CLR_CMAKE_TARGET_OS STREQUAL alpine)
+    set(CLR_CMAKE_TARGET_UNIX 1)
+    set(CLR_CMAKE_TARGET_LINUX 1)
+    set(CLR_CMAKE_TARGET_ALPINE_LINUX 1)
+endif(CLR_CMAKE_TARGET_OS STREQUAL alpine)
+
+if(CLR_CMAKE_TARGET_OS STREQUAL Android)
+    set(CLR_CMAKE_TARGET_UNIX 1)
+    set(CLR_CMAKE_TARGET_LINUX 1)
+    set(CLR_CMAKE_TARGET_ANDROID 1)
+endif(CLR_CMAKE_TARGET_OS STREQUAL Android)
+
+if(CLR_CMAKE_TARGET_OS STREQUAL Darwin)
+    set(CLR_CMAKE_TARGET_UNIX 1)
+
+    if(CMAKE_SYSTEM_VARIANT STREQUAL MacCatalyst)
+        set(CLR_CMAKE_TARGET_MACCATALYST 1)
+    else()
+        set(CLR_CMAKE_TARGET_OSX 1)
+    endif(CMAKE_SYSTEM_VARIANT STREQUAL MacCatalyst)
+endif(CLR_CMAKE_TARGET_OS STREQUAL Darwin)
+
+if(CLR_CMAKE_TARGET_OS STREQUAL iOS OR CLR_CMAKE_TARGET_OS STREQUAL iOSSimulator)
+    set(CLR_CMAKE_TARGET_UNIX 1)
+    set(CLR_CMAKE_TARGET_IOS 1)
+endif(CLR_CMAKE_TARGET_OS STREQUAL iOS OR CLR_CMAKE_TARGET_OS STREQUAL iOSSimulator)
+
+if(CLR_CMAKE_TARGET_OS STREQUAL tvOS OR CLR_CMAKE_TARGET_OS STREQUAL tvOSSimulator)
+    set(CLR_CMAKE_TARGET_UNIX 1)
+    set(CLR_CMAKE_TARGET_TVOS 1)
+endif(CLR_CMAKE_TARGET_OS STREQUAL tvOS OR CLR_CMAKE_TARGET_OS STREQUAL tvOSSimulator)
+
+if(CLR_CMAKE_TARGET_OS STREQUAL FreeBSD)
+    set(CLR_CMAKE_TARGET_UNIX 1)
+    set(CLR_CMAKE_TARGET_FREEBSD 1)
+endif(CLR_CMAKE_TARGET_OS STREQUAL FreeBSD)
+
+if(CLR_CMAKE_TARGET_OS STREQUAL OpenBSD)
+    set(CLR_CMAKE_TARGET_UNIX 1)
+    set(CLR_CMAKE_TARGET_OPENBSD 1)
+endif(CLR_CMAKE_TARGET_OS STREQUAL OpenBSD)
+
+if(CLR_CMAKE_TARGET_OS STREQUAL NetBSD)
+    set(CLR_CMAKE_TARGET_UNIX 1)
+    set(CLR_CMAKE_TARGET_NETBSD 1)
+endif(CLR_CMAKE_TARGET_OS STREQUAL NetBSD)
+
+if(CLR_CMAKE_TARGET_OS STREQUAL SunOS)
+    set(CLR_CMAKE_TARGET_UNIX 1)
+    if(CLR_CMAKE_HOST_OS_ILLUMOS)
+        set(CLR_CMAKE_TARGET_OS_ILLUMOS 1)
+    else(CLR_CMAKE_HOST_OS_ILLUMOS)
+        set(CLR_CMAKE_TARGET_OS_SOLARIS 1)
+    endif(CLR_CMAKE_HOST_OS_ILLUMOS)
+    set(CLR_CMAKE_TARGET_SUNOS 1)
+endif(CLR_CMAKE_TARGET_OS STREQUAL SunOS)
+
+if(CLR_CMAKE_TARGET_OS STREQUAL Emscripten)
+    set(CLR_CMAKE_TARGET_UNIX 1)
+    set(CLR_CMAKE_TARGET_LINUX 1)
+    set(CLR_CMAKE_TARGET_BROWSER 1)
+endif(CLR_CMAKE_TARGET_OS STREQUAL Emscripten)
+
+if(CLR_CMAKE_TARGET_UNIX)
+    if(CLR_CMAKE_TARGET_ARCH STREQUAL x64)
+        set(CLR_CMAKE_TARGET_UNIX_AMD64 1)
+    elseif(CLR_CMAKE_TARGET_ARCH STREQUAL armel)
+        set(CLR_CMAKE_TARGET_UNIX_ARM 1)
+    elseif(CLR_CMAKE_TARGET_ARCH STREQUAL arm)
+        set(CLR_CMAKE_TARGET_UNIX_ARM 1)
+    elseif(CLR_CMAKE_TARGET_ARCH STREQUAL arm64)
+        set(CLR_CMAKE_TARGET_UNIX_ARM64 1)
+    elseif(CLR_CMAKE_TARGET_ARCH STREQUAL x86)
+        set(CLR_CMAKE_TARGET_UNIX_X86 1)
+    elseif(CLR_CMAKE_TARGET_ARCH STREQUAL s390x)
+        set(CLR_CMAKE_TARGET_UNIX_S390X 1)
+    elseif(CLR_CMAKE_TARGET_ARCH STREQUAL wasm)
+        set(CLR_CMAKE_TARGET_UNIX_WASM 1)
+    elseif(CLR_CMAKE_TARGET_ARCH STREQUAL mips64)
+        set(CLR_CMAKE_TARGET_UNIX_MIPS64 1)
+    else()
+        clr_unknown_arch()
+    endif()
+else()
+    set(CLR_CMAKE_TARGET_WIN32 1)
+endif(CLR_CMAKE_TARGET_UNIX)
+
+# check if host & target os/arch combination are valid
+if (CLR_CMAKE_TARGET_OS STREQUAL CLR_CMAKE_HOST_OS)
+    if(NOT(CLR_CMAKE_TARGET_ARCH STREQUAL CLR_CMAKE_HOST_ARCH))
+        if(NOT((CLR_CMAKE_HOST_ARCH_AMD64 AND CLR_CMAKE_TARGET_ARCH_ARM64) OR (CLR_CMAKE_HOST_ARCH_I386 AND CLR_CMAKE_TARGET_ARCH_ARM) OR (CLR_CMAKE_HOST_ARCH_AMD64 AND CLR_CMAKE_TARGET_ARCH_ARM) OR (CLR_CMAKE_HOST_ARCH_AMD64 AND CLR_CMAKE_TARGET_ARCH_I386)))
+            message(FATAL_ERROR "Invalid platform and target arch combination TARGET_ARCH=${CLR_CMAKE_TARGET_ARCH} HOST_ARCH=${CLR_CMAKE_HOST_ARCH}")
+        endif()
+    endif()
+else()
+    if(NOT (CLR_CMAKE_HOST_OS STREQUAL windows))
+        message(FATAL_ERROR "Invalid host and target os/arch combination. Host OS: ${CLR_CMAKE_HOST_OS}")
+    endif()
+    if(NOT (CLR_CMAKE_TARGET_LINUX OR CLR_CMAKE_TARGET_ALPINE_LINUX))
+        message(FATAL_ERROR "Invalid host and target os/arch combination. Target OS: ${CLR_CMAKE_TARGET_OS}")
+    endif()
+    if(NOT ((CLR_CMAKE_HOST_ARCH_AMD64 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)) OR (CLR_CMAKE_HOST_ARCH_I386 AND CLR_CMAKE_TARGET_ARCH_ARM)))
+        message(FATAL_ERROR "Invalid host and target os/arch combination. Host Arch: ${CLR_CMAKE_HOST_ARCH} Target Arch: ${CLR_CMAKE_TARGET_ARCH}")
+    endif()
+endif()
+
+if(NOT CLR_CMAKE_TARGET_BROWSER)
+    # The default linker on Solaris also does not support PIE.
+    if(NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_SUNOS AND NOT CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_HOST_TVOS AND NOT CLR_CMAKE_HOST_IOS AND NOT MSVC)
+        set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie")
+        add_compile_options($<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:-fPIE>)
+        add_compile_options($<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:-fPIC>)
+    endif()
+
+    set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+endif()
+
+string(TOLOWER "${CMAKE_BUILD_TYPE}" LOWERCASE_CMAKE_BUILD_TYPE)
+if(LOWERCASE_CMAKE_BUILD_TYPE STREQUAL debug)
+    # Clear _FORTIFY_SOURCE=2, if set
+    string(REPLACE "-D_FORTIFY_SOURCE=2 " "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+    string(REPLACE "-D_FORTIFY_SOURCE=2 " "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+endif()
diff --git a/eng/native/configuretools.cmake b/eng/native/configuretools.cmake
new file mode 100644 (file)
index 0000000..136cd67
--- /dev/null
@@ -0,0 +1,82 @@
+include(${CMAKE_CURRENT_LIST_DIR}/configureplatform.cmake)
+
+# Get the version of the compiler that is in the file name for tool location.
+set (CLR_CMAKE_COMPILER_FILE_NAME_VERSION "")
+if (CMAKE_C_COMPILER MATCHES "-?[0-9]+(\.[0-9]+)?$")
+  set(CLR_CMAKE_COMPILER_FILE_NAME_VERSION "${CMAKE_MATCH_0}")
+endif()
+
+if(NOT WIN32 AND NOT CLR_CMAKE_TARGET_BROWSER)
+  if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+    if(APPLE)
+      set(TOOLSET_PREFIX "")
+    else()
+      set(TOOLSET_PREFIX "llvm-")
+    endif()
+  elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+    if(CMAKE_CROSSCOMPILING)
+      set(TOOLSET_PREFIX "${CMAKE_CXX_COMPILER_TARGET}-")
+    else()
+      set(TOOLSET_PREFIX "")
+    endif()
+  endif()
+
+  function(locate_toolchain_exec exec var)
+    string(TOUPPER ${exec} EXEC_UPPERCASE)
+    if(NOT "$ENV{CLR_${EXEC_UPPERCASE}}" STREQUAL "")
+      set(${var} "$ENV{CLR_${EXEC_UPPERCASE}}" PARENT_SCOPE)
+      return()
+    endif()
+
+    find_program(EXEC_LOCATION_${exec}
+      NAMES
+      "${TOOLSET_PREFIX}${exec}${CLR_CMAKE_COMPILER_FILE_NAME_VERSION}"
+      "${TOOLSET_PREFIX}${exec}")
+
+    if (EXEC_LOCATION_${exec} STREQUAL "EXEC_LOCATION_${exec}-NOTFOUND")
+      message(FATAL_ERROR "Unable to find toolchain executable. Name: ${exec}, Prefix: ${TOOLSET_PREFIX}.")
+    endif()
+    set(${var} ${EXEC_LOCATION_${exec}} PARENT_SCOPE)
+  endfunction()
+
+  locate_toolchain_exec(ar CMAKE_AR)
+  locate_toolchain_exec(nm CMAKE_NM)
+  locate_toolchain_exec(ranlib CMAKE_RANLIB)
+
+  if(CMAKE_C_COMPILER_ID MATCHES "Clang")
+    locate_toolchain_exec(link CMAKE_LINKER)
+  endif()
+
+  if(NOT CLR_CMAKE_TARGET_OSX AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND (NOT CLR_CMAKE_TARGET_ANDROID OR CROSS_ROOTFS))
+    locate_toolchain_exec(objdump CMAKE_OBJDUMP)
+
+    if(CLR_CMAKE_TARGET_ANDROID)
+      set(TOOLSET_PREFIX ${ANDROID_TOOLCHAIN_PREFIX})
+    elseif(CMAKE_CROSSCOMPILING AND NOT DEFINED CLR_CROSS_COMPONENTS_BUILD AND (CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l OR
+       CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL arm OR CMAKE_SYSTEM_PROCESSOR STREQUAL s390x))
+      set(TOOLSET_PREFIX "${TOOLCHAIN}-")
+    else()
+      set(TOOLSET_PREFIX "")
+    endif()
+
+    locate_toolchain_exec(objcopy CMAKE_OBJCOPY)
+  endif()
+endif()
+
+if (NOT CLR_CMAKE_HOST_WIN32)
+  # detect linker
+  separate_arguments(ldVersion UNIX_COMMAND "${CMAKE_C_COMPILER} ${CMAKE_SHARED_LINKER_FLAGS} -Wl,--version")
+  execute_process(COMMAND ${ldVersion}
+    ERROR_QUIET
+    OUTPUT_VARIABLE ldVersionOutput)
+
+  if("${ldVersionOutput}" MATCHES "LLD")
+    set(LD_LLVM 1)
+  elseif("${ldVersionOutput}" MATCHES "GNU ld" OR "${ldVersionOutput}" MATCHES "GNU gold" OR "${ldVersionOutput}" MATCHES "GNU linkers")
+    set(LD_GNU 1)
+  elseif("${ldVersionOutput}" MATCHES "Solaris Link")
+    set(LD_SOLARIS 1)
+  else(CLR_CMAKE_HOST_OSX OR CLR_CMAKE_HOST_MACCATALYST)
+    set(LD_OSX 1)
+  endif()
+endif()
diff --git a/eng/native/functions.cmake b/eng/native/functions.cmake
new file mode 100644 (file)
index 0000000..66a91ca
--- /dev/null
@@ -0,0 +1,526 @@
+function(clr_unknown_arch)
+    if (WIN32)
+        message(FATAL_ERROR "Only AMD64, ARM64, ARM and I386 are supported. Found: ${CMAKE_SYSTEM_PROCESSOR}")
+    elseif(CLR_CROSS_COMPONENTS_BUILD)
+        message(FATAL_ERROR "Only AMD64, I386 host are supported for linux cross-architecture component. Found: ${CMAKE_SYSTEM_PROCESSOR}")
+    else()
+        message(FATAL_ERROR "Only AMD64, ARM64 and ARM are supported. Found: ${CMAKE_SYSTEM_PROCESSOR}")
+    endif()
+endfunction()
+
+# Build a list of compiler definitions by putting -D in front of each define.
+function(get_compile_definitions DefinitionName)
+    # Get the current list of definitions
+    get_directory_property(COMPILE_DEFINITIONS_LIST COMPILE_DEFINITIONS)
+
+    # The entries that contain generator expressions must have the -D inside of the
+    # expression. So we transform e.g. $<$<CONFIG:Debug>:_DEBUG> to $<$<CONFIG:Debug>:-D_DEBUG>
+
+    # CMake's support for multiple values within a single generator expression is somewhat ad-hoc.
+    # Since we have a number of complex generator expressions, we use them with multiple values to ensure that
+    # we don't forget to update all of the generator expressions if one needs to be updated.
+    # As a result, we need to expand out the multi-valued generator expression to wrap each individual value here.
+    # Otherwise, CMake will fail to expand it.
+    set(LastGeneratorExpression "")
+    foreach(DEFINITION IN LISTS COMPILE_DEFINITIONS_LIST)
+      # If there is a definition that uses the $<TARGET_PROPERTY:prop> generator expression
+      # we need to remove it since that generator expression is only valid on binary targets.
+      # Assume that the value is 0.
+      string(REGEX REPLACE "\\$<TARGET_PROPERTY:[^,>]+>" "0" DEFINITION "${DEFINITION}")
+
+      if (${DEFINITION} MATCHES "^\\$<(.+):([^>]+)(>?)$")
+        if("${CMAKE_MATCH_3}" STREQUAL "")
+          set(DEFINITION "$<${CMAKE_MATCH_1}:-D${CMAKE_MATCH_2}>")
+          set(LastGeneratorExpression "${CMAKE_MATCH_1}")
+        else()
+          set(DEFINITION "$<${CMAKE_MATCH_1}:-D${CMAKE_MATCH_2}>")
+        endif()
+      elseif(${DEFINITION} MATCHES "([^>]+)>$")
+        # This entry is the last in a list nested within a generator expression.
+        set(DEFINITION "$<${LastGeneratorExpression}:-D${CMAKE_MATCH_1}>")
+        set(LastGeneratorExpression "")
+      elseif(NOT "${LastGeneratorExpression}" STREQUAL "")
+        set(DEFINITION "$<${LastGeneratorExpression}:-D${DEFINITION}>")
+      else()
+        set(DEFINITION -D${DEFINITION})
+      endif()
+      list(APPEND DEFINITIONS ${DEFINITION})
+    endforeach()
+    set(${DefinitionName} ${DEFINITIONS} PARENT_SCOPE)
+endfunction(get_compile_definitions)
+
+# Build a list of include directories
+function(get_include_directories IncludeDirectories)
+    get_directory_property(dirs INCLUDE_DIRECTORIES)
+    foreach(dir IN LISTS dirs)
+
+      if (CLR_CMAKE_HOST_ARCH_ARM AND WIN32)
+        list(APPEND INC_DIRECTORIES /I${dir})
+      else()
+        list(APPEND INC_DIRECTORIES -I${dir})
+      endif(CLR_CMAKE_HOST_ARCH_ARM AND WIN32)
+
+    endforeach()
+    set(${IncludeDirectories} ${INC_DIRECTORIES} PARENT_SCOPE)
+endfunction(get_include_directories)
+
+# Build a list of include directories for consumption by the assembler
+function(get_include_directories_asm IncludeDirectories)
+    get_directory_property(dirs INCLUDE_DIRECTORIES)
+
+    foreach(dir IN LISTS dirs)
+      list(APPEND INC_DIRECTORIES -I${dir};)
+    endforeach()
+
+    set(${IncludeDirectories} ${INC_DIRECTORIES} PARENT_SCOPE)
+endfunction(get_include_directories_asm)
+
+# Finds and returns unwind libs
+function(find_unwind_libs UnwindLibs)
+    if(CLR_CMAKE_HOST_ARCH_ARM)
+      find_library(UNWIND_ARCH NAMES unwind-arm)
+    endif()
+
+    if(CLR_CMAKE_HOST_ARCH_ARM64)
+      find_library(UNWIND_ARCH NAMES unwind-aarch64)
+    endif()
+
+    if(CLR_CMAKE_HOST_ARCH_AMD64)
+      find_library(UNWIND_ARCH NAMES unwind-x86_64)
+    endif()
+
+    if(CLR_CMAKE_HOST_ARCH_S390X)
+      find_library(UNWIND_ARCH NAMES unwind-s390x)
+    endif()
+
+    if(NOT UNWIND_ARCH STREQUAL UNWIND_ARCH-NOTFOUND)
+       set(UNWIND_LIBS ${UNWIND_ARCH})
+    endif()
+
+    find_library(UNWIND_GENERIC NAMES unwind-generic)
+
+    if(NOT UNWIND_GENERIC STREQUAL UNWIND_GENERIC-NOTFOUND)
+      set(UNWIND_LIBS ${UNWIND_LIBS} ${UNWIND_GENERIC})
+    endif()
+
+    find_library(UNWIND NAMES unwind)
+
+    if(UNWIND STREQUAL UNWIND-NOTFOUND)
+      message(FATAL_ERROR "Cannot find libunwind. Try installing libunwind8-dev or libunwind-devel.")
+    endif()
+
+    set(${UnwindLibs} ${UNWIND_LIBS} ${UNWIND} PARENT_SCOPE)
+endfunction(find_unwind_libs)
+
+# Set the passed in RetSources variable to the list of sources with added current source directory
+# to form absolute paths.
+# The parameters after the RetSources are the input files.
+function(convert_to_absolute_path RetSources)
+    set(Sources ${ARGN})
+    foreach(Source IN LISTS Sources)
+        list(APPEND AbsolutePathSources ${CMAKE_CURRENT_SOURCE_DIR}/${Source})
+    endforeach()
+    set(${RetSources} ${AbsolutePathSources} PARENT_SCOPE)
+endfunction(convert_to_absolute_path)
+
+#Preprocess file
+function(preprocess_file inputFilename outputFilename)
+  get_compile_definitions(PREPROCESS_DEFINITIONS)
+  get_include_directories(PREPROCESS_INCLUDE_DIRECTORIES)
+  if (MSVC)
+    add_custom_command(
+        OUTPUT ${outputFilename}
+        COMMAND ${CMAKE_CXX_COMPILER} ${PREPROCESS_INCLUDE_DIRECTORIES} /P /EP /TC ${PREPROCESS_DEFINITIONS}  /Fi${outputFilename}  ${inputFilename} /nologo
+        DEPENDS ${inputFilename}
+        COMMENT "Preprocessing ${inputFilename}. Outputting to ${outputFilename}"
+    )
+  else()
+    add_custom_command(
+        OUTPUT ${outputFilename}
+        COMMAND ${CMAKE_CXX_COMPILER} -E -P ${PREPROCESS_DEFINITIONS} ${PREPROCESS_INCLUDE_DIRECTORIES} -o ${outputFilename} -x c ${inputFilename}
+        DEPENDS ${inputFilename}
+        COMMENT "Preprocessing ${inputFilename}. Outputting to ${outputFilename}"
+    )
+  endif()
+
+  set_source_files_properties(${outputFilename}
+                              PROPERTIES GENERATED TRUE)
+endfunction()
+
+# preprocess_files(PreprocessedFilesList [fileToPreprocess1 [fileToPreprocess2 ...]])
+function(preprocess_files PreprocessedFilesList)
+  set(FilesToPreprocess ${ARGN})
+  foreach(ASM_FILE IN LISTS FilesToPreprocess)
+    # Inserts a custom command in CMake build to preprocess each asm source file
+    get_filename_component(name ${ASM_FILE} NAME_WE)
+    file(TO_CMAKE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${name}.asm" ASM_PREPROCESSED_FILE)
+    preprocess_file(${ASM_FILE} ${ASM_PREPROCESSED_FILE})
+    list(APPEND PreprocessedFiles ${ASM_PREPROCESSED_FILE})
+  endforeach()
+  set(${PreprocessedFilesList} ${PreprocessedFiles} PARENT_SCOPE)
+endfunction()
+
+function(set_exports_linker_option exports_filename)
+    if(LD_GNU OR LD_SOLARIS OR LD_LLVM)
+        # Add linker exports file option
+        if(LD_SOLARIS)
+            set(EXPORTS_LINKER_OPTION -Wl,-M,${exports_filename} PARENT_SCOPE)
+        else()
+            set(EXPORTS_LINKER_OPTION -Wl,--version-script=${exports_filename} PARENT_SCOPE)
+        endif()
+    elseif(LD_OSX)
+        # Add linker exports file option
+        set(EXPORTS_LINKER_OPTION -Wl,-exported_symbols_list,${exports_filename} PARENT_SCOPE)
+    endif()
+endfunction()
+
+# compile_asm(TARGET target ASM_FILES file1 [file2 ...] OUTPUT_OBJECTS [variableName])
+# CMake does not support the ARM or ARM64 assemblers on Windows when using the
+# MSBuild generator. When the MSBuild generator is in use, we manually compile the assembly files
+# using this function.
+function(compile_asm)
+  set(options "")
+  set(oneValueArgs TARGET OUTPUT_OBJECTS)
+  set(multiValueArgs ASM_FILES)
+  cmake_parse_arguments(COMPILE_ASM "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGV})
+
+  get_include_directories_asm(ASM_INCLUDE_DIRECTORIES)
+
+  set (ASSEMBLED_OBJECTS "")
+
+  foreach(ASM_FILE ${COMPILE_ASM_ASM_FILES})
+    get_filename_component(name ${ASM_FILE} NAME_WE)
+    # Produce object file where CMake would store .obj files for an OBJECT library.
+    # ex: artifacts\obj\coreclr\windows.arm64.Debug\src\vm\wks\cee_wks.dir\Debug\AsmHelpers.obj
+    set (OBJ_FILE "${CMAKE_CURRENT_BINARY_DIR}/${COMPILE_ASM_TARGET}.dir/${CMAKE_CFG_INTDIR}/${name}.obj")
+
+    # Need to compile asm file using custom command as include directories are not provided to asm compiler
+    add_custom_command(OUTPUT ${OBJ_FILE}
+                        COMMAND "${CMAKE_ASM_COMPILER}" -g ${ASM_INCLUDE_DIRECTORIES} -o ${OBJ_FILE} ${ASM_FILE}
+                        DEPENDS ${ASM_FILE}
+                        COMMENT "Assembling ${ASM_FILE} ---> \"${CMAKE_ASM_COMPILER}\" -g ${ASM_INCLUDE_DIRECTORIES} -o ${OBJ_FILE} ${ASM_FILE}")
+
+    # mark obj as source that does not require compile
+    set_source_files_properties(${OBJ_FILE} PROPERTIES EXTERNAL_OBJECT TRUE)
+
+    # Add the generated OBJ in the dependency list so that it gets consumed during linkage
+    list(APPEND ASSEMBLED_OBJECTS ${OBJ_FILE})
+  endforeach()
+
+  set(${COMPILE_ASM_OUTPUT_OBJECTS} ${ASSEMBLED_OBJECTS} PARENT_SCOPE)
+endfunction()
+
+# add_component(componentName [targetName] [EXCLUDE_FROM_ALL])
+function(add_component componentName)
+  if (${ARGC} GREATER 2 OR ${ARGC} EQUAL 2)
+    set(componentTargetName "${ARGV1}")
+  else()
+    set(componentTargetName "${componentName}")
+  endif()
+  if (${ARGC} EQUAL 3 AND "${ARG2}" STREQUAL "EXCLUDE_FROM_ALL")
+    set(exclude_from_all_flag "EXCLUDE_FROM_ALL")
+  endif()
+  get_property(definedComponents GLOBAL PROPERTY CLR_CMAKE_COMPONENTS)
+  list (FIND definedComponents "${componentName}" componentIndex)
+  if (${componentIndex} EQUAL -1)
+    list (APPEND definedComponents "${componentName}")
+    add_custom_target("${componentTargetName}"
+      COMMAND "${CMAKE_COMMAND}" "-DCMAKE_INSTALL_COMPONENT=${componentName}" "-DBUILD_TYPE=$<CONFIG>" -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
+      ${exclude_from_all_flag})
+    set_property(GLOBAL PROPERTY CLR_CMAKE_COMPONENTS ${definedComponents})
+  endif()
+endfunction()
+
+function(generate_exports_file)
+  set(INPUT_LIST ${ARGN})
+  list(GET INPUT_LIST -1 outputFilename)
+  list(REMOVE_AT INPUT_LIST -1)
+
+  if(CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
+    set(SCRIPT_NAME generateexportedsymbols.sh)
+  else()
+    set(SCRIPT_NAME generateversionscript.sh)
+  endif()
+
+  add_custom_command(
+    OUTPUT ${outputFilename}
+    COMMAND ${CLR_ENG_NATIVE_DIR}/${SCRIPT_NAME} ${INPUT_LIST} >${outputFilename}
+    DEPENDS ${INPUT_LIST} ${CLR_ENG_NATIVE_DIR}/${SCRIPT_NAME}
+    COMMENT "Generating exports file ${outputFilename}"
+  )
+  set_source_files_properties(${outputFilename}
+                              PROPERTIES GENERATED TRUE)
+endfunction()
+
+function(generate_exports_file_prefix inputFilename outputFilename prefix)
+
+  if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+    set(SCRIPT_NAME generateexportedsymbols.sh)
+  else()
+    set(SCRIPT_NAME generateversionscript.sh)
+    if (NOT ${prefix} STREQUAL "")
+        set(EXTRA_ARGS ${prefix})
+    endif()
+  endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+
+  add_custom_command(
+    OUTPUT ${outputFilename}
+    COMMAND ${CLR_ENG_NATIVE_DIR}/${SCRIPT_NAME} ${inputFilename} ${EXTRA_ARGS} >${outputFilename}
+    DEPENDS ${inputFilename} ${CLR_ENG_NATIVE_DIR}/${SCRIPT_NAME}
+    COMMENT "Generating exports file ${outputFilename}"
+  )
+  set_source_files_properties(${outputFilename}
+                              PROPERTIES GENERATED TRUE)
+endfunction()
+
+function (get_symbol_file_name targetName outputSymbolFilename)
+  if (CLR_CMAKE_HOST_UNIX)
+    if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
+      set(strip_destination_file $<TARGET_FILE:${targetName}>.dwarf)
+    else ()
+      set(strip_destination_file $<TARGET_FILE:${targetName}>.dbg)
+    endif ()
+
+    set(${outputSymbolFilename} ${strip_destination_file} PARENT_SCOPE)
+  else(CLR_CMAKE_HOST_UNIX)
+    # We can't use the $<TARGET_PDB_FILE> generator expression here since
+    # the generator expression isn't supported on resource DLLs.
+    set(${outputSymbolFilename} $<TARGET_FILE_DIR:${targetName}>/$<TARGET_FILE_PREFIX:${targetName}>$<TARGET_FILE_BASE_NAME:${targetName}>.pdb PARENT_SCOPE)
+  endif(CLR_CMAKE_HOST_UNIX)
+endfunction()
+
+function(strip_symbols targetName outputFilename)
+  get_symbol_file_name(${targetName} strip_destination_file)
+  set(${outputFilename} ${strip_destination_file} PARENT_SCOPE)
+  if (CLR_CMAKE_HOST_UNIX)
+    set(strip_source_file $<TARGET_FILE:${targetName}>)
+
+    if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
+
+      # Ensure that dsymutil and strip are present
+      find_program(DSYMUTIL dsymutil)
+      if (DSYMUTIL STREQUAL "DSYMUTIL-NOTFOUND")
+        message(FATAL_ERROR "dsymutil not found")
+      endif()
+
+      find_program(STRIP strip)
+      if (STRIP STREQUAL "STRIP-NOTFOUND")
+        message(FATAL_ERROR "strip not found")
+      endif()
+
+      string(TOLOWER "${CMAKE_BUILD_TYPE}" LOWERCASE_CMAKE_BUILD_TYPE)
+      if (LOWERCASE_CMAKE_BUILD_TYPE STREQUAL release)
+        set(strip_command ${STRIP} -no_code_signature_warning -S ${strip_source_file} && codesign -f -s - ${strip_source_file})
+      else ()
+        set(strip_command)
+      endif ()
+
+      add_custom_command(
+        TARGET ${targetName}
+        POST_BUILD
+        VERBATIM
+        COMMAND ${DSYMUTIL} --flat --minimize ${strip_source_file}
+        COMMAND ${strip_command}
+        COMMENT "Stripping symbols from ${strip_source_file} into file ${strip_destination_file}"
+        )
+    else (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
+
+      add_custom_command(
+        TARGET ${targetName}
+        POST_BUILD
+        VERBATIM
+        COMMAND ${CMAKE_OBJCOPY} --only-keep-debug ${strip_source_file} ${strip_destination_file}
+        COMMAND ${CMAKE_OBJCOPY} --strip-unneeded ${strip_source_file}
+        COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=${strip_destination_file} ${strip_source_file}
+        COMMENT "Stripping symbols from ${strip_source_file} into file ${strip_destination_file}"
+        )
+    endif (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
+  endif(CLR_CMAKE_HOST_UNIX)
+endfunction()
+
+function(install_with_stripped_symbols targetName kind destination)
+    if(NOT CLR_CMAKE_KEEP_NATIVE_SYMBOLS)
+      strip_symbols(${targetName} symbol_file)
+      install_symbol_file(${symbol_file} ${destination} ${ARGN})
+    endif()
+
+    if ((CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) AND ("${kind}" STREQUAL "TARGETS"))
+      # We want to avoid the kind=TARGET install behaviors which corrupt code signatures on osx-arm64
+      set(kind PROGRAMS)
+    endif()
+
+    if ("${kind}" STREQUAL "TARGETS")
+      set(install_source ${targetName})
+    elseif("${kind}" STREQUAL "PROGRAMS")
+      set(install_source $<TARGET_FILE:${targetName}>)
+    else()
+      message(FATAL_ERROR "The `kind` argument has to be either TARGETS or PROGRAMS, ${kind} was provided instead")
+    endif()
+    install(${kind} ${install_source} DESTINATION ${destination} ${ARGN})
+endfunction()
+
+function(install_symbol_file symbol_file destination_path)
+  if(CLR_CMAKE_TARGET_WIN32)
+      install(FILES ${symbol_file} DESTINATION ${destination_path}/PDB ${ARGN})
+  else()
+      install(FILES ${symbol_file} DESTINATION ${destination_path} ${ARGN})
+  endif()
+endfunction()
+
+# install_clr(TARGETS targetName [targetName2 ...] [DESTINATIONS destination [destination2 ...]] [COMPONENT componentName])
+function(install_clr)
+  set(multiValueArgs TARGETS DESTINATIONS)
+  set(singleValueArgs COMPONENT)
+  set(options "")
+  cmake_parse_arguments(INSTALL_CLR "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGV})
+
+  if ("${INSTALL_CLR_TARGETS}" STREQUAL "")
+    message(FATAL_ERROR "At least one target must be passed to install_clr(TARGETS )")
+  endif()
+
+  if ("${INSTALL_CLR_DESTINATIONS}" STREQUAL "")
+    message(FATAL_ERROR "At least one destination must be passed to install_clr.")
+  endif()
+
+  set(destinations "")
+
+  if (NOT "${INSTALL_CLR_DESTINATIONS}" STREQUAL "")
+    list(APPEND destinations ${INSTALL_CLR_DESTINATIONS})
+  endif()
+
+  if ("${INSTALL_CLR_COMPONENT}" STREQUAL "")
+    set(INSTALL_CLR_COMPONENT ${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME})
+  endif()
+
+  foreach(targetName ${INSTALL_CLR_TARGETS})
+    if (NOT "${INSTALL_CLR_COMPONENT}" STREQUAL "${targetName}")
+      get_property(definedComponents GLOBAL PROPERTY CLR_CMAKE_COMPONENTS)
+      list(FIND definedComponents "${INSTALL_CLR_COMPONENT}" componentIdx)
+      if (${componentIdx} EQUAL -1)
+        message(FATAL_ERROR "The ${INSTALL_CLR_COMPONENT} component is not defined. Add a call to `add_component(${INSTALL_CLR_COMPONENT})` to define the component in the build.")
+      endif()
+      add_dependencies(${INSTALL_CLR_COMPONENT} ${targetName})
+    endif()
+    get_target_property(targetType ${targetName} TYPE)
+    if (NOT CLR_CMAKE_KEEP_NATIVE_SYMBOLS AND NOT "${targetType}" STREQUAL "STATIC_LIBRARY")
+      get_symbol_file_name(${targetName} symbolFile)
+    endif()
+
+    foreach(destination ${destinations})
+      # We don't need to install the export libraries for our DLLs
+      # since they won't be directly linked against.
+      install(PROGRAMS $<TARGET_FILE:${targetName}> DESTINATION ${destination} COMPONENT ${INSTALL_CLR_COMPONENT})
+      if (NOT "${symbolFile}" STREQUAL "")
+        install_symbol_file(${symbolFile} ${destination} COMPONENT ${INSTALL_CLR_COMPONENT})
+      endif()
+
+      if(CLR_CMAKE_PGO_INSTRUMENT)
+        if(WIN32)
+          get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+          if(is_multi_config)
+              install(FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${targetName}.pgd DESTINATION ${destination}/PGD OPTIONAL COMPONENT ${INSTALL_CLR_COMPONENT})
+          else()
+              install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${targetName}.pgd DESTINATION ${destination}/PGD OPTIONAL COMPONENT ${INSTALL_CLR_COMPONENT})
+          endif()
+        endif()
+      endif()
+    endforeach()
+  endforeach()
+endfunction()
+
+# Disable PAX mprotect that would prevent JIT and other codegen in coreclr from working.
+# PAX mprotect prevents:
+# - changing the executable status of memory pages that were
+#   not originally created as executable,
+# - making read-only executable pages writable again,
+# - creating executable pages from anonymous memory,
+# - making read-only-after-relocations (RELRO) data pages writable again.
+function(disable_pax_mprotect targetName)
+  # Disabling PAX hardening only makes sense in systems that use Elf image formats. Particularly, looking
+  # for paxctl in macOS is problematic as it collides with popular software for that OS that performs completely
+  # unrelated functionality. Only look for it when we'll generate Elf images.
+  if (CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD OR CLR_CMAKE_HOST_SUNOS)
+    # Try to locate the paxctl tool. Failure to find it is not fatal,
+    # but the generated executables won't work on a system where PAX is set
+    # to prevent applications to create executable memory mappings.
+    find_program(PAXCTL paxctl)
+
+    if (NOT PAXCTL STREQUAL "PAXCTL-NOTFOUND")
+        add_custom_command(
+        TARGET ${targetName}
+        POST_BUILD
+        VERBATIM
+        COMMAND ${PAXCTL} -c -m $<TARGET_FILE:${targetName}>
+        )
+    endif()
+  endif(CLR_CMAKE_HOST_LINUX OR CLR_CMAKE_HOST_FREEBSD OR CLR_CMAKE_HOST_NETBSD OR CLR_CMAKE_HOST_SUNOS)
+endfunction()
+
+if (CMAKE_VERSION VERSION_LESS "3.12")
+  # Polyfill add_compile_definitions when it is unavailable
+  function(add_compile_definitions)
+    get_directory_property(DIR_COMPILE_DEFINITIONS COMPILE_DEFINITIONS)
+    list(APPEND DIR_COMPILE_DEFINITIONS ${ARGV})
+    set_directory_properties(PROPERTIES COMPILE_DEFINITIONS "${DIR_COMPILE_DEFINITIONS}")
+  endfunction()
+endif()
+
+if (CMAKE_VERSION VERSION_LESS "3.16")
+  # Provide a no-op polyfill for precompiled headers on old CMake versions
+  function(target_precompile_headers)
+  endfunction()
+endif()
+
+# add_linker_flag(Flag [Config1 Config2 ...])
+function(add_linker_flag Flag)
+  if (ARGN STREQUAL "")
+    set("CMAKE_EXE_LINKER_FLAGS" "${CMAKE_EXE_LINKER_FLAGS} ${Flag}" PARENT_SCOPE)
+    set("CMAKE_SHARED_LINKER_FLAGS" "${CMAKE_SHARED_LINKER_FLAGS} ${Flag}" PARENT_SCOPE)
+  else()
+    foreach(Config ${ARGN})
+      set("CMAKE_EXE_LINKER_FLAGS_${Config}" "${CMAKE_EXE_LINKER_FLAGS_${Config}} ${Flag}" PARENT_SCOPE)
+      set("CMAKE_SHARED_LINKER_FLAGS_${Config}" "${CMAKE_SHARED_LINKER_FLAGS_${Config}} ${Flag}" PARENT_SCOPE)
+    endforeach()
+  endif()
+endfunction()
+
+function(link_natvis_sources_for_target targetName linkKind)
+    if (NOT CLR_CMAKE_HOST_WIN32)
+        return()
+    endif()
+    foreach(source ${ARGN})
+        if (NOT IS_ABSOLUTE "${source}")
+            convert_to_absolute_path(source ${source})
+        endif()
+        get_filename_component(extension "${source}" EXT)
+        if ("${extension}" STREQUAL ".natvis")
+            message("Embedding natvis ${source}")
+            # Since natvis embedding is only supported on Windows
+            # we can use target_link_options since our minimum version is high enough
+            target_link_options(${targetName} "${linkKind}" "-NATVIS:${source}")
+        endif()
+    endforeach()
+endfunction()
+
+function(add_executable_clr targetName)
+    if(NOT WIN32)
+      add_executable(${ARGV} ${VERSION_FILE_PATH})
+      disable_pax_mprotect(${ARGV})
+    else()
+      add_executable(${ARGV})
+    endif(NOT WIN32)
+    if(NOT CLR_CMAKE_KEEP_NATIVE_SYMBOLS)
+      strip_symbols(${ARGV0} symbolFile)
+    endif()
+endfunction()
+
+function(add_library_clr targetName kind)
+    if(NOT WIN32 AND "${kind}" STREQUAL "SHARED")
+      add_library(${ARGV} ${VERSION_FILE_PATH})
+    else()
+      add_library(${ARGV})
+    endif()
+    if("${kind}" STREQUAL "SHARED" AND NOT CLR_CMAKE_KEEP_NATIVE_SYMBOLS)
+      strip_symbols(${ARGV0} symbolFile)
+    endif()
+endfunction()
diff --git a/eng/native/gen-buildsys.cmd b/eng/native/gen-buildsys.cmd
new file mode 100644 (file)
index 0000000..243921d
--- /dev/null
@@ -0,0 +1,106 @@
+@if not defined _echo @echo off
+rem
+rem This file invokes cmake and generates the build system for windows.
+
+setlocal
+
+set argC=0
+for %%x in (%*) do Set /A argC+=1
+
+if %argC% lss 4 GOTO :USAGE
+if %1=="/?" GOTO :USAGE
+
+setlocal enabledelayedexpansion
+set basePath=%~dp0
+set __repoRoot=%~dp0..\..\
+:: remove quotes
+set "basePath=%basePath:"=%"
+:: remove trailing slash
+if %basePath:~-1%==\ set "basePath=%basePath:~0,-1%"
+
+set __SourceDir=%1
+set __IntermediatesDir=%2
+set __VSVersion=%3
+set __Arch=%4
+set __CmakeGenerator=Visual Studio
+set __UseEmcmake=0
+if /i "%__Ninja%" == "1" (
+    set __CmakeGenerator=Ninja
+) else (
+    if /i NOT "%__Arch%" == "wasm" (
+        if /i "%__VSVersion%" == "vs2022" (set __CmakeGenerator=%__CmakeGenerator% 17 2022)
+        if /i "%__VSVersion%" == "vs2019" (set __CmakeGenerator=%__CmakeGenerator% 16 2019)
+        if /i "%__VSVersion%" == "vs2017" (set __CmakeGenerator=%__CmakeGenerator% 15 2017)
+
+        if /i "%__Arch%" == "x64" (set __ExtraCmakeParams=%__ExtraCmakeParams% -A x64)
+        if /i "%__Arch%" == "arm" (set __ExtraCmakeParams=%__ExtraCmakeParams% -A ARM)
+        if /i "%__Arch%" == "arm64" (set __ExtraCmakeParams=%__ExtraCmakeParams% -A ARM64)
+        if /i "%__Arch%" == "x86" (set __ExtraCmakeParams=%__ExtraCmakeParams% -A Win32)
+    ) else (
+        set __CmakeGenerator=NMake Makefiles
+    )
+)
+
+if /i "%__Arch%" == "wasm" (
+
+    if "%EMSDK_PATH%" == "" (
+        if not exist "%__repoRoot%src\mono\wasm\emsdk" (
+            echo Error: Should set EMSDK_PATH environment variable pointing to emsdk root.
+            exit /B 1
+        )
+
+        set EMSDK_PATH=%__repoRoot%src\mono\wasm\emsdk
+        set EMSDK_PATH=!EMSDK_PATH:\=/!
+    )
+
+    set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCMAKE_TOOLCHAIN_FILE=!EMSDK_PATH!/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake"
+    set __UseEmcmake=1
+) else (
+    set __ExtraCmakeParams=%__ExtraCmakeParams%  "-DCMAKE_SYSTEM_VERSION=10.0"
+)
+
+:loop
+if [%5] == [] goto end_loop
+set __ExtraCmakeParams=%__ExtraCmakeParams% %5
+shift
+goto loop
+:end_loop
+
+set __ExtraCmakeParams="-DCMAKE_INSTALL_PREFIX=%__CMakeBinDir%" "-DCLR_CMAKE_HOST_ARCH=%__Arch%" %__ExtraCmakeParams%
+
+set __CmdLineOptionsUpToDateFile=%__IntermediatesDir%\cmake_cmd_line.txt
+set __CMakeCmdLineCache=
+if not "%__ConfigureOnly%" == "1" (
+    REM MSBuild can't reload from a CMake reconfigure during build correctly, so only do this
+    REM command-line up to date check for non-VS generators.
+    if "%__CmakeGenerator:Visual Studio=%" == "%__CmakeGenerator%" (
+        if exist "%__CmdLineOptionsUpToDateFile%" (
+            set /p __CMakeCmdLineCache=<"%__CmdLineOptionsUpToDateFile%"
+            REM Strip the extra space from the end of the cached command line
+            if "!__ExtraCmakeParams!" == "!__CMakeCmdLineCache:~0,-1!" (
+                echo The CMake command line is the same as the last run. Skipping running CMake.
+                exit /B 0
+            ) else (
+                echo The CMake command line differs from the last run. Running CMake again.
+                echo %__ExtraCmakeParams% > %__CmdLineOptionsUpToDateFile%
+            )
+        ) else (
+            echo %__ExtraCmakeParams% > %__CmdLineOptionsUpToDateFile%
+        )
+    )
+)
+
+if /i "%__UseEmcmake%" == "1" (
+    call "!EMSDK_PATH!/emsdk_env.bat" > nul 2>&1 && emcmake "%CMakePath%" %__ExtraCmakeParams% --no-warn-unused-cli -G "%__CmakeGenerator%" -B %__IntermediatesDir% -S %__SourceDir%
+) else (
+    "%CMakePath%" %__ExtraCmakeParams% --no-warn-unused-cli -G "%__CmakeGenerator%" -B %__IntermediatesDir% -S %__SourceDir%
+)
+endlocal
+exit /B %errorlevel%
+
+:USAGE
+  echo "Usage..."
+  echo "gen-buildsys.cmd <path to top level CMakeLists.txt> <path to location for intermediate files> <VSVersion> <arch>"
+  echo "Specify the path to the top level CMake file - <ProjectK>/src/NDP"
+  echo "Specify the VSVersion to be used - VS2017 or VS2019"
+  EXIT /B 1
diff --git a/eng/native/gen-buildsys.sh b/eng/native/gen-buildsys.sh
new file mode 100755 (executable)
index 0000000..730d4dc
--- /dev/null
@@ -0,0 +1,128 @@
+#!/usr/bin/env bash
+#
+# This file invokes cmake and generates the build system for Clang.
+#
+
+scriptroot="$( cd -P "$( dirname "$0" )" && pwd )"
+
+if [[ "$#" -lt 4 ]]; then
+  echo "Usage..."
+  echo "gen-buildsys.sh <path to top level CMakeLists.txt> <path to intermediate directory> <Architecture> <compiler> <compiler major version> <compiler minor version> [build flavor] [ninja] [scan-build] [cmakeargs]"
+  echo "Specify the path to the top level CMake file."
+  echo "Specify the path that the build system files are generated in."
+  echo "Specify the target architecture."
+  echo "Specify the name of compiler (clang or gcc)."
+  echo "Specify the major version of compiler."
+  echo "Specify the minor version of compiler."
+  echo "Optionally specify the build configuration (flavor.) Defaults to DEBUG."
+  echo "Optionally specify 'scan-build' to enable build with clang static analyzer."
+  echo "Use the Ninja generator instead of the Unix Makefiles generator."
+  echo "Pass additional arguments to CMake call."
+  exit 1
+fi
+
+build_arch="$3"
+compiler="$4"
+majorVersion="$5"
+minorVersion="$6"
+
+if [[ "$compiler" != "default" ]]; then
+    nativescriptroot="$( cd -P "$scriptroot/../common/native" && pwd )"
+    source "$nativescriptroot/init-compiler.sh" "$nativescriptroot" "$build_arch" "$compiler" "$majorVersion" "$minorVersion"
+
+    CCC_CC="$CC"
+    CCC_CXX="$CXX"
+fi
+
+export CCC_CC CCC_CXX
+
+buildtype=DEBUG
+code_coverage=OFF
+build_tests=OFF
+scan_build=OFF
+generator="Unix Makefiles"
+__UnprocessedCMakeArgs=""
+
+for i in "${@:7}"; do
+    upperI="$(echo "$i" | tr "[:lower:]" "[:upper:]")"
+    case "$upperI" in
+      # Possible build types are DEBUG, CHECKED, RELEASE, RELWITHDEBINFO.
+      DEBUG | CHECKED | RELEASE | RELWITHDEBINFO)
+      buildtype="$upperI"
+      ;;
+      NINJA)
+      generator=Ninja
+      ;;
+      SCAN-BUILD)
+      echo "Static analysis is turned on for this build."
+      scan_build=ON
+      ;;
+      *)
+      __UnprocessedCMakeArgs="${__UnprocessedCMakeArgs}${__UnprocessedCMakeArgs:+ }$i"
+    esac
+done
+
+cmake_extra_defines=
+if [[ "$CROSSCOMPILE" == "1" ]]; then
+    platform="$(uname)"
+    # OSX doesn't use rootfs
+    if ! [[ -n "$ROOTFS_DIR" || "$platform" == "Darwin" ]]; then
+        echo "ROOTFS_DIR not set for crosscompile"
+        exit 1
+    fi
+
+    TARGET_BUILD_ARCH="$build_arch"
+    export TARGET_BUILD_ARCH
+
+    cmake_extra_defines="$cmake_extra_defines -C $scriptroot/tryrun.cmake"
+
+    if [[ "$platform" == "Darwin" ]]; then
+        cmake_extra_defines="$cmake_extra_defines -DCMAKE_SYSTEM_NAME=Darwin"
+    else
+        cmake_extra_defines="$cmake_extra_defines -DCMAKE_TOOLCHAIN_FILE=$scriptroot/../common/cross/toolchain.cmake"
+    fi
+fi
+
+if [[ "$build_arch" == "armel" ]]; then
+    cmake_extra_defines="$cmake_extra_defines -DARM_SOFTFP=1"
+fi
+
+if ! cmake_command=$(command -v cmake); then
+    echo "CMake was not found in PATH."
+    exit 1
+fi
+
+if [[ "$scan_build" == "ON" && -n "$SCAN_BUILD_COMMAND" ]]; then
+    cmake_command="$SCAN_BUILD_COMMAND $cmake_command"
+fi
+
+if [[ "$build_arch" == "wasm" ]]; then
+    cmake_command="emcmake $cmake_command"
+fi
+
+cmake_args_to_cache="$scan_build\n$SCAN_BUILD_COMMAND\n$generator\n$__UnprocessedCMakeArgs"
+cmake_args_cache_file="$2/cmake_cmd_line.txt"
+if [[ -z "$__ConfigureOnly" ]]; then
+    if [[ -e "$cmake_args_cache_file" ]]; then
+        cmake_args_cache=$(<"$cmake_args_cache_file")
+        if [[ "$cmake_args_cache" == "$cmake_args_to_cache" ]]; then
+            echo "CMake command line is unchanged. Reusing previous cache instead of regenerating."
+            exit 0
+        fi
+    fi
+    echo $cmake_args_to_cache > $cmake_args_cache_file
+fi
+
+# We have to be able to build with CMake 3.6.2, so we can't use the -S or -B options
+pushd "$2"
+
+$cmake_command \
+  --no-warn-unused-cli \
+  -G "$generator" \
+  "-DCMAKE_BUILD_TYPE=$buildtype" \
+  "-DCMAKE_INSTALL_PREFIX=$__CMakeBinDir" \
+  $cmake_extra_defines \
+  $__UnprocessedCMakeArgs \
+  "$1"
+
+popd
diff --git a/eng/native/generateexportedsymbols.sh b/eng/native/generateexportedsymbols.sh
new file mode 100755 (executable)
index 0000000..4a23aa8
--- /dev/null
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+
+saved=("$@")
+while test $# -gt 0; do
+  case "$1" in
+    --help|-h)
+      printf "Usage:\ngenerateexportedsymbols.sh <filename>\n"
+      exit 1;;
+    esac
+    shift
+done
+set -- "${saved[@]}"
+
+while read -r line; do
+  # Skip empty lines and comment lines starting with semicolon
+  if [[ "$line" =~ ^\;.*$|^[[:space:]]*$ ]]; then
+    continue
+  fi
+
+  # Remove the CR character in case the sources are mapped from
+  # a Windows share and contain CRLF line endings
+  line="${line//$'\r'/}"
+
+  printf "_%s\n" "${line//#/}"
+done < "$1"
diff --git a/eng/native/generateversionscript.sh b/eng/native/generateversionscript.sh
new file mode 100755 (executable)
index 0000000..83e2490
--- /dev/null
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+
+saved=("$@")
+while test $# -gt 0; do
+  case "$1" in
+    --help|-h)
+      printf "Usage:\ngenerateversionscript.sh <filename> <prefix>\n"
+      exit 1;;
+    esac
+    shift
+done
+set -- "${saved[@]}"
+
+prefix="$2"
+
+printf "V1.0 {\n    global:\n"
+
+while read -r line; do
+  # Skip empty lines and comment lines starting with semicolon
+  if [[ "$line" =~ ^\;.*$|^[[:space:]]*$ ]]; then
+    continue
+  fi
+
+  # Remove the CR character in case the sources are mapped from
+  # a Windows share and contain CRLF line endings
+  line="${line//$'\r'/}"
+
+  # Only prefix the entries that start with "#"
+  if [[ "$line" =~ ^#.*$ ]]; then
+    printf "        %s%s;\n" "$prefix" "${line//#/}"
+  else
+    printf "        %s;\n" "$line"
+  fi
+done < "$1"
+
+printf "    local: *;\n};\n"
diff --git a/eng/native/genmoduleindex.cmd b/eng/native/genmoduleindex.cmd
new file mode 100644 (file)
index 0000000..a6be851
--- /dev/null
@@ -0,0 +1,25 @@
+@echo off
+REM Generate module index header
+
+if [%1]==[] goto :Usage
+if [%2]==[] goto :Usage
+
+setlocal
+for /f "tokens=1" %%i in ('dumpbin /HEADERS %1 ^| findstr /c:"size of image"') do set imagesize=%%i
+REM Pad the extracted size to 8 hex digits
+set imagesize=00000000%imagesize%
+set imagesize=%imagesize:~-8%
+
+for /f "tokens=1" %%i in ('dumpbin /HEADERS %1 ^| findstr /c:"time date"') do set timestamp=%%i
+REM Pad the extracted time stamp to 8 hex digits
+set timestamp=00000000%timestamp%
+set timestamp=%timestamp:~-8%
+
+echo 0x08, 0x%timestamp:~6,2%, 0x%timestamp:~4,2%, 0x%timestamp:~2,2%, 0x%timestamp:~0,2%, 0x%imagesize:~6,2%, 0x%imagesize:~4,2%, 0x%imagesize:~2,2%, 0x%imagesize:~0,2%, > %2
+
+endlocal
+exit /b 0
+
+:Usage
+echo Usage: genmoduleindex.cmd ModuleBinaryFile IndexHeaderFile
+exit /b 1
diff --git a/eng/native/genmoduleindex.sh b/eng/native/genmoduleindex.sh
new file mode 100755 (executable)
index 0000000..399a972
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+#
+# Generate module index header
+#
+set -euo pipefail
+
+if [[ "$#" -lt 2 ]]; then
+  echo "Usage: genmoduleindex.sh ModuleBinaryFile IndexHeaderFile"
+  exit 1
+fi
+
+function printIdAsBinary() {
+  id="$1"
+
+  # Print length in bytes
+  bytesLength="${#id}"
+  printf "0x%02x, " "$((bytesLength/2))"
+
+  # Print each pair of hex digits with 0x prefix followed by a comma
+  while [[ "$id" ]]; do
+    printf '0x%s, ' "${id:0:2}"
+    id=${id:2}
+  done
+}
+
+case "$(uname -s)" in
+Darwin)
+  cmd="dwarfdump -u $1"
+  pattern='^UUID: ([0-9A-Fa-f\-]+)';;
+*)
+  cmd="readelf -n $1"
+  pattern='^[[:space:]]*Build ID: ([0-9A-Fa-f\-]+)';;
+esac
+
+while read -r line; do
+  if [[ "$line" =~ $pattern ]]; then
+    printIdAsBinary "${BASH_REMATCH[1]//-/}"
+    break
+  fi
+done < <(eval "$cmd") > "$2"
diff --git a/eng/native/init-distro-rid.sh b/eng/native/init-distro-rid.sh
new file mode 100644 (file)
index 0000000..5f6b194
--- /dev/null
@@ -0,0 +1,206 @@
+#!/usr/bin/env bash
+
+# initNonPortableDistroRid
+#
+# Input:
+#   targetOs: (str)
+#   buildArch: (str)
+#   isPortable: (int)
+#   rootfsDir: (str)
+#
+# Return:
+#   None
+#
+# Notes:
+#
+# initNonPortableDistroRid will attempt to initialize a non portable rid. These
+# rids are specific to distros need to build the product/package and consume
+# them on the same platform.
+#
+# If -portablebuild=false is passed a non-portable rid will be created for any
+# distro.
+#
+# It is important to note that the function does not return anything, but it
+# exports __DistroRid, if there is a non-portable distro rid to be used.
+#
+initNonPortableDistroRid()
+{
+    # Make sure out parameter is cleared.
+    __DistroRid=
+
+    local targetOs="$1"
+    local buildArch="$2"
+    local isPortable="$3"
+    local rootfsDir="$4"
+    local nonPortableBuildID=""
+
+    if [ "$targetOs" = "Linux" ]; then
+        if [ -e "${rootfsDir}/etc/os-release" ]; then
+            source "${rootfsDir}/etc/os-release"
+
+            # We have forced __PortableBuild=0. This is because -portablebuld
+            # has been passed as false.
+            if (( isPortable == 0 )); then
+                if [ "${ID}" = "rhel" ] || [ "${ID}" = "rocky" ]; then
+                    # remove the last version digit
+                    VERSION_ID="${VERSION_ID%.*}"
+                fi
+
+                if [ -z "${VERSION_ID+x}" ]; then
+                        # Rolling release distros do not set VERSION_ID, so omit
+                        # it here to be consistent with everything else.
+                        nonPortableBuildID="${ID}-${buildArch}"
+                else
+                        nonPortableBuildID="${ID}.${VERSION_ID}-${buildArch}"
+                fi
+            fi
+
+        elif [ -e "${rootfsDir}/android_platform" ]; then
+            source "$rootfsDir"/android_platform
+            nonPortableBuildID="$RID"
+        fi
+    fi
+
+    if [ "$targetOs" = "FreeBSD" ]; then
+        if (( isPortable == 0 )); then
+            # $rootfsDir can be empty. freebsd-version is shell script and it should always work.
+            __freebsd_major_version=$($rootfsDir/bin/freebsd-version | { read v; echo "${v%%.*}"; })
+            nonPortableBuildID="freebsd.$__freebsd_major_version-${buildArch}"
+        fi
+    elif command -v getprop && getprop ro.product.system.model 2>&1 | grep -qi android; then
+        __android_sdk_version=$(getprop ro.build.version.sdk)
+        nonPortableBuildID="android.$__android_sdk_version-${buildArch}"
+    elif [ "$targetOs" = "illumos" ]; then
+        __uname_version=$(uname -v)
+        case "$__uname_version" in
+            omnios-*)
+                __omnios_major_version=$(echo "${__uname_version:8:2}")
+                nonPortableBuildID=omnios."$__omnios_major_version"-"$buildArch"
+            ;;
+            joyent_*)
+                __smartos_major_version=$(echo "${__uname_version:7:4}")
+                nonPortableBuildID=smartos."$__smartos_major_version"-"$buildArch"
+            ;;
+            illumos_*)
+                nonPortableBuildID=openindiana-"$buildArch"
+            ;;
+        esac
+    elif [ "$targetOs" = "Solaris" ]; then
+        __uname_version=$(uname -v)
+        __solaris_major_version=$(echo "${__uname_version%.*}")
+        nonPortableBuildID=solaris."$__solaris_major_version"-"$buildArch"
+    fi
+
+    if [ -n "${nonPortableBuildID}" ]; then
+        __DistroRid="${nonPortableBuildID}"
+
+        # We are using a non-portable build rid. Force __PortableBuild to false.
+        __PortableBuild=0
+
+        export __DistroRid __PortableBuild
+    fi
+}
+
+# initDistroRidGlobal
+#
+# Input:
+#   os: (str)
+#   arch: (str)
+#   isPortable: (int)
+#   rootfsDir?: (nullable:string)
+#
+# Return:
+#   None
+#
+# Notes:
+#
+# It is important to note that the function does not return anything, but it
+# exports the following variables on success:
+#
+#   __DistroRid
+#   __PortableBuild
+#
+initDistroRidGlobal()
+{
+    # __DistroRid must be set at the end of the function.
+    # Previously we would create a variable __HostDistroRid and/or __DistroRid.
+    #
+    # __HostDistroRid was used in the case of a non-portable build, it has been
+    # deprecated. Now only __DistroRid is supported. It will be used for both
+    # portable and non-portable rids and will be used in build-packages.sh
+
+    local targetOs="$1"
+    local buildArch="$2"
+    local isPortable="$3"
+    local rootfsDir=""
+    if [ "$#" -ge 4 ]; then
+        rootfsDir="$4"
+    fi
+
+    if [ -n "${rootfsDir}" ]; then
+        # We may have a cross build. Check for the existance of the rootfsDir
+        if [ ! -e "${rootfsDir}" ]; then
+            echo "Error rootfsDir has been passed, but the location is not valid."
+            exit 1
+        fi
+    fi
+
+    initNonPortableDistroRid "${targetOs}" "${buildArch}" "${isPortable}" "${rootfsDir}"
+
+    if [ "$buildArch" = "wasm" ]; then
+        __DistroRid=browser-wasm
+        export __DistroRid
+    fi
+
+    if [ -z "${__DistroRid}" ]; then
+        # The non-portable build rid was not set. Set the portable rid.
+
+        __PortableBuild=1
+        export __PortableBuild
+        local distroRid=""
+
+        # Check for musl-based distros (e.g Alpine Linux, Void Linux).
+        if "${rootfsDir}/usr/bin/ldd" --version 2>&1 | grep -q musl ||
+                strings "${rootfsDir}/usr/bin/ldd" 2>&1 | grep -q musl; then
+            distroRid="linux-musl-${buildArch}"
+        fi
+
+        if [ -z "${distroRid}" ]; then
+            if [ "$targetOs" = "Linux" ]; then
+                distroRid="linux-$buildArch"
+            elif [ "$targetOs" = "OSX" ]; then
+                distroRid="osx-$buildArch"
+            elif [ "$targetOs" = "MacCatalyst" ]; then
+                distroRid="maccatalyst-$buildArch"
+            elif [ "$targetOs" = "tvOS" ]; then
+                distroRid="tvos-$buildArch"
+            elif [ "$targetOs" = "tvOSSimulator" ]; then
+                distroRid="tvossimulator-$buildArch"
+            elif [ "$targetOs" = "iOS" ]; then
+                distroRid="ios-$buildArch"
+            elif [ "$targetOs" = "iOSSimulator" ]; then
+                distroRid="iossimulator-$buildArch"
+            elif [ "$targetOs" = "Android" ]; then
+                distroRid="android-$buildArch"
+            elif [ "$targetOs" = "Browser" ]; then
+                distroRid="browser-$buildArch"
+            elif [ "$targetOs" = "FreeBSD" ]; then
+                distroRid="freebsd-$buildArch"
+            elif [ "$targetOs" = "illumos" ]; then
+                distroRid="illumos-$buildArch"
+            elif [ "$targetOs" = "Solaris" ]; then
+                distroRid="solaris-$buildArch"
+            fi
+        fi
+
+        __DistroRid="${distroRid}"
+        export __DistroRid
+    fi
+
+    if [ -z "$__DistroRid" ]; then
+        echo "DistroRid is not set. This is almost certainly an error"
+        exit 1
+    fi
+
+    echo "__DistroRid: ${__DistroRid}"
+}
diff --git a/eng/native/init-os-and-arch.sh b/eng/native/init-os-and-arch.sh
new file mode 100644 (file)
index 0000000..fc4078f
--- /dev/null
@@ -0,0 +1,65 @@
+#!/usr/bin/env bash
+
+# Use uname to determine what the OS is.
+OSName=$(uname -s)
+
+if command -v getprop && getprop ro.product.system.model 2>&1 | grep -qi android; then
+    OSName="Android"
+fi
+
+case "$OSName" in
+FreeBSD|Linux|NetBSD|OpenBSD|SunOS|Android)
+    os="$OSName" ;;
+Darwin)
+    os=OSX ;;
+*)
+    echo "Unsupported OS $OSName detected, configuring as if for Linux"
+    os=Linux ;;
+esac
+
+# On Solaris, `uname -m` is discouraged, see https://docs.oracle.com/cd/E36784_01/html/E36870/uname-1.html
+# and `uname -p` returns processor type (e.g. i386 on amd64).
+# The appropriate tool to determine CPU is isainfo(1) https://docs.oracle.com/cd/E36784_01/html/E36870/isainfo-1.html.
+if [ "$os" = "SunOS" ]; then
+    if uname -o 2>&1 | grep -q illumos; then
+        os="illumos"
+    else
+        os="Solaris"
+    fi
+    CPUName=$(isainfo -n)
+else
+    # For the rest of the operating systems, use uname(1) to determine what the CPU is.
+    CPUName=$(uname -m)
+fi
+
+case "$CPUName" in
+    arm64|aarch64)
+        arch=arm64
+        ;;
+
+    amd64|x86_64)
+        arch=x64
+        ;;
+
+    armv7l)
+        if (NAME=""; . /etc/os-release; test "$NAME" = "Tizen"); then
+            arch=armel
+        else
+            arch=arm
+        fi
+        ;;
+
+    i[3-6]86)
+        echo "Unsupported CPU $CPUName detected, build might not succeed!"
+        arch=x86
+        ;;
+
+    s390x)
+        arch=s390x
+       ;;
+
+    *)
+        echo "Unknown CPU $CPUName detected, configuring as if for x64"
+        arch=x64
+        ;;
+esac
diff --git a/eng/native/init-vs-env.cmd b/eng/native/init-vs-env.cmd
new file mode 100644 (file)
index 0000000..7eefeea
--- /dev/null
@@ -0,0 +1,76 @@
+@if not defined _echo @echo off
+
+:: Initializes Visual Studio developer environment. If a build architecture is passed
+:: as an argument, it also initializes VC++ build environment and CMakePath.
+
+set "__VCBuildArch="
+if /i "%~1" == "x86"   (set __VCBuildArch=x86)
+if /i "%~1" == "x64"   (set __VCBuildArch=x86_amd64)
+if /i "%~1" == "arm"   (set __VCBuildArch=x86_arm)
+if /i "%~1" == "arm64" (set __VCBuildArch=x86_arm64)
+if /i "%~1" == "wasm"  (set __VCBuildArch=x86_amd64)
+
+:: Default to highest Visual Studio version available that has Visual C++ tools.
+::
+:: For VS2017 and later, multiple instances can be installed on the same box SxS and VS1*0COMNTOOLS
+:: is no longer set as a global environment variable and is instead only set if the user
+:: has launched the Visual Studio Developer Command Prompt.
+::
+:: Following this logic, we will default to the Visual Studio toolset assocated with the active
+:: Developer Command Prompt. Otherwise, we will query VSWhere to locate the later version of
+:: Visual Studio available on the machine. Finally, we will fail the script if no supported
+:: instance can be found.
+
+if defined VisualStudioVersion goto :VSDetected
+
+set "__VSWhere=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
+set "__VSCOMNTOOLS="
+
+if exist "%__VSWhere%" (
+    for /f "tokens=*" %%p in (
+        '"%__VSWhere%" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath'
+    ) do set __VSCOMNTOOLS=%%p\Common7\Tools
+)
+
+if not exist "%__VSCOMNTOOLS%" goto :VSMissing
+
+:: Make sure the current directory stays intact
+set "VSCMD_START_DIR=%CD%"
+
+call "%__VSCOMNTOOLS%\VsDevCmd.bat" -no_logo
+
+:: Clean up helper variables
+set "__VSWhere="
+set "__VSCOMNTOOLS="
+set "VSCMD_START_DIR="
+
+:VSDetected
+if "%VisualStudioVersion%"=="16.0" (
+    set __VSVersion=vs2019
+    set __PlatformToolset=v142
+    goto :SetVCEnvironment
+)
+if "%VisualStudioVersion%"=="17.0" (
+    set __VSVersion=vs2022
+    set __PlatformToolset=v142
+    goto :SetVCEnvironment
+)
+
+:VSMissing
+echo %__MsgPrefix%Error: Visual Studio 2019 or 2022 with C++ tools required. ^
+Please see https://github.com/dotnet/runtime/blob/main/docs/workflow/requirements/windows-requirements.md for build requirements.
+exit /b 1
+
+:SetVCEnvironment
+
+if "%__VCBuildArch%"=="" exit /b 0
+
+:: Set the environment for the native build
+call "%VCINSTALLDIR%Auxiliary\Build\vcvarsall.bat" %__VCBuildArch%
+if not "%ErrorLevel%"=="0" exit /b 1
+
+set "__VCBuildArch="
+
+:: Set CMakePath by evaluating the output from set-cmake-path.ps1.
+:: In case of a failure the output is "exit /b 1".
+for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy ByPass -File "%~dp0set-cmake-path.ps1"') do %%a
diff --git a/eng/native/naming.props b/eng/native/naming.props
new file mode 100644 (file)
index 0000000..7a02d6c
--- /dev/null
@@ -0,0 +1,54 @@
+<Project>
+  <PropertyGroup>
+    <StaticLibPrefix>lib</StaticLibPrefix>
+  </PropertyGroup>
+
+  <!-- Add path globs specific to native binaries to exclude unnecessary files from packages. -->
+  <Choose>
+    <When Condition="$(PackageRID.StartsWith('win'))">
+      <PropertyGroup>
+        <ExeSuffix>.exe</ExeSuffix>
+        <LibSuffix>.dll</LibSuffix>
+        <StaticLibSuffix>.lib</StaticLibSuffix>
+        <SymbolsSuffix>.pdb</SymbolsSuffix>
+      </PropertyGroup>
+    </When>
+    <When Condition="$(PackageRID.StartsWith('osx'))">
+      <PropertyGroup>
+        <LibPrefix Condition=" '$(SkipLibraryPrefixFromUnix)' == '' ">lib</LibPrefix>
+        <LibSuffix>.dylib</LibSuffix>
+        <StaticLibSuffix>.a</StaticLibSuffix>
+        <SymbolsSuffix>.dwarf</SymbolsSuffix>
+      </PropertyGroup>
+    </When>
+    <When Condition="$(PackageRID.StartsWith('android'))">
+      <PropertyGroup>
+        <LibPrefix Condition=" '$(SkipLibraryPrefixFromUnix)' == '' ">lib</LibPrefix>
+        <LibSuffix>.so</LibSuffix>
+        <StaticLibSuffix>.a</StaticLibSuffix>
+        <!--symbols included in .so, like Linux, but can be generated externally and if so, uses .debug ext-->
+        <SymbolsSuffix>.debug</SymbolsSuffix>
+      </PropertyGroup>
+    </When>
+    <Otherwise>
+      <PropertyGroup>
+        <LibPrefix Condition=" '$(SkipLibraryPrefixFromUnix)' == '' ">lib</LibPrefix>
+        <LibSuffix>.so</LibSuffix>
+        <StaticLibSuffix>.a</StaticLibSuffix>
+        <SymbolsSuffix>.dbg</SymbolsSuffix>
+      </PropertyGroup>
+    </Otherwise>
+  </Choose>
+
+  <ItemGroup>
+    <AdditionalLibPackageExcludes Condition="'$(SymbolsSuffix)' != ''" Include="%2A%2A\%2A$(SymbolsSuffix)" />
+    <AdditionalSymbolPackageExcludes Condition="'$(LibSuffix)' != ''" Include="%2A%2A\%2A.a;%2A%2A\%2A$(LibSuffix)" />
+  </ItemGroup>
+
+  <!-- arcade is using long name for this property; 'SymbolFileExtension'.
+       remove this property group when arcade is updated with short name (SymbolsSuffix). -->
+  <PropertyGroup>
+    <SymbolFileExtension>$(SymbolsSuffix)</SymbolFileExtension>
+  </PropertyGroup>
+
+</Project>
diff --git a/eng/native/output-toolchain-info.cmake b/eng/native/output-toolchain-info.cmake
new file mode 100644 (file)
index 0000000..8eed988
--- /dev/null
@@ -0,0 +1,21 @@
+# Output the toolchain information required to create a command line that builds with the right rootfs as XML
+
+set (ADDED_COMPILE_OPTIONS)
+if (CMAKE_SCRIPT_MODE_FILE)
+  # add_compile_options and add_definitions can't be used in scripts,
+  # so override the implementations to append to a local property
+  macro(add_compile_options)
+    list(APPEND ADDED_COMPILE_OPTIONS ${ARGV})
+  endmacro()
+  macro(add_definitions)
+    list(APPEND ADDED_COMPILE_OPTIONS ${ARGV})
+  endmacro()
+endif()
+
+include(${CMAKE_CURRENT_LIST_DIR}/../common/cross/toolchain.cmake)
+
+message("<toolchain-info>")
+message("<target-triple>${TOOLCHAIN}</target-triple>")
+message("<linker-args>${CMAKE_SHARED_LINKER_FLAGS_INIT}</linker-args>")
+message("<compiler-args>${ADDED_COMPILE_OPTIONS}</compiler-args>")
+message("</toolchain-info>")
\ No newline at end of file
diff --git a/eng/native/sanitizerblacklist.txt b/eng/native/sanitizerblacklist.txt
new file mode 100644 (file)
index 0000000..ecc8bef
--- /dev/null
@@ -0,0 +1,14 @@
+# This file has exclusions to the Clang address sanitizer to suppress error reports
+# When Clang 3.8 is available, convert these to suppression list instead as that is preferred for internal code
+
+# CMiniMdBase::UsesAllocatedMemory - suppress stack-buffer-underflow (code backs up pointer by -1 to check allocation ownership)
+fun:_ZN11CMiniMdBase19UsesAllocatedMemoryEP11CMiniColDef
+
+# JIT_InitPInvokeFrame - suppress unknown sanitizer issue causing SEGV on unknown address 0x000000000000
+# 0 0x4e8a0c in __ubsan::checkDynamicType(void*, void*, unsigned long)
+# 1 0x4e807f in HandleDynamicTypeCacheMiss(__ubsan::DynamicTypeCacheMissData*, unsigned long, unsigned long, __ubsan::ReportOptions)
+# 2 0x4e8051 in __ubsan_handle_dynamic_type_cache_miss
+# 3 0x7f02ce676cd8 in JIT_InitPInvokeFrame(InlinedCallFrame*, void*) /home/steveharter/git/dotnet_coreclr/vm/jithelpers.cpp:6491:9
+# 4 0x7f0252bbceb2  (<unknown module>)
+fun:_Z20JIT_InitPInvokeFrameP16InlinedCallFramePv
+
diff --git a/eng/native/set-cmake-path.ps1 b/eng/native/set-cmake-path.ps1
new file mode 100644 (file)
index 0000000..d83ce5a
--- /dev/null
@@ -0,0 +1,48 @@
+# This script locates the CMake executable for the build system and outputs either the "set CMakePath=..."
+# command (if CMake is found) or the "exit /b 1" command (if not found) for evaluating from batch files.
+
+Set-StrictMode -Version 3
+
+function LocateCMake {
+  # Find the first cmake.exe on the PATH
+  $cmakeApp = (Get-Command cmake.exe -ErrorAction SilentlyContinue)
+  if ($cmakeApp -ne $null) {
+    return $cmakeApp.Path
+  }
+
+  # Find cmake.exe using the registry
+  $cmakeRegKey = Get-ItemProperty HKLM:\SOFTWARE\Kitware\CMake -Name InstallDir -ErrorAction SilentlyContinue
+  if ($cmakeRegKey -eq $null) {
+    $cmakeRegKey = Get-ItemProperty HKLM:\SOFTWARE\Wow6432Node\Kitware\CMake -Name InstallDir -ErrorAction SilentlyContinue
+  }
+
+  if ($cmakeRegKey -ne $null) {
+    $cmakePath = $cmakeRegKey.InstallDir + "bin\cmake.exe"
+    if (Test-Path $cmakePath -PathType Leaf) {
+      return $cmakePath
+    }
+  }
+
+  return $null
+}
+
+try {
+  $cmakePath = LocateCMake
+
+  if ($cmakePath -eq $null) {
+    throw "CMake is a pre-requisite to build this repository but it was not found on the PATH or in the registry. Please install CMake from https://cmake.org/download/."
+  }
+
+  $version = [Version]$(& $cmakePath --version | Select-String -Pattern '\d+\.\d+\.\d+' | %{$_.Matches.Value})
+
+  if ($version -lt [Version]"3.16.4") {
+    throw "CMake 3.16.4 or newer is required for building this repository. The newest version of CMake installed is $version. Please install CMake 3.16.4 or newer from https://cmake.org/download/."
+  }
+
+  [System.Console]::WriteLine("set CMakePath=" + $cmakePath)
+
+}
+catch {
+  [System.Console]::Error.WriteLine($_.Exception.Message)
+  [System.Console]::WriteLine("exit /b 1")
+}
diff --git a/eng/native/tryrun.cmake b/eng/native/tryrun.cmake
new file mode 100644 (file)
index 0000000..9619996
--- /dev/null
@@ -0,0 +1,154 @@
+set(CROSS_ROOTFS $ENV{ROOTFS_DIR})
+set(TARGET_ARCH_NAME $ENV{TARGET_BUILD_ARCH})
+
+macro(set_cache_value)
+  set(${ARGV0} ${ARGV1} CACHE STRING "Result from TRY_RUN" FORCE)
+  set(${ARGV0}__TRYRUN_OUTPUT "dummy output" CACHE STRING "Output from TRY_RUN" FORCE)
+endmacro()
+
+if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv7-alpine-linux-musleabihf OR
+   EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv6-alpine-linux-musleabihf OR
+   EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/aarch64-alpine-linux-musl)
+
+  set(ALPINE_LINUX 1)
+elseif(EXISTS ${CROSS_ROOTFS}/bin/freebsd-version)
+  set(FREEBSD 1)
+  set(CMAKE_SYSTEM_NAME FreeBSD)
+  set(CLR_CMAKE_TARGET_OS FreeBSD)
+elseif(EXISTS ${CROSS_ROOTFS}/usr/platform/i86pc)
+  set(ILLUMOS 1)
+  set(CLR_CMAKE_TARGET_OS SunOS)
+elseif(EXISTS /System/Library/CoreServices)
+  set(DARWIN 1)
+endif()
+
+if(DARWIN)
+  if(TARGET_ARCH_NAME MATCHES "^(arm64|x64)$")
+    set_cache_value(FILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL_EXITCODE 1)
+    set_cache_value(GETPWUID_R_SETS_ERRNO_EXITCODE 1)
+    set_cache_value(HAS_POSIX_SEMAPHORES_EXITCODE 1)
+    set_cache_value(HAVE_BROKEN_FIFO_KEVENT_EXITCODE 1)
+    set_cache_value(HAVE_BROKEN_FIFO_SELECT_EXITCODE 1)
+    set_cache_value(HAVE_CLOCK_MONOTONIC_COARSE_EXITCODE 1)
+    set_cache_value(HAVE_CLOCK_MONOTONIC_EXITCODE 0)
+    set_cache_value(HAVE_CLOCK_REALTIME_EXITCODE 0)
+    set_cache_value(HAVE_CLOCK_THREAD_CPUTIME_EXITCODE 0)
+    set_cache_value(HAVE_CLOCK_GETTIME_NSEC_NP_EXITCODE 0)
+    set_cache_value(HAVE_COMPATIBLE_ACOS_EXITCODE 0)
+    set_cache_value(HAVE_COMPATIBLE_ASIN_EXITCODE 0)
+    set_cache_value(HAVE_COMPATIBLE_ATAN2_EXITCODE 0)
+    set_cache_value(HAVE_COMPATIBLE_EXP_EXITCODE 1)
+    set_cache_value(HAVE_COMPATIBLE_ILOGB0_EXITCODE 0)
+    set_cache_value(HAVE_COMPATIBLE_ILOGBNAN_EXITCODE 1)
+    set_cache_value(HAVE_COMPATIBLE_LOG10_EXITCODE 0)
+    set_cache_value(HAVE_COMPATIBLE_LOG_EXITCODE 0)
+    set_cache_value(HAVE_COMPATIBLE_POW_EXITCODE 0)
+    set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 1)
+    set_cache_value(HAVE_LARGE_SNPRINTF_SUPPORT_EXITCODE 0)
+    set_cache_value(HAVE_MMAP_DEV_ZERO_EXITCODE 1)
+    set_cache_value(HAVE_PROCFS_CTL_EXITCODE 1)
+    set_cache_value(HAVE_PROCFS_MAPS_EXITCODE 1)
+    set_cache_value(HAVE_PROCFS_STATUS_EXITCODE 1)
+    set_cache_value(HAVE_PROCFS_STAT_EXITCODE 1)
+    set_cache_value(HAVE_SCHED_GETCPU_EXITCODE 1)
+    set_cache_value(HAVE_SCHED_GET_PRIORITY_EXITCODE 0)
+    set_cache_value(HAVE_VALID_NEGATIVE_INF_POW_EXITCODE 0)
+    set_cache_value(HAVE_VALID_POSITIVE_INF_POW_EXITCODE 0)
+    set_cache_value(HAVE_WORKING_CLOCK_GETTIME_EXITCODE 0)
+    set_cache_value(HAVE_WORKING_GETTIMEOFDAY_EXITCODE 0)
+    set_cache_value(MMAP_ANON_IGNORES_PROTECTION_EXITCODE 1)
+    set_cache_value(ONE_SHARED_MAPPING_PER_FILEREGION_PER_PROCESS_EXITCODE 1)
+    set_cache_value(PTHREAD_CREATE_MODIFIES_ERRNO_EXITCODE 1)
+    set_cache_value(REALPATH_SUPPORTS_NONEXISTENT_FILES_EXITCODE 1)
+    set_cache_value(SEM_INIT_MODIFIES_ERRNO_EXITCODE 1)
+    set_cache_value(SSCANF_CANNOT_HANDLE_MISSING_EXPONENT_EXITCODE 1)
+    set_cache_value(SSCANF_SUPPORT_ll_EXITCODE 0)
+    set_cache_value(UNGETC_NOT_RETURN_EOF_EXITCODE 1)
+    set_cache_value(HAVE_SHM_OPEN_THAT_WORKS_WELL_ENOUGH_WITH_MMAP_EXITCODE 0)
+  else()
+    message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only arm64 or x64 is supported for OSX cross build!")
+  endif()
+elseif(TARGET_ARCH_NAME MATCHES "^(armel|arm|arm64|s390x|x86)$" OR FREEBSD OR ILLUMOS)
+  set_cache_value(FILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL_EXITCODE 1)
+  set_cache_value(GETPWUID_R_SETS_ERRNO_EXITCODE 0)
+  set_cache_value(HAS_POSIX_SEMAPHORES_EXITCODE 0)
+  set_cache_value(HAVE_CLOCK_MONOTONIC_COARSE_EXITCODE 0)
+  set_cache_value(HAVE_CLOCK_MONOTONIC_EXITCODE 0)
+  set_cache_value(HAVE_CLOCK_REALTIME_EXITCODE 0)
+  set_cache_value(HAVE_CLOCK_THREAD_CPUTIME_EXITCODE 0)
+  set_cache_value(HAVE_COMPATIBLE_ACOS_EXITCODE 0)
+  set_cache_value(HAVE_COMPATIBLE_ASIN_EXITCODE 0)
+  set_cache_value(HAVE_COMPATIBLE_ATAN2_EXITCODE 0)
+  set_cache_value(HAVE_COMPATIBLE_ILOGB0_EXITCODE 1)
+  set_cache_value(HAVE_COMPATIBLE_ILOGBNAN_EXITCODE 1)
+  set_cache_value(HAVE_COMPATIBLE_LOG10_EXITCODE 0)
+  set_cache_value(HAVE_COMPATIBLE_LOG_EXITCODE 0)
+  set_cache_value(HAVE_COMPATIBLE_POW_EXITCODE 0)
+  set_cache_value(HAVE_LARGE_SNPRINTF_SUPPORT_EXITCODE 0)
+  set_cache_value(HAVE_MMAP_DEV_ZERO_EXITCODE 0)
+  set_cache_value(HAVE_PROCFS_CTL_EXITCODE 1)
+  set_cache_value(HAVE_PROCFS_MAPS_EXITCODE 0)
+  set_cache_value(HAVE_PROCFS_STATUS_EXITCODE 0)
+  set_cache_value(HAVE_PROCFS_STAT_EXITCODE 0)
+  set_cache_value(HAVE_SCHED_GETCPU_EXITCODE 0)
+  set_cache_value(HAVE_SCHED_GET_PRIORITY_EXITCODE 0)
+  set_cache_value(HAVE_VALID_NEGATIVE_INF_POW_EXITCODE 0)
+  set_cache_value(HAVE_VALID_POSITIVE_INF_POW_EXITCODE 0)
+  set_cache_value(HAVE_WORKING_CLOCK_GETTIME_EXITCODE 0)
+  set_cache_value(HAVE_WORKING_GETTIMEOFDAY_EXITCODE 0)
+  set_cache_value(ONE_SHARED_MAPPING_PER_FILEREGION_PER_PROCESS_EXITCODE 1)
+  set_cache_value(PTHREAD_CREATE_MODIFIES_ERRNO_EXITCODE 1)
+  set_cache_value(REALPATH_SUPPORTS_NONEXISTENT_FILES_EXITCODE 1)
+  set_cache_value(SEM_INIT_MODIFIES_ERRNO_EXITCODE 1)
+
+
+  if(ALPINE_LINUX)
+    set_cache_value(HAVE_SHM_OPEN_THAT_WORKS_WELL_ENOUGH_WITH_MMAP_EXITCODE 1)
+    set_cache_value(SSCANF_CANNOT_HANDLE_MISSING_EXPONENT_EXITCODE 0)
+    set_cache_value(SSCANF_SUPPORT_ll_EXITCODE 1)
+    set_cache_value(UNGETC_NOT_RETURN_EOF_EXITCODE 1)
+  else()
+    set_cache_value(HAVE_SHM_OPEN_THAT_WORKS_WELL_ENOUGH_WITH_MMAP_EXITCODE 0)
+    set_cache_value(SSCANF_CANNOT_HANDLE_MISSING_EXPONENT_EXITCODE 1)
+    set_cache_value(SSCANF_SUPPORT_ll_EXITCODE 0)
+    set_cache_value(UNGETC_NOT_RETURN_EOF_EXITCODE 0)
+  endif()
+
+  if (FREEBSD)
+    set_cache_value(HAVE_SHM_OPEN_THAT_WORKS_WELL_ENOUGH_WITH_MMAP 1)
+    set_cache_value(HAVE_CLOCK_MONOTONIC 1)
+    set_cache_value(HAVE_CLOCK_REALTIME 1)
+    set_cache_value(HAVE_BROKEN_FIFO_KEVENT_EXITCODE 1)
+    set_cache_value(HAVE_PROCFS_MAPS 0)
+    set_cache_value(HAVE_PROCFS_STAT 0)
+    set_cache_value(HAVE_PROCFS_STATUS_EXITCODE 1)
+    set_cache_value(GETPWUID_R_SETS_ERRNO 0)
+    set_cache_value(UNGETC_NOT_RETURN_EOF 0)
+    set_cache_value(HAVE_COMPATIBLE_ILOGBNAN 1)
+    set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 0)
+  elseif(ILLUMOS)
+    set_cache_value(GETPWUID_R_SETS_ERRNO_EXITCODE 1)
+    set_cache_value(HAVE_COMPATIBLE_ACOS_EXITCODE 1)
+    set_cache_value(HAVE_COMPATIBLE_ASIN_EXITCODE 1)
+    set_cache_value(HAVE_COMPATIBLE_ATAN2_EXITCODE 1)
+    set_cache_value(HAVE_COMPATIBLE_POW_EXITCODE 1)
+    set_cache_value(HAVE_COMPATIBLE_ILOGBNAN_EXITCODE 0)
+    set_cache_value(HAVE_COMPATIBLE_LOG10_EXITCODE 1)
+    set_cache_value(HAVE_COMPATIBLE_LOG_EXITCODE 1)
+    set_cache_value(HAVE_LARGE_SNPRINTF_SUPPORT_EXITCODE 1)
+    set_cache_value(HAVE_PROCFS_CTL_EXITCODE 0)
+    set_cache_value(SSCANF_CANNOT_HANDLE_MISSING_EXPONENT_EXITCODE 1)
+    set_cache_value(SSCANF_SUPPORT_ll_EXITCODE 1)
+    set_cache_value(UNGETC_NOT_RETURN_EOF_EXITCODE 0)
+    set_cache_value(COMPILER_SUPPORTS_W_CLASS_MEMACCESS 1)
+    set_cache_value(HAVE_SET_MAX_VARIABLE 1)
+    set_cache_value(HAVE_FULLY_FEATURED_PTHREAD_MUTEXES 1)
+    set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 0)
+  endif()
+else()
+  message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only armel, arm, arm64, s390x and x86 are supported!")
+endif()
+
+if(TARGET_ARCH_NAME STREQUAL "x86" OR TARGET_ARCH_NAME STREQUAL "s390x")
+  set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 0)
+endif()
diff --git a/eng/native/version/NativeVersion.rc b/eng/native/version/NativeVersion.rc
new file mode 100644 (file)
index 0000000..618bb11
--- /dev/null
@@ -0,0 +1,41 @@
+#include "_version.h"
+
+#include <windows.h>
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION     VER_FILEVERSION
+PRODUCTVERSION  VER_PRODUCTVERSION
+FILEFLAGSMASK   VS_FFI_FILEFLAGSMASK
+FILEFLAGS       VER_DEBUG
+FILEOS          VOS__WINDOWS32
+FILETYPE        VFT_DLL
+FILESUBTYPE     VFT2_UNKNOWN
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904E4"
+        BEGIN
+            VALUE "CompanyName",      VER_COMPANYNAME_STR
+            VALUE "FileDescription",  VER_FILEDESCRIPTION_STR
+            VALUE "FileVersion",      VER_FILEVERSION_STR
+            VALUE "InternalName",     VER_INTERNALNAME_STR
+            VALUE "LegalCopyright",   VER_LEGALCOPYRIGHT_STR
+            VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR
+            VALUE "ProductName",      VER_PRODUCTNAME_STR
+            VALUE "ProductVersion",   VER_PRODUCTVERSION_STR
+        END
+    END
+
+    BLOCK "VarFileInfo"
+    BEGIN
+        /* The following line should only be modified for localized versions.     */
+        /* It consists of any number of WORD,WORD pairs, with each pair           */
+        /* describing a language,codepage combination supported by the file.      */
+        /*                                                                        */
+        /* For example, a file might have values "0x409,1252" indicating that it  */
+        /* supports English language (0x409) in the Windows ANSI codepage (1252). */
+
+        VALUE "Translation", 0x409, 1252
+
+    END
+END
diff --git a/eng/native/version/_version.c b/eng/native/version/_version.c
new file mode 100644 (file)
index 0000000..153d9f0
--- /dev/null
@@ -0,0 +1,4 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+static char sccsid[] __attribute__((used)) = "@(#)No version information produced";
diff --git a/eng/native/version/_version.h b/eng/native/version/_version.h
new file mode 100644 (file)
index 0000000..25268bf
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef VER_COMPANYNAME_STR
+#define VER_COMPANYNAME_STR         ".NET Foundation"
+#endif
+#ifndef VER_FILEDESCRIPTION_STR
+#define VER_FILEDESCRIPTION_STR     ".NET Runtime"
+#endif
+#ifndef VER_INTERNALNAME_STR
+#define VER_INTERNALNAME_STR        VER_FILEDESCRIPTION_STR
+#endif
+#ifndef VER_ORIGINALFILENAME_STR
+#define VER_ORIGINALFILENAME_STR    VER_FILEDESCRIPTION_STR
+#endif
+#ifndef VER_PRODUCTNAME_STR
+#define VER_PRODUCTNAME_STR         ".NET"
+#endif
+#undef VER_PRODUCTVERSION
+#define VER_PRODUCTVERSION          00,00,00,00000
+#undef VER_PRODUCTVERSION_STR
+#define VER_PRODUCTVERSION_STR      "0.0.0"
+#undef VER_FILEVERSION
+#define VER_FILEVERSION             00,00,00,00000
+#undef VER_FILEVERSION_STR
+#define VER_FILEVERSION_STR         "00,00,00,00000"
+#ifndef VER_LEGALCOPYRIGHT_STR
+#define VER_LEGALCOPYRIGHT_STR      ".NET Foundation"
+#endif
+#ifndef VER_DEBUG
+#define VER_DEBUG                   VS_FF_DEBUG
+#endif
diff --git a/eng/native/version/copy_version_files.cmd b/eng/native/version/copy_version_files.cmd
new file mode 100644 (file)
index 0000000..ef5f31e
--- /dev/null
@@ -0,0 +1,12 @@
+@if not defined _echo @echo off
+setlocal EnableDelayedExpansion EnableExtensions
+
+set __VersionFolder=%~dp0
+set __RepoRoot=%~dp0..\..\..
+set __artifactsObjDir=%__RepoRoot%\artifacts\obj
+
+for /r "%__VersionFolder%" %%a in (*.h *.rc) do (
+    if not exist "%__artifactsObjDir%\%%~nxa" (
+        copy "%%a" "%__artifactsObjDir%"
+    )
+)
diff --git a/eng/native/version/copy_version_files.sh b/eng/native/version/copy_version_files.sh
new file mode 100755 (executable)
index 0000000..d60ed47
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+
+__VersionFolder="$(cd "$(dirname "$0")"; pwd -P)"
+__RepoRoot="$(cd "$(dirname "$__VersionFolder")/../../"; pwd -P)"
+
+for path in "${__VersionFolder}/"*{.h,.c}; do
+    if [[ "$(basename $path)" == _version.c ]]; then
+        # For _version.c, update the commit ID if it has changed from the last build.
+        # Set IFS to nothing to prevent the shell from combining all of the piped output into a single line in the script below
+        IFS=
+        # update commit
+        commit="$(git rev-parse HEAD 2>/dev/null)"
+        commit="${commit:-N/A}"
+        substitute="$(printf 'static char sccsid[] __attribute__((used)) = "@(#)Version N/A @Commit: %s";\n' "$commit")"
+        version_file_contents="$(cat "$path" | sed "s|^static.*|$substitute|")"
+        version_file_destination="$__RepoRoot/artifacts/obj/_version.c"
+        current_contents=
+        is_placeholder_file=
+        if [[ -e "$version_file_destination" ]]; then
+            current_contents="$(<"$__RepoRoot/artifacts/obj/_version.c")"
+            # If the current file has the version placeholder this script uses, we can update it
+            # to have the current commit. Otherwise, use the current version file that has the actual product version.
+            is_placeholder_file="$(echo $current_contents | grep "@(#)Version N/A @Commit:")"
+        else
+            # Treat a non-existent file like a file that doesn't exist.
+            is_placeholder_file=1
+        fi
+        if [[ "$is_placeholder_file" && "$version_file_contents" != "$current_contents" ]]; then
+            echo "$version_file_contents" > "$version_file_destination"
+        fi
+    elif [[ ! -e "$__RepoRoot/artifacts/obj/$(basename "$path")" ]]; then
+        cp "$path" "$__RepoRoot/artifacts/obj/"
+    fi
+done
diff --git a/eng/native/version/runtime_version.h b/eng/native/version/runtime_version.h
new file mode 100644 (file)
index 0000000..12b55fe
--- /dev/null
@@ -0,0 +1,10 @@
+#define RuntimeAssemblyMajorVersion 0
+#define RuntimeAssemblyMinorVersion 0
+#define RuntimeFileMajorVersion 0
+#define RuntimeFileMinorVersion 0
+#define RuntimeFileBuildVersion 0
+#define RuntimeFileRevisionVersion 0
+#define RuntimeProductMajorVersion 0
+#define RuntimeProductMinorVersion 0
+#define RuntimeProductPatchVersion 0
+#define RuntimeProductVersion 0.0.0-dev