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 # 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