Fix buildsystem for linux cross-architecture component build (#8646)
authorHyeongseok Oh <hseok82.oh@samsung.com>
Fri, 16 Dec 2016 19:06:16 +0000 (04:06 +0900)
committerJan Vorlicek <janvorli@microsoft.com>
Fri, 16 Dec 2016 19:06:16 +0000 (20:06 +0100)
* Fix buildsystem for linux cross-architecture component build

* refactoring build.sh, bug fix and typo fix

* Update build.sh

CMakeLists.txt
build.sh
functions.cmake
src/pal/tools/gen-buildsys-clang.sh

index 702d177..395f602 100644 (file)
@@ -101,7 +101,7 @@ else (WIN32)
     else (CMAKE_SYSTEM_NAME STREQUAL Darwin)
 
       # Ensure that objcopy is present
-      if (DEFINED ENV{CROSSCOMPILE})
+      if (DEFINED ENV{CROSSCOMPILE} AND NOT DEFINED CLR_CROSS_COMPONENTS_BUILD)
         if (CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l OR CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
           find_program(OBJCOPY ${TOOLCHAIN}-objcopy)
         elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL i686)
@@ -122,25 +122,40 @@ endif(WIN32)
 
 #----------------------------------------
 # Detect and set platform variable names
-#     - for non-windows build platform & architecture is detected using inbuilt CMAKE variables
+#     - 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_PLATFORM_UNIX 1)
-    # CMAKE_SYSTEM_PROCESSOR returns the value of `uname -p`.
-    # For the AMD/Intel 64bit architecure 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_PLATFORM_UNIX_AMD64 1)
-    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l)
-        set(CLR_CMAKE_PLATFORM_UNIX_ARM 1)
-    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
-        set(CLR_CMAKE_PLATFORM_UNIX_ARM64 1)
-    elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL i686)
-        set(CLR_CMAKE_PLATFORM_UNIX_X86 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_SYSTEM_PROCESSOR STREQUAL amd64)
+            if(CLR_CMAKE_TARGET_ARCH STREQUAL "arm")
+                set(CLR_CMAKE_PLATFORM_UNIX_X86 1)
+            else()
+                set(CLR_CMAKE_PLATFORM_UNIX_AMD64 1)
+            endif()
+        elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL i686)
+            set(CLR_CMAKE_PLATFORM_UNIX_X86 1)
+        else()
+            clr_unknown_arch()
+        endif()
     else()
-        clr_unknown_arch()
+        # CMAKE_SYSTEM_PROCESSOR returns the value of `uname -p` on target.
+        # For the AMD/Intel 64bit architecure 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_PLATFORM_UNIX_AMD64 1)
+        elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l)
+            set(CLR_CMAKE_PLATFORM_UNIX_ARM 1)
+        elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
+            set(CLR_CMAKE_PLATFORM_UNIX_ARM64 1)
+        elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL i686)
+            set(CLR_CMAKE_PLATFORM_UNIX_X86 1)
+        else()
+            clr_unknown_arch()
+        endif()
     endif()
     set(CLR_CMAKE_PLATFORM_LINUX 1)
 
@@ -211,30 +226,30 @@ endif(CMAKE_SYSTEM_NAME STREQUAL SunOS)
 #-------------------------------------------------------------
 # Set HOST architecture variables
 if(CLR_CMAKE_PLATFORM_UNIX_ARM)
-  set(CLR_CMAKE_PLATFORM_ARCH_ARM 1)
-  set(CLR_CMAKE_HOST_ARCH "arm")
+    set(CLR_CMAKE_PLATFORM_ARCH_ARM 1)
+    set(CLR_CMAKE_HOST_ARCH "arm")
 elseif(CLR_CMAKE_PLATFORM_UNIX_ARM64)
-  set(CLR_CMAKE_PLATFORM_ARCH_ARM64 1) 
-  set(CLR_CMAKE_HOST_ARCH "arm64")
+    set(CLR_CMAKE_PLATFORM_ARCH_ARM64 1)
+    set(CLR_CMAKE_HOST_ARCH "arm64")
 elseif(CLR_CMAKE_PLATFORM_UNIX_AMD64)
-  set(CLR_CMAKE_PLATFORM_ARCH_AMD64 1)
-  set(CLR_CMAKE_HOST_ARCH "x64")
-elseif(CLR_CMAKE_PLATFORM_UNIX_X86)
-  set(CLR_CMAKE_PLATFORM_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_PLATFORM_ARCH_AMD64 1)
-  elseif(CLR_CMAKE_HOST_ARCH STREQUAL x86)
+    set(CLR_CMAKE_HOST_ARCH "x64")
+elseif(CLR_CMAKE_PLATFORM_UNIX_X86)
     set(CLR_CMAKE_PLATFORM_ARCH_I386 1)
