1# Copyright (C) 2010 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14#
15
16# This file is designed to be called from the 'ndk-build' script
17# or similar wrapper tool.
18#
19
20# Detect the NDK installation path by processing this Makefile's location.
21# This assumes we are located under $NDK_ROOT/build/core/main.mk
22#
23
24# Don't output to stdout if we're being invoked to dump a variable
25DUMP_VAR := $(patsubst DUMP_%,%,$(filter DUMP_%,$(MAKECMDGOALS)))
26ifneq (,$(DUMP_VAR))
27    NDK_NO_INFO := 1
28    NDK_NO_WARNINGS := 1
29endif
30
31NDK_ROOT := $(dir $(lastword $(MAKEFILE_LIST)))
32NDK_ROOT := $(subst \,/,$(NDK_ROOT))
33NDK_ROOT := $(strip $(NDK_ROOT:%build/core/=%))
34NDK_ROOT := $(NDK_ROOT:%/=%)
35ifeq ($(NDK_ROOT),)
36    # for the case when we're invoked from the NDK install path
37    NDK_ROOT := .
38endif
39ifeq ($(NDK_LOG),1)
40    $(info Android NDK: NDK installation path auto-detected: '$(NDK_ROOT)')
41endif
42ifneq ($(words $(NDK_ROOT)),1)
43    $(info Android NDK: Your NDK installation path contains spaces.)
44    $(info Android NDK: Please re-install to a different location to fix the issue !)
45    $(error Aborting.)
46endif
47
48include $(NDK_ROOT)/build/core/init.mk
49
50# ====================================================================
51#
52# If NDK_PROJECT_PATH is not defined, find the application's project
53# path by looking at the manifest file in the current directory or
54# any of its parents. If none is found, try again with 'jni/Android.mk'
55#
56# Note that we first look at the current directory to avoid using
57# absolute NDK_PROJECT_PATH values. This reduces the length of all
58# source, object and binary paths that are passed to build commands.
59#
60# It turns out that some people use ndk-build to generate static
61# libraries without a full Android project tree.
62#
63# If NDK_PROJECT_PATH=null, ndk-build make no attempt to look for it, but does
64# need the following variables depending on NDK_PROJECT_PATH to be explicitly
65# specified (from the default, if any):
66#
67#   NDK_OUT
68#   NDK_LIBS_OUT
69#   APP_BUILD_SCRIPT
70#   NDK_DEBUG (optional, default to 0)
71#   Other APP_* used to be in Application.mk
72#
73# This behavior may be useful in an integrated build system.
74#
75# ====================================================================
76
77find-project-dir = $(strip $(call find-project-dir-inner,$(abspath $1),$2))
78
79find-project-dir-inner = \
80    $(eval __found_project_path := )\
81    $(eval __find_project_path := $1)\
82    $(eval __find_project_file := $2)\
83    $(call find-project-dir-inner-2)\
84    $(__found_project_path)
85
86find-project-dir-inner-2 = \
87    $(call ndk_log,Looking for $(__find_project_file) in $(__find_project_path))\
88    $(eval __find_project_manifest := $(strip $(wildcard $(__find_project_path)/$(__find_project_file))))\
89    $(if $(__find_project_manifest),\
90        $(call ndk_log,    Found it !)\
91        $(eval __found_project_path := $(__find_project_path))\
92        ,\
93        $(eval __find_project_parent := $(call parent-dir,$(__find_project_path)))\
94        $(if $(__find_project_parent),\
95            $(eval __find_project_path := $(__find_project_parent))\
96            $(call find-project-dir-inner-2)\
97        )\
98    )
99
100NDK_PROJECT_PATH := $(strip $(NDK_PROJECT_PATH))
101APP_PROJECT_PATH := $(strip $(APP_PROJECT_PATH))
102
103ifneq (,$(APP_PROJECT_PATH))
104    ifeq (,$(NDK_PROJECT_PATH))
105        # If NDK_PROJECT_PATH isn't set and APP_PROJECT_PATH is present, use APP_PROJECT_PATH
106        $(call ndk_log,Use APP_PROJECT_PATH for NDK_PROJECT_PATH: $(APP_PROJECT_PATH))
107        NDK_PROJECT_PATH := $(APP_PROJECT_PATH)
108    else
109        # If both NDK_PROJECT_PATH and APP_PROJECT_PATH are present, check consistency
110        ifneq ($(NDK_PROJECT_PATH),$(APP_PROJECT_PATH))
111            $(call __ndk_info,WARNING: NDK_PROJECT_PATH and APP_PROJECT_PATH are both set but not equal literally)
112            $(call __ndk_info,  NDK_PROJECT_PATH = $(NDK_PROJECT_PATH))
113            $(call __ndk_info,  APP_PROJECT_PATH = $(APP_PROJECT_PATH))
114        endif
115    endif
116endif
117
118ifeq (null,$(NDK_PROJECT_PATH))
119
120$(call ndk_log,Make no attempt to look for NDK_PROJECT_PATH.)
121
122else
123
124# To keep paths as short as possible during the build, we first look if the
125# current directory is the top of our project path. If this is the case, we
126# will define NDK_PROJECT_PATH to simply '.'
127#
128# Otherwise, we will use find-project-dir which will first get the absolute
129# path of the current directory the climb back the hierarchy until we find
130# something. The result will always be a much longer definition for
131# NDK_PROJECT_PATH
132#
133ifndef NDK_PROJECT_PATH
134    ifneq (,$(strip $(wildcard AndroidManifest.xml)))
135        NDK_PROJECT_PATH := .
136    else
137        ifneq (,$(strip $(wildcard jni/Android.mk)))
138            NDK_PROJECT_PATH := .
139        endif
140    endif
141endif
142ifndef NDK_PROJECT_PATH
143    NDK_PROJECT_PATH := $(call find-project-dir,.,jni/Android.mk)
144endif
145ifndef NDK_PROJECT_PATH
146    NDK_PROJECT_PATH := $(call find-project-dir,.,AndroidManifest.xml)
147endif
148ifndef NDK_PROJECT_PATH
149    $(call __ndk_info,Could not find application project directory !)
150    $(call __ndk_info,Please define the NDK_PROJECT_PATH variable to point to it.)
151    $(call __ndk_error,Aborting)
152endif
153
154# Check that there are no spaces in the project path, or bad things will happen
155ifneq ($(words $(NDK_PROJECT_PATH)),1)
156    $(call __ndk_info,Your Android application project path contains spaces: '$(NDK_PROJECT_PATH)')
157    $(call __ndk_info,The Android NDK build cannot work here. Please move your project to a different location.)
158    $(call __ndk_error,Aborting.)
159endif
160
161$(call ndk_log,Found project path: $(NDK_PROJECT_PATH))
162
163NDK_APPLICATION_MK := $(strip $(wildcard $(NDK_PROJECT_PATH)/jni/Application.mk))
164
165endif # NDK_PROJECT_PATH == null
166
167ifndef NDK_APPLICATION_MK
168    NDK_APPLICATION_MK := $(NDK_ROOT)/build/core/default-application.mk
169endif
170
171
172# Place all generated intermediate files here
173NDK_APP_OUT := $(strip $(NDK_OUT))
174ifndef NDK_APP_OUT
175  ifeq (null,$(NDK_PROJECT_PATH))
176    $(call __ndk_info,NDK_PROJECT_PATH==null.  Please explicitly set NDK_OUT to directory for all generated intermediate files.)
177    $(call __ndk_error,Aborting.)
178  endif
179  NDK_APP_OUT := $(NDK_PROJECT_PATH)/obj
180endif
181$(call ndk_log,Ouput path for intermediate files: $(NDK_APP_OUT))
182
183# Place all generated library files here.  This is rarely changed since aapt expects the default libs/
184NDK_APP_LIBS_OUT := $(strip $(NDK_LIBS_OUT))
185ifndef NDK_APP_LIBS_OUT
186  ifeq (null,$(NDK_PROJECT_PATH))
187    $(call __ndk_info,NDK_PROJECT_PATH==null.  Please explicitly set NDK_LIBS_OUT to directory for generated library files.)
188    $(call __ndk_error,Aborting.)
189  endif
190  NDK_APP_LIBS_OUT := $(NDK_PROJECT_PATH)/libs
191endif
192$(call ndk_log,Ouput path for generated library files: $(NDK_APP_LIBS_OUT))
193
194# Fake an application named 'local'
195_app            := local
196_application_mk := $(NDK_APPLICATION_MK)
197NDK_APPS        := $(_app)
198
199include $(BUILD_SYSTEM)/add-application.mk
200
201# For cygwin, put generated dependency conversion script here
202# Do not define this variable for other host platforms
203#
204ifeq ($(HOST_OS),cygwin)
205NDK_DEPENDENCIES_CONVERTER := $(NDK_APP_OUT)/convert-dependencies.sh
206endif
207
208# If a goal is DUMP_xxx then we dump a variable xxx instead
209# of building anything
210#
211MAKECMDGOALS := $(filter-out DUMP_$(DUMP_VAR),$(MAKECMDGOALS))
212
213include $(BUILD_SYSTEM)/setup-imports.mk
214
215ifneq (,$(DUMP_VAR))
216
217# We only support a single DUMP_XXX goal at a time for now.
218ifneq ($(words $(DUMP_VAR)),1)
219    $(call __ndk_error,!!TOO-MANY-DUMP-VARIABLES!!)
220endif
221
222$(foreach _app,$(NDK_APPS),\
223  $(eval include $(BUILD_SYSTEM)/setup-app.mk)\
224)
225
226DUMP_$(DUMP_VAR):
227	@echo $($(DUMP_VAR))
228else
229    # Build it
230    include $(BUILD_SYSTEM)/build-all.mk
231endif
232