| |
| #!/bin/sh |
| |
| # Copyright 2015 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| . $(dirname "$0")/utils/common.shi |
| |
| shell_import utils/aosp_dir.shi |
| shell_import utils/option_parser.shi |
| |
| PROGRAM_PARAMETERS="<install-dir>" |
| |
| PROGRAM_DESCRIPTION=\ |
| "Generate a special toolchain wrapper that can be used to build binaries to be |
| included with the Android SDK. These binaries are guaranteed to run on systems |
| older than the build machine. |
| |
| This is achieved by using the prebuilt toolchains found under: |
| |
| \$AOSP/prebuilts/gcc/<system>/host/ |
| |
| Where \$AOSP is the path to an AOSP checkout, and <system> corresponds to the |
| host system this script runs on (i.e. linux-x86_64 or darwin-x86_64). The toolchain |
| will be capable of handling C++11 |
| |
| If you have the 'ccache' program installed, the wrapper will use it |
| automatically unless you use the --no-ccache option. |
| |
| The script will put under <install-dir>/ various tools, e.g. |
| 'x86_64-linux-c++' for the 64-bit Linux compiler. |
| |
| You can use the --print=<tool> option to print the corresponding name |
| or path, *instead* of creating a toolchain. Valid values for <tool> are: |
| |
| binprefix -> Print the binprefix (e.g. 'x86_64-linux-') |
| cc -> Print the compiler name (e.g. 'x86_64_linux-cc') |
| c++ -> Print the c++ compiler name. |
| ld, ar, as, ... -> Same for other tools. |
| sysroot -> Print the path to directory corresponding to the current |
| toolchain. |
| |
| Note: If you wish to cross compile to windows on darwin you will have to have a mingw |
| installation (brew install mingw-w64) |
| " |
| |
| aosp_dir_register_option |
| aosp_register_clang_option |
| |
| OPT_HOST= |
| option_register_var "--host=<system>" OPT_HOST "Host system to support." |
| |
| OPT_BINPREFIX= |
| option_register_var "--binprefix=<prefix>" OPT_BINPREFIX "Specify toolchain binprefix [autodetected]" |
| |
| OPT_PREFIX= |
| option_register_var "--prefix=<prefix>" OPT_PREFIX "Specify extra include/lib prefix." |
| |
| OPT_PRINT= |
| option_register_var "--print=<tool>" OPT_PRINT "Print the exact name of a specific tool." |
| |
| OPT_CCACHE= |
| option_register_var "--ccache=<program>" OPT_CCACHE "Use specific ccache program." |
| |
| OPT_NO_CCACHE= |
| option_register_var "--no-ccache" OPT_NO_CCACHE "Don't try to probe and use ccache." |
| |
| OPT_CXX11= |
| option_register_var "--cxx11" OPT_CXX11 "Enable C++11 features." |
| |
| OPT_FORCE_FETCH_WINTOOLCHAIN= |
| option_register_var "--force-fetch-wintoolchain" OPT_FORCE_FETCH_WINTOOLCHAIN "Force fetch the Windows toolchain (google internal)" |
| |
| OPT_VSDIR=/mnt/msvc/win8sdk |
| option_register_var "--vsdir=<msvc_install_dir>" OPT_VSDIR "Location of the msvc sdk. See documentation for details." |
| |
| |
| option_parse "$@" |
| |
| if [ "$PARAMETER_COUNT" != 1 ]; then |
| panic "This script requires a single parameter! See --help." |
| fi |
| |
| INSTALL_DIR=$PARAMETER_1 |
| # Determine host system type. |
| BUILD_HOST=$(get_build_os) |
| BUILD_ARCH=$(get_build_arch) |
| BUILD_BUILD_TARGET_TAG=${BUILD_HOST}-${BUILD_ARCH} |
| log "Found current build machine: $BUILD_BUILD_TARGET_TAG" |
| |
| # Handle CCACHE related arguments. |
| CCACHE= |
| if [ "$OPT_CCACHE" ]; then |
| if [ "$OPT_NO_CCACHE" ]; then |
| panic "You cannot use both --ccache=<program> and --no-ccache at the same time." |
| fi |
| CCACHE=$(find_program "$OPT_CCACHE") |
| if [ -z "$CCACHE" ]; then |
| panic "Missing ccache program: $OPT_CCACHE" |
| fi |
| elif [ -z "$OPT_NO_CCACHE" ]; then |
| CCACHE=$(find_program ccache) |
| if [ "$CCACHE" ]; then |
| log "Auto-config: --ccache=$CCACHE" |
| fi |
| fi |
| |
| aosp_dir_parse_option |
| |
| # Handle --host option. |
| if [ "$OPT_HOST" ]; then |
| case $OPT_HOST in |
| linux-x86_64|linux-aarch64|darwin-x86_64|windows-x86_64|windows_msvc-x86_64) |
| ;; |
| *) |
| panic "Invalid --host value: $OPT_HOST" |
| ;; |
| esac |
| HOST=$OPT_HOST |
| else |
| HOST=$BUILD_BUILD_TARGET_TAG |
| log "Auto-config: --host=$HOST" |
| fi |
| |
| # Handle --binprefix option. |
| BINPREFIX= |
| if [ "$OPT_BINPREFIX" ]; then |
| # Allow a final - after the binprefix |
| BINPREFIX=${OPT_BINPREFIX%%-} |
| if [ "$BINPREFIX" ]; then |
| BINPREFIX=${BINPREFIX}- |
| fi |
| fi |
| |
| # Generate a small toolchain wrapper program |
| # |
| # $1: program name, without any prefix (e.g. gcc, g++, ar, etc..) |
| # $2: source prefix (e.g. 'i586-mingw32msvc-') |
| # $3: destination prefix (e.g. 'i586-px-mingw32msvc-') |
| # $4: destination directory for the generated program |
| # $5: option, CLANG installation path. |
| # |
| # You may also define the following variables to pass extra tool flags: |
| # |
| # EXTRA_CFLAGS |
| # EXTRA_POSTCFLAGS |
| # EXTRA_CXXFLAGS |
| # EXTRA_POSTCXXFLAGS |
| # EXTRA_LDFLAGS |
| # EXTRA_POSTLDFLAGS |
| # EXTRA_ARFLAGS |
| # EXTRA_ASFLAGS |
| # EXTRA_WINDRESFLAGS |
| # |
| # As well as a special variable containing commands to setup the |
| # environment before tool invocation: |
| # |
| # EXTRA_ENV_SETUP |
| # |
| gen_wrapper_program () |
| { |
| local PROG="$1" |
| local SRC_PREFIX="$2" |
| local DST_PREFIX="$3" |
| local DST_FILE="$4/${SRC_PREFIX}$PROG" |
| local CLANG_BINDIR="$5" |
| local FLAGS="" |
| local POST_FLAGS="" |
| local DST_PROG="$PROG" |
| case $PROG in |
| cc|gcc|cpp|clang) |
| FLAGS=$FLAGS" $EXTRA_CFLAGS" |
| POST_FLAGS=" $POST_CFLAGS" |
| ;; |
| c++|g++|clang++) |
| FLAGS=$FLAGS" $EXTRA_CXXFLAGS" |
| POST_FLAGS=" $POST_CXXFLAGS" |
| ;; |
| ar) FLAGS=$FLAGS" $EXTRA_ARFLAGS";; |
| as) FLAGS=$FLAGS" $EXTRA_ASFLAGS";; |
| ld|ld.bfd|ld.gold) |
| FLAGS=$FLAGS" $EXTRA_LDFLAGS" |
| POST_FLAGS=" $POST_LDFLAGS" |
| ;; |
| windres) FLAGS=$FLAGS" $EXTRA_WINDRESFLAGS";; |
| esac |
| |
| # Redirect gcc -> clang if we are using clang. |
| if [ "$CLANG_BINDIR" ]; then |
| CLANG_BINDIR=${CLANG_BINDIR%/} |
| case $PROG in |
| cc|gcc|clang) |
| DST_PROG=clang |
| DST_PREFIX=$CLANG_BINDIR/ |
| ;; |
| c++|g++|clang++) |
| DST_PROG=clang++ |
| DST_PREFIX=$CLANG_BINDIR/ |
| ;; |
| clang-tidy) |
| DST_PREFIX=$CLANG_BINDIR/ |
| ;; |
| ar) |
| DST_PROG=llvm-ar |
| DST_PREFIX=$CLANG_BINDIR/ |
| ;; |
| esac |
| fi |
| |
| if [ -z "$DST_PREFIX" ]; then |
| # Avoid infinite loop by getting real path of destination |
| # program |
| DST_PROG=$(which "$PROG" 2>/dev/null || true) |
| if [ -z "$DST_PROG" ]; then |
| log "Ignoring: ${SRC_PREFIX}$PROG" |
| return |
| fi |
| DST_PREFIX=$(dirname "$DST_PROG")/ |
| DST_PROG=$(basename "$DST_PROG") |
| fi |
| |
| if [ ! -f "${DST_PREFIX}$DST_PROG" ]; then |
| case $DST_PROG in |
| cc) |
| # Our toolset doen't have separate cc binary for some platforms; |
| # let those use 'gcc' directly. |
| DST_PROG=gcc |
| if [ ! -f "${DST_PREFIX}$DST_PROG" ]; then |
| log " Skipping: ${SRC_PREFIX}$PROG [missing destination program, ${DST_PREFIX}$DST_PROG]" |
| return |
| fi |
| ;; |
| *) |
| log " Skipping: ${SRC_PREFIX}$PROG [missing destination program, ${DST_PREFIX}$DST_PROG]" |
| return |
| ;; |
| esac |
| fi |
| |
| if [ "$CCACHE" ]; then |
| DST_PREFIX="$CCACHE $DST_PREFIX" |
| fi |
| |
| cat > "$DST_FILE" << EOF |
| #!/bin/sh |
| # Auto-generated by $(program_name), DO NOT EDIT!! |
| # Environment setup |
| $EXTRA_ENV_SETUP |
| # Tool invocation. |
| ${DST_PREFIX}$DST_PROG $FLAGS "\$@" $POST_FLAGS |
| |
| EOF |
| chmod +x "$DST_FILE" |
| log " Generating: ${SRC_PREFIX}$PROG" |
| } |
| |
| gen_dbg_splitter() { |
| local SRC_PREFIX="$1" |
| local DST_PREFIX="$2" |
| local DST_FILE="$3/${SRC_PREFIX}strip" |
| cat > "$DST_FILE" << EOF |
| #!/bin/sh |
| # Auto-generated by $(program_name), DO NOT EDIT!! |
| $EXTRA_ENV_SETUP |
| target=\$(basename \$1) |
| mkdir -p build/debug_info |
| ${DST_PREFIX}objcopy --only-keep-debug "\$1" "build/debug_info/\$target.debug" |
| ${DST_PREFIX}objcopy --strip-unneeded "\$1" |
| ${DST_PREFIX}objcopy --add-gnu-debuglink="build/debug_info/\$target.debug" "\$1" |
| |
| EOF |
| chmod +x "$DST_FILE" |
| log " Generating: ${SRC_PREFIX}strip" |
| } |
| |
| gen_dbg_splitter_darwin() { |
| local SRC_PREFIX="$1" |
| local DST_PREFIX="$2" |
| local DST_FILE="$3/${SRC_PREFIX}strip" |
| |
| cat > "$DST_FILE" << EOF |
| #!/bin/sh |
| # Auto-generated by $(program_name), DO NOT EDIT!! |
| # Environment setup |
| $EXTRA_ENV_SETUP |
| # Tool invocation. |
| target=\$(basename \$1) |
| $AOSP_DIR/prebuilts/android-emulator-build/qemu-android-deps/darwin-x86_64/bin/dsymutil --out build/debug_info/\$target.dSYM \$1 |
| EOF |
| chmod +x "$DST_FILE" |
| log " Generating: ${SRC_PREFIX}strip" |
| } |
| |
| # $1: source prefix |
| # $2: destination prefix |
| # $3: destination directory. |
| # $4: optional. Clang installation path. |
| gen_wrapper_toolchain () { |
| local SRC_PREFIX="$1" |
| local DST_PREFIX="$2" |
| local DST_DIR="$3" |
| local CLANG_BINDIR="$4" |
| local PROG |
| case "$CURRENT_HOST" in |
| windows_msvc*) |
| local COMPILERS="cc gcc clang c++ g++ clang++ cpp ld clang-tidy ar" |
| local PROGRAMS="as ranlib strings nm objdump objcopy dlltool" |
| ;; |
| *) |
| local COMPILERS="cc gcc clang c++ g++ clang++ cpp ld clang-tidy" |
| local PROGRAMS="as ar ranlib strings nm objdump objcopy dlltool" |
| esac |
| |
| log "Generating toolchain wrappers in: $DST_DIR" |
| run mkdir -p "$DST_DIR" |
| |
| if [ -n "$SRC_PREFIX" ]; then |
| SRC_PREFIX=${SRC_PREFIX%%-}- |
| fi |
| |
| case $SRC_PREFIX in |
| *mingw*) |
| PROGRAMS="$PROGRAMS windres" |
| ;; |
| *) |
| # We are doing clang on a posix system.. So lets |
| # Symlink symbolizer, asan really wants this to be named llvm-symbolizer.. |
| ln -sf ${CLANG_BINDIR}/llvm-symbolizer ${DST_DIR}/llvm-symbolizer |
| ;; |
| esac |
| |
| case "$CURRENT_HOST" in |
| windows_msvc*) |
| PROGRAMS="$PROGRAMS windres" |
| ;; |
| esac |
| |
| if [ "$CCACHE" ]; then |
| # If this is clang, disable ccache-induced warnings and |
| # restore colored diagnostics. |
| # http://petereisentraut.blogspot.fr/2011/05/ccache-and-clang.html |
| if (${DST_PREFIX}gcc --version 2>/dev/null | grep --color=never -q clang); then |
| EXTRA_CLANG_FLAGS="-Qunused-arguments -fcolor-diagnostics" |
| EXTRA_CFLAGS="$EXTRA_CFLAGS $EXTRA_CLANG_FLAGS" |
| EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS $EXTRA_CLANG_FLAGS" |
| fi |
| fi |
| |
| for PROG in $COMPILERS; do |
| gen_wrapper_program $PROG "$SRC_PREFIX" "$DST_PREFIX" "$DST_DIR" "$CLANG_BINDIR" |
| done |
| |
| for PROG in $PROGRAMS; do |
| gen_wrapper_program $PROG "$SRC_PREFIX" "$DST_PREFIX" "$DST_DIR" |
| done |
| |
| # Setup additional host specific things |
| case "$CURRENT_HOST" in |
| windows-x86_64|linux-x86_64) |
| gen_dbg_splitter "$SRC_PREFIX" "$DST_PREFIX" "$DST_DIR" |
| ;; |
| darwin-x86_64) |
| gen_dbg_splitter_darwin "$SRC_PREFIX" "$DST_PREFIX" "$DST_DIR" |
| ;; |
| esac |
| |
| EXTRA_CFLAGS= |
| EXTRA_CXXFLAGS= |
| EXTRA_LDFLAGS= |
| EXTRA_ARFLAGS= |
| EXTRA_ASFLAGS= |
| EXTRA_WINDRESFLAGS= |
| EXTRA_ENV_SETUP= |
| } |
| |
| |
| # Configure the darwin toolchain. |
| prepare_build_for_darwin() { |
| OSX_VERSION=$(sw_vers -productVersion) |
| OSX_DEPLOYMENT_TARGET=10.11 |
| OSX_SDK_SUPPORTED="10.11 10.12 10.13 10.14" |
| OSX_SDK_INSTALLED_LIST=$(xcodebuild -showsdks 2>/dev/null | \ |
| grep --color=never macosx | sed -e "s/.*macosx10\.//g" | sort -n | \ |
| sed -e 's/^/10./g' | tr '\n' ' ') |
| if [ -z "$OSX_SDK_INSTALLED_LIST" ]; then |
| panic "Please install XCode on this machine!" |
| fi |
| log "OSX: Installed SDKs: $OSX_SDK_INSTALLED_LIST" |
| for supported_sdk in $(echo "$OSX_SDK_SUPPORTED" | tr ' ' '\n' | sort -r) |
| do |
| POSSIBLE_OSX_SDK_VERSION=$(echo "$OSX_SDK_INSTALLED_LIST" | tr ' ' '\n' | grep $supported_sdk | head -1) |
| if [ -n "$POSSIBLE_OSX_SDK_VERSION" ]; then |
| OSX_SDK_VERSION=$POSSIBLE_OSX_SDK_VERSION |
| fi |
| done |
| log "OSX: Using SDK version $OSX_SDK_VERSION" |
| if [ -z "$OSX_SDK_VERSION" ]; then |
| panic "No supported OSX SDKs found on the machine (Need any of: [$OSX_SDK_SUPPORTED], have: [$OSX_SDK_INSTALLED_LIST])" |
| fi |
| |
| XCODE_PATH=$(xcode-select -print-path 2>/dev/null) |
| log "OSX: XCode path: $XCODE_PATH" |
| |
| OSX_SDK_ROOT=$XCODE_PATH/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${OSX_SDK_VERSION}.sdk |
| log "OSX: Looking for $OSX_SDK_ROOT" |
| if [ ! -d "$OSX_SDK_ROOT" ]; then |
| OSX_SDK_ROOT=/Developer/SDKs/MacOSX${OSX_SDK_VERSION}.sdk |
| log "OSX: Looking for $OSX_SDK_ROOT" |
| if [ ! -d "$OSX_SDK_ROOT" ]; then |
| panic "Could not find SDK $OSX_SDK_VERSION at $OSX_SDK_ROOT" |
| fi |
| fi |
| log "OSX: Using SDK at $OSX_SDK_ROOT" |
| EXTRA_ENV_SETUP="export SDKROOT=$OSX_SDK_ROOT" |
| CLANG_BINDIR=$PREBUILT_TOOLCHAIN_DIR/bin |
| PREBUILT_TOOLCHAIN_DIR= |
| |
| GNU_CONFIG_HOST= |
| |
| common_FLAGS="-target x86_64-apple-darwin12.0.0" |
| var_append common_FLAGS " -isysroot $OSX_SDK_ROOT" |
| var_append common_FLAGS " -mmacosx-version-min=$OSX_DEPLOYMENT_TARGET" |
| var_append common_FLAGS " -DMACOSX_DEPLOYMENT_TARGET=$OSX_DEPLOYMENT_TARGET" |
| EXTRA_CFLAGS="$common_FLAGS -B/usr/bin" |
| EXTRA_CXXFLAGS="$common_FLAGS -B/usr/bin" |
| var_append EXTRA_CXXFLAGS "-stdlib=libc++" |
| EXTRA_LDFLAGS="$common_FLAGS" |
| DST_PREFIX= |
| |
| if [ "$OPT_CXX11" ]; then |
| var_append EXTRA_CXXFLAGS "-std=c++14" "-Werror=c++14-compat" |
| fi |
| } |
| |
| prepare_build_for_linux_x86_64() { |
| GCC_DIR="${PREBUILT_TOOLCHAIN_DIR}/lib/gcc/x86_64-linux/4.8.3/" |
| CLANG_BINDIR=$AOSP_DIR/$(aosp_prebuilt_clang_dir_for linux) |
| CLANG_DIR=$(realpath $CLANG_BINDIR/..) |
| GNU_CONFIG_HOST=x86_64-linux |
| CLANG_VERSION=$(get_clang_version) |
| SYSROOT="${PREBUILT_TOOLCHAIN_DIR}/sysroot" |
| |
| # Clang will invoke the linker, but will not correctly infer the |
| # -gcc-toolchain, so we have to manually configure the various paths. |
| # Note that this can result in warnings of unused flags if we are not |
| # linking and merely translating a .c or .cpp file |
| local GCC_LINK_FLAGS= |
| var_append GCC_LINK_FLAGS "--gcc-toolchain=$PREBUILT_TOOLCHAIN_DIR" |
| var_append GCC_LINK_FLAGS "-B$PREBUILT_TOOLCHAIN_DIR/lib/gcc/x86_64-linux/4.8.3/" |
| var_append GCC_LINK_FLAGS "-L$PREBUILT_TOOLCHAIN_DIR/lib/gcc/x86_64-linux/4.8.3/" |
| var_append GCC_LINK_FLAGS "-L$PREBUILT_TOOLCHAIN_DIR/x86_64-linux/lib64/" |
| var_append GCC_LINK_FLAGS "-fuse-ld=${PREBUILT_TOOLCHAIN_DIR}/bin/x86_64-linux-ld" |
| var_append GCC_LINK_FLAGS "-L${CLANG_BINDIR}/../lib64/clang/${CLANG_VERSION}/lib/linux/" |
| var_append GCC_LINK_FLAGS "-L${CLANG_BINDIR}/../lib64/" |
| var_append GCC_LINK_FLAGS "--sysroot=${SYSROOT}" |
| |
| if [ $(get_verbosity) -gt 3 ]; then |
| # This will get pretty crazy, but useful if you want to debug linker issues. |
| var_append GCC_LINK_FLAGS "-Wl,-verbose" |
| var_append GCC_LINK_FLAGS "-v" |
| else |
| # You're likely to always hit this due to our linker workarounds.. |
| var_append GCC_LINK_FLAGS "-Wno-unused-command-line-argument" |
| fi |
| |
| |
| EXTRA_CFLAGS="-m64" |
| # var_append EXTRA_CFLAGS "-std=c89" |
| var_append EXTRA_CFLAGS "-isystem $SYSROOT/usr/include" |
| var_append EXTRA_CFLAGS "-isystem $SYSROOT/usr/include/x86_64-linux-gnu" |
| var_append EXTRA_CFLAGS ${GCC_LINK_FLAGS} |
| |
| |
| EXTRA_CXXFLAGS="-m64" |
| var_append EXTRA_CXXFLAGS "-stdlib=libc++" |
| var_append EXTRA_CXXFLAGS ${GCC_LINK_FLAGS} |
| |
| if [ "$OPT_CXX11" ]; then |
| var_append EXTRA_CXXFLAGS "-std=c++14" "-Werror=c++14-compat" |
| fi |
| |
| # Make sure we can find libc++ |
| EXTRA_LDFLAGS="-m64" |
| var_append EXTRA_LDFLAGS "-L${CLANG_BINDIR}/../lib64/clang/${CLANG_VERSION}/lib/linux/" |
| var_append EXTRA_LDFLAGS "-L${CLANG_BINDIR}/../lib64/" |
| # Make sure we don't accidently pick up libstdc++ |
| var_append EXTRA_LDFLAGS "-nodefaultlibs" |
| |
| # If we manually call the linker we need to pass in the correct default libs |
| # we link against. These have to go last! |
| POST_LDFLAGS= |
| var_append POST_LDFLAGS "-lc" |
| var_append POST_LDFLAGS "-lc++" |
| var_append POST_LDFLAGS "-lm" |
| var_append POST_LDFLAGS "-lgcc" |
| var_append POST_LDFLAGS "-lgcc_s" |
| } |
| |
| prepare_build_for_linux_aarch64() { |
| GCC_DIR="/usr/" |
| CLANG_BINDIR= |
| CLANG_DIR= |
| GNU_CONFIG_HOST=aarch64-linux |
| CLANG_VERSION= |
| SYSROOT="/" |
| |
| # Clang will invoke the linker, but will not correctly infer the |
| # -gcc-toolchain, so we have to manually configure the various paths. |
| # Note that this can result in warnings of unused flags if we are not |
| # linking and merely translating a .c or .cpp file |
| local GCC_LINK_FLAGS= |
| |
| if [ $(get_verbosity) -gt 3 ]; then |
| # This will get pretty crazy, but useful if you want to debug linker issues. |
| var_append GCC_LINK_FLAGS "-Wl,-verbose" |
| var_append GCC_LINK_FLAGS "-v" |
| else |
| var_append GCC_LINK_FLAGS "" |
| fi |
| |
| |
| EXTRA_CFLAGS= |
| var_append EXTRA_CFLAGS ${GCC_LINK_FLAGS} |
| |
| |
| EXTRA_CXXFLAGS= |
| var_append EXTRA_CXXFLAGS ${GCC_LINK_FLAGS} |
| |
| if [ "$OPT_CXX11" ]; then |
| var_append EXTRA_CXXFLAGS "-std=c++14" "-Werror=c++14-compat" |
| fi |
| |
| # Make sure we can find libgcc on aarch64 |
| EXTRA_LDFLAGS="-L/usr/lib/gcc/aarch64-linux-gnu/5" |
| |
| # If we manually call the linker we need to pass in the correct default libs |
| # we link against. These have to go last! |
| POST_LDFLAGS= |
| var_append POST_LDFLAGS "-lc" |
| var_append POST_LDFLAGS "-lc++" |
| var_append POST_LDFLAGS "-lm" |
| var_append POST_LDFLAGS "-lgcc" |
| var_append POST_LDFLAGS "-lgcc_s" |
| var_append POST_LDFLAGS "-ldl" |
| |
| # aarch64 use host toolchain. no prefix needed. |
| DST_PREFIX= |
| } |
| |
| prepare_build_for_windows () { |
| local GCC_LINK_FLAGS="-Wno-missing-braces -Wno-aggressive-loop-optimizations" |
| |
| case $CURRENT_HOST in |
| windows-x86_64) |
| GNU_CONFIG_HOST=x86_64-w64-mingw32 |
| EXTRA_CFLAGS="-m64" |
| EXTRA_CXXFLAGS="-m64" |
| ;; |
| esac |
| |
| if [ "$OPT_CXX11" ]; then |
| var_append EXTRA_CXXFLAGS "-std=c++11" "-Werror=c++11-compat" |
| fi |
| |
| var_append EXTRA_CFLAGS ${GCC_LINK_FLAGS} |
| var_append EXTRA_CXXFLAGS ${GCC_LINK_FLAGS} |
| } |
| |
| configure_google_storage() { |
| local DEPOT_TOOLS=$(aosp_depot_tools_dir) |
| ${DEPOT_TOOLS}/download_from_google_storage --config |
| } |
| |
| fetch_dependencies_msvc() { |
| # Takes two parameters: |
| # $1: The path to the mount point for ciopfs, |
| # $2: The path to the data directory for ciopfs |
| |
| # if you really want to force pull-down the sdk again, you can specify it in the rebuild script via |
| # --force-refresh-winsdk |
| CLANG_VERSION=$(get_clang_version) |
| # The mount point for ciopfs (case-insensitive) |
| local MOUNT_POINT="$1" |
| # Where the windows sdk is actually stored in ciopfs |
| local DATA_POINT="$2" |
| |
| if [ -d "$MOUNT_POINT" ] && [ -d "$DATA_POINT" ]; then |
| # We will cache the windows sdk and reuse it for each build, unless you specify to force pull it down |
| # via --force-fetch-wintoolchain |
| if [ "$OPT_FORCE_FETCH_WINTOOLCHAIN" ]; then |
| # Need to unmount $MOUNT_POINT first or we can't delete it |
| run fusermount -u ${MOUNT_POINT} |
| run rm -rf $MOUNT_POINT |
| run rm -rf $DATA_POINT |
| else |
| return 0 |
| fi |
| fi |
| |
| # Create the case-insensitive filesystem |
| run mkdir -p {$MOUNT_POINT,$DATA_POINT} |
| local CIOPFS="${AOSP_DIR}/prebuilts/android-emulator-build/common/ciopfs/linux-x86_64/ciopfs" |
| run $CIOPFS -o use_ino $DATA_POINT $MOUNT_POINT |
| |
| # Download the windows sdk |
| local DEPOT_TOOLS=$(aosp_depot_tools_dir) |
| local MSVC_HASH=$(aosp_msvc_hash) |
| |
| log "Looking to get tools version: ${MSVC_HASH}" |
| log "Downloading the SDK (this might take a couple of minutes ...)" |
| run ${DEPOT_TOOLS}/win_toolchain/get_toolchain_if_necessary.py --force --toolchain-dir=$MOUNT_POINT $MSVC_HASH |
| } |
| |
| get_clang_version() { |
| CLANG_BINDIR=$AOSP_DIR/$(aosp_prebuilt_clang_dir_for ${BUILD_HOST}) |
| CLANG_DIR=$(realpath $CLANG_BINDIR/..) |
| if [[ $BUILD_HOST == "darwin" ]]; then |
| CLANG_VERSION=$(${CLANG_BINDIR}/clang -v 2>&1 | egrep -E 'clang version \d+.\d+.\d' -o | egrep -E '\d+.\d+.\d+' -o) |
| else |
| CLANG_VERSION=$(${CLANG_BINDIR}/clang -v 2>&1 | grep -P 'clang version \d+.\d+.\d' -o | grep -P '\d+.\d+.\d+' -o) |
| fi |
| echo $CLANG_VERSION |
| } |
| |
| prepare_build_for_windows_msvc() { |
| CLANG_BINDIR=$AOSP_DIR/$(aosp_prebuilt_clang_dir_for ${BUILD_HOST}) |
| CLANG_DIR=$(realpath $CLANG_BINDIR/..) |
| CLANG_VERSION=$(get_clang_version) |
| |
| # Let's cache the Windows SDK toolchain in the prebuilts/android-emulator-build/msvc |
| # fetch_dependencies_msvc will pull down the sdk from google storage if the provided directories are |
| # not found. |
| MSVC_ROOT_DIR="${AOSP_DIR}/prebuilts/android-emulator-build/msvc" |
| CIOPFS_DIR="${AOSP_DIR}/prebuilts/android-emulator-build/.ciopfs" |
| |
| # Check to see if we need to fetch the toolchain.. |
| if [ -d "$OPT_VSDIR" ]; then |
| MSVC_DIR=$OPT_VSDIR |
| else |
| log "Configuring msvc.." |
| MSVC_HASH=$(aosp_msvc_hash) |
| MSVC_DIR=${MSVC_ROOT_DIR}/vs_files/${MSVC_HASH} |
| fetch_dependencies_msvc "${MSVC_ROOT_DIR}" "${CIOPFS_DIR}" |
| fi |
| |
| # We cannot have multiple SDK versions in the same dir |
| MSVC_VER=$(ls -1 ${MSVC_DIR}/win_sdk/Include) |
| log "Using version [${MSVC_VER}]" |
| |
| VC_VER=$(ls -1 ${MSVC_DIR}/VC/Tools/MSVC) |
| log "Using visual studio version: ${VC_VER}" |
| |
| run mkdir -p $MSVC_DIR/clang-intrins/${CLANG_VERSION}/include |
| run rsync -r ${CLANG_DIR}/lib64/clang/${CLANG_VERSION}/include $MSVC_DIR/clang-intrins/${CLANG_VERSION} |
| |
| local CLANG_LINK_FLAGS= |
| var_append CLANG_LINK_FLAGS "-fuse-ld=lld" |
| var_append CLANG_LINK_FLAGS "-L${MSVC_DIR}/VC/Tools/MSVC/${VC_VER}/lib/x64" |
| var_append CLANG_LINK_FLAGS "-L${MSVC_DIR}/VC/Tools/MSVC/${VC_VER}/atlmfc/lib/x64" |
| var_append CLANG_LINK_FLAGS "-L${MSVC_DIR}/win_sdk/lib/${MSVC_VER}/ucrt/x64" |
| var_append CLANG_LINK_FLAGS "-L${MSVC_DIR}/win_sdk/lib/${MSVC_VER}/um/x64" |
| var_append CLANG_LINK_FLAGS "\"-L${MSVC_DIR}/DIA SDK/lib/amd64\"" |
| var_append CLANG_LINK_FLAGS "-Wl,-nodefaultlib:libcmt,-defaultlib:msvcrt,-defaultlib:oldnames" |
| # Other linker flags to make cross-compiling upstream-qemu work without adding any additional |
| # flags to it's makefile. |
| var_append CLANG_LINK_FLAGS "-lshell32 -luser32 -ladvapi32 -liphlpapi -lwldap32 -lmfuuid -lwinmm" |
| |
| if [ $(get_verbosity) -gt 3 ]; then |
| # This will get pretty crazy, but useful if you want to debug linker issues. |
| var_append CLANG_LINK_FLAGS "-Wl,-verbose" |
| var_append CLANG_LINK_FLAGS "-v" |
| else |
| # You're likely to always hit this due to our linker workarounds.. |
| var_append CLANG_LINK_FLAGS "-Wno-unused-command-line-argument" |
| fi |
| |
| |
| EXTRA_CFLAGS="-target x86_64-pc-win32" |
| var_append EXTRA_CFLAGS "-DLIEF_DISABLE_FROZEN=on" |
| var_append EXTRA_CFLAGS "-D_MD" |
| var_append EXTRA_CFLAGS "-D_DLL" |
| var_append EXTRA_CFLAGS "-D_AMD64_" |
| var_append EXTRA_CFLAGS "-DWIN32_LEAN_AND_MEAN" |
| var_append EXTRA_CFLAGS "-DNOMINMAX" |
| var_append EXTRA_CFLAGS "-D_CRT_SECURE_NO_WARNINGS" |
| var_append EXTRA_CFLAGS "-D_USE_MATH_DEFINES" |
| var_append EXTRA_CFLAGS "-Wno-msvc-not-found" |
| var_append EXTRA_CFLAGS "-Wno-address-of-packed-member" |
| var_append EXTRA_CFLAGS "-Wno-incompatible-ms-struct" |
| var_append EXTRA_CFLAGS "-Wno-c++11-narrowing" |
| # Disable builtin #include directories |
| var_append EXTRA_CFLAGS "-nobuiltininc" |
| var_append EXTRA_CFLAGS "-isystem $MSVC_DIR/clang-intrins/${CLANG_VERSION}/include" |
| var_append EXTRA_CFLAGS "-isystem $MSVC_DIR/VC/Tools/MSVC/${VC_VER}/include" |
| var_append EXTRA_CFLAGS "-isystem $MSVC_DIR/win_sdk/include/${MSVC_VER}/ucrt" |
| var_append EXTRA_CFLAGS "-isystem $MSVC_DIR/win_sdk/include/${MSVC_VER}/um" |
| var_append EXTRA_CFLAGS "-isystem $MSVC_DIR/win_sdk/include/${MSVC_VER}/winrt" |
| var_append EXTRA_CFLAGS "-isystem $MSVC_DIR/win_sdk/include/${MSVC_VER}/shared" |
| var_append EXTRA_CFLAGS "-isystem \"$MSVC_DIR/DIA SDK/include\"" |
| |
| |
| var_append EXTRA_CFLAGS ${CLANG_LINK_FLAGS} |
| |
| |
| EXTRA_CXXFLAGS="-target x86_64-pc-win32" |
| var_append EXTRA_CXXFLAGS "-DLIEF_DISABLE_FROZEN=on" |
| var_append EXTRA_CXXFLAGS "-D_MD" |
| var_append EXTRA_CXXFLAGS "-D_DLL" |
| var_append EXTRA_CXXFLAGS "-D_AMD64_" |
| var_append EXTRA_CXXFLAGS "-DWIN32_LEAN_AND_MEAN" |
| var_append EXTRA_CXXFLAGS "-DNOMINMAX" |
| var_append EXTRA_CXXFLAGS "-D_CRT_SECURE_NO_WARNINGS" |
| var_append EXTRA_CXXFLAGS "-D_USE_MATH_DEFINES" |
| var_append EXTRA_CXXFLAGS "-Wno-msvc-not-found" |
| var_append EXTRA_CXXFLAGS "-Wno-address-of-packed-member" |
| var_append EXTRA_CXXFLAGS "-Wno-incompatible-ms-struct" |
| var_append EXTRA_CXXFLAGS "-Wno-c++11-narrowing" |
| var_append EXTRA_CXXFLAGS "-fms-compatibility" |
| var_append EXTRA_CXXFLAGS "-fdelayed-template-parsing" |
| var_append EXTRA_CXXFLAGS "-fms-extensions" |
| # Disable builtin #include directories |
| var_append EXTRA_CXXFLAGS "-nobuiltininc" |
| # Disable standard #include directories for the C++ standard library |
| var_append EXTRA_CXXFLAGS "-nostdinc++" |
| var_append EXTRA_CXXFLAGS "-isystem $MSVC_DIR/clang-intrins/${CLANG_VERSION}/include" |
| var_append EXTRA_CXXFLAGS "-isystem $MSVC_DIR/VC/Tools/MSVC/${VC_VER}/include" |
| var_append EXTRA_CXXFLAGS "-isystem $MSVC_DIR/VC/Tools/MSVC/${VC_VER}/atlmfc/include" |
| var_append EXTRA_CXXFLAGS "-isystem $MSVC_DIR/win_sdk/include/${MSVC_VER}/ucrt" |
| var_append EXTRA_CXXFLAGS "-isystem $MSVC_DIR/win_sdk/include/${MSVC_VER}/um" |
| var_append EXTRA_CXXFLAGS "-isystem $MSVC_DIR/win_sdk/include/${MSVC_VER}/winrt" |
| var_append EXTRA_CXXFLAGS "-isystem $MSVC_DIR/win_sdk/include/${MSVC_VER}/shared" |
| var_append EXTRA_CXXFLAGS "-isystem \"$MSVC_DIR/DIA SDK/include\"" |
| var_append EXTRA_CXXFLAGS ${CLANG_LINK_FLAGS} |
| var_append EXTRA_CXXFLAGS "-std=c++14" "-Werror=c++14-compat" |
| |
| EXTRA_LDFLAGS="-target x86_64-pc-win32" |
| # Make sure we don't accidently pick up any clang libs or msvc libs |
| # that are included by default (libcmt). |
| var_append EXTRA_LDFLAGS "-nodefaultlibs" |
| } |
| |
| |
| # Prints info based on the passed in parameter |
| # $1 The information we want to print, from { binprefix, sysroot, clang-dir, |
| # clang-version} |
| print_info () { |
| local PRINT=$1 |
| |
| # If $BINPREFIX is not empty, ensure it has a trailing -. |
| if [ "$BINPREFIX" ]; then |
| BINPREFIX=${BINPREFIX%%-}- |
| fi |
| case $PRINT in |
| binprefix) |
| if [[ $BUILD_HOST == "darwin" ]]; then |
| BINPREFIX="" |
| fi |
| printf "%s\n" "$BINPREFIX" |
| ;; |
| sysroot) |
| local SUBDIR |
| SUBDIR="$(aosp_prebuilt_toolchain_sysroot_subdir_for "${CURRENT_HOST}")" |
| if [ -n "${SUBDIR}" ]; then |
| printf "${AOSP_DIR}/${SUBDIR}" |
| fi |
| ;; |
| clang-dir) |
| printf "%s\n" "${CLANG_DIR}" |
| ;; |
| clang-version) |
| CLANG_VERSION=$(${CLANG_BINDIR}/clang -v 2>&1 | head -n 1 | awk '{print $4}') |
| printf "%s\n" "$CLANG_VERSION" |
| ;; |
| libcplusplus) |
| if [ "$BUILD_HOST" = "linux" -a "$BUILD_ARCH" = "aarch64" ]; then |
| printf "%s\n" "/usr/lib/aarch64-linux-gnu/libc++.so" |
| else |
| printf "%s\n" "$CLANG_DIR/lib64/libc++.so" |
| fi |
| ;; |
| libasan-dir) |
| printf "%s" "$CLANG_DIR/lib64/clang/5.0/lib/linux/" |
| ;; |
| *) |
| printf "%s\n" "${BINPREFIX}$PRINT" |
| ;; |
| esac |
| } |
| |
| |
| # Prepare the build for a given host system. |
| # $1: Host system tag (e.g. linux-x86_64) |
| prepare_build_for_host () { |
| local CURRENT_HOST=$1 |
| EXTRA_ENV_SETUP= |
| CLANG_BINDIR= |
| PREBUILT_TOOLCHAIN_SUBDIR=$(aosp_prebuilt_toolchain_subdir_for $CURRENT_HOST) |
| PREBUILT_TOOLCHAIN_DIR=$AOSP_DIR/$PREBUILT_TOOLCHAIN_SUBDIR |
| TOOLCHAIN_PREFIX=$(aosp_prebuilt_toolchain_prefix_for $CURRENT_HOST) |
| DST_PREFIX=$PREBUILT_TOOLCHAIN_DIR/bin/$TOOLCHAIN_PREFIX |
| |
| case $CURRENT_HOST in |
| linux-*) |
| prepare_build_for_linux_$(get_build_arch) |
| ;; |
| darwin-*) |
| prepare_build_for_darwin |
| ;; |
| windows_msvc-*) |
| if [ $BUILD_HOST == "darwin" ]; then |
| which x86_64-w64-mingw32-gcc > /dev/null || panic "No mingw install available!" |
| TOOLCHAIN_PREFIX=x86_64-w64-mingw32- |
| DST_PREFIX=$(dirname $(which x86_64-w64-mingw32-gcc)) |
| DST_PREFIX=${DST_PREFIX}/$TOOLCHAIN_PREFIX |
| fi |
| prepare_build_for_windows_msvc |
| ;; |
| windows-*) |
| prepare_build_for_windows |
| esac |
| |
| |
| if [ "$OPT_BINPREFIX" ]; then |
| BINPREFIX=${OPT_BINPREFIX%%-} |
| else |
| BINPREFIX=$GNU_CONFIG_HOST |
| fi |
| |
| if [ "$OPT_PREFIX" ]; then |
| var_append EXTRA_CFLAGS "-I$OPT_PREFIX/include" |
| var_append EXTRA_CXXFLAGS "-I$OPT_PREFIX/include" |
| var_append EXTRA_LDFLAGS "-L$OPT_PREFIX/lib" |
| fi |
| if [ "$OPT_PRINT" ]; then |
| print_info $OPT_PRINT |
| elif [ "$OPT_FORCE_FETCH_WINTOOLCHAIN" ]; then |
| # The windows toolchain should have been refreshed in prepare_build_for_windows_msvc |
| # so don't need to do anything here. |
| return 0 |
| else |
| log "Generating ${BINPREFIX%%-} wrapper toolchain in $INSTALL_DIR" |
| gen_wrapper_toolchain "$BINPREFIX" "$DST_PREFIX" "$INSTALL_DIR" "$CLANG_BINDIR" |
| |
| # Create pkgconfig link for other scripts. |
| case $CURRENT_HOST in |
| linux-x86*) |
| ln -sfn "$PREBUILT_TOOLCHAIN_DIR/sysroot/usr/lib/pkgconfig" "$INSTALL_DIR/pkgconfig" |
| ;; |
| esac |
| fi |
| } |
| prepare_build_for_host $HOST |