From bedc2a0f2031538ac236ff129572739d1ecd97bb Mon Sep 17 00:00:00 2001 From: Hyeongseok Oh Date: Sat, 17 Dec 2016 04:06:16 +0900 Subject: [PATCH] Fix buildsystem for linux cross-architecture component build (#8646) * Fix buildsystem for linux cross-architecture component build * refactoring build.sh, bug fix and typo fix * Update build.sh --- CMakeLists.txt | 91 ++++++++++++++++----------- build.sh | 98 ++++++++++++++++++++++------- functions.cmake | 2 + src/pal/tools/gen-buildsys-clang.sh | 22 ++++--- 4 files changed, 142 insertions(+), 71 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 702d177325cc..395f602492fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() #----------------------------------------------------- diff --git a/build.sh b/build.sh index d42bf37b969f..efdd5cbff626 100755 --- 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. diff --git a/functions.cmake b/functions.cmake index bac20e8bc65a..e1a9abb46938 100644 --- a/functions.cmake +++ b/functions.cmake @@ -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() diff --git a/src/pal/tools/gen-buildsys-clang.sh b/src/pal/tools/gen-buildsys-clang.sh index 022a9ccf56a6..4054266f0bd7 100755 --- a/src/pal/tools/gen-buildsys-clang.sh +++ b/src/pal/tools/gen-buildsys-clang.sh @@ -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"