Home | History | Annotate | Download | only in tools
      1 #!/bin/sh
      2 #
      3 # Copyright (C) 2010 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 #
     17 
     18 . `dirname $0`/prebuilt-common.sh
     19 PROGDIR=`dirname $0`
     20 PROGNAME=`basename $0`
     21 
     22 # This sets HOST_TAG to linux-x86 or darwin-x86 on 64-bit systems
     23 force_32bit_binaries
     24 
     25 PLATFORM=
     26 register_option "--platform=<name>" do_platform "Specify API level [autodetect]"
     27 do_platform () { PLATFORM=$1; }
     28 
     29 ARCH=
     30 register_option "--arch=<name>" do_arch "Specify architecture name [autodetect]"
     31 do_arch () { ARCH=$1; }
     32 
     33 OUT_DIR=/tmp/ndk-$USER/platforms-import
     34 register_var_option "--out-dir=<path>" OUT_DIR "Specify output directory"
     35 
     36 TOOLCHAIN_PREFIX=
     37 
     38 PROGRAM_PARAMETERS="<build-path>"
     39 PROGRAM_DESCRIPTION=\
     40 "This script is used to import the NDK-exposed system libraries and headers from
     41 an existing platform build, and copy them to a temporary directory that will later
     42 be processed by another script (dev-platform-pack.sh) to archive them properly into
     43 the NDK directory structure (e.g. under development/ndk/platforms/).
     44 
     45 By default, the files will be copied to $OUT_DIR, but you can
     46 override this with the --out-dir=<path> option.
     47 
     48 The script also extracts the list of dynamic symbols exported by system libraries,
     49 filtering those that should not be exposed through the NDK. You can disable this
     50 with the --no-symbol-filtering option.
     51 
     52 The <build-path> parameter must point to the platform build output directory
     53 of a valid Android reference platform build. This is the value of the
     54 \$ANDROID_PRODUCT_OUT variable when doing a build configured with the 'lunch'
     55 utility. It usually looks like <top>/out/target/product/<name> where <top> is
     56 the top-level Android source tree, and <name> is the build product name
     57 (e.g. 'generic' or 'generic_x86' for emulator-specific builds).
     58 
     59 The API level is auto-detected from the content of <build-path>, but you
     60 can override it with --platform=<number>.
     61 
     62 This script is really in charge of the following tasks:
     63   
     64   1/ Detect the platform build's API level by parsing the build.prop
     65      file. This can overriden with --platform=<number>
     66 
     67   2/ Detect the platform build's target CPU architecture by parsing
     68      the build.prop file. This can be overriden with --arch=<name>
     69 
     70   3/ Copy system headers from \$ANDROID/framework/base/ and other
     71      locations into \$OUT_DIR/android-\$API/include or
     72      \$OUT_DIR/android-\$API/arch-\$ARCH/include
     73 
     74   4/ Locate system shared libraries from \$ANDROID_PRODUCT_OUT/system/lib
     75      and generate symbol files in \$OUT_DIR/android-\$API/arch-\$ARCH/symbols.
     76 
     77   5/ Copy a few system static libraries (libc.a, libm.a, etc...) used
     78      to generate static executables. As well as a few key object files
     79      required by the C runtime (e.g. crtbegin_dynamic.o), when needed.
     80 
     81 "
     82 
     83 
     84 extract_parameters "$@"
     85 
     86 if [ -z "$PARAMETERS" ] ; then
     87     if [ -z "$ANDROID_PRODUCT_OUT" ]; then
     88         dump "ERROR: Missing path parameter to platform build, see --help for details"
     89         exit 1
     90     fi
     91     # ANDROID_PRODUCT_OUT is defined, so use it
     92     log "Auto-config: using build path: $ANDROID_PRODUCT_OUT"
     93 else
     94     ANDROID_PRODUCT_OUT=$PARAMETERS
     95 fi
     96 
     97 # Sanity checks for the Android build path
     98 if [ ! -d "$ANDROID_PRODUCT_OUT" ]; then
     99     dump "ERROR: Not a directory: $ANDROID_PRODUCT_OUT"
    100     dump "Please point to a valid and complete Android build directory"
    101     exit 1
    102 fi
    103 
    104 BUILD_PROP=$ANDROID_PRODUCT_OUT/system/build.prop
    105 if [ ! -f "$BUILD_PROP" ]; then
    106     dump "ERROR: Missing file: $BUILD_PROP"
    107     dump "Please point to a valid and complete Android build directory"
    108     exit 1
    109 fi
    110 log "Extracting build properties from: $BUILD_PROP"
    111 
    112 # Try to get the architecture from build.prop if needed
    113 if [ -z "$ARCH" ]; then
    114     CPU_ABI=$(awk -F '=' '$1 == "ro.product.cpu.abi"  { print $2; }' $BUILD_PROP)
    115     if [ $? != 0 ]; then
    116         dump "ERROR: Could not extract CPU ABI from $BUILD_PROP"
    117         dump "Please use --arch=<name> to override this. See --help"
    118         exit 1
    119     fi
    120     log "Found target CPU ABI: $CPU_ABI"
    121     ARCH=$(convert_abi_to_arch $CPU_ABI)
    122     if [ -z "$ARCH" ]; then
    123         dump "ERROR: Can't translate $CPU_ABI ABI into CPU architecture!"
    124         exit 1
    125     fi
    126     log "Auto-config: --arch=$ARCH"
    127 fi
    128 
    129 # Try to get the API level from build.prop if needed
    130 if [ -z "$PLATFORM" ]; then
    131     PLATFORM=$(awk -F '=' '$1 == "ro.build.version.sdk" { print $2; }' $BUILD_PROP)
    132     if [ $? != 0 ] ; then
    133         dump "WARNING: Could not extract default platform level from $BUILD_PROP!"
    134         dump "Please use --platform=<name> to override this. See --help"
    135         exit 1
    136     fi
    137     if [ -z "$PLATFORM" ]; then
    138         dump "ERROR: Couldn't extract API level from: $BUILD_PROP"
    139         exit 1
    140     fi
    141     log "Auto-config: --platform=$PLATFORM"
    142 fi
    143 
    144 # Normalize platform name, i.e.
    145 #  3         -> 3
    146 #  android-3 -> 3
    147 #
    148 PLATFORM=${PLATFORM##android-}
    149 
    150 PLATFORM_ROOT=$OUT_DIR/android-$PLATFORM/arch-$ARCH
    151 log "Using platform destination path: $PLATFORM_ROOT"
    152 
    153 # Return the list of files under a given directory
    154 # $1: directory
    155 # $2: (optional) file patterns
    156 list_regular_files_in ()
    157 {
    158     local DIR="$1"
    159     shift
    160     local PATTERNS="$@"
    161     if [ -z "$PATTERNS" ]; then
    162         PATTERNS="."
    163     fi
    164     cd "$DIR" && find $PATTERNS -type f | sed -e 's!^./!!g'
    165 }
    166 
    167 # Check that a given platform level was listed on the command line
    168 # $1: Platform numerical level (e.g. '3')
    169 # returns true if the platform is listed
    170 platform_check ()
    171 {
    172     [ "$PLATFORM" -ge "$1" ]
    173 }
    174 
    175 # Determine Android build tree root
    176 ANDROID_ROOT=`cd $ANDROID_PRODUCT_OUT/../../../.. && pwd`
    177 log "Android build tree root: $ANDROID_ROOT"
    178 log "Android product out: $ANDROID_PRODUCT_OUT"
    179 
    180 if [ -z "$TOOLCHAIN_PREFIX" ]; then
    181     TOOLCHAIN_NAME=$(get_default_toolchain_name_for_arch $ARCH)
    182     TOOLCHAIN_PREFIX=$(get_default_toolchain_prefix_for_arch $ARCH)
    183     TOOLCHAIN_PREFIX=$(get_toolchain_install $ANDROID_NDK_ROOT $TOOLCHAIN_NAME)/bin/$TOOLCHAIN_PREFIX
    184     TOOLCHAIN_PREFIX=${TOOLCHAIN_PREFIX%%-}
    185     if [ -z "$TOOLCHAIN_PREFIX" ]; then
    186         echo "ERROR: Unsupported architecture"
    187         exit 1
    188     fi
    189     log "Auto-config: --toolchain-prefix=$TOOLCHAIN_PREFIX"
    190 fi
    191 
    192 if [ ! -d "$(dirname $TOOLCHAIN_PREFIX)" ]; then
    193     echo "ERROR: Toolchain not installed, missing directory: $(dirname $TOOLCHAIN_PREFIX)"
    194     exit 1
    195 fi
    196 
    197 if [ ! -f "$TOOLCHAIN_PREFIX-readelf" ]; then
    198     echo "ERROR: Toolchain not installed, missing program: $TOOLCHAIN_PREFIX-readelf"
    199     exit 1
    200 fi
    201 
    202 
    203 # 'Copy' a given system library. This really reads the shared library to
    204 # to generate a small shell version that will be installed at the destination
    205 # $1: Library name (e.g. libEGL.so)
    206 #
    207 copy_system_shared_library ()
    208 {
    209     local src="$ANDROID_PRODUCT_OUT/system/lib/$1.so"
    210     if [ ! -f "$src" ] ; then
    211         dump "ERROR: Missing system library: $src"
    212         exit 1
    213     fi
    214     local dst="$PLATFORM_ROOT/lib/$1.so"
    215     mkdir -p `dirname "$dst"` && cp "$src" "$dst"
    216 }
    217 
    218 copy_system_static_library ()
    219 {
    220     local src="$ANDROID_PRODUCT_OUT/obj/STATIC_LIBRARIES/$1_intermediates/$1.a"
    221     if [ ! -f "$src" ] ; then
    222         dump "ERROR: Missing system static library: $src"
    223         exit 1
    224     fi
    225     local dst="$PLATFORM_ROOT/lib/$1.a"
    226     log "Copying system static library: $1.a"
    227     mkdir -p `dirname "$dst"` && cp -f "$src" "$dst"
    228 }
    229 
    230 copy_system_object_file ()
    231 {
    232     local src="$ANDROID_PRODUCT_OUT/obj/lib/$1.o"
    233     if [ ! -f "$src" ] ; then
    234         dump "ERROR: Missing system object file: $src"
    235         exit 1
    236     fi
    237     local dst="$PLATFORM_ROOT/lib/$1.o"
    238     log "Copying system object file: $1.o"
    239     mkdir -p `dirname "$dst"` &&
    240     cp -f "$src" "$dst"
    241 }
    242 
    243 # Copy the content of a given directory to $SYSROOT/usr/include
    244 # $1: Source directory
    245 # $2+: List of headers
    246 copy_system_headers ()
    247 {
    248     local srcdir="$1"
    249     shift
    250     local header
    251     log "Copying system headers from: $srcdir"
    252     for header; do
    253         log "  $header"
    254         local src="$srcdir/$header"
    255         local dst="$PLATFORM_ROOT/../include/$header"
    256         if [ ! -f "$srcdir/$header" ] ; then
    257             dump "ERROR: Missing system header: $srcdir/$header"
    258             exit 1
    259         fi
    260         mkdir -p `dirname "$dst"` && cp -f "$src" "$dst"
    261         if [ $? != 0 ] ; then
    262             dump "ERROR: Could not copy system header: $src"
    263             dump "Target location: $dst"
    264             exit 1
    265         fi
    266     done
    267 }
    268 
    269 # Copy all headers found under $1
    270 # $1: source directory
    271 copy_system_headers_from ()
    272 {
    273     local headers=$(list_regular_files_in "$1")
    274     copy_system_headers $1 $headers
    275 }
    276 
    277 # Same as copy_system_headers, but for arch-specific files
    278 # $1: Source directory
    279 # $2+: List of headers
    280 copy_arch_system_headers ()
    281 {
    282     local srcdir="$1"
    283     shift
    284     local header
    285     for header; do
    286         log "Copying $arch system header: $header"
    287         local src="$srcdir/$header"
    288         local dst="$PLATFORM_ROOT/include/$header"
    289         if [ ! -f "$srcdir/$header" ] ; then
    290             dump "ERROR: Missing $ARCH system header: $srcdir/$header"
    291             exit 1
    292         fi
    293         mkdir -p `dirname "$dst"` && cp -f "$src" "$dst"
    294         if [ $? != 0 ] ; then
    295             dump "ERROR: Could not copy $ARCH system header: $src"
    296             dump "Target location: $dst"
    297             exit 1
    298         fi
    299     done
    300 }
    301 
    302 copy_arch_system_headers_from ()
    303 {
    304     local headers=$(list_regular_files_in "$1")
    305     copy_arch_system_headers $1 $headers
    306 }
    307 
    308 copy_arch_kernel_headers_from ()
    309 {
    310     local headers=$(list_regular_files_in "$1" asm)
    311     copy_arch_system_headers $1 $headers
    312 }
    313 
    314 # Probe for the location of the OpenSLES sources in the
    315 # platform tree. This used to be system/media/opensles but
    316 # was moved to system/media/wilhelm in Android 4.0
    317 OPENSLES_SUBDIR=system/media/wilhelm
    318 if [ ! -d "$ANDROID_ROOT/$OPENSLES_SUBDIR" ]; then
    319     OPENSLES_SUBDIR=system/media/opensles
    320 fi
    321 
    322 # Now do the work
    323 
    324 # API level 3
    325 if platform_check 3; then
    326     copy_system_shared_library libc
    327     copy_system_static_library libc
    328     copy_system_headers_from $ANDROID_ROOT/bionic/libc/include
    329     copy_arch_system_headers_from $ANDROID_ROOT/bionic/libc/arch-$ARCH/include
    330     copy_arch_kernel_headers_from $ANDROID_ROOT/bionic/libc/kernel/arch-$ARCH
    331 
    332     copy_system_object_file crtbegin_dynamic
    333     copy_system_object_file crtbegin_static
    334     copy_system_object_file crtend_android
    335     case $ARCH in
    336     x86)
    337         copy_system_object_file crtbegin_so
    338         copy_system_object_file crtend_so
    339         ;;
    340     esac
    341 
    342     copy_system_shared_library libm
    343     copy_system_static_library libm
    344     copy_system_headers $ANDROID_ROOT/bionic/libm/include math.h
    345     case "$ARCH" in
    346     x86 )
    347         copy_arch_system_headers $ANDROID_ROOT/bionic/libm/include/i387 fenv.h
    348         ;;
    349     * )
    350         copy_arch_system_headers $ANDROID_ROOT/bionic/libm/$ARCH fenv.h
    351         ;;
    352     esac
    353 
    354     # The <dlfcn.h> header was already copied from bionic/libc/include
    355     copy_system_shared_library libdl
    356     # There is no libdl.a at the moment, we might need one in
    357     # the future to build gdb-7.1.x though.
    358 
    359     copy_system_shared_library libz
    360     copy_system_static_library libz
    361     copy_system_headers $ANDROID_ROOT/external/zlib zconf.h zlib.h
    362 
    363     copy_system_shared_library liblog
    364     copy_system_headers $ANDROID_ROOT/system/core/include android/log.h
    365 
    366     # NOTE: We do not copy the C++ headers, they are part of the NDK
    367     #        under $NDK/source/cxx-stl. They were separated from the rest
    368     #        of the platform headers in order to make room for other STL
    369     #        implementations (e.g. STLport or GNU Libstdc++-v3)
    370     #
    371     copy_system_shared_library libstdc++
    372     copy_system_static_library libstdc++
    373 
    374     copy_system_headers $ANDROID_ROOT/libnativehelper/include/nativehelper jni.h
    375 fi
    376 
    377 # API level 4
    378 if platform_check 4; then
    379     copy_system_shared_library libGLESv1_CM
    380     copy_system_headers $ANDROID_ROOT/frameworks/base/opengl/include \
    381         GLES/gl.h \
    382         GLES/glext.h \
    383         GLES/glplatform.h
    384 
    385     copy_system_headers $ANDROID_ROOT/frameworks/base/opengl/include \
    386         KHR/khrplatform.h
    387 fi
    388 
    389 # API level 5
    390 if platform_check 5; then
    391     copy_system_shared_library libGLESv2
    392     copy_system_headers $ANDROID_ROOT/frameworks/base/opengl/include \
    393         GLES2/gl2.h \
    394         GLES2/gl2ext.h \
    395         GLES2/gl2platform.h
    396 fi
    397 
    398 # API level 8
    399 if platform_check 8; then
    400     copy_system_shared_library libandroid
    401     copy_system_shared_library libjnigraphics
    402     copy_system_headers $ANDROID_ROOT/frameworks/base/native/include \
    403         android/bitmap.h
    404 fi
    405 
    406 # API level 9
    407 if platform_check 9; then
    408     case $ARCH in
    409     arm)
    410         copy_system_object_file crtbegin_so
    411         copy_system_object_file crtend_so
    412         ;;
    413     esac
    414 
    415     copy_system_shared_library libandroid
    416     copy_system_headers $ANDROID_ROOT/frameworks/base/native/include \
    417         android/asset_manager.h \
    418         android/asset_manager_jni.h \
    419         android/configuration.h \
    420         android/input.h \
    421         android/keycodes.h \
    422         android/looper.h \
    423         android/native_activity.h \
    424         android/native_window.h \
    425         android/native_window_jni.h \
    426         android/obb.h \
    427         android/rect.h \
    428         android/sensor.h \
    429         android/storage_manager.h \
    430         android/window.h
    431 
    432     copy_system_shared_library libEGL
    433     copy_system_headers $ANDROID_ROOT/frameworks/base/opengl/include \
    434         EGL/egl.h \
    435         EGL/eglext.h \
    436         EGL/eglplatform.h
    437 
    438     copy_system_shared_library libOpenSLES
    439     copy_system_headers $ANDROID_ROOT/$OPENSLES_SUBDIR/include \
    440         SLES/OpenSLES.h \
    441         SLES/OpenSLES_Android.h \
    442         SLES/OpenSLES_AndroidConfiguration.h \
    443         SLES/OpenSLES_Platform.h
    444 fi
    445 
    446 # API level 14
    447 if platform_check 14; then
    448     copy_system_shared_library libOpenMAXAL
    449     copy_system_headers $ANDROID_ROOT/system/media/wilhelm/include \
    450 	OMXAL/OpenMAXAL.h \
    451         OMXAL/OpenMAXAL_Android.h \
    452         OMXAL/OpenMAXAL_Platform.h
    453 
    454     # This header is new in API level 14
    455     copy_system_headers $ANDROID_ROOT/$OPENSLES_SUBDIR/include \
    456         SLES/OpenSLES_AndroidMetadata.h
    457 fi
    458 
    459 # Now extract dynamic symbols from the copied shared libraries
    460 # Note that this script will also filter unwanted symbols
    461 log "Generating symbol files"
    462 $PROGDIR/gen-system-symbols.sh "$PLATFORM_ROOT/lib" "$PLATFORM_ROOT/symbols"
    463 
    464 # Remove copied shared libraries, we don't need them anymore
    465 # They will be replaced by auto-generated shells by gen-platforms.sh
    466 #
    467 log "Cleaning: $PLATFORM_ROOT/lib/lib*.so"
    468 rm -f "$PLATFORM_ROOT"/lib/lib*.so
    469 
    470 log "Done!"
    471