#!/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_SRC_DIR}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 } 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" CFG_OSTYPE=$(uname -s) CFG_CPUTYPE=$(uname -m) if [ $CFG_OSTYPE = Darwin -a $CFG_CPUTYPE = i386 ] then # Darwin's `uname -s` lies and always returns i386. We have to use sysctl # instead. if sysctl hw.optional.x86_64 | grep -q ': 1' then CFG_CPUTYPE=x86_64 fi fi # 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. case $CFG_OSTYPE in Linux) CFG_OSTYPE=unknown-linux-gnu ;; FreeBSD) CFG_OSTYPE=unknown-freebsd ;; Darwin) CFG_OSTYPE=apple-darwin ;; MINGW32*) CFG_OSTYPE=pc-mingw32 ;; *) err "unknown OS type: $CFG_OSTYPE" ;; esac case $CFG_CPUTYPE in i386 | i486 | i686 | i786 | x86) CFG_CPUTYPE=i686 ;; xscale | arm) CFG_CPUTYPE=arm ;; x86_64 | x86-64 | x64 | amd64) CFG_CPUTYPE=x86_64 ;; *) err "unknown CPU type: $CFG_CPUTYPE" esac DEFAULT_HOST_TRIPLE="${CFG_CPUTYPE}-${CFG_OSTYPE}" CFG_SRC_DIR="$(cd $(dirname $0) && pwd)/" CFG_BUILD_DIR="$(pwd)/" CFG_SELF=${CFG_SRC_DIR}$(basename $0) CFG_CONFIGURE_ARGS="$@" 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_SRC_DIR}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" valopt local-rust-root "/usr/local" "set prefix for local rust binary" if [ $HELP -eq 1 ] then echo "" exit 0 fi step_msg "looking for build programs" probe_need CFG_GIT git probe CFG_CLANG clang++ probe CFG_GCC gcc probe CFG_LD ld # Spidermonkey requires autoconf 2.13 exactly probe_need CFG_AUTOCONF213 autoconf213 \ autoconf2.13 \ autoconf-2.13 if [ ! -z "$CFG_LOCAL_RUST_ROOT" ] then if [ ! -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc ] then msg "using in-tree rust compiler" # The Rust compiler we're going to build CFG_RUSTC="${CFG_BUILD_DIR}src/rust/${DEFAULT_HOST_TRIPLE}/stage2/bin/rustc" else 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 fi else probe_need CFG_RUSTC rustc fi if [ ! -z "$CFG_ENABLE_CLANG" ] then if [ -z "$CFG_CLANG" ] then err "clang requested but not found" fi CFG_CLANG_VERSION=$("$CFG_CLANG" \ --version \ | grep version \ | sed 's/.*\(version .*\)/\1/' \ | cut -d ' ' -f 2) case $CFG_CLANG_VERSION in (3.0svn | 3.0 | 3.1 | 4.0) step_msg "found ok version of CLANG: $CFG_CLANG_VERSION" CFG_C_COMPILER="clang" ;; (*) err "bad CLANG version: $CFG_CLANG_VERSION, need >=3.0svn" ;; esac else CFG_C_COMPILER="gcc" fi if [ -z "$CFG_ENABLE_CLANG" -a -z "$CFG_GCC" ] 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 --quiet update --init --recursive need_ok "git failed" msg "git: submodule clobber" "${CFG_GIT}" submodule --quiet foreach --recursive git clean -dxf need_ok "git failed" "${CFG_GIT}" submodule --quiet foreach --recursive git checkout . need_ok "git failed" cd ${CFG_BUILD_DIR} fi step_msg "running submodule autoconf scripts" # Run the SpiderMonkey autoconf using autoconf 2.13 (cd ${CFG_SRC_DIR}src/mozjs/js/src && "${CFG_AUTOCONF213}") || exit $? # Pixman and cairo require some care to autoconf correctly for our in-tree build. # The normal autogen.sh files mostly just run autoreconfig but we need more fine control if [ $CFG_OSTYPE = "apple-darwin" ] then # pkg-config is installed in a different place on mac (via homebrew? not sure) # and the way to set this seems to be calling aclocal by hand (instead of via autoreconf) if [ -d "/usr/local/share/aclocal" ] then OSX_PKG_CONFIG_M4_MACROS="-I/usr/local/share/aclocal" fi if [ -d "/usr/share/aclocal" ] then OSX_PKG_CONFIG_M4_MACROS="-I/usr/share/aclocal" fi LIBTOOLIZE=glibtoolize else OSX_PKG_CONFIG_M4_MACROS="" LIBTOOLIZE=libtoolize fi PIXMAN_ACLOCALCMD="aclocal ${OSX_PKG_CONFIG_M4_MACROS}" CAIRO_ACLOCALCMD="aclocal ${OSX_PKG_CONFIG_M4_MACROS} -Ibuild" AUTOCMD="${LIBTOOLIZE} && autoconf && autoheader && automake --add-missing --copy --force" # Copied from cairo's autogen.sh. Build fails without CAIRO_BOILERPLATE="touch boilerplate/Makefile.am.features && touch src/Makefile.am.features" PIXMAN_AUTOCMD="${PIXMAN_ACLOCALCMD} && ${AUTOCMD}" CAIRO_AUTOCMD="${CAIRO_BOILERPLATE} && ${CAIRO_ACLOCALCMD} && ${AUTOCMD}" (cd ${CFG_SRC_DIR}src/pixman && eval ${PIXMAN_AUTOCMD}) || exit $? (cd ${CFG_SRC_DIR}src/cairo && eval ${CAIRO_AUTOCMD}) || exit $? CFG_SUBMODULES="libwapcaplet rust-wapcaplet rust-harfbuzz rust-opengles skia rust-azure rust-cairo rust-stb-image rust-geom rust-glut rust-layers rust-http-client libparserutils libhubbub libcss rust-netsurfcss rust-css rust-hubbub sharegl rust-mozjs mozjs pixman cairo" if [ $CFG_OSTYPE = "apple-darwin" ] then CFG_SUBMODULES="rust-cocoa rust-io-surface rust-core-foundation rust-core-graphics rust-core-text ${CFG_SUBMODULES}" fi if [ $CFG_OSTYPE = "unknown-linux-gnu" ] then CFG_SUBMODULES="rust-freetype rust-fontconfig rust-xlib ${CFG_SUBMODULES}" fi 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/servo-gfx make_dir src/test/ref make_dir src/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/rust/index" index2="${CFG_SRC_DIR}src/rust/.git/index" for index in ${index1} ${index2} do config_stamp="${CFG_BUILD_DIR}src/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/rust ${CFG_SRC_DIR}src/rust/configure cd ${CFG_BUILD_DIR} fi # Cairo expects to use an installed pixman, but we want to override that # behavior to use our version export pixman_CFLAGS="-I${CFG_SRC_DIR}src/pixman/pixman -I${CFG_BUILD_DIR}src/pixman/pixman" export pixman_LDFLAGS="-I${CFG_BUILD_DIR}src/pixman/pixman/.libs" # PIC all the things export CFLAGS="${CFLAGS} -fPIC" export LDFLAGS="${CFLAGS} -fPIC" 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" # needed because Spidermonkey configure is in non-standard location if [ $i = mozjs ]; then CONFIGURE_SCRIPT="${CFG_SRC_DIR}src/${i}/js/src/configure" fi # needed because Azure's configure wants "--enable-cairo --enable-skia" CONFIGURE_ARGS="" ENV_VARS="" if [ $i = "rust-azure" ]; then CONFIGURE_ARGS="--enable-cairo --enable-skia" fi # libpng isn't available by default on OS X so don't make it required for cairo # png is in turn required for the svg backend if [ $i = "cairo" -a ${CFG_OSTYPE} = "apple-darwin" ]; then CONFIGURE_ARGS="--enable-png=no --enable-svg=no --enable-ft=no --enable-xlib=no" fi # Tell pkg-config that the pixman library is in-tree if [ $i = "cairo" ]; then export PKG_CONFIG_PATH=../pixman else export PKG_CONFIG_PATH= fi if [ -f ${CONFIGURE_SCRIPT} ] then (sh ${CONFIGURE_SCRIPT} ${CONFIGURE_ARGS}) || exit $? fi done step_msg "writing configuration" putvar DEFAULT_HOST_TRIPLE putvar CFG_CPUTYPE putvar CFG_OSTYPE putvar CFG_SRC_DIR putvar CFG_BUILD_DIR putvar CFG_CONFIGURE_ARGS putvar CFG_C_COMPILER putvar CFG_SUBMODULES putvar CFG_DISABLE_MANAGE_SUBMODULES putvar CFG_RUSTC msg copy_if_changed ${CFG_SRC_DIR}Makefile.in ${CFG_BUILD_DIR}Makefile move_if_changed ${CFG_SRC_DIR}config.tmp ${CFG_SRC_DIR}config.mk copy_if_changed ${CFG_SRC_DIR}config.mk ${CFG_BUILD_DIR}config.mk rm -f ${CFG_SRC_DIR}config.tmp touch ${CFG_SRC_DIR}config.stamp step_msg "complete"