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#  This shell script is a wrapper to launch the NDK build from the
18#  command-line inside an application project path.
19#
20#  Typical usage is:
21#
22#     cd $PROJECT_PATH
23#     ndk-build
24#
25#  Assuming that the Android NDK root path is in your PATH. However,
26#  you can also invoke it directly as:
27#
28#     $NDK_ROOT/ndk-build
29#
30#  This really is a tiny wrapper around GNU Make.
31#
32
33# Ensure we get the full path of this script's directory
34# this is needed if the caller uses the -C <path> GNU Make
35# option, as in:
36#
37#    cd ndk
38#    ./ndk-build -C <project-path>
39#
40PROGDIR=`dirname $0`
41PROGDIR=`cd $PROGDIR && pwd`
42
43# Check if absolute NDK path contain space
44#
45case $PROGDIR in
46    *\ *) echo "ERROR: NDK path cannot contain space"
47          exit 1
48        ;;
49esac
50
51# If NDK_LOG is set to 1 or true in the environment, or the command-line
52# then enable log messages below
53if [ -z "$NDK_LOG" ]; then
54  NDK_LOG=0
55fi
56
57for opt; do
58    case $opt in
59      NDK_LOG=1|NDK_LOG=true)
60        NDK_LOG=1
61        ;;
62      NDK_LOG=*)
63        NDK_LOG=0
64        ;;
65    esac
66done
67
68if [ "$NDK_LOG" = "true" ]; then
69  NDK_LOG=1
70fi
71if [ "$NDK_LOG" = 1 ]; then
72  log () {
73    echo "$@"
74  }
75else
76  log () {
77    : # nothing
78  }
79fi
80
81# Detect host operating system and architecture
82# The 64-bit / 32-bit distinction gets tricky on Linux and Darwin because
83# uname -m returns the kernel's bit size, and it's possible to run with
84# a 64-bit kernel and a 32-bit userland.
85#
86HOST_OS=$(uname -s)
87case $HOST_OS in
88  Darwin) HOST_OS=darwin;;
89  Linux) HOST_OS=linux;;
90  FreeBsd) HOST_OS=freebsd;;
91  CYGWIN*|*_NT-*) HOST_OS=cygwin;;
92  *) echo "ERROR: Unknown host operating system: $HOST_OS"
93     exit 1
94esac
95log "HOST_OS=$HOST_OS"
96
97HOST_ARCH=$(uname -m)
98case $HOST_ARCH in
99    i?86) HOST_ARCH=x86;;
100    x86_64|amd64) HOST_ARCH=x86_64;;
101    *) echo "ERROR: Unknown host CPU architecture: $HOST_ARCH"
102       exit 1
103esac
104log "HOST_ARCH=$HOST_ARCH"
105
106# Detect 32-bit userland on 64-bit kernels
107HOST_TAG="$HOST_OS-$HOST_ARCH"
108case $HOST_TAG in
109  linux-x86_64|darwin-x86_64)
110    # we look for x86_64 or x86-64 in the output of 'file' for our shell
111    # the -L flag is used to dereference symlinks, just in case.
112    file -L "$SHELL" | grep -q "x86[_-]64"
113    if [ $? != 0 ]; then
114      HOST_ARCH=x86
115      HOST_TAG=$HOST_OS-x86
116      log "HOST_ARCH=$HOST_ARCH (32-bit userland detected)"
117    fi
118    ;;
119  windows-x86) # Special case windows-x86 -> windows
120    HOST_TAG=windows
121esac
122
123# Check that we have 64-bit binaries on 64-bit system, otherwise fallback
124# on 32-bit ones. This gives us more freedom in packaging the NDK.
125if [ $HOST_ARCH = x86_64 -a ! -d $PROGDIR/prebuilt/$HOST_TAG ]; then
126  HOST_TAG=$HOST_OS-x86
127  if [ $HOST_TAG = windows-x86 ]; then
128    HOST_TAG=windows
129  fi
130  log "HOST_TAG=$HOST_TAG (no 64-bit prebuilt binaries detected)"
131else
132  log "HOST_TAG=$HOST_TAG"
133fi
134
135# If GNUMAKE is defined, check that it points to a valid file
136if [ -n "$GNUMAKE" ] ; then
137    ABS_GNUMAKE=`which $GNUMAKE 2> /dev/null`
138    if [ $? != 0 ] ; then
139        echo "ERROR: Your GNUMAKE variable is defined to an invalid name: $GNUMAKE"
140        echo "Please fix it to point to a valid make executable (e.g. /usr/bin/make)"
141        exit 1
142    fi
143    GNUMAKE="$ABS_GNUMAKE"
144    log "GNUMAKE=$GNUMAKE (from environment variable)"
145else
146    # Otherwise use the prebuilt version for our host tag, if it exists
147    # Note: we intentionally do not provide prebuilt make binaries for Cygwin
148    # or MSys.
149    GNUMAKE=$PROGDIR/prebuilt/$HOST_TAG/bin/make
150    if [ ! -f "$GNUMAKE" ]; then
151        # Otherwise, use 'make' and check that it is available
152        GNUMAKE=`which make 2> /dev/null`
153        if [ $? != 0 ] ; then
154            echo "ERROR: Cannot find 'make' program. Please install Cygwin make package"
155            echo "or define the GNUMAKE variable to point to it."
156            exit 1
157        fi
158        log "GNUMAKE=$GNUMAKE (system path)"
159    else
160        log "GNUMAKE=$GNUMAKE (NDK prebuilt)"
161    fi
162fi
163
164# On Windows, when running under cygwin, check that we are
165# invoking a cygwin-compatible GNU Make binary. It is unfortunately
166# common for app developers to have another non cygwin-compatible
167# 'make' program in their PATH.
168#
169if [ "$OSTYPE" = "cygwin" ] ; then
170    GNUMAKE=`cygpath -u $GNUMAKE`
171    PROGDIR_MIXED=`cygpath -m $PROGDIR`
172    CYGWIN_GNUMAKE=`$GNUMAKE -f "$PROGDIR_MIXED/build/core/check-cygwin-make.mk" 2>&1`
173    if [ $? != 0 ] ; then
174        echo "ERROR: You are using a non-Cygwin compatible Make program."
175        echo "Currently using: `cygpath -m $GNUMAKE`"
176        echo ""
177        echo "To solve the issue, follow these steps:"
178        echo ""
179        echo "1. Ensure that the Cygwin 'make' package is installed."
180        echo "   NOTE: You will need GNU Make 3.81 or later!"
181        echo ""
182        echo "2. Define the GNUMAKE environment variable to point to it, as in:"
183        echo ""
184        echo "     export GNUMAKE=/usr/bin/make"
185        echo ""
186        echo "3. Call 'ndk-build' again."
187        echo ""
188        exit 1
189    fi
190    log "Cygwin-compatible GNU make detected"
191fi
192
193$GNUMAKE -f $PROGDIR/build/core/build-local.mk "$@"
194