-  elseif(CLR_CMAKE_HOST_ARCH STREQUAL arm)
-    set(CLR_CMAKE_PLATFORM_ARCH_ARM 1)
-  elseif(CLR_CMAKE_HOST_ARCH STREQUAL arm64)
-    set(CLR_CMAKE_PLATFORM_ARCH_ARM64 1)
-  else()
-    clr_unknown_arch()
-  endif()
+    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_PLATFORM_ARCH_AMD64 1)
+    elseif(CLR_CMAKE_HOST_ARCH STREQUAL x86)
+        set(CLR_CMAKE_PLATFORM_ARCH_I386 1)
+    elseif(CLR_CMAKE_HOST_ARCH STREQUAL arm)
+        set(CLR_CMAKE_PLATFORM_ARCH_ARM 1)
+    elseif(CLR_CMAKE_HOST_ARCH STREQUAL arm64)
+        set(CLR_CMAKE_PLATFORM_ARCH_ARM64 1)
+    else()
+        clr_unknown_arch()
+    endif()
 endif()
 
 # Set TARGET architecture variables
@@ -259,9 +274,9 @@ endif()
 
 # check if host & target arch combination are valid
 if(NOT(CLR_CMAKE_TARGET_ARCH STREQUAL CLR_CMAKE_HOST_ARCH))
-  if(NOT((CLR_CMAKE_PLATFORM_ARCH_AMD64 AND CLR_CMAKE_TARGET_ARCH_ARM64) OR (CLR_CMAKE_PLATFORM_ARCH_I386 AND CLR_CMAKE_TARGET_ARCH_ARM)))
-    message(FATAL_ERROR "Invalid host and target arch combination")
-  endif()
+    if(NOT((CLR_CMAKE_PLATFORM_ARCH_AMD64 AND CLR_CMAKE_TARGET_ARCH_ARM64) OR (CLR_CMAKE_PLATFORM_ARCH_I386 AND CLR_CMAKE_TARGET_ARCH_ARM)))
+        message(FATAL_ERROR "Invalid host and target arch combination")
+    endif()
 endif()
 
 #-----------------------------------------------------
index d42bf37..efdd5cb 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -94,6 +94,11 @@ setup_dirs()
     mkdir -p "$__BinDir"
     mkdir -p "$__LogsDir"
     mkdir -p "$__IntermediatesDir"
+
+    if [ $__CrossBuild == 1 ]; then
+        mkdir -p "$__CrossComponentBinDir"
+        mkdir -p "$__CrossCompIntermediatesDir"
+    fi
 }
 
 # Check the system to ensure the right prereqs are in place
@@ -110,11 +115,10 @@ check_prereqs()
 
 }
 
