Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/eng
diff options
context:
space:
mode:
authorAdeel Mujahid <adeelbm@outlook.com>2020-01-23 11:47:40 +0300
committerJan Vorlicek <janvorli@microsoft.com>2020-01-23 11:47:40 +0300
commit879e5964a9fe57eb96d0e0d313dd05d58a3351c7 (patch)
treed47a62b53ba4d7f048d0a6f02ce61bfe1ad64078 /eng
parentc6e91455a206d391ed6a23c9208645cff3a058f6 (diff)
Unify build_native via eng/native/build-commons (#1753)
* Unify build_native via eng/native/build-commons In order to add new platform, architecture, compiler or its newer version, there are currently multiple places to update, which can be deduplicated. This patch unifies: * directories creation * prerequisites checking * `version.c` generation * native build invocation * common argument parsing * building help menu for various build scripts under coreclr, installer and libraries. The common entry-point script is now `eng/native/build-commons.sh` and rest of the scripts under `eng/native` are implementation detail. Also extracted CMake platform detection in `eng/native/configureplatform.cmake`, to share with coreclr and `installer/corehost`. * Use if [[ cond ]] in all places
Diffstat (limited to 'eng')
-rwxr-xr-xeng/native/build-commons.sh479
-rw-r--r--eng/native/configureplatform.cmake182
-rw-r--r--eng/native/functions.cmake389
-rwxr-xr-xeng/native/gen-buildsys.sh97
-rw-r--r--eng/native/init-distro-rid.sh168
-rw-r--r--eng/pipelines/installer/jobs/base-job.yml2
-rw-r--r--eng/pipelines/libraries/base-job.yml6
-rw-r--r--eng/pipelines/libraries/build-job.yml2
8 files changed, 1272 insertions, 53 deletions
diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh
new file mode 100755
index 00000000000..4728876c0db
--- /dev/null
+++ b/eng/native/build-commons.sh
@@ -0,0 +1,479 @@
+#!/usr/bin/env bash
+
+initTargetDistroRid()
+{
+ source "$__RepoRootDir/eng/native/init-distro-rid.sh"
+
+ local passedRootfsDir=""
+
+ # Only pass ROOTFS_DIR if cross is specified.
+ if [[ "$__CrossBuild" == 1 ]]; then
+ passedRootfsDir="$ROOTFS_DIR"
+ fi
+
+ initDistroRidGlobal "$__BuildOS" "$__BuildArch" "$__PortableBuild" "$passedRootfsDir"
+}
+
+isMSBuildOnNETCoreSupported()
+{
+ __IsMSBuildOnNETCoreSupported="$__msbuildonunsupportedplatform"
+
+ if [[ "$__IsMSBuildOnNETCoreSupported" == 1 ]]; then
+ return
+ fi
+
+ if [[ "$__SkipManaged" == 1 ]]; then
+ __IsMSBuildOnNETCoreSupported=0
+ return
+ fi
+
+ if [[ ( "$__HostOS" == "Linux" ) && ( "$__HostArch" == "x64" || "$__HostArch" == "arm" || "$__HostArch" == "arm64" ) ]]; then
+ __IsMSBuildOnNETCoreSupported=1
+ elif [[ "$__HostArch" == "x64" && ( "$__HostOS" == "OSX" || "$__HostOS" == "FreeBSD" ) ]]; then
+ __IsMSBuildOnNETCoreSupported=1
+ fi
+}
+
+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..."
+
+ # Check presence of CMake on the path
+ command -v cmake 2>/dev/null || { echo >&2 "Please install cmake before running this script"; exit 1; }
+
+ function version { echo "$@" | awk -F. '{ printf("%d%02d%02d\n", $1,$2,$3); }'; }
+
+ local cmake_version="$(cmake --version | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+")"
+
+ if [[ "$(version "$cmake_version")" -lt "$(version 3.14.2)" ]]; then
+ echo "Please install CMake 3.14.2 or newer from http://www.cmake.org/download/ or https://apt.kitware.com and ensure it is on your path."; exit 1;
+ 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()
+{
+ platformArch="$1"
+ cmakeDir="$2"
+ tryrunDir="$3"
+ intermediatesDir="$4"
+ message="$5"
+
+ # All set to commence the build
+ echo "Commencing build of \"$message\" for $__BuildOS.$__BuildArch.$__BuildType in $intermediatesDir"
+
+ if [[ "$__UseNinja" == 1 ]]; then
+ generator="ninja"
+ buildTool="$(command -v ninja || command -v ninja-build)"
+ else
+ buildTool="make"
+ fi
+
+ if [[ "$__SkipConfigure" == 0 ]]; then
+ # if msbuild is not supported, then set __SkipGenerateVersion to 1
+ if [[ "$__IsMSBuildOnNETCoreSupported" == 0 ]]; then __SkipGenerateVersion=1; fi
+ # Drop version.c file
+ __versionSourceFile="$intermediatesDir/version.c"
+ if [[ "$__SkipGenerateVersion" == 0 ]]; then
+ "$__RepoRootDir/eng/common/msbuild.sh" /clp:nosummary "$__ArcadeScriptArgs" "$__RepoRootDir"/eng/empty.csproj \
+ /p:NativeVersionFile="$__versionSourceFile" \
+ /t:GenerateNativeVersionFile /restore \
+ $__CommonMSBuildArgs $__UnprocessedBuildArgs
+ local exit_code="$?"
+ if [[ "$exit_code" != 0 ]]; then
+ echo "${__ErrMsgPrefix}Failed to generate native version file."
+ exit "$exit_code"
+ fi
+ else
+ # Generate the dummy version.c, but only if it didn't exist to make sure we don't trigger unnecessary rebuild
+ __versionSourceLine="static char sccsid[] __attribute__((used)) = \"@(#)No version information produced\";"
+ if [[ -e "$__versionSourceFile" ]]; then
+ read existingVersionSourceLine < "$__versionSourceFile"
+ fi
+ if [[ "$__versionSourceLine" != "$existingVersionSourceLine" ]]; then
+ echo "$__versionSourceLine" > "$__versionSourceFile"
+ fi
+ fi
+
+ if [[ "$__StaticAnalyzer" == 1 ]]; then
+ scan_build=scan-build
+ fi
+
+ engNativeDir="$__RepoRootDir/eng/native"
+ __CMakeArgs="-DCLR_ENG_NATIVE_DIR=\"$engNativeDir\" $__CMakeArgs"
+ nextCommand="\"$engNativeDir/gen-buildsys.sh\" \"$cmakeDir\" \"$tryrunDir\" \"$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
+
+ if [[ "$__StaticAnalyzer" == 1 ]]; then
+ pushd "$intermediatesDir"
+
+ buildTool="$SCAN_BUILD_COMMAND -o $__BinDir/scan-build-log $buildTool"
+ echo "Executing $buildTool install -j $__NumProc"
+ "$buildTool" install -j "$__NumProc"
+
+ popd
+ else
+ echo "Executing cmake --build \"$intermediatesDir\" --target install -j $__NumProc"
+ cmake --build "$intermediatesDir" --target install -j "$__NumProc"
+ fi
+
+ local exit_code="$?"
+ 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, -armel, x64, x86, -wasm"
+ echo "BuildType can be: -debug, -checked, -release"
+ 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 "-msbuildonunsupportedplatform: build managed binaries even if distro is not officially supported."
+ 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 "-skipgenerateversion: disable version generation even if MSBuild is supported."
+ echo "-stripsymbols: skip native image generation."
+ 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
+}
+
+# Use uname to determine what the CPU is.
+CPUName=$(uname -p)
+
+# Some Linux platforms report unknown for platform, but the arch for machine.
+if [[ "$CPUName" == "unknown" ]]; then
+ CPUName=$(uname -m)
+fi
+
+case "$CPUName" in
+ aarch64)
+ __BuildArch=arm64
+ __HostArch=arm64
+ ;;
+
+ amd64)
+ __BuildArch=x64
+ __HostArch=x64
+ ;;
+
+ armv7l)
+ echo "Unsupported CPU $CPUName detected, build might not succeed!"
+ __BuildArch=arm
+ __HostArch=arm
+ ;;
+
+ i686)
+ echo "Unsupported CPU $CPUName detected, build might not succeed!"
+ __BuildArch=x86
+ __HostArch=x86
+ ;;
+
+ x86_64)
+ __BuildArch=x64
+ __HostArch=x64
+ ;;
+
+ *)
+ echo "Unknown CPU $CPUName detected, configuring as if for x64"
+ __BuildArch=x64
+ __HostArch=x64
+ ;;
+esac
+
+# Use uname to determine what the OS is.
+OSName=$(uname -s)
+case "$OSName" in
+ Darwin)
+ __BuildOS=OSX
+ __HostOS=OSX
+ ;;
+
+ FreeBSD)
+ __BuildOS=FreeBSD
+ __HostOS=FreeBSD
+ ;;
+
+ Linux)
+ __BuildOS=Linux
+ __HostOS=Linux
+ ;;
+
+ NetBSD)
+ __BuildOS=NetBSD
+ __HostOS=NetBSD
+ ;;
+
+ OpenBSD)
+ __BuildOS=OpenBSD
+ __HostOS=OpenBSD
+ ;;
+
+ SunOS)
+ __BuildOS=SunOS
+ __HostOS=SunOS
+ ;;
+
+ *)
+ echo "Unsupported OS $OSName detected, configuring as if for Linux"
+ __BuildOS=Linux
+ __HostOS=Linux
+ ;;
+esac
+
+__msbuildonunsupportedplatform=0
+
+while :; do
+ if [[ "$#" -le 0 ]]; then
+ break
+ fi
+
+ lowerI="$(echo "$1" | awk '{print tolower($0)}')"
+ 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]}"
+ ;;
+
+ msbuildonunsupportedplatform|-msbuildonunsupportedplatform)
+ __msbuildonunsupportedplatform=1
+ ;;
+
+ 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
+ ;;
+
+ skipgenerateversion|-skipgenerateversion)
+ __SkipGenerateVersion=1
+ ;;
+
+ stripsymbols|-stripsymbols)
+ __CMakeArgs="-DSTRIP_SYMBOLS=true $__CMakeArgs"
+ ;;
+
+ verbose|-verbose)
+ __VerboseBuild=1
+ ;;
+
+ x86|-x86)
+ __BuildArch=x86
+ ;;
+
+ x64|-x64)
+ __BuildArch=x64
+ ;;
+
+ wasm|-wasm)
+ __BuildArch=wasm
+ ;;
+
+ *)
+ handle_arguments "$1" "$2"
+ if [[ "$__ShiftArgs" == 1 ]]; then
+ shift
+ __ShiftArgs=0
+ fi
+ ;;
+ esac
+
+ shift
+done
+
+# 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 hw.ncpu | awk '{ print $2+1 }')
+elif [[ "$platform" == "NetBSD" ]]; then
+ __NumProc=$(($(getconf NPROCESSORS_ONLN)+1))
+elif [[ "$platform" == "Darwin" ]]; then
+ __NumProc=$(($(getconf _NPROCESSORS_ONLN)+1))
+else
+ __NumProc=$(nproc --all)
+fi
+
+__CommonMSBuildArgs="/p:__BuildArch=$__BuildArch /p:__BuildType=$__BuildType /p:__BuildOS=$__BuildOS /nodeReuse:false $__OfficialBuildIdArg $__SignTypeArg $__SkipRestoreArg"
+
+# Configure environment if we are doing a verbose build
+if [[ "$__VerboseBuild" == 1 ]]; then
+ export VERBOSE=1
+ __CommonMSBuildArgs="$__CommonMSBuildArgs /v:detailed"
+fi
+
+if [[ "$__PortableBuild" == 0 ]]; then
+ __CommonMSBuildArgs="$__CommonMSBuildArgs /p:PortableBuild=false"
+fi
+
+# Configure environment if we are doing a cross compile.
+if [[ "$__CrossBuild" == 1 ]]; then
+ export CROSSCOMPILE=1
+ if [[ ! -n "$ROOTFS_DIR" ]]; then
+ export ROOTFS_DIR="$__RepoRootDir/.tools/rootfs/$__BuildArch"
+ fi
+fi
+
+# init the target distro name
+initTargetDistroRid
+
+# Init if MSBuild for .NET Core is supported for this platform
+isMSBuildOnNETCoreSupported
diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake
new file mode 100644
index 00000000000..f529f7ed5e3
--- /dev/null
+++ b/eng/native/configureplatform.cmake
@@ -0,0 +1,182 @@
+include(CheckPIESupported)
+
+# All code we build should be compiled as position independent
+check_pie_supported(OUTPUT_VARIABLE PIE_SUPPORT_OUTPUT LANGUAGES CXX)
+if(NOT MSVC AND NOT CMAKE_CXX_LINK_PIE_SUPPORTED)
+ message(WARNING "PIE is not supported at link time: ${PIE_SUPPORT_OUTPUT}.\n"
+ "PIE link options will not be passed to linker.")
+endif()
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+#----------------------------------------
+# 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
+#----------------------------------------
+if(CMAKE_SYSTEM_NAME 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)
+ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL arm)
+ 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()
+ 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()
+
+ execute_process(
+ COMMAND bash -c "source ${LINUX_ID_FILE} && echo \$ID"
+ OUTPUT_VARIABLE CLR_CMAKE_LINUX_ID
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(DEFINED CLR_CMAKE_LINUX_ID)
+ if(CLR_CMAKE_LINUX_ID STREQUAL tizen)
+ set(CLR_CMAKE_TARGET_TIZEN_LINUX 1)
+ elseif(CLR_CMAKE_LINUX_ID STREQUAL alpine)
+ set(CLR_CMAKE_HOST_ALPINE_LINUX 1)
+ endif()
+ endif(DEFINED CLR_CMAKE_LINUX_ID)
+endif(CMAKE_SYSTEM_NAME STREQUAL Linux)
+
+if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+ set(CLR_CMAKE_HOST_UNIX 1)
+ set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+ set(CLR_CMAKE_HOST_DARWIN 1)
+ set(CMAKE_ASM_COMPILE_OBJECT "${CMAKE_C_COMPILER} <FLAGS> <DEFINES> <INCLUDES> -o <OBJECT> -c <SOURCE>")
+endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+
+if(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+ set(CLR_CMAKE_HOST_UNIX 1)
+ set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+ set(CLR_CMAKE_HOST_FREEBSD 1)
+endif(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+
+if(CMAKE_SYSTEM_NAME STREQUAL OpenBSD)
+ set(CLR_CMAKE_HOST_UNIX 1)
+ set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+ set(CLR_CMAKE_HOST_OPENBSD 1)
+endif(CMAKE_SYSTEM_NAME STREQUAL OpenBSD)
+
+if(CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+ set(CLR_CMAKE_HOST_UNIX 1)
+ set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+ set(CLR_CMAKE_HOST_NETBSD 1)
+endif(CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+
+if(CMAKE_SYSTEM_NAME 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")
+ set(CLR_CMAKE_HOST_UNIX_AMD64 1)
+ set(CMAKE_SYSTEM_PROCESSOR "amd64")
+ else()
+ clr_unknown_arch()
+ endif()
+ set(CLR_CMAKE_HOST_SUNOS 1)
+endif(CMAKE_SYSTEM_NAME STREQUAL SunOS)
+
+#--------------------------------------------
+# 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")
+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(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})
+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(ARM_SOFTFP 1)
+ else()
+ clr_unknown_arch()
+endif()
+
+# check if host & target arch combination are valid
+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)))
+ message(FATAL_ERROR "Invalid host and target arch combination")
+ endif()
+endif()
diff --git a/eng/native/functions.cmake b/eng/native/functions.cmake
new file mode 100644
index 00000000000..f11c56c8283
--- /dev/null
+++ b/eng/native/functions.cmake
@@ -0,0 +1,389 @@
+function(clr_unknown_arch)
+ if (WIN32)
+ message(FATAL_ERROR "Only AMD64, ARM64, ARM and I386 are supported")
+ elseif(CLR_CROSS_COMPONENTS_BUILD)
+ message(FATAL_ERROR "Only AMD64, I386 host are supported for linux cross-architecture component")
+ else()
+ message(FATAL_ERROR "Only AMD64, ARM64 and ARM are supported")
+ 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)
+
+ if (CLR_CMAKE_HOST_ARCH_ARM AND WIN32)
+ list(APPEND INC_DIRECTORIES "-I ")
+ endif()
+
+ foreach(dir IN LISTS dirs)
+ if (CLR_CMAKE_HOST_ARCH_ARM AND WIN32)
+ list(APPEND INC_DIRECTORIES ${dir};)
+ else()
+ list(APPEND INC_DIRECTORIES -I${dir})
+ endif()
+ endforeach()
+
+ set(${IncludeDirectories} ${INC_DIRECTORIES} PARENT_SCOPE)
+endfunction(get_include_directories_asm)
+
+# 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}
+ 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_compile_asm(ASM_FILES file1 [file2 ...] OUTPUT_OBJECTS [variableName])
+function(preprocess_compile_asm)
+ set(options "")
+ set(oneValueArgs OUTPUT_OBJECTS)
+ set(multiValueArgs ASM_FILES)
+ cmake_parse_arguments(PARSE_ARGV 0 COMPILE_ASM "${options}" "${oneValueArgs}" "${multiValueArgs}")
+
+ get_include_directories_asm(ASM_INCLUDE_DIRECTORIES)
+
+ set (ASSEMBLED_OBJECTS "")
+
+ foreach(ASM_FILE ${COMPILE_ASM_ASM_FILES})
+ # 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})
+
+ # We do not pass any defines since we have already done pre-processing above
+ set (ASM_CMDLINE "-o ${CMAKE_CURRENT_BINARY_DIR}/${name}.obj ${ASM_PREPROCESSED_FILE}")
+
+ # Generate the batch file that will invoke the assembler
+ file(TO_CMAKE_PATH "${CMAKE_CURRENT_BINARY_DIR}/runasm_${name}.cmd" ASM_SCRIPT_FILE)
+
+ file(GENERATE OUTPUT "${ASM_SCRIPT_FILE}"
+ CONTENT "\"${CMAKE_ASM_MASM_COMPILER}\" -g ${ASM_INCLUDE_DIRECTORIES} ${ASM_CMDLINE}")
+
+ message("Generated - ${ASM_SCRIPT_FILE}")
+
+ # Need to compile asm file using custom command as include directories are not provided to asm compiler
+ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}.obj
+ COMMAND ${ASM_SCRIPT_FILE}
+ DEPENDS ${ASM_PREPROCESSED_FILE}
+ COMMENT "Assembling ${ASM_PREPROCESSED_FILE} - ${ASM_SCRIPT_FILE}")
+
+ # mark obj as source that does not require compile
+ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${name}.obj PROPERTIES EXTERNAL_OBJECT TRUE)
+
+ # Add the generated OBJ in the dependency list so that it gets consumed during linkage
+ list(APPEND ASSEMBLED_OBJECTS ${CMAKE_CURRENT_BINARY_DIR}/${name}.obj)
+ endforeach()
+
+ set(${COMPILE_ASM_OUTPUT_OBJECTS} ${ASSEMBLED_OBJECTS} PARENT_SCOPE)
+endfunction()
+
+function(generate_exports_file)
+ set(INPUT_LIST ${ARGN})
+ list(GET INPUT_LIST -1 outputFilename)
+ list(REMOVE_AT INPUT_LIST -1)
+
+ if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+ set(AWK_SCRIPT generateexportedsymbols.awk)
+ else()
+ set(AWK_SCRIPT generateversionscript.awk)
+ endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+
+ add_custom_command(
+ OUTPUT ${outputFilename}
+ COMMAND ${AWK} -f ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT} ${INPUT_LIST} >${outputFilename}
+ DEPENDS ${INPUT_LIST} ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT}
+ 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(AWK_SCRIPT generateexportedsymbols.awk)
+ else()
+ set(AWK_SCRIPT generateversionscript.awk)
+ if (NOT ${prefix} STREQUAL "")
+ set(AWK_VARS ${AWK_VARS} -v prefix=${prefix})
+ endif()
+ endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+
+ add_custom_command(
+ OUTPUT ${outputFilename}
+ COMMAND ${AWK} -f ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT} ${AWK_VARS} ${inputFilename} >${outputFilename}
+ DEPENDS ${inputFilename} ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT}
+ COMMENT "Generating exports file ${outputFilename}"
+ )
+ set_source_files_properties(${outputFilename}
+ PROPERTIES GENERATED TRUE)
+endfunction()
+
+# target_precompile_header(TARGET targetName HEADER headerName [ADDITIONAL_INCLUDE_DIRECTORIES includeDirs])
+function(target_precompile_header)
+ set(options "")
+ set(oneValueArgs TARGET HEADER)
+ set(multiValueArgs ADDITIONAL_INCLUDE_DIRECTORIES)
+ cmake_parse_arguments(PARSE_ARGV 0 PRECOMPILE_HEADERS "${options}" "${oneValueArgs}" "${multiValueArgs}")
+
+ if ("${PRECOMPILE_HEADERS_TARGET}" STREQUAL "")
+ message(SEND_ERROR "No target supplied to target_precompile_header.")
+ endif()
+ if ("${PRECOMPILE_HEADERS_HEADER}" STREQUAL "")
+ message(SEND_ERROR "No header supplied to target_precompile_header.")
+ endif()
+
+ if(MSVC)
+ get_filename_component(PCH_NAME ${PRECOMPILE_HEADERS_HEADER} NAME_WE)
+ # We need to use the $<TARGET_PROPERTY:NAME> generator here instead of the ${targetName} variable since
+ # CMake evaluates source file properties once per directory. If we just use ${targetName}, we end up sharing
+ # the same PCH between targets, which doesn't work.
+ set(precompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${PCH_NAME}.$<TARGET_PROPERTY:NAME>.pch")
+ set(pchSourceFile "${CMAKE_CURRENT_BINARY_DIR}/${PCH_NAME}.${PRECOMPILE_HEADERS_TARGET}.cpp")
+
+ file(GENERATE OUTPUT ${pchSourceFile} CONTENT "#include \"${PRECOMPILE_HEADERS_HEADER}\"")
+
+ set(PCH_SOURCE_FILE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR} ${PRECOMPILE_HEADERS_ADDITIONAL_INCLUDE_DIRECTORIES})
+
+ set_source_files_properties(${pchSourceFile}
+ PROPERTIES COMPILE_FLAGS "/Yc\"${PRECOMPILE_HEADERS_HEADER}\" /Fp\"${precompiledBinary}\""
+ OBJECT_OUTPUTS "${precompiledBinary}"
+ INCLUDE_DIRECTORIES "${PCH_SOURCE_FILE_INCLUDE_DIRECTORIES}")
+ get_target_property(TARGET_SOURCES ${PRECOMPILE_HEADERS_TARGET} SOURCES)
+
+ foreach (SOURCE ${TARGET_SOURCES})
+ get_source_file_property(SOURCE_LANG ${SOURCE} LANGUAGE)
+ if (("${SOURCE_LANG}" STREQUAL "C") OR ("${SOURCE_LANG}" STREQUAL "CXX"))
+ set_source_files_properties(${SOURCE}
+ PROPERTIES COMPILE_FLAGS "/Yu\"${PRECOMPILE_HEADERS_HEADER}\" /Fp\"${precompiledBinary}\""
+ OBJECT_DEPENDS "${precompiledBinary}")
+ endif()
+ endforeach()
+
+ # Add pchSourceFile to PRECOMPILE_HEADERS_TARGET target
+ target_sources(${PRECOMPILE_HEADERS_TARGET} PRIVATE ${pchSourceFile})
+ endif(MSVC)
+endfunction()
+
+function(strip_symbols targetName outputFilename skipStrip)
+ if (CLR_CMAKE_HOST_UNIX)
+ if (STRIP_SYMBOLS)
+ set(strip_source_file $<TARGET_FILE:${targetName}>)
+
+ if (CMAKE_SYSTEM_NAME STREQUAL Darwin)
+ set(strip_destination_file ${strip_source_file}.dwarf)
+
+ if(NOT ${skipStrip})
+ add_custom_command(
+ TARGET ${targetName}
+ POST_BUILD
+ VERBATIM
+ COMMAND ${DSYMUTIL} --flat --minimize ${strip_source_file}
+ COMMAND ${STRIP} -S ${strip_source_file}
+ COMMENT Stripping symbols from ${strip_source_file} into file ${strip_destination_file}
+ )
+ endif()
+ else (CMAKE_SYSTEM_NAME STREQUAL Darwin)
+ set(strip_destination_file ${strip_source_file}.dbg)
+
+ if(NOT ${skipStrip})
+ add_custom_command(
+ TARGET ${targetName}
+ POST_BUILD
+ VERBATIM
+ COMMAND ${OBJCOPY} --only-keep-debug ${strip_source_file} ${strip_destination_file}
+ COMMAND ${OBJCOPY} --strip-debug ${strip_source_file}
+ COMMAND ${OBJCOPY} --add-gnu-debuglink=${strip_destination_file} ${strip_source_file}
+ COMMENT Stripping symbols from ${strip_source_file} into file ${strip_destination_file}
+ )
+ endif()
+ endif (CMAKE_SYSTEM_NAME STREQUAL Darwin)
+
+ set(${outputFilename} ${strip_destination_file} PARENT_SCOPE)
+ endif (STRIP_SYMBOLS)
+ endif(CLR_CMAKE_HOST_UNIX)
+endfunction()
+
+# install_clr(TARGETS TARGETS targetName [targetName2 ...] [DESTINATION destination] [SKIP_STRIP])
+function(install_clr)
+ set(options SKIP_STRIP)
+ set(oneValueArgs DESTINATION)
+ set(multiValueArgs TARGETS)
+ cmake_parse_arguments(PARSE_ARGV 0 INSTALL_CLR "${options}" "${oneValueArgs}" "${multiValueArgs}")
+
+ if ("${INSTALL_CLR_TARGETS}" STREQUAL "")
+ message(FATAL_ERROR "At least one target must be passed to install_clr(TARGETS )")
+ endif()
+
+ if ("${INSTALL_CLR_DESTINATION}" STREQUAL "")
+ set(INSTALL_CLR_DESTINATION ".")
+ endif()
+
+ foreach(targetName ${INSTALL_CLR_TARGETS})
+ list(FIND CLR_CROSS_COMPONENTS_LIST ${targetName} INDEX)
+ if (NOT DEFINED CLR_CROSS_COMPONENTS_LIST OR NOT ${INDEX} EQUAL -1)
+ if("${INSTALL_CLR_SKIP_STRIP}" STREQUAL "")
+ set(INSTALL_CLR_SKIP_STRIP FALSE)
+ endif()
+ strip_symbols(${targetName} strip_destination_file ${INSTALL_CLR_SKIP_STRIP})
+
+ # 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 ${INSTALL_CLR_DESTINATION})
+ if(WIN32)
+ # We can't use the $<TARGET_PDB_FILE> generator expression here since
+ # the generator expression isn't supported on resource DLLs.
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${targetName}.pdb DESTINATION ${INSTALL_CLR_DESTINATION}/PDB)
+ else()
+ install(FILES ${strip_destination_file} DESTINATION ${INSTALL_CLR_DESTINATION})
+ endif()
+ if(CLR_CMAKE_PGO_INSTRUMENT)
+ if(WIN32)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${targetName}.pgd DESTINATION ${INSTALL_CLR_DESTINATION}/PGD OPTIONAL)
+ endif()
+ endif()
+ endif()
+ 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)
+ if (NOT PAXCTL STREQUAL "PAXCTL-NOTFOUND")
+ add_custom_command(
+ TARGET ${targetName}
+ POST_BUILD
+ VERBATIM
+ COMMAND ${PAXCTL} -c -m $<TARGET_FILE:${targetName}>
+ )
+ endif()
+endfunction()
+
+function(_add_executable)
+ if(NOT WIN32)
+ add_executable(${ARGV} ${VERSION_FILE_PATH})
+ disable_pax_mprotect(${ARGV})
+ else()
+ add_executable(${ARGV})
+ endif(NOT WIN32)
+ list(FIND CLR_CROSS_COMPONENTS_LIST ${ARGV0} INDEX)
+ if (DEFINED CLR_CROSS_COMPONENTS_LIST AND ${INDEX} EQUAL -1)
+ set_target_properties(${ARGV0} PROPERTIES EXCLUDE_FROM_ALL 1)
+ endif()
+endfunction()
+
+function(_add_library)
+ if(NOT WIN32)
+ add_library(${ARGV} ${VERSION_FILE_PATH})
+ else()
+ add_library(${ARGV})
+ endif(NOT WIN32)
+ list(FIND CLR_CROSS_COMPONENTS_LIST ${ARGV0} INDEX)
+ if (DEFINED CLR_CROSS_COMPONENTS_LIST AND ${INDEX} EQUAL -1)
+ set_target_properties(${ARGV0} PROPERTIES EXCLUDE_FROM_ALL 1)
+ endif()
+endfunction()
+
+function(_install)
+ if(NOT DEFINED CLR_CROSS_COMPONENTS_BUILD)
+ install(${ARGV})
+ endif()
+endfunction()
+
+function(add_library_clr)
+ _add_library(${ARGV})
+endfunction()
+
+function(add_executable_clr)
+ _add_executable(${ARGV})
+endfunction()
diff --git a/eng/native/gen-buildsys.sh b/eng/native/gen-buildsys.sh
index 32e82f2fd05..ae2e0eb2d0b 100755
--- a/eng/native/gen-buildsys.sh
+++ b/eng/native/gen-buildsys.sh
@@ -3,26 +3,14 @@
# This file invokes cmake and generates the build system for Clang.
#
-source="${BASH_SOURCE[0]}"
+scriptroot="$( cd -P "$( dirname "$0" )" && pwd )"
-# resolve $SOURCE until the file is no longer a symlink
-while [[ -h $source ]]; do
- scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
- source="$(readlink "$source")"
-
- # if $source was a relative symlink, we need to resolve it relative to the path where the
- # symlink file was located
- [[ $source != /* ]] && source="$scriptroot/$source"
-done
-scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
-
-if [ $# -lt 4 ]
-then
+if [[ "$#" -lt 4 ]]; then
echo "Usage..."
- echo "gen-buildsys.sh <path to top level CMakeLists.txt> <path to intermediate directory> <path to tryrun.cmake directory> <Architecture> <compiler> <compiler major version> <compiler minor version> [build flavor] [ninja] [scan-build] [cmakeargs]"
+ echo "gen-buildsys.sh <path to top level CMakeLists.txt> <path to tryrun.cmake directory> <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 to the directory with tryrun.cmake file."
echo "Specify the path that the build system files are generated in."
+ echo "Specify the path to the directory with tryrun.cmake file."
echo "Specify the target architecture."
echo "Specify the name of compiler (clang or gcc)."
echo "Specify the major version of compiler."
@@ -41,7 +29,7 @@ cxxCompiler="$compiler++"
majorVersion="$6"
minorVersion="$7"
-if [ "$compiler" = "gcc" ]; then cxxCompiler="g++"; fi
+if [[ "$compiler" == "gcc" ]]; then cxxCompiler="g++"; fi
check_version_exists() {
desired_version=-1
@@ -58,38 +46,38 @@ check_version_exists() {
echo "$desired_version"
}
-if [ -z "$CLR_CC" ]; then
+if [[ -z "$CLR_CC" ]]; then
# Set default versions
- if [ -z "$majorVersion" ]; then
+ if [[ -z "$majorVersion" ]]; then
# note: gcc (all versions) and clang versions higher than 6 do not have minor version in file name, if it is zero.
- if [ "$compiler" = "clang" ]; then versions=( 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5 )
- elif [ "$compiler" = "gcc" ]; then versions=( 9 8 7 6 5 4.9 ); fi
+ if [[ "$compiler" == "clang" ]]; then versions=( 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5 )
+ elif [[ "$compiler" == "gcc" ]]; then versions=( 9 8 7 6 5 4.9 ); fi
for version in "${versions[@]}"; do
parts=(${version//./ })
desired_version="$(check_version_exists "${parts[0]}" "${parts[1]}")"
- if [ "$desired_version" != "-1" ]; then majorVersion="${parts[0]}"; break; fi
+ if [[ "$desired_version" != "-1" ]]; then majorVersion="${parts[0]}"; break; fi
done
- if [ -z "$majorVersion" ]; then
+ if [[ -z "$majorVersion" ]]; then
if command -v "$compiler" > /dev/null; then
- if [ "$(uname)" != "Darwin" ]; then
+ if [[ "$(uname)" != "Darwin" ]]; then
echo "WARN: Specific version of $compiler not found, falling back to use the one in PATH."
fi
- export CC="$(command -v "$compiler")"
- export CXX="$(command -v "$cxxCompiler")"
+ CC="$(command -v "$compiler")"
+ CXX="$(command -v "$cxxCompiler")"
else
echo "ERROR: No usable version of $compiler found."
exit 1
fi
else
- if [ "$compiler" = "clang" ] && [ "$majorVersion" -lt 5 ]; then
- if [ "$build_arch" = "arm" ] || [ "$build_arch" = "armel" ]; then
+ if [[ "$compiler" == "clang" && "$majorVersion" -lt 5 ]]; then
+ if [[ "$build_arch" == "arm" || "$build_arch" == "armel" ]]; then
if command -v "$compiler" > /dev/null; then
echo "WARN: Found clang version $majorVersion which is not supported on arm/armel architectures, falling back to use clang from PATH."
- export CC="$(command -v "$compiler")"
- export CXX="$(command -v "$cxxCompiler")"
+ CC="$(command -v "$compiler")"
+ CXX="$(command -v "$cxxCompiler")"
else
echo "ERROR: Found clang version $majorVersion which is not supported on arm/armel architectures, and there is no clang in PATH."
exit 1
@@ -99,34 +87,36 @@ if [ -z "$CLR_CC" ]; then
fi
else
desired_version="$(check_version_exists "$majorVersion" "$minorVersion")"
- if [ "$desired_version" = "-1" ]; then
+ if [[ "$desired_version" == "-1" ]]; then
echo "ERROR: Could not find specific version of $compiler: $majorVersion $minorVersion."
exit 1
fi
fi
- if [ -z "$CC" ]; then
- export CC="$(command -v "$compiler$desired_version")"
- export CXX="$(command -v "$cxxCompiler$desired_version")"
- if [ -z "$CXX" ]; then export CXX="$(command -v "$cxxCompiler")"; fi
+ if [[ -z "$CC" ]]; then
+ CC="$(command -v "$compiler$desired_version")"
+ CXX="$(command -v "$cxxCompiler$desired_version")"
+ if [[ -z "$CXX" ]]; then CXX="$(command -v "$cxxCompiler")"; fi
fi
else
- if [ ! -f "$CLR_CC" ]; then
+ if [[ ! -f "$CLR_CC" ]]; then
echo "ERROR: CLR_CC is set but path '$CLR_CC' does not exist"
exit 1
fi
- export CC="$CLR_CC"
- export CXX="$CLR_CXX"
+ CC="$CLR_CC"
+ CXX="$CLR_CXX"
fi
-if [ -z "$CC" ]; then
+if [[ -z "$CC" ]]; then
echo "ERROR: Unable to find $compiler."
exit 1
fi
-export CCC_CC="$CC"
-export CCC_CXX="$CXX"
-export SCAN_BUILD_COMMAND="$(command -v "scan-build$desired_version")"
+CCC_CC="$CC"
+CCC_CXX="$CXX"
+SCAN_BUILD_COMMAND="$(command -v "scan-build$desired_version")"
+
+export CC CCC_CC CXX CCC_CXX SCAN_BUILD_COMMAND
buildtype=DEBUG
code_coverage=OFF
@@ -136,11 +126,11 @@ generator="Unix Makefiles"
__UnprocessedCMakeArgs=""
for i in "${@:8}"; do
- upperI="$(echo $i | awk '{print toupper($0)}')"
- case $upperI in
+ upperI="$(echo "$i" | awk '{print toupper($0)}')"
+ case "$upperI" in
# Possible build types are DEBUG, CHECKED, RELEASE, RELWITHDEBINFO.
DEBUG | CHECKED | RELEASE | RELWITHDEBINFO)
- buildtype=$upperI
+ buildtype="$upperI"
;;
NINJA)
generator=Ninja
@@ -154,26 +144,29 @@ for i in "${@:8}"; do
esac
done
-OS=`uname`
-
cmake_extra_defines=
-if [ "$CROSSCOMPILE" == "1" ]; then
+if [[ "$CROSSCOMPILE" == "1" ]]; then
if ! [[ -n "$ROOTFS_DIR" ]]; then
echo "ROOTFS_DIR not set for crosscompile"
exit 1
fi
- export TARGET_BUILD_ARCH=$build_arch
- cmake_extra_defines="$cmake_extra_defines -C $tryrun_dir/tryrun.cmake"
+
+ TARGET_BUILD_ARCH="$build_arch"
+ export TARGET_BUILD_ARCH
+
+ if [[ -n "$tryrun_dir" ]]; then
+ cmake_extra_defines="$cmake_extra_defines -C $tryrun_dir/tryrun.cmake"
+ fi
cmake_extra_defines="$cmake_extra_defines -DCMAKE_TOOLCHAIN_FILE=$scriptroot/../common/cross/toolchain.cmake"
fi
-if [ "$build_arch" == "armel" ]; then
+if [[ "$build_arch" == "armel" ]]; then
cmake_extra_defines="$cmake_extra_defines -DARM_SOFTFP=1"
fi
cmake_command=$(command -v cmake)
-if [[ "$scan_build" == "ON" && "$SCAN_BUILD_COMMAND" != "" ]]; then
+if [[ "$scan_build" == "ON" && -n "$SCAN_BUILD_COMMAND" ]]; then
cmake_command="$SCAN_BUILD_COMMAND $cmake_command"
fi
diff --git a/eng/native/init-distro-rid.sh b/eng/native/init-distro-rid.sh
new file mode 100644
index 00000000000..8868c9b3663
--- /dev/null
+++ b/eng/native/init-distro-rid.sh
@@ -0,0 +1,168 @@
+#!/usr/bin/env bash
+
+# initNonPortableDistroRid
+#
+# Input:
+# buildOs: (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.
+#
+# Below is the list of current non-portable platforms.
+#
+# Builds from the following *must* be non-portable:
+#
+# | OS | Expected RID |
+# -------------------------------------------------
+# | freeBSD | freebsd.(version)-x64 |
+#
+# 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 buildOs="$1"
+ local buildArch="$2"
+ local isPortable="$3"
+ local rootfsDir="$4"
+
+ if [ "$buildOs" = "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" ]; 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 [ "$buildOs" = "FreeBSD" ]; then
+ __freebsd_major_version=$(freebsd-version | { read v; echo "${v%%.*}"; })
+ nonPortableBuildID="freebsd.$__freebsd_major_version-${buildArch}"
+ fi
+
+ if [ -n "${nonPortableBuildID}" ]; then
+ export __DistroRid="${nonPortableBuildID}"
+
+ # We are using a non-portable build rid. Force __PortableBuild to false.
+ export __PortableBuild=0
+ 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
+# __RuntimeId
+#
+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 buildOs="$1"
+ local buildArch="$2"
+ local isPortable="$3"
+ local rootfsDir="$4"
+
+ 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
+
+ if [ "$buildArch" = "armel" ]; then
+ # Armel cross build is Tizen specific and does not support Portable RID build
+ export __PortableBuild=0
+ isPortable=0
+ fi
+
+ initNonPortableDistroRid "${buildOs}" "${buildArch}" "${isPortable}" "${rootfsDir}"
+
+ if [ -z "${__DistroRid}" ]; then
+ # The non-portable build rid was not set. Set the portable rid.
+
+ export __PortableBuild=1
+ local distroRid=""
+
+ # Check for musl-based distros (e.g Alpine Linux, Void Linux).
+ if "${rootfsDir}/usr/bin/ldd" --version 2>&1 | grep -q musl; then
+ distroRid="linux-musl-${buildArch}"
+ fi
+
+ if [ -z "${distroRid}" ]; then
+ if [ "$buildOs" = "Linux" ]; then
+ distroRid="linux-$buildArch"
+ elif [ "$buildOs" = "OSX" ]; then
+ distroRid="osx-$buildArch"
+ elif [ "$buildOs" = "FreeBSD" ]; then
+ distroRid="freebsd-$buildArch"
+ fi
+ fi
+
+ export __DistroRid="${distroRid}"
+ fi
+
+ if [ -z "$__DistroRid" ]; then
+ echo "DistroRid is not set. This is almost certainly an error"
+
+ exit 1
+ else
+ echo "__DistroRid: ${__DistroRid}"
+ echo "__RuntimeId: ${__DistroRid}"
+
+ export __RuntimeId="${__DistroRid}"
+ fi
+}
diff --git a/eng/pipelines/installer/jobs/base-job.yml b/eng/pipelines/installer/jobs/base-job.yml
index 385762a03cf..18675962bc2 100644
--- a/eng/pipelines/installer/jobs/base-job.yml
+++ b/eng/pipelines/installer/jobs/base-job.yml
@@ -183,6 +183,8 @@ jobs:
# lowercase for RID format. (Detection normally converts, but we're preventing it.)
- name: OutputRidArg
value: /p:OutputRid=linux-musl-${{ parameters.archType }}
+ - name: _PortableBuild
+ value: true
- name: BuildArguments
value: >-
diff --git a/eng/pipelines/libraries/base-job.yml b/eng/pipelines/libraries/base-job.yml
index e9ac1f42911..a08275e2a38 100644
--- a/eng/pipelines/libraries/base-job.yml
+++ b/eng/pipelines/libraries/base-job.yml
@@ -3,6 +3,7 @@ parameters:
osGroup: ''
archType: ''
osSubgroup: ''
+ crossrootfsDir: ''
framework: ''
isOfficialBuild: false
isOfficialAllConfigurations: false
@@ -50,6 +51,9 @@ jobs:
- ${{ if ne(parameters.testScope, '') }}:
- _testScopeArg: -testscope ${{ parameters.testScope }}
+ - ${{ if eq(parameters.osGroup, 'Linux') }}:
+ - _crossBuildPropertyArg: /p:CrossBuild=${{ ne(parameters.crossrootfsDir, '') }}
+
- ${{ if and(eq(parameters.osGroup, 'Linux'), eq(parameters.osSubGroup, '_musl')) }}:
- _runtimeOSArg: /p:RuntimeOS=linux-musl
@@ -98,7 +102,7 @@ jobs:
- ${{ if eq(parameters.isOfficialBuild, 'true') }}:
- _stripSymbolsArg: -stripSymbols
- - _buildArguments: -configuration ${{ parameters.buildConfig }} -ci -arch ${{ parameters.archType }} $(_finalFrameworkArg) $(_stripSymbolsArg) $(_testScopeArg) $(_warnAsErrorArg) $(_runtimeOSArg) $(_msbuildCommonParameters) $(_runtimeArtifactsPathArg)
+ - _buildArguments: -configuration ${{ parameters.buildConfig }} -ci -arch ${{ parameters.archType }} $(_finalFrameworkArg) $(_stripSymbolsArg) $(_testScopeArg) $(_warnAsErrorArg) $(_runtimeOSArg) $(_msbuildCommonParameters) $(_runtimeArtifactsPathArg) $(_crossBuildPropertyArg)
- ${{ parameters.variables }}
dependsOn:
diff --git a/eng/pipelines/libraries/build-job.yml b/eng/pipelines/libraries/build-job.yml
index 0e3e3b8cfb3..7fdc4e7c868 100644
--- a/eng/pipelines/libraries/build-job.yml
+++ b/eng/pipelines/libraries/build-job.yml
@@ -3,6 +3,7 @@ parameters:
osGroup: ''
osSubgroup: ''
archType: ''
+ crossrootfsDir: ''
framework: netcoreapp
isOfficialBuild: false
isOfficialAllConfigurations: false
@@ -31,6 +32,7 @@ jobs:
osGroup: ${{ parameters.osGroup }}
osSubgroup: ${{ parameters.osSubgroup }}
archType: ${{ parameters.archType }}
+ crossrootfsDir: ${{ parameters.crossrootfsDir }}
framework: ${{ parameters.framework }}
isOfficialBuild: ${{ parameters.isOfficialBuild }}
isOfficialAllConfigurations: ${{ parameters.isOfficialAllConfigurations }}