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