-build_coreclr()
-{
 
+generate_event_logging_sources()
+{
     if [ $__SkipCoreCLR == 1 ]; then
-        echo "Skipping CoreCLR build."
         return
     fi
 
@@ -160,10 +164,23 @@ build_coreclr()
     fi
 
     rm -rf "$__GeneratedIntermediateEventProvider"
+}
 
-    # All set to commence the build
+build_native()
+{
+    skipCondition=$1
+    platformArch="$2"
+    intermediatesForBuild="$3"
+    extraCmakeArguments="$4"
+    message="$5"
+
+    if [ $skipCondition == 1 ]; then
+        echo "Skipping $message build."
+        return
+    fi
 
-    echo "Commencing build of native components for $__BuildOS.$__BuildArch.$__BuildType in $__IntermediatesDir"
+    # All set to commence the build
+    echo "Commencing build of $message for $__BuildOS.$__BuildArch.$__BuildType in $intermediatesForBuild"
 
     generator=""
     buildFile="Makefile"
@@ -185,8 +202,9 @@ build_coreclr()
         # if msbuild is not supported, then set __SkipGenerateVersion to 1
         if [ $__isMSBuildOnNETCoreSupported == 0 ]; then __SkipGenerateVersion=1; fi
         # Drop version.cpp file
-        __versionSourceFile=$__IntermediatesDir/version.cpp
+        __versionSourceFile="$intermediatesForBuild/version.cpp"
         if [ $__SkipGenerateVersion == 0 ]; then
+            pwd
             "$__ProjectRoot/run.sh" build -Project=$__ProjectDir/build.proj -generateHeaderUnix -NativeVersionSourceFile=$__versionSourceFile $__RunArgs $__UnprocessedBuildArgs
         else
             # Generate the dummy version.cpp, but only if it didn't exist to make sure we don't trigger unnecessary rebuild
@@ -199,22 +217,18 @@ build_coreclr()
             fi
         fi
 
-        pushd "$__IntermediatesDir"
+        pushd "$intermediatesForBuild"
         # Regenerate the CMake solution
-        __ExtraCmakeArgs="-DCLR_CMAKE_TARGET_OS=$__BuildOS -DCLR_CMAKE_PACKAGES_DIR=$__PackagesDir -DCLR_CMAKE_PGO_INSTRUMENT=$__PgoInstrument"
-        echo "Invoking \"$__ProjectRoot/src/pal/tools/gen-buildsys-clang.sh\" \"$__ProjectRoot\" $__ClangMajorVersion $__ClangMinorVersion $__BuildArch $__BuildType $__CodeCoverage $__IncludeTests $generator $__ExtraCmakeArgs $__cmakeargs"
-        "$__ProjectRoot/src/pal/tools/gen-buildsys-clang.sh" "$__ProjectRoot" $__ClangMajorVersion $__ClangMinorVersion $__BuildArch $__BuildType $__CodeCoverage $__IncludeTests $generator "$__ExtraCmakeArgs" "$__cmakeargs"
+        echo "Invoking \"$__ProjectRoot/src/pal/tools/gen-buildsys-clang.sh\" \"$__ProjectRoot\" $__ClangMajorVersion $__ClangMinorVersion $platformArch $__BuildType $__CodeCoverage $__IncludeTests $generator $extraCmakeArguments $__cmakeargs"
+        "$__ProjectRoot/src/pal/tools/gen-buildsys-clang.sh" "$__ProjectRoot" $__ClangMajorVersion $__ClangMinorVersion $platformArch $__BuildType $__CodeCoverage $__IncludeTests $generator "$extraCmakeArguments" "$__cmakeargs"
         popd
     fi
 
-    # Check that the makefiles were created.
-    pushd "$__IntermediatesDir"
-    
-    if [ ! -f "$__IntermediatesDir/$buildFile" ]; then
-        echo "Failed to generate native component build project!"
+    if [ ! -f "$intermediatesForBuild/$buildFile" ]; then
+        echo "Failed to generate $message build project!"
         exit 1
     fi
-
+    
     # Get the number of processors available to the scheduler
     # Other techniques such as `nproc` only get the number of
     # processors available to a single process.
@@ -226,22 +240,24 @@ build_coreclr()
         NumProc=$(($(getconf _NPROCESSORS_ONLN)+1))
     fi
 
-    # Build CoreCLR
-
+    # Build
     if [ $__ConfigureOnly == 1 ]; then
-        echo "Skipping CoreCLR build."
+        echo "Finish configuration & skipping $message build."
         return
     fi
 
+    # Check that the makefiles were created.
+    pushd "$intermediatesForBuild"
+
     echo "Executing $buildTool install -j $NumProc"
 
     $buildTool install -j $NumProc
     if [ $? != 0 ]; then
-        echo "Failed to build coreclr components."
+        echo "Failed to build $message."
         exit 1
     fi
 
-       popd
+    popd
 }
 
 isMSBuildOnNETCoreSupported()
@@ -503,6 +519,7 @@ __HostDistroRid=""
 __DistroRid=""
 __cmakeargs=""
 __SkipGenerateVersion=0
+__DoCrossArchBuild=0
 
 while :; do
     if [ $# -le 0 ]; then
@@ -613,6 +630,10 @@ while :; do
             __SkipCoreCLR=1
             ;;
 
+        crosscomponent)
+            __DoCrossArchBuild=1
+            ;;
+
         skipmscorlib)
             __SkipMSCorLib=1
             ;;
@@ -699,6 +720,18 @@ __TestWorkingDir="$__RootBinDir/tests/$__BuildOS.$__BuildArch.$__BuildType"
 export __IntermediatesDir="$__RootBinDir/obj/$__BuildOS.$__BuildArch.$__BuildType"
 __TestIntermediatesDir="$__RootBinDir/tests/obj/$__BuildOS.$__BuildArch.$__BuildType"
 __isMSBuildOnNETCoreSupported=0
