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 # build-platforms.sh 18 # 19 # This tool is used when packaging a new release, or when developing 20 # the NDK itself. It will populate DST ($NDK/platforms by default) 21 # with the content of SRC ($NDK/../development/ndk/platforms/ by default). 22 # 23 # The idea is that the content of $SRC/android-N/ only contains stuff 24 # that is relevant to API level N, and not contain anything that is already 25 # provided by API level N-1, N-2, etc.. 26 # 27 # More precisely, for each architecture A: 28 # $SRC/android-N/include --> $DST/android-N/arch-A/usr/include 29 # $SRC/android-N/arch-A/include --> $DST/android-N/arch-A/usr/include 30 # $SRC/android-N/arch-A/lib --> $DST/android-N/arch-A/usr/lib 31 # 32 # For backwards compatibility: 33 # $SRC/android-N/arch-A/usr/include --> $DST/android-N/arch-A/usr/include 34 # $SRC/android-N/arch-A/usr/lib --> $DST/android-N/arch-A/usr/lib 35 # 36 # Repeat after that for N+1, N+2, etc.. 37 # 38 39 . `dirname $0`/../core/ndk-common.sh 40 41 # Return the list of platform supported from $1/platforms 42 # as a single space-separated list of levels. (e.g. "3 4 5 8 9") 43 # $1: source directory 44 extract_platforms_from () 45 { 46 if [ -d "$1" ] ; then 47 (cd "$1/platforms" && ls -d android-*) | sed -e "s!android-!!" | tr '\n' ' ' 48 else 49 echo "" 50 fi 51 } 52 53 # Remove trailing path of a path 54 # $1: path 55 remove_trailing_slash () { 56 echo $1 | sed -e 's!/$!!g' 57 } 58 59 # Reverse a file path directory 60 # foo -> . 61 # foo/bar -> .. 62 # foo/bar/zoo -> ../.. 63 reverse_path () 64 { 65 local path cur item 66 path=`remove_trailing_slash $1` 67 cur="." 68 if [ "$path" != "." ] ; then 69 for item in `echo "$path" | tr '/' ' '`; do 70 cur="../$cur" 71 done 72 fi 73 echo `echo $cur | sed -e 's!/.$!!g'` 74 } 75 76 test_reverse_path () 77 { 78 rr=`reverse_path $1` 79 if [ "$rr" != "$2" ] ; then 80 echo "ERROR: reverse_path '$1' -> '$rr' (expected '$2')" 81 fi 82 } 83 84 test_reverse_path . . 85 test_reverse_path ./ . 86 test_reverse_path foo .. 87 test_reverse_path foo/ .. 88 test_reverse_path foo/bar ../.. 89 test_reverse_path foo/bar/ ../.. 90 test_reverse_path foo/bar/zoo ../../.. 91 test_reverse_path foo/bar/zoo/ ../../.. 92 93 SRCDIR="../development/ndk" 94 DSTDIR="$ANDROID_NDK_ROOT" 95 96 ABIS="arm" 97 PLATFORMS=`extract_platforms_from "$SRCDIR"` 98 99 OPTION_HELP=no 100 OPTION_PLATFORMS= 101 OPTION_SRCDIR= 102 OPTION_DSTDIR= 103 OPTION_NO_SAMPLES=no 104 OPTION_NO_SYMLINKS=no 105 106 VERBOSE=no 107 VERBOSE2=no 108 109 for opt do 110 optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'` 111 case "$opt" in 112 --help|-h|-\?) OPTION_HELP=yes 113 ;; 114 --verbose) 115 if [ "$VERBOSE" = "yes" ] ; then 116 VERBOSE2=yes 117 else 118 VERBOSE=yes 119 fi 120 ;; 121 --src-dir=*) 122 OPTION_SRCDIR="$optarg" 123 ;; 124 --dst-dir=*) 125 OPTION_DSTDIR="$optarg" 126 ;; 127 --platform=*) 128 OPTION_PLATFORM=$optarg 129 ;; 130 --abi=*) 131 OPTION_ABI=$optarg 132 ;; 133 --no-samples) 134 OPTION_NO_SAMPLES=yes 135 ;; 136 --no-symlinks) 137 OPTION_NO_SYMLINKS=yes 138 ;; 139 *) 140 echo "unknown option '$opt', use --help" 141 exit 1 142 esac 143 done 144 145 if [ $OPTION_HELP = "yes" ] ; then 146 echo "Collect files from an Android NDK development tree and assemble" 147 echo "the platform files appropriately into a final release structure." 148 echo "" 149 echo "options:" 150 echo "" 151 echo " --help Print this message" 152 echo " --verbose Enable verbose messages" 153 echo " --src-dir=<path> Source directory for development platform files [$SRCDIR]" 154 echo " --dst-dir=<path> Destination directory [$DSTDIR]" 155 echo " --platform=<list> Space-separated list of API levels [$PLATFORMS]" 156 echo " --abi=<list> Space-separated list of ABIs [$ABIS]" 157 echo " --no-samples Ignore samples" 158 echo " --no-symlinks Don't create symlinks, copy files instead" 159 echo "" 160 exit 0 161 fi 162 163 if [ -n "$OPTION_SRCDIR" ] ; then 164 SRCDIR="$OPTION_SRCDIR"; 165 if [ ! -d "$SRCDIR" ] ; then 166 echo "ERROR: Source directory $SRCDIR does not exist !" 167 exit 1 168 fi 169 if [ ! -d "$SRCDIR/platforms/android-3" ] ; then 170 echo "ERROR: Invalid source directory: $SRCDIR" 171 echo "Please make sure it contains platforms/android-3 etc..." 172 exit 1 173 fi 174 else 175 SRCDIR=`dirname $ANDROID_NDK_ROOT`/development/ndk 176 log "Using source directory: $SRCDIR" 177 fi 178 179 if [ -n "$OPTION_PLATFORM" ] ; then 180 PLATFORMS="$OPTION_PLATFORM" 181 else 182 # Build the list from the content of SRCDIR 183 PLATFORMS=`extract_platforms_from "$SRCDIR"` 184 log "Using platforms: $PLATFORMS" 185 fi 186 187 188 if [ -n "$OPTION_DSTDIR" ] ; then 189 DSTDIR="$OPTION_DSTDIR" 190 else 191 log "Using destination directory: $DSTDIR" 192 fi 193 194 if [ -n "$OPTION_ABI" ] ; then 195 ABIS="$OPTION_ABI" 196 fi 197 198 log "Checking source platforms." 199 for PLATFORM in $PLATFORMS; do 200 DIR="$SRCDIR/platforms/android-$PLATFORM" 201 if [ ! -d $DIR ] ; then 202 echo "ERROR: Directory missing: $DIR" 203 echo "Please check your --platform=<list> option and try again." 204 exit 2 205 else 206 log " $DIR" 207 fi 208 done 209 210 log "Checking source platform ABIs." 211 BAD_ABIS= 212 for ABI in $ABIS; do 213 eval CHECK_$ABI=no 214 done 215 for PLATFORM in $PLATFORMS; do 216 for ABI in $ABIS; do 217 DIR="$SRCDIR/platforms/android-$PLATFORM/arch-$ABI" 218 if [ -d $DIR ] ; then 219 log " $DIR" 220 eval CHECK_$ABI=yes 221 fi 222 done 223 done 224 225 BAD_ABIS= 226 for ABI in $ABIS; do 227 CHECK=`var_value CHECK_$ABI` 228 log " $ABI check: $CHECK" 229 if [ "$CHECK" = no ] ; then 230 if [ -z "$BAD_ABIS" ] ; then 231 BAD_ABIS=$ABI 232 else 233 BAD_ABIS="$BAD_ABIS $ABI" 234 fi 235 fi 236 done 237 238 if [ -n "$BAD_ABIS" ] ; then 239 echo "ERROR: Source directory doesn't support these ABIs: $BAD_ABIS" 240 exit 3 241 fi 242 243 # $1: source directory (relative to $SRCDIR) 244 # $2: destination directory (relative to $DSTDIR) 245 # $3: description of directory contents (e.g. "sysroot" or "samples") 246 copy_directory () 247 { 248 local SDIR="$SRCDIR/$1" 249 local DDIR="$DSTDIR/$2" 250 if [ -d "$SDIR" ] ; then 251 log "Copying $3 from \$SRC/$1 to \$DST/$2." 252 mkdir -p "$DDIR" && cp -rf "$SDIR"/* "$DDIR" 253 if [ $? != 0 ] ; then 254 echo "ERROR: Could not copy $3 directory $SDIR into $DDIR !" 255 exit 5 256 fi 257 fi 258 } 259 260 # Create a symlink-copy of directory $1 into $2 261 # This function is recursive. 262 # 263 # $1: source directory (relative to $SRCDIR) 264 # $2: destination directory (relative to $DSTDIR) 265 symlink_directory () 266 { 267 mkdir -p "$DSTDIR/$2" 268 local files=`cd $DSTDIR/$1 && ls -1p | grep -v -e '.*/'` 269 local subdirs=`cd $DSTDIR/$1 && ls -1p | grep -e '.*/' | sed -e 's!/$!!g'` 270 local file subdir rev 271 rev=`reverse_path $1` 272 for file in $files; do 273 ln -s $rev/$1/$file $DSTDIR/$2/$file 274 done 275 for subdir in $subdirs; do 276 symlink_directory $1/$subdir $2/$subdir 277 done 278 } 279 280 # Overwrite the content of a symlink-copy with new content. 281 # This takes care of removing the symlinks before copying the new content 282 # 283 # $1: source directory (relative to $SRCDIR) 284 # $2: destination directory (relative to $DSTDIR) 285 overcopy_directory () 286 { 287 if [ ! -d "$SRCDIR/$1" ] ; then 288 return 289 fi 290 local files=`cd $SRCDIR/$1 && ls -1p | grep -v -e '.*/'` 291 local subdirs=`cd $SRCDIR/$1 && ls -1p | grep -e '.*/' | sed -e 's!/$!!g'` 292 local file subdir 293 mkdir -p $DSTDIR/$2 294 for file in $files; do 295 # remove symlink, if already there 296 rm -f $DSTDIR/$2/$file 297 cp -f $SRCDIR/$1/$file $DSTDIR/$2/$file 298 #log2 "copy: $SRCDIR/$1/$file --> $DSTDIR/$2/$file" 299 done 300 for subdir in $subdirs; do 301 overcopy_directory $1/$subdir $2/$subdir 302 done 303 } 304 305 # Copy platform sysroot and samples into your destination 306 # 307 308 # $SRC/android-$PLATFORM/include --> $DST/platforms/android-$PLATFORM/arch-$ABI/usr/include 309 # $SRC/android-$PLATFORM/arch-$ABI/include --> $DST/platforms/android-$PLATFORM/arch-$ABI/usr/include 310 # for compatibility: 311 # $SRC/android-$PLATFORM/arch-$ABI/usr/include --> $DST/platforms/android-$PLATFORM/arch-$ABI/usr/include 312 313 314 315 # $SRC/android-$PLATFORM/arch-$ABI/usr --> $DST/platforms/android-$PLATFORM/arch-$ABI/usr 316 # $SRC/android-$PLATFORM/samples --> $DST/samples 317 # 318 rm -rf $DSTDIR/platforms && mkdir -p $DSTDIR/platforms 319 PREV_PLATFORM_DST= 320 for PLATFORM in $PLATFORMS; do 321 NEW_PLATFORM=platforms/android-$PLATFORM 322 PLATFORM_SRC=$NEW_PLATFORM 323 PLATFORM_DST=$NEW_PLATFORM 324 if [ -n "$PREV_PLATFORM_DST" ] ; then 325 if [ "$OPTION_NO_SYMLINKS" = "yes" ] ; then 326 log "Copying \$DST/$PREV_PLATFORM_DST to \$DST/$PLATFORM_DST" 327 cp -r $DSTDIR/$PREV_PLATFORM_DST $DSTDIR/$PLATFORM_DST 328 else 329 log "Symlink-copying \$DST/$PREV_PLATFORM_DST to \$DST/$PLATFORM_DST" 330 symlink_directory $PREV_PLATFORM_DST $PLATFORM_DST 331 fi 332 if [ $? != 0 ] ; then 333 echo "ERROR: Could not copy previous sysroot to $DSTDIR/$NEW_PLATFORM" 334 exit 4 335 fi 336 fi 337 for ABI in $ABIS; do 338 SYSROOT=arch-$ABI/usr 339 overcopy_directory $PLATFORM_SRC/include $PLATFORM_DST/$SYSROOT/include "sysroot headers" 340 overcopy_directory $PLATFORM_SRC/arch-$ABI/include $PLATFORM_DST/$SYSROOT/include "sysroot headers" 341 overcopy_directory $PLATFORM_SRC/arch-$ABI/lib $PLATFORM_DST/$SYSROOT/lib "sysroot libs" 342 overcopy_directory $PLATFORM_SRC/$SYSROOT $PLATFORM_DST/$SYSROOT "sysroot" 343 done 344 PREV_PLATFORM_DST=$PLATFORM_DST 345 done 346 347 if [ "$OPTION_NO_SAMPLES" = no ] ; then 348 # Copy platform samples and generic samples into your destination 349 # 350 # $SRC/samples/ --> $DST/samples/ 351 # $SRC/android-$PLATFORM/samples/ --> $DST/samples 352 # 353 rm -rf $DSTDIR/samples && mkdir -p $DSTDIR/samples 354 copy_directory samples samples samples 355 356 for PLATFORM in $PLATFORMS; do 357 # $SRC/platform-$PLATFORM/samples --> $DST/samples 358 copy_directory platforms/android-$PLATFORM/samples samples samples 359 done 360 361 # Cleanup generated files in samples 362 rm -rf "$DSTDIR/samples/*/obj" 363 rm -rf "$DSTDIR/samples/*/libs" 364 fi 365 366 log "Done !" 367