blob: 0426aab132db5c1e074fa8eb8a92aac8f95b7150 [file] [log] [blame]
#!/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/emulator_prebuilts.shi
shell_import utils/install_dir.shi
shell_import utils/option_parser.shi
shell_import utils/package_builder.shi
shell_import utils/package_list_parser.shi
package_builder_register_options qemu-android-deps
aosp_dir_register_option
prebuilts_dir_register_option
install_dir_register_option
DEFAULT_PREBUILTS_SUBDIR=prebuilts/android-emulator-build
DEFAULT_INSTALL_SUBDIR=qemu-android-deps
PROGRAM_PARAMETERS=""
PROGRAM_DESCRIPTION=\
"Build qemu-android dependency libraries if needed. This script probes
<prebuilts>/$DEFAULT_INSTALL_SUBDIR/ and will rebuild the libraries from sources
if they are not available.
The default value of <prebuilts> is: \$AOSP/$DEFAULT_PREBUILTS_SUBDIR
Use --prebuilts-dir=<path> or define ANDROID_EMULATOR_PREBUILTS_DIR in your
environment to change it.
Source tarball are probed under <prebuilts>/archive/. If not available,
the 'download-sources.sh' script will be invoked automatically.
Similarly, the script will try to auto-detect the AOSP source tree, to use
prebuilt SDK-compatible toolchains, but you can use --aosp-dir=<path> or
define ANDROID_EMULATOR_AOSP_DIR in your environment to override this.
By default, this script builds binaries for the following host sytems:
$DEFAULT_HOST_SYSTEMS
You can use --host=<list> to change this.
Final binaries are installed into <prebuilts>/$DEFAULT_INSTALL_SUBDIR/ by
default, but you can change this location with --install-dir=<dir>.
By default, everything is rebuilt in a temporary directory that is
automatically removed after script completion (and after the binaries are
copied into build-prefix/). You can use --build-dir=<path> to specify the
build directory instead. In this case, the directory will not be removed,
allowing one to inspect build failures easily."
option_parse "$@"
##
## Parameters checks
##
if [ "$PARAMETER_COUNT" != "0" ]; then
panic "This script doesn't take arguments, see --help for details."
fi
package_builder_process_options
aosp_dir_parse_option
prebuilts_dir_parse_option
install_dir_parse_option
package_builder_parse_package_list
export PKG_CONFIG=$(find_program pkg-config)
if [ "$PKG_CONFIG" ]; then
log "Found pkg-config at: $PKG_CONFIG"
else
log "pkg-config is not installed on this system."
fi
# Handle zlib, only on Win32 because the zlib configure script
# doesn't know how to generate a static library with -fPIC!
do_windows_zlib_package () {
local ZLIB_VERSION ZLIB_PACKAGE
local LOC LDFLAGS
local PREFIX=$(builder_install_prefix)
local BUILD_DIR=$(builder_build_dir)
case $(builder_host) in
windows-x86)
LOC=-m32
LDFLAGS=-m32
;;
windows-x86_64)
LOC=-m64
LDFLAGS=-m64
;;
esac
ZLIB_VERSION=$(package_list_get_version zlib)
dump "$(builder_text) Building zlib-$ZLIB_VERSION"
ZLIB_PACKAGE=$(package_list_get_filename zlib)
unpack_archive "$(builder_archive_dir)/$ZLIB_PACKAGE" "$BUILD_DIR"
(
run cd "$BUILD_DIR/zlib-$ZLIB_VERSION" &&
export BINARY_PATH=$PREFIX/bin &&
export INCLUDE_PATH=$PREFIX/include &&
export LIBRARY_PATH=$PREFIX/lib &&
run make -fwin32/Makefile.gcc install \
PREFIX=$(builder_gnu_config_host_prefix) \
LOC=$LOC \
LDFLAGS=$LDFLAGS
)
}
do_zlib_package () {
local ZLIB_VERSION ZLIB_PACKAGE
local LOC LDFLAGS
local BUILD_DIR=$(builder_build_dir)
case $(builder_host) in
*-x86)
LOC=-m32
LDFLAGS=-m32
;;
*-x86_64)
LOC=-m64
LDFLAGS=-m64
;;
esac
ZLIB_VERSION=$(package_list_get_version zlib)
dump "$(builder_text) Building zlib-$ZLIB_VERSION"
ZLIB_PACKAGE=$(package_list_get_filename zlib)
unpack_archive "$(builder_archive_dir)/$ZLIB_PACKAGE" "$BUILD_DIR"
(
run cd "$BUILD_DIR/zlib-$ZLIB_VERSION" &&
export CROSS_PREFIX=$(builder_gnu_config_host_prefix) &&
run ./configure --prefix=$(builder_install_prefix) &&
run make -j$NUM_JOBS &&
run make install
)
}
require_program () {
local VARNAME PROGNAME CMD
VARNAME=$1
PROGNAME=$2
CMD=$(find_program "$PROGNAME")
if [ -z "$CMD" ]; then
panic "Cannot find required build executable: $PROGNAME"
fi
eval $VARNAME=\'$CMD\'
}
# Unpack and patch GLib sources
# $1: Unversioned package name (e.g. 'glib')
unpack_and_patch () {
package_list_unpack_and_patch \
$1 "$(builder_archive_dir)" "$(builder_build_dir)"
}
# Cross-compiling glib for Win32 is broken and requires special care.
# The following was inspired by the glib.mk from MXE (http://mxe.cc/)
# $1: bitness (32 or 64)
do_windows_glib_package () {
local PREFIX=$(builder_install_prefix)
local GNU_CONFIG_HOST_PREFIX=$(builder_gnu_config_host_prefix)
package_list_unpack_and_patch \
glib "$(builder_archive_dir)" "$(builder_build_dir)"
local GLIB_VERSION GLIB_PACKAGE GLIB_DIR
GLIB_VERSION=$(package_list_get_version glib)
GLIB_DIR=$(builder_build_dir)/glib-$GLIB_VERSION
dump "$(builder_text) Building glib-$GLIB_VERSION"
require_program GLIB_GENMARSHAL glib-genmarshal
require_program GLIB_COMPILE_SCHEMAS glib-compile-schemas
require_program GLIB_COMPILE_RESOURCES glib-compile-resources
(
run cd "$GLIB_DIR" &&
export LDFLAGS="-L$PREFIX/lib -L$PREFIX/lib$1" &&
export CPPFLAGS="-I$PREFIX/include -I$GLIB_DIR -I$GLIB_DIR/glib" &&
export CC=${GNU_CONFIG_HOST_PREFIX}gcc &&
export CXX=${GNU_CONFIG_HOST_PREFIX}c++ &&
export PKG_CONFIG=$(find_program pkg-config) &&
export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig &&
run ./configure \
--prefix=$PREFIX \
$(builder_gnu_config_host_flag) \
--disable-shared \
--with-threads=win32 \
--with-pcre=internal \
--disable-debug \
--disable-man \
--with-libiconv=no \
GLIB_GENMARSHAL=$GLIB_GENMARSHAL \
GLIB_COMPILE_SCHEMAS=$GLIB_COMPILE_SCHEMAS \
GLIB_COMPILE_RESOURCES=$GLIB_COMPILE_RESOURCES &&
# Necessary to build gio stuff properly.
run ln -s "$GLIB_COMPILE_RESOURCES" gio/ &&
run make -j$NUM_JOBS -C glib install sbin_PROGRAMS= noinst_PROGRAMS= &&
run make -j$NUM_JOBS -C gmodule install bin_PROGRAMS= sbin_PROGRAMS= noinst_PROGRAMS= &&
run make -j$NUM_JOBS -C gthread install bin_PROGRAMS= sbin_PROGRAMS= noinst_PROGRAMS= &&
run make -j$NUM_JOBS -C gobject install bin_PROGRAMS= sbin_PROGRAMS= noinst_PROGRAMS= &&
run make -j$NUM_JOBS -C gio install bin_PROGRAMS= sbin_PROGRAMS= noinst_PROGRAMS= MISC_STUFF= &&
run make -j$NUM_JOBS install-pkgconfigDATA &&
run make -j$NUM_JOBS -C m4macros install &&
# Missing -lole32 results in link failure later!
sed -i -e 's|\-lglib-2.0|-lglib-2.0 -lole32|g' \
$PREFIX/lib/pkgconfig/glib-2.0.pc
)
}
# Generic routine used to unpack and rebuild a generic auto-tools package
# $1: package name, unversioned and unsuffixed (e.g. 'libpng')
# $2+: extra configuration flags
do_autotools_package () {
builder_unpack_package_source $1
builder_build_autotools_package "$@" --disable-shared --with-pic
}
do_dtc_package () {
local PKG=dtc
unpack_and_patch $PKG
PKG_VERSION=$(package_list_get_version $PKG)
PKG_NAME=$(package_list_get_filename $PKG)
dump "$(builder_text) Building libfdt from $PKG-$PKG_VERSION"
# NOTE: Cannot use the dtc Makefiles here, but since the library is
# really simple, just compile the source files straight into a
# library, then 'install' it manually !!
(
run cd "$(builder_build_dir)/$PKG-$PKG_VERSION" &&
CC=$(builder_gnu_config_host_prefix)gcc
AR=$(builder_gnu_config_host_prefix)ar
CCFLAGS=
LIBNAME=libfdt.a
var_append CCFLAGS "-Ilibfdt"
case $(builder_host) in
linux-*|darwin-*)
var_append CCFLAGS "-fPIC"
;;
esac
run $CC -c $CCFLAGS libfdt/*.c
run $AR crs $LIBNAME *.o
run mkdir -p "$PREFIX/include"
run cp libfdt/*.h "$PREFIX"/include/
run mkdir -p "$PREFIX/lib"
run cp $LIBNAME "$PREFIX/lib"
) || panic "Cannot rebuild libfdt"
}
# $1: host os name.
# $2: environment shell script.
build_qemu_android_deps () {
builder_prepare_for_host "$1" "$AOSP_DIR"
if [ -z "$OPT_FORCE" ]; then
if timestamp_check \
"$INSTALL_DIR/$(builder_host)" qemu-android-deps; then
log "$(builder_text) Already built."
return 0
fi
fi
local PREFIX=$(builder_install_prefix)
export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig
# Handle zlib for Windows
case $1 in
windows-*)
do_windows_zlib_package
;;
*)
do_zlib_package
;;
esac
# libfdt, from the dtc package, is needed.
do_dtc_package dtc
# libffi is required by glib.
do_autotools_package libffi
# Must define LIBFFI_CFLAGS and LIBFFI_LIBS to ensure
# that GLib picks it up properly. Note that libffi places
# its headers and libraries in uncommon places.
LIBFFI_VERSION=$(package_list_get_version libffi)
LIBFFI_CFLAGS="-I$PREFIX/lib/libffi-$LIBFFI_VERSION/include"
LIBFFI_LIBS="$PREFIX/lib/libffi.la"
if [ ! -f "$LIBFFI_LIBS" ]; then
LIBFFI_LIBS="$PREFIX/lib64/libffi.la"
fi
if [ ! -f "$LIBFFI_LIBS" ]; then
LIBFFI_LIBS="$PREFIX/lib32/libffi.la"
fi
if [ ! -f "$LIBFFI_LIBS" ]; then
panic "Cannot locate libffi libraries!"
fi
log "Using LIBFFI_CFLAGS=[$LIBFFI_CFLAGS]"
log "Using LIBFFI_LIBS=[$LIBFFI_LIBS]"
export LIBFFI_CFLAGS LIBFFI_LIBS
# libiconv and gettext are needed on Darwin only
case $1 in
darwin-*)
do_autotools_package libiconv
do_autotools_package gettext \
--disable-rpath \
--disable-acl \
--disable-curses \
--disable-openmp \
--disable-java \
--disable-native-java \
--without-emacs \
--disable-c++ \
--without-libexpat-prefix
;;
esac
# glib is required by pkg-config and qemu-android
case $1 in
windows-x86)
do_windows_glib_package 32
;;
windows-x86_64)
do_windows_glib_package 64
;;
*)
do_autotools_package glib \
--disable-always-build-tests \
--disable-debug \
--disable-fam \
--disable-included-printf \
--disable-installed-tests \
--disable-libelf \
--disable-man \
--disable-selinux \
--disable-xattr \
--disable-compile-warnings
;;
esac
# Export these to ensure that pkg-config picks them up properly.
export GLIB_CFLAGS="-I$PREFIX/include/glib-2.0 -I$PREFIX/lib/glib-2.0/include"
export GLIB_LIBS="$PREFIX/lib/libglib-2.0.la"
case $(get_build_os) in
darwin)
GLIB_LIBS="$GLIB_LIBS -Wl,-framework,Carbon -Wl,-framework,Foundation"
;;
esac
# pkg-config is required by qemu-android, and not available on
# Windows and OS X
do_autotools_package pkg-config \
--without-pc-path \
--disable-host-tool
# Handle libpng
do_autotools_package libpng
do_autotools_package pixman \
--disable-gtk \
--disable-libpng
# Handle SDL2
do_autotools_package SDL2
SDL_CONFIG=$PREFIX/bin/sdl2-config
# default sdl2.pc libs doesn't work with our cross-compiler,
# append missing libs
case $1 in
windows-*)
sed -i -e '/^Libs: -L\${libdir} /s/$/ -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc/' $PREFIX/lib/pkgconfig/sdl2.pc
;;
darwin-*)
sed -i "" -e '/^Libs: -L\${libdir} /s/$/ -lm -Wl,-framework,OpenGL -Wl,-framework,ForceFeedback -lobjc -Wl,-framework,Cocoa -Wl,-framework,Carbon -Wl,-framework,IOKit -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit/' $PREFIX/lib/pkgconfig/sdl2.pc
;;
linux-*)
sed -i -e '/^Libs: -L\${libdir} /s/$/ -Wl,--no-undefined -lm -ldl -lrt/' $PREFIX/lib/pkgconfig/sdl2.pc
;;
esac
PKG_CONFIG_LIBDIR=$PREFIX/lib/pkgconfig
case $1 in
windows-*)
# Use the host version, or the build will freeze.
PKG_CONFIG=pkg-config
;;
*)
PKG_CONFIG=$PREFIX/bin/pkg-config
;;
esac
export SDL_CONFIG PKG_CONFIG PKG_CONFIG_LIBDIR
# Create script to setup the environment correctly for the
# later qemu-android build.
ENV_SH=$(builder_build_dir)/env-qemu-prebuilts-$(builder_host).sh
cat > $ENV_SH <<EOF
# Auto-generated automatically - DO NOT EDIT
export PREFIX=$PREFIX
export LIBFFI_CFLAGS="$LIBFFI_CFLAGS"
export LIBFFI_LIBS="$LIBFFI_LIBS"
export GLIB_CFLAGS="$GLIB_CFLAGS"
export GLIB_LIBS="$GLIB_LIBS"
export SDL_CONFIG=$SDL_CONFIG
export PKG_CONFIG=$PKG_CONFIG
export PKG_CONFIG_LIBDIR=$PKG_CONFIG_LIBDIR
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH
export PATH=$PATH
EOF
dump "$(builder_text) Copying prebuilts to $INSTALL_DIR/$(builder_host)"
BINARY_DIR=$INSTALL_DIR/$(builder_host)
run mkdir -p "$BINARY_DIR" ||
panic "Could not create final directory: $BINARY_DIR"
local SUBDIR
for SUBDIR in include lib lib32 lib64 bin; do
if [ ! -d "$PREFIX/$SUBDIR" ]; then
continue
fi
run copy_directory "$PREFIX/$SUBDIR" "$BINARY_DIR/$SUBDIR"
done
unset PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR SDL_CONFIG
unset LIBFFI_CFLAGS LIBFFI_LIBS GLIB_CFLAGS GLIB_LIBS
timestamp_set "$INSTALL_DIR/$(builder_host)" qemu-android-deps
}
# Ignore prebuilt Darwin binaries if --force is not used.
if [ -z "$OPT_FORCE" ]; then
builder_check_all_timestamps "$INSTALL_DIR" qemu-android-deps
fi
if [ "$DARWIN_SSH" -a "$DARWIN_SYSTEMS" ]; then
# Perform remote Darwin build first.
dump "Remote qemu-android-deps build for: $DARWIN_SYSTEMS"
builder_prepare_remote_darwin_build \
"/tmp/$USER-rebuild-darwin-ssh-$$/qemu-android-deps-build"
if [ "$OPT_FORCE" ]; then
var_append DARWIN_BUILD_FLAGS "--force"
fi
builder_run_remote_darwin_build
for SYSTEM in $DARWIN_SYSTEMS; do
builder_remote_darwin_retrieve_install_dir $SYSTEM $INSTALL_DIR
timestamp_set "$INSTALL_DIR/$SYSTEM" qemu-android-deps
done
fi
for SYSTEM in $LOCAL_HOST_SYSTEMS; do
build_qemu_android_deps $SYSTEM
done
log "Done building qemu-android dependencies."