+__CrossComponentBinDir="$__BinDir"
+__CrossCompIntermediatesDir="$__IntermediatesDir/crossgen"
+
+__CrossArch="$__HostArch"
+if [[ "$__HostArch" == "x64" && "$__BuildArch" == "arm" ]]; then
+    __CrossArch="x86"
+fi
+if [ $__CrossBuild == 1 ]; then
+    __CrossComponentBinDir="$__CrossComponentBinDir/$__CrossArch"
+fi
+__CrossgenCoreLibLog="$__LogsDir/CrossgenCoreLib_$__BuildOS.$BuildArch.$__BuildType.log"
+__CrossgenExe="$__CrossComponentBinDir/crossgen"
 
 # Init if MSBuild for .NET Core is supported for this platform
 isMSBuildOnNETCoreSupported
@@ -729,16 +762,33 @@ fi
 initTargetDistroRid
 
 # Make the directories necessary for build if they don't exist
-
 setup_dirs
 
 # Check prereqs.
-
 check_prereqs
 
+# Generate event logging infrastructure sources
+generate_event_logging_sources
+
 # Build the coreclr (native) components.
+__ExtraCmakeArgs="-DCLR_CMAKE_TARGET_OS=$__BuildOS -DCLR_CMAKE_PACKAGES_DIR=$__PackagesDir -DCLR_CMAKE_PGO_INSTRUMENT=$__PgoInstrument"
+build_native $__SkipCoreCLR "$__BuildArch" "$__IntermediatesDir" "$__ExtraCmakeArgs" "CoreCLR component"
+
+# Build cross-architecture components
+if [ $__CrossBuild == 1 ]; then
+    __SkipCrossArchBuild=1
+    if [ $__DoCrossArchBuild == 1 ]; then
+        # build cross-architecture components for x86-host/arm-target
+        if [[ "$__BuildArch" == "arm" && "$__CrossArch" == "x86" ]]; then
+            __SkipCrossArchBuild=0
+        fi
+    fi
 
-build_coreclr
+    export __CMakeBinDir="$__CrossComponentBinDir"
+    export CROSSCOMPONENT=1
+    __ExtraCmakeArgs="-DCLR_CMAKE_TARGET_ARCH=$__BuildArch -DCLR_CMAKE_TARGET_OS=$__BuildOS -DCLR_CMAKE_PACKAGES_DIR=$__PackagesDir -DCLR_CMAKE_PGO_INSTRUMENT=$__PgoInstrument"
+    build_native $__SkipCrossArchBuild "$__CrossArch" "$__CrossCompIntermediatesDir" "$__ExtraCmakeArgs" "cross-architecture component"
+fi
 
 # Build System.Private.CoreLib.
 
index bac20e8..e1a9abb 100644 (file)
@@ -1,6 +1,8 @@
 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 are supported for cross-architecture component")
     else()
         message(FATAL_ERROR "Only AMD64, ARM64 and ARM are supported")
     endif()
index 022a9cc..4054266 100755 (executable)
@@ -126,16 +126,20 @@ fi
 if [[ -n "$LLDB_INCLUDE_DIR" ]]; then
     cmake_extra_defines="$cmake_extra_defines -DWITH_LLDB_INCLUDES=$LLDB_INCLUDE_DIR"
 fi
-if [[ -n "$CROSSCOMPILE" ]]; then
-    if ! [[ -n "$ROOTFS_DIR" ]]; then
-        echo "ROOTFS_DIR not set for crosscompile"
-        exit 1
-    fi
-    if [[ -z $CONFIG_DIR ]]; then
-      CONFIG_DIR="$1/cross/$build_arch"
+if [[ -n "$CROSSCOMPONENT" ]]; then
+    cmake_extra_defines="$cmake_extra_defines -DCLR_CROSS_COMPONENTS_BUILD=1"
+else
+    if [[ -n "$CROSSCOMPILE" ]]; then
+        if ! [[ -n "$ROOTFS_DIR" ]]; then
+            echo "ROOTFS_DIR not set for crosscompile"
+            exit 1
+        fi
+        if [[ -z $CONFIG_DIR ]]; then
+          CONFIG_DIR="$1/cross/$build_arch"
+        fi
+        cmake_extra_defines="$cmake_extra_defines -C $CONFIG_DIR/tryrun.cmake"
+        cmake_extra_defines="$cmake_extra_defines -DCMAKE_TOOLCHAIN_FILE=$CONFIG_DIR/toolchain.cmake"
     fi
-    cmake_extra_defines="$cmake_extra_defines -C $CONFIG_DIR/tryrun.cmake"
-    cmake_extra_defines="$cmake_extra_defines -DCMAKE_TOOLCHAIN_FILE=$CONFIG_DIR/toolchain.cmake"
 fi
 if [ "$build_arch" == "arm-softfp" ]; then
     cmake_extra_defines="$cmake_extra_defines -DARM_SOFTFP=1"