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# 23NDK_ROOT := $(dir $(lastword $(MAKEFILE_LIST))) 24NDK_ROOT := $(strip $(NDK_ROOT:%build/core/=%)) 25NDK_ROOT := $(subst \,/,$(NDK_ROOT)) 26NDK_ROOT := $(NDK_ROOT:%/=%) 27ifeq ($(NDK_ROOT),) 28 # for the case when we're invoked from the NDK install path 29 NDK_ROOT := . 30endif 31ifeq ($(NDK_LOG),1) 32 $(info Android NDK: NDK installation path auto-detected: '$(NDK_ROOT)') 33endif 34ifneq ($(words $(NDK_ROOT)),1) 35 $(info Android NDK: You NDK installation path contains spaces.) 36 $(info Android NDK: Please re-install to a different location to fix the issue !) 37 $(error Aborting.) 38endif 39 40include $(NDK_ROOT)/build/core/init.mk 41 42# ==================================================================== 43# 44# If NDK_PROJECT_PATH is not defined, find the application's project 45# path by looking at the manifest file in the current directory or 46# any of its parents. If none is found, try again with 'jni/Android.mk' 47# 48# Note that we first look at the current directory to avoid using 49# absolute NDK_PROJECT_PATH values. This reduces the length of all 50# source, object and binary paths that are passed to build commands. 51# 52# It turns out that some people use ndk-build to generate static 53# libraries without a full Android project tree. 54# 55# If NDK_PROJECT_PATH=null, ndk-build make no attempt to look for it, but does 56# need the following variables depending on NDK_PROJECT_PATH to be explicitly 57# specified (from the default, if any): 58# 59# NDK_OUT 60# NDK_LIBS_OUT 61# APP_BUILD_SCRIPT 62# NDK_DEBUG (optional, default to 0) 63# Other APP_* used to be in Application.mk 64# 65# This behavior may be useful in an integrated build system. 66# 67# ==================================================================== 68 69ifeq ($(HOST_OS),windows) 70# On Windows, defining host-dir-parent is a bit more tricky because the 71# GNU Make $(dir ...) function doesn't return an empty string when it 72# reaches the top of the directory tree, and we want to enforce this to 73# avoid infinite loops. 74# 75# $(dir C:) -> C: (empty expected) 76# $(dir C:/) -> C:/ (empty expected) 77# $(dir C:\) -> C:\ (empty expected) 78# $(dir C:/foo) -> C:/ (correct) 79# $(dir C:\foo) -> C:\ (correct) 80# 81host-dir-parent = $(patsubst %/,%,$(strip \ 82 $(eval __host_dir_node := $(patsubst %/,%,$(subst \,/,$1)))\ 83 $(eval __host_dir_parent := $(dir $(__host_dir_node)))\ 84 $(filter-out $1,$(__host_dir_parent))\ 85 )) 86else 87host-dir-parent = $(patsubst %/,%,$(dir $1)) 88endif 89 90find-project-dir = $(strip $(call find-project-dir-inner,$(abspath $1),$2)) 91 92find-project-dir-inner = \ 93 $(eval __found_project_path := )\ 94 $(eval __find_project_path := $1)\ 95 $(eval __find_project_file := $2)\ 96 $(call find-project-dir-inner-2)\ 97 $(__found_project_path) 98 99find-project-dir-inner-2 = \ 100 $(call ndk_log,Looking for $(__find_project_file) in $(__find_project_path))\ 101 $(eval __find_project_manifest := $(strip $(wildcard $(__find_project_path)/$(__find_project_file))))\ 102 $(if $(__find_project_manifest),\ 103 $(call ndk_log, Found it !)\ 104 $(eval __found_project_path := $(__find_project_path))\ 105 ,\ 106 $(eval __find_project_parent := $(call host-dir-parent,$(__find_project_path)))\ 107 $(if $(__find_project_parent),\ 108 $(eval __find_project_path := $(__find_project_parent))\ 109 $(call find-project-dir-inner-2)\ 110 )\ 111 ) 112 113NDK_PROJECT_PATH := $(strip $(NDK_PROJECT_PATH)) 114APP_PROJECT_PATH := $(strip $(APP_PROJECT_PATH)) 115 116ifneq (,$(APP_PROJECT_PATH)) 117 ifeq (,$(NDK_PROJECT_PATH)) 118 # If NDK_PROJECT_PATH isn't set and APP_PROJECT_PATH is present, use APP_PROJECT_PATH 119 $(call ndk_log,Use APP_PROJECT_PATH for NDK_PROJECT_PATH: $(APP_PROJECT_PATH)) 120 NDK_PROJECT_PATH := $(APP_PROJECT_PATH) 121 else 122 # If both NDK_PROJECT_PATH and APP_PROJECT_PATH are present, check consistency 123 ifneq ($(NDK_PROJECT_PATH),$(APP_PROJECT_PATH)) 124 $(call __ndk_info,WARNING: NDK_PROJECT_PATH and APP_PROJECT_PATH are both set but not equal literally) 125 $(call __ndk_info, NDK_PROJECT_PATH = $(NDK_PROJECT_PATH)) 126 $(call __ndk_info, APP_PROJECT_PATH = $(APP_PROJECT_PATH)) 127 endif 128 endif 129endif 130 131ifeq (null,$(NDK_PROJECT_PATH)) 132 133$(call ndk_log,Make no attempt to look for NDK_PROJECT_PATH.) 134 135else 136 137# To keep paths as short as possible during the build, we first look if the 138# current directory is the top of our project path. If this is the case, we 139# will define NDK_PROJECT_PATH to simply '.' 140# 141# Otherwise, we will use find-project-dir which will first get the absolute 142# path of the current directory the climb back the hierarchy until we find 143# something. The result will always be a much longer definition for 144# NDK_PROJECT_PATH 145# 146ifndef NDK_PROJECT_PATH 147 ifneq (,$(strip $(wildcard AndroidManifest.xml))) 148 NDK_PROJECT_PATH := . 149 else 150 ifneq (,$(strip $(wildcard jni/Android.mk))) 151 NDK_PROJECT_PATH := . 152 endif 153 endif 154endif 155ifndef NDK_PROJECT_PATH 156 NDK_PROJECT_PATH := $(call find-project-dir,.,jni/Android.mk) 157endif 158ifndef NDK_PROJECT_PATH 159 NDK_PROJECT_PATH := $(call find-project-dir,.,AndroidManifest.xml) 160endif 161ifndef NDK_PROJECT_PATH 162 $(call __ndk_info,Could not find application project directory !) 163 $(call __ndk_info,Please define the NDK_PROJECT_PATH variable to point to it.) 164 $(call __ndk_error,Aborting) 165endif 166 167# Check that there are no spaces in the project path, or bad things will happen 168ifneq ($(words $(NDK_PROJECT_PATH)),1) 169 $(call __ndk_info,Your Android application project path contains spaces: '$(NDK_PROJECT_PATH)') 170 $(call __ndk_info,The Android NDK build cannot work here. Please move your project to a different location.) 171 $(call __ndk_error,Aborting.) 172endif 173 174$(call ndk_log,Found project path: $(NDK_PROJECT_PATH)) 175 176NDK_APPLICATION_MK := $(strip $(wildcard $(NDK_PROJECT_PATH)/jni/Application.mk)) 177 178endif # NDK_PROJECT_PATH == null 179 180ifndef NDK_APPLICATION_MK 181 NDK_APPLICATION_MK := $(NDK_ROOT)/build/core/default-application.mk 182endif 183 184 185# Place all generated intermediate files here 186NDK_APP_OUT := $(strip $(NDK_OUT)) 187ifndef NDK_APP_OUT 188 ifeq (null,$(NDK_PROJECT_PATH)) 189 $(call __ndk_info,NDK_PROJECT_PATH==null. Please explicitly set NDK_OUT to directory for all generated intermediate files.) 190 $(call __ndk_error,Aborting.) 191 endif 192 NDK_APP_OUT := $(NDK_PROJECT_PATH)/obj 193endif 194$(call ndk_log,Ouput path for intermediate files: $(NDK_APP_OUT)) 195 196# Place all generated library files here. This is rarely changed since aapt expects the default libs/ 197NDK_APP_LIBS_OUT := $(strip $(NDK_LIBS_OUT)) 198ifndef NDK_APP_LIBS_OUT 199 ifeq (null,$(NDK_PROJECT_PATH)) 200 $(call __ndk_info,NDK_PROJECT_PATH==null. Please explicitly set NDK_LIBS_OUT to directory for generated library files.) 201 $(call __ndk_error,Aborting.) 202 endif 203 NDK_APP_LIBS_OUT := $(NDK_PROJECT_PATH)/libs 204endif 205$(call ndk_log,Ouput path for generated library files: $(NDK_APP_LIBS_OUT)) 206 207# Fake an application named 'local' 208_app := local 209_application_mk := $(NDK_APPLICATION_MK) 210NDK_APPS := $(_app) 211 212include $(BUILD_SYSTEM)/add-application.mk 213 214# For cygwin, put generated dependency conversion script here 215# Do not define this variable for other host platforms 216# 217ifeq ($(HOST_OS),cygwin) 218NDK_DEPENDENCIES_CONVERTER := $(NDK_APP_OUT)/convert-dependencies.sh 219endif 220 221# If a goal is DUMP_xxx then we dump a variable xxx instead 222# of building anything 223# 224DUMP_VAR := $(patsubst DUMP_%,%,$(filter DUMP_%,$(MAKECMDGOALS))) 225MAKECMDGOALS := $(filter-out DUMP_$(DUMP_VAR),$(MAKECMDGOALS)) 226 227include $(BUILD_SYSTEM)/setup-imports.mk 228 229ifneq (,$(DUMP_VAR)) 230 231# We only support a single DUMP_XXX goal at a time for now. 232ifneq ($(words $(DUMP_VAR)),1) 233 $(call __ndk_error,!!TOO-MANY-DUMP-VARIABLES!!) 234endif 235 236$(foreach _app,$(NDK_APPS),\ 237 $(eval include $(BUILD_SYSTEM)/setup-app.mk)\ 238) 239 240DUMP_$(DUMP_VAR): 241 @echo $($(DUMP_VAR)) 242else 243 # Build it 244 include $(BUILD_SYSTEM)/build-all.mk 245endif 246