#!/bin/sh msg() { echo "configure: $1" } step_msg() { msg msg "$1" msg } warn() { echo "configure: WARNING: $1" } err() { echo "configure: error: $1" exit 1 } need_ok() { if [ $? -ne 0 ] then err $1 fi } need_cmd() { if which $1 >/dev/null 2>&1 then msg "found $1" else err "need $1" fi } make_dir() { if [ ! -d $1 ] then msg "mkdir -p $1" mkdir -p $1 fi } copy_if_changed() { if cmp -s $1 $2 then msg "leaving $2 unchanged" else msg "cp $1 $2" cp -f $1 $2 chmod u-w $2 # make copied artifact read-only fi } move_if_changed() { if cmp -s $1 $2 then msg "leaving $2 unchanged" else msg "mv $1 $2" mv -f $1 $2 chmod u-w $2 # make moved artifact read-only fi } putvar() { local T eval T=\$$1 eval TLEN=\${#$1} if [ $TLEN -gt 35 ] then printf "configure: %-20s := %.35s ...\n" $1 "$T" else printf "configure: %-20s := %s %s\n" $1 "$T" "$2" fi printf "%-20s ?= %s\n" $1 "$T" >>${CFG_BUILD_HOME}config.tmp } probe() { local V=$1 shift local P local T for P do T=$(which $P 2>&1) if [ $? -eq 0 ] then VER0=$($P --version 2>/dev/null | head -1 \ | sed -e 's/[^0-9]*\([vV]\?[0-9.]\+[^ ]*\).*/\1/' ) if [ $? -eq 0 -a "x${VER0}" != "x" ] then VER="($VER0)" else VER="" fi break else VER="" T="" fi done eval $V=\$T putvar $V "$VER" } probe_need() { local V=$1 probe $* eval VV=\$$V if [ -z "$VV" ] then err "needed, but unable to find any of: $*" fi } valopt() { local OP=$1 local DEFAULT=$2 shift shift local DOC="$*" if [ $HELP -eq 0 ] then local UOP=$(echo $OP | tr '[:lower:]' '[:upper:]' | tr '\-' '\_') local V="CFG_${UOP}" eval $V="$DEFAULT" for arg in $CFG_CONFIGURE_ARGS do if echo "$arg" | grep -q -- "--$OP=" then val=$(echo "$arg" | cut -f2 -d=) eval $V=$val fi done putvar $V else if [ -z "$DEFAULT" ] then DEFAULT="" fi OP="${OP}=[${DEFAULT}]" printf " --%-30s %s\n" "$OP" "$DOC" fi } opt() { local OP=$1 local DEFAULT=$2 shift shift local DOC="$*" local FLAG="" if [ $DEFAULT -eq 0 ] then FLAG="enable" else FLAG="disable" DOC="don't $DOC" fi if [ $HELP -eq 0 ] then for arg in $CFG_CONFIGURE_ARGS do if [ "$arg" = "--${FLAG}-${OP}" ] then OP=$(echo $OP | tr 'a-z-' 'A-Z_') FLAG=$(echo $FLAG | tr 'a-z' 'A-Z') local V="CFG_${FLAG}_${OP}" eval $V=1 putvar $V fi done else if [ ! -z "$META" ] then OP="$OP=<$META>" fi printf " --%-30s %s\n" "$FLAG-$OP" "$DOC" fi } split_triple() { local TRIPLE=$1 local ARCH=$2 local VENDOR=$3 local OS=$4 eval $ARCH=$(echo "$TRIPLE" | cut -d'-' -f1) eval $VENDOR=$(echo "$TRIPLE" | cut -d'-' -f2) eval $OS=$(echo "$TRIPLE" | cut -d'-' -f3) if [ $(echo "$TRIPLE" | cut -d'-' -f3) = "androideabi" ] then eval $OS="android" fi } os_type() { # The goal here is to come up with the same triple as LLVM would, # at least for the subset of platforms we're willing to target. local OP=$1 local OSTYPE=$(echo "$2" | tr '[:upper:]' '[:lower:]') local V="${OP}" case $OSTYPE in linux) eval $V=unknown-linux-gnu ;; freebsd) eval $V=unknown-freebsd ;; darwin) eval $V=apple-darwin ;; mingw32*) eval $V=pc-mingw32 ;; android) eval $V=linux-androideabi ;; *) err "unknown OS type: $OSTYPE" ;; esac } cpu_type() { local OP=$1 local CPUTYPE=$2 local V="${OP}" case $CPUTYPE in i386 | i486 | i686 | i786 | x86) eval $V=i686 ;; xscale | arm) eval $V=arm ;; x86_64 | x86-64 | x64 | amd64) eval $V=x86_64 ;; *) err "unknown CPU type: $CPUTYPE" esac } if [ -f configure -a -f Makefile.in ]; then msg "You seem to be running configure within the source tree root." msg "This is not supported. Instead, make a build directory:" msg "" msg " mkdir -p build && cd build && ../configure" msg "" msg "See README.md for more information." exit 1 fi msg "looking for configure programs" need_cmd cmp need_cmd mkdir need_cmd printf need_cmd cut need_cmd grep need_cmd xargs need_cmd cp need_cmd find need_cmd uname need_cmd date need_cmd tr need_cmd sed msg "inspecting environment" OSTYPE=$(uname -s) CPUTYPE=$(uname -m) if [ $OSTYPE = Darwin -a $CPUTYPE = i386 ] then # Darwin's `uname -m` lies and always returns i386. We have to use sysctl # instead. if sysctl hw.optional.x86_64 | grep -q ': 1' then CPUTYPE=x86_64 fi fi os_type CFG_BUILD_OSTYPE ${OSTYPE} cpu_type CFG_BUILD_CPUTYPE ${CPUTYPE} DEFAULT_TARGET="${CFG_BUILD_CPUTYPE}-${CFG_BUILD_OSTYPE}" CFG_SRC_DIR="$(cd $(dirname $0) && pwd)/" CFG_BUILD_HOME="$(pwd)/" CFG_SELF=${CFG_SRC_DIR}$(basename $0) CFG_CONFIGURE_ARGS="$@" CFG_PATH=$PATH if [ -n "$CFG_DISABLE_MANAGE_SUBMODULES" ] then if git status $CFG_SRC_DIR/src/compiler $CFG_SRC_DIR/src/support $CFG_SRC_DIR/src/platform \ | grep -q 'modified:.*modified content'; then err "Some submodule has a dirty working tree. See 'git status'." fi fi OPTIONS="" HELP=0 if [ "$1" = "--help" ] then HELP=1 shift echo "" echo "Usage: $CFG_SELF [options]" echo "" echo "Options:" echo "" else msg "recreating config.tmp" echo '' >${CFG_BUILD_HOME}config.tmp step_msg "processing $CFG_SELF args" fi opt optimize 1 "build optimized rust code" opt optimize-cxx 1 "build optimized C++ code" opt manage-submodules 1 "let the build manage the git submodules" opt fast-make 0 "use .gitmodules as timestamp for submodule deps" opt debug 0 "build with debugging code and symbols" opt debug-skia 0 "build Skia and Azure for debugging (significant performance hit)" valopt local-rust-root "" "set prefix for local rust binary" valopt target "${DEFAULT_TARGET}" "target to be compiled" valopt android-cross-path "/opt/ndk_standalone" "Android NDK cross compiler path" valopt android-ndk-path "/opt/android-ndk" "Android NDK path" valopt android-sdk-path "/opt/android-sdk" "Android SDK path" valopt android-font-path "/system/fonts" "Android Font path" valopt android-resource-path "/sdcard/servo" "Android Resource path" if [ $HELP -eq 1 ] then echo "" exit 0 fi # Split target triple split_triple "${CFG_TARGET}" TARGET_CPUTYPE TARGET_VENDOR TARGET_OSTYPE # Set target os and cpu type os_type CFG_OSTYPE ${TARGET_OSTYPE} cpu_type CFG_CPUTYPE ${TARGET_CPUTYPE} # probe before updating PATH so we don't get ndk-toolchain stuff probe_need CFG_GIT git probe_need CFG_PYTHON2 python2 python2.7 python export PYTHON=${CFG_PYTHON2} echo "exporting python = ${CFG_PYTHON2}" # Spidermonkey requires autoconf 2.13 exactly probe_need CFG_AUTOCONF213 autoconf213 \ autoconf2.13 \ autoconf-2.13 step_msg "looking for build programs" case ${TARGET_OSTYPE} in android) CFG_PATH=$PATH:"${CFG_ANDROID_CROSS_PATH}/bin" OLD_PATH=$PATH export PATH=${CFG_PATH} probe CFG_CC arm-linux-androideabi-gcc probe CFG_CXX arm-linux-androideabi-g++ probe CFG_LD arm-linux-androideabi-ld probe CFG_AR arm-linux-androideabi-ar probe CFG_RANLIB arm-linux-androideabi-ranlib export PATH=${OLD_PATH} ;; *) CFG_PATH=$PATH probe CFG_CC gcc probe CFG_CXX g++ probe CFG_LD ld probe CFG_AR ar probe CFG_RANLIB ranlib CFG_RUSTC_FLAGS="" ;; esac probe CFG_CLANG clang++ CFG_BUILD_DIR="${CFG_BUILD_HOME}${CFG_TARGET}/" make_dir "${CFG_BUILD_DIR}" if [ ! -z "$CFG_LOCAL_RUST_ROOT" ] then if [ -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc ] then LRV=`${CFG_LOCAL_RUST_ROOT}/bin/rustc --version` step_msg "using rustc at: ${CFG_LOCAL_RUST_ROOT} with version: $LRV" CFG_RUSTC=${CFG_LOCAL_RUST_ROOT}/bin/rustc CFG_RUST_HOME=${CFG_LOCAL_RUST_ROOT} CFG_LOCAL_RUSTC=1 else err "No rustc found at ${CFG_LOCAL_RUST_ROOT}/bin/rustc" fi else step_msg "using in-tree rust compiler" # The Rust compiler we're going to build CFG_RUSTC="${CFG_BUILD_DIR}src/compiler/rust/${DEFAULT_TARGET}/stage2/bin/rustc" CFG_RUST_HOME="${CFG_BUILD_DIR}src/compiler/rust/${DEFAULT_TARGET}/stage2" fi if [ -z "$CFG_ENABLE_CLANG" -a -z "$CFG_CC" ] then err "either clang or gcc is required" fi # Configure submodules step_msg "configuring submodules" # Have to be in the top of src directory for this if [ -z $CFG_DISABLE_MANAGE_SUBMODULES ] then cd ${CFG_SRC_DIR} msg "git: submodule sync" "${CFG_GIT}" submodule --quiet sync # NB: this is just for the sake of getting the submodule SHA1 values # and status written into the build log. msg "git: submodule status" "${CFG_GIT}" submodule status --recursive msg "git: submodule update" "${CFG_GIT}" submodule update --init need_ok "git failed" msg "git: submodule foreach sync" "${CFG_GIT}" submodule foreach --recursive 'if test -e .gitmodules; then git submodule sync; fi' need_ok "git failed" msg "git: submodule foreach update" "${CFG_GIT}" submodule update --init --recursive need_ok "git failed" msg "git: submodule clobber" "${CFG_GIT}" submodule foreach --recursive \ 'if [ -n "$(git status --porcelain)" ] ; then echo "Refusing to clobber $path" ; else git clean -dxf ; git checkout . ; fi' need_ok "git failed" cd ${CFG_BUILD_DIR} fi step_msg "running submodule autoconf scripts" msg "configuring src/mozjs" AUTOCONF213_M4_MACROS="$(dirname ${CFG_AUTOCONF213})/../share/$(basename ${CFG_AUTOCONF213})/" # Run the SpiderMonkey autoconf using autoconf 2.13 (cd ${CFG_SRC_DIR}src/support/spidermonkey/mozjs/js/src && "${CFG_AUTOCONF213}" -l "${AUTOCONF213_M4_MACROS}") || exit $? if [ $CFG_OSTYPE = "linux-androideabi" ] then msg "configuring src/libexpat" (cd ${CFG_SRC_DIR}src/platform/android/libexpat/expat && sh "buildconf.sh") || exit $? ## expat is missing install-sh and other tools and doesn't use automake ## which is what creates it. use the ones from spidermonkey for name in install-sh config.sub config.guess do cp ${CFG_SRC_DIR}src/support/spidermonkey/mozjs/js/src/build/autoconf/${name} ${CFG_SRC_DIR}src/platform/android/libexpat/expat/conftools/ done fi CFG_SUBMODULES="\ support/alert/rust-alert \ support/azure/rust-azure \ support/css/rust-cssparser \ support/encoding/rust-encoding \ support/harfbuzz/rust-harfbuzz \ support/http/rust-http \ support/hubbub/libhubbub \ support/hubbub/rust-hubbub \ support/libparserutils/libparserutils \ support/skia/skia \ support/spidermonkey/mozjs \ support/spidermonkey/rust-mozjs \ support/stb-image/rust-stb-image \ support/png/libpng \ support/png/rust-png \ support/geom/rust-geom \ support/layers/rust-layers \ support/opengles/rust-opengles \ support/sharegl/sharegl" if [ $CFG_OSTYPE = "apple-darwin" ] then CFG_SUBMODULES="\ platform/macos/rust-core-foundation \ platform/macos/rust-core-graphics \ platform/macos/rust-core-text \ platform/macos/rust-io-surface \ support/glfw/glfw \ support/glfw/glfw-rs \ platform/macos/rust-cocoa \ ${CFG_SUBMODULES}" fi if [ $CFG_OSTYPE = "unknown-linux-gnu" ] then CFG_SUBMODULES="\ platform/linux/rust-xlib \ platform/linux/fontconfig \ support/glfw/glfw \ support/glfw/glfw-rs \ platform/linux/rust-fontconfig \ platform/linux/rust-freetype \ ${CFG_SUBMODULES}" fi if [ $CFG_OSTYPE = "linux-androideabi" ] then CFG_SUBMODULES="\ support/glut/rust-glut \ support/egl/rust-egl \ platform/android/libexpat \ platform/android/libfreetype2 \ platform/android/fontconfig \ platform/linux/rust-fontconfig \ platform/linux/rust-freetype \ ${CFG_SUBMODULES}" fi step_msg "writing configuration" putvar CFG_TARGET putvar CFG_CPUTYPE putvar CFG_OSTYPE putvar CFG_SRC_DIR putvar CFG_BUILD_HOME putvar CFG_BUILD_DIR putvar CFG_CONFIGURE_ARGS putvar CFG_SUBMODULES putvar CFG_DISABLE_MANAGE_SUBMODULES putvar CFG_RUSTC putvar CFG_RUSTC_FLAGS putvar CFG_RUST_HOME putvar CFG_PATH putvar CFG_LOCAL_RUSTC putvar CFG_LOCAL_RUST_ROOT putvar CFG_ENABLE_DEBUG putvar CFG_ENABLE_DEBUG_SKIA msg copy_if_changed ${CFG_SRC_DIR}Makefile.in ${CFG_BUILD_HOME}Makefile move_if_changed ${CFG_BUILD_HOME}config.tmp ${CFG_BUILD_HOME}config.mk copy_if_changed ${CFG_BUILD_HOME}config.mk ${CFG_SRC_DIR}/.config.mk.last rm -f ${CFG_BUILD_HOME}config.tmp touch ${CFG_BUILD_HOME}config.stamp export CFG_CONFIG_MK="${CFG_BUILD_HOME}config.mk" step_msg "making build directories" cd "${CFG_BUILD_DIR}" for i in ${CFG_SUBMODULES} do make_dir ${CFG_BUILD_DIR}src/${i} done make_dir ${CFG_BUILD_DIR}src/components/macros make_dir ${CFG_BUILD_DIR}src/components/util make_dir ${CFG_BUILD_DIR}src/components/embedding make_dir ${CFG_BUILD_DIR}src/components/msg make_dir ${CFG_BUILD_DIR}src/components/net make_dir ${CFG_BUILD_DIR}src/components/gfx make_dir ${CFG_BUILD_DIR}src/components/script make_dir ${CFG_BUILD_DIR}src/components/style make_dir ${CFG_BUILD_DIR}src/components/main make_dir src/test/html/ref make_dir src/compiler/rust # TODO: don't run configure on submodules unless necessary. For an example, # see how Rust's configure script optionally reconfigures the LLVM module. step_msg "running submodule configure scripts" # Only reconfigure Rust when it changes do_reconfigure=1 index1="${CFG_SRC_DIR}.git/modules/src/compiler/rust/index" index2="${CFG_SRC_DIR}src/compiler/rust/.git/index" for index in ${index1} ${index2} do config_stamp="${CFG_BUILD_DIR}src/compiler/rust/config.stamp" if test -e ${index} -a -e ${config_stamp} -a ${config_stamp} -nt ${index} then msg "not reconfiguring Rust, config.stamp is fresh" do_reconfigure=0 fi done if [ ${do_reconfigure} -ne 0 ] then cd ${CFG_BUILD_DIR}src/compiler/rust RUST_CONFIGURE_ARGS="--enable-debug" if [ $CFG_OSTYPE = "linux-androideabi" ]; then RUST_CONFIGURE_ARGS="--target=arm-linux-androideabi --android-cross-path=${CFG_ANDROID_CROSS_PATH}" fi ${CFG_SRC_DIR}src/compiler/rust/configure ${RUST_CONFIGURE_ARGS} cd ${CFG_BUILD_DIR} fi # fontconfig expects to use an installed freetype, but we want to use our version on Android if [ $CFG_OSTYPE = "linux-androideabi" ] then export FREETYPE_CFLAGS="-I${CFG_SRC_DIR}src/platform/android/libfreetype2/include -I${CFG_BUILD_DIR}src/platform/android/libfreetype2/include" export FREETYPE_LIBS="-L${CFG_BUILD_DIR}src/platform/android/libfreetype2/.libs -lfreetype" fi # PIC all the things export CFLAGS="${CFLAGS} -fPIC" export LDFLAGS="${CFLAGS} -fPIC" if [ $CFG_BUILD_OSTYPE = "apple-darwin" ] then export LIBTOOLIZE=glibtoolize fi # cross compile configurations EXTRA_CONFIGURE_ARGS="CC=${CFG_CC} CXX=${CFG_CXX} LD=${CFG_LD} AR=${CFG_AR} RANLIB=${CFG_RANLIB}" for i in ${CFG_SUBMODULES} do if [ -d ${CFG_BUILD_DIR}src/${i} ] then cd ${CFG_BUILD_DIR}src/${i} fi CONFIGURE_SCRIPT="${CFG_SRC_DIR}src/${i}/configure" CONFIGURE_ARGS="" ENV_VARS="" ENABLE_DEBUG="$CFG_ENABLE_DEBUG" case $i in platform/android/libexpat) CONFIGURE_SCRIPT="${CFG_SRC_DIR}src/${i}/expat/configure" CONFIGURE_ARGS="${CONFIGURE_ARGS} --host=arm-linux-androideabi" CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-sysroot=${CFG_ANDROID_CROSS_PATH}/sysroot" CONFIGURE_ARGS="${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS}" ;; platform/android/libfreetype2) CONFIGURE_ARGS="${CONFIGURE_ARGS} --host=arm-linux" CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-sysroot=${CFG_ANDROID_CROSS_PATH}/sysroot" CONFIGURE_ARGS="${CONFIGURE_ARGS} --without-zlib" CONFIGURE_ARGS="${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS}" ;; platform/linux/fontconfig) CONFIGURE_SCRIPT="${CFG_SRC_DIR}src/${i}/autogen.sh" CONFIGURE_ARGS="${CONFIGURE_ARGS} --sysconfdir=/etc" CONFIGURE_ARGS="${CONFIGURE_ARGS} --localstatedir=/var" CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-docs" CONFIGURE_ARGS="${CONFIGURE_ARGS} --disable-shared" # work around Rust #12557 if [ -f /etc/redhat-release ]; then # Some RedHat-based distros (including our CentOS 6 build machines) are missing # pkg-config files for expat: https://bugzilla.redhat.com/show_bug.cgi?id=833338 CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-expat=/usr" fi CONFIGURE_ARGS="${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS}" ;; platform/android/fontconfig) CONFIGURE_SCRIPT="${CFG_SRC_DIR}src/${i}/autogen.sh" CONFIGURE_ARGS="${CONFIGURE_ARGS} --host=arm-linux-androideabi" CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-arch=arm" CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-expat-includes=${CFG_SRC_DIR}src/platform/android/libexpat/expat/lib" CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-expat-lib=${CFG_BUILD_DIR}src/platform/android/libexpat/.libs" CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-sysroot=${CFG_ANDROID_CROSS_PATH}/sysroot" CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-cache-dir=${CFG_ANDROID_RESOURCE_PATH}/.fccache" CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-confdir=${CFG_ANDROID_RESOURCE_PATH}/.fcconfig" CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-default-fonts=${CFG_ANDROID_FONT_PATH}" CONFIGURE_ARGS="${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS}" ;; support/spidermonkey/mozjs) # needed because Spidermonkey configure is in non-standard location CONFIGURE_SCRIPT="${CFG_SRC_DIR}src/${i}/js/src/configure" if [ ${CFG_OSTYPE} = "linux-androideabi" ]; then CONFIGURE_ARGS="${CONFIGURE_ARGS} --target=arm-linux-androideabi" CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-android-ndk=${CFG_ANDROID_NDK_PATH}" CONFIGURE_ARGS="${CONFIGURE_ARGS} --with-android-toolchain=${CFG_ANDROID_CROSS_PATH}" fi CONFIGURE_ARGS="${CONFIGURE_ARGS} --enable-gczeal" ;; support/skia/skia) # Right now the skia configure script actually ignores --enable-debug and the # build looks only at CFG_ENABLE_DEBUG_SKIA exported from our Makefile. But we # still refrain from passing --enable-debug if we didn't get --enable-debug-skia, # in order to be more future-proof. # # The same applies to rust-azure below. Also note that the two libraries won't # link if one is built with debugging and the other isn't. ENABLE_DEBUG="$CFG_ENABLE_DEBUG_SKIA" ;; support/azure/rust-azure) # needed because Azure's configure wants "--enable-skia" CONFIGURE_ARGS="${CONFIGURE_ARGS} --enable-skia" ENABLE_DEBUG="$CFG_ENABLE_DEBUG_SKIA" ;; *) ;; esac if [ -n "$ENABLE_DEBUG" ]; then CONFIGURE_ARGS="${CONFIGURE_ARGS} --enable-debug" fi if [ -f ${CONFIGURE_SCRIPT} ]; then (sh ${CONFIGURE_SCRIPT} ${CONFIGURE_ARGS}) || exit $? fi done step_msg "complete"