| # Copyright (C) 2009 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| # Common definitions for the Android NDK build system |
| # |
| |
| # We use the GNU Make Standard Library |
| include $(NDK_ROOT)/build/gmsl/gmsl |
| |
| # If NDK_TRACE is enabled then calls to the library functions are |
| # traced to stdout using warning messages with their arguments |
| |
| ifdef NDK_TRACE |
| __ndk_tr1 = $(warning $0('$1')) |
| __ndk_tr2 = $(warning $0('$1','$2')) |
| __ndk_tr3 = $(warning $0('$1','$2','$3')) |
| else |
| __ndk_tr1 := |
| __ndk_tr2 := |
| __ndk_tr3 := |
| endif |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : empty |
| # Returns : an empty macro |
| # Usage : $(empty) |
| # ----------------------------------------------------------------------------- |
| empty := |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : space |
| # Returns : a single space |
| # Usage : $(space) |
| # ----------------------------------------------------------------------------- |
| space := $(empty) $(empty) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : last2 |
| # Arguments: a list |
| # Returns : the penultimate (next-to-last) element of a list |
| # Usage : $(call last2, <LIST>) |
| # ----------------------------------------------------------------------------- |
| last2 = $(word $(words $1), x $1) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : last3 |
| # Arguments: a list |
| # Returns : the antepenultimate (second-next-to-last) element of a list |
| # Usage : $(call last3, <LIST>) |
| # ----------------------------------------------------------------------------- |
| last3 = $(word $(words $1), x x $1) |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : this-makefile |
| # Returns : the name of the current Makefile in the inclusion stack |
| # Usage : $(this-makefile) |
| # ----------------------------------------------------------------------------- |
| this-makefile = $(lastword $(MAKEFILE_LIST)) |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : local-makefile |
| # Returns : the name of the last parsed Android.mk file |
| # Usage : $(local-makefile) |
| # ----------------------------------------------------------------------------- |
| local-makefile = $(lastword $(filter %Android.mk,$(MAKEFILE_LIST))) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : assert-defined |
| # Arguments: 1: list of variable names |
| # Returns : None |
| # Usage : $(call assert-defined, VAR1 VAR2 VAR3...) |
| # Rationale: Checks that all variables listed in $1 are defined, or abort the |
| # build |
| # ----------------------------------------------------------------------------- |
| assert-defined = $(foreach __varname,$(strip $1),\ |
| $(if $(strip $($(__varname))),,\ |
| $(call __ndk_error, Assertion failure: $(__varname) is not defined)\ |
| )\ |
| ) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : clear-vars |
| # Arguments: 1: list of variable names |
| # 2: file where the variable should be defined |
| # Returns : None |
| # Usage : $(call clear-vars, VAR1 VAR2 VAR3...) |
| # Rationale: Clears/undefines all variables in argument list |
| # ----------------------------------------------------------------------------- |
| clear-vars = $(foreach __varname,$1,$(eval $(__varname) := $(empty))) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : check-required-vars |
| # Arguments: 1: list of variable names |
| # 2: file where the variable(s) should be defined |
| # Returns : None |
| # Usage : $(call check-required-vars, VAR1 VAR2 VAR3..., <file>) |
| # Rationale: Checks that all required vars listed in $1 were defined by $2 |
| # or abort the build with an error |
| # ----------------------------------------------------------------------------- |
| check-required-vars = $(foreach __varname,$1,\ |
| $(if $(strip $($(__varname))),,\ |
| $(call __ndk_info, Required variable $(__varname) is not defined by $2)\ |
| $(call __ndk_error,Aborting)\ |
| )\ |
| ) |
| |
| # ============================================================================= |
| # |
| # Modules database |
| # |
| # The following declarations are used to manage the list of modules |
| # defined in application's Android.mk files. |
| # |
| # Technical note: |
| # We use __ndk_modules to hold the list of all modules corresponding |
| # to a given application. |
| # |
| # For each module 'foo', __ndk_modules.foo.<field> is used |
| # to store module-specific information. |
| # |
| # type -> type of module (e.g. 'static', 'shared', ...) |
| # depends -> list of other modules this module depends on |
| # |
| # Also, LOCAL_XXXX values defined for a module are recorded in XXXX, e.g.: |
| # |
| # PATH -> recorded LOCAL_PATH for the module |
| # CFLAGS -> recorded LOCAL_CFLAGS for the module |
| # ... |
| # |
| # Some of these are created by build scripts like BUILD_STATIC_LIBRARY: |
| # |
| # MAKEFILE -> The Android.mk where the module is defined. |
| # LDFLAGS -> Final linker flags |
| # OBJECTS -> List of module objects |
| # BUILT_MODULE -> location of module built file (e.g. obj/<app>/<abi>/libfoo.so) |
| # |
| # Note that some modules are never installed (e.g. static libraries). |
| # |
| # ============================================================================= |
| |
| # The list of LOCAL_XXXX variables that are recorded for each module definition |
| # These are documented by docs/ANDROID-MK.TXT. Exception is LOCAL_MODULE |
| # |
| modules-LOCALS := \ |
| MODULE \ |
| MODULE_FILENAME \ |
| PATH \ |
| SRC_FILES \ |
| CPP_EXTENSION \ |
| C_INCLUDES \ |
| CFLAGS \ |
| CXXFLAGS \ |
| CPPFLAGS \ |
| STATIC_LIBRARIES \ |
| SHARED_LIBRARIES \ |
| PREBUILTS \ |
| LDLIBS \ |
| ALLOW_UNDEFINED_SYMBOLS \ |
| ARM_MODE \ |
| ARM_NEON \ |
| DISABLE_NO_EXECUTE \ |
| EXPORT_CFLAGS \ |
| EXPORT_CPPFLAGS \ |
| EXPORT_LDLIBS \ |
| EXPORT_C_INCLUDES \ |
| |
| # The following are generated by the build scripts themselves |
| modules-LOCALS += \ |
| MAKEFILE \ |
| LDFLAGS \ |
| OBJECTS \ |
| BUILT_MODULE \ |
| OBJS_DIR \ |
| IS_HOST_MODULE \ |
| INSTALLED |
| |
| # the list of managed fields per module |
| modules-fields = type depends \ |
| $(modules-LOCALS) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : modules-clear |
| # Arguments: None |
| # Returns : None |
| # Usage : $(call modules-clear) |
| # Rationale: clears the list of defined modules known by the build system |
| # ----------------------------------------------------------------------------- |
| modules-clear = \ |
| $(foreach __mod,$(__ndk_modules),\ |
| $(foreach __field,$(modules-fields),\ |
| $(eval __ndk_modules.$(__mod).$(__field) := $(empty))\ |
| )\ |
| )\ |
| $(eval __ndk_modules := $(empty_set)) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : modules-get-list |
| # Arguments: None |
| # Returns : The list of all recorded modules |
| # Usage : $(call modules-get-list) |
| # ----------------------------------------------------------------------------- |
| modules-get-list = $(__ndk_modules) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : modules-add |
| # Arguments: 1: module name |
| # 2: type of module (e.g. 'static') |
| # Returns : None |
| # Usage : $(call modules-add,<modulename>,<Android.mk path>) |
| # Rationale: add a new module. If it is already defined, print an error message |
| # and abort. This will record all LOCAL_XXX variables for the module. |
| # ----------------------------------------------------------------------------- |
| module-add = \ |
| $(call assert-defined,LOCAL_MAKEFILE LOCAL_BUILT_MODULE LOCAL_OBJS_DIR)\ |
| $(if $(call set_is_member,$(__ndk_modules),$1),\ |
| $(call __ndk_info,Trying to define local module '$1' in $(LOCAL_MAKEFILE).)\ |
| $(call __ndk_info,But this module was already defined by $(__ndk_modules.$1.MAKEFILE).)\ |
| $(call __ndk_error,Aborting.)\ |
| )\ |
| $(eval __ndk_modules := $(call set_insert,$(__ndk_modules),$1))\ |
| $(eval __ndk_modules.$1.type := $2)\ |
| $(foreach __local,$(modules-LOCALS),\ |
| $(eval __ndk_modules.$1.$(__local) := $(LOCAL_$(__local)))\ |
| ) |
| |
| module-add-static-library = $(call module-add,$1,static-library) |
| |
| module-add-shared-library = \ |
| $(eval LOCAL_INSTALLED := $(NDK_APP_DST_DIR)/$(notdir $(LOCAL_BUILT_MODULE)))\ |
| $(call module-add,$1,shared-library) |
| |
| module-add-executable = \ |
| $(eval LOCAL_INSTALLED := $(NDK_APP_DST_DIR)/$(notdir $(LOCAL_BUILT_MODULE)))\ |
| $(call module-add,$1,executable) |
| |
| module-add-prebuilt-shared-library = \ |
| $(eval LOCAL_INSTALLED := $(NDK_APP_DST_DIR)/$(notdir $(LOCAL_BUILT_MODULE)))\ |
| $(call module-add,$1,prebuilt-shared-library) |
| |
| # Returns $(true) iff module $1 is of type $2 |
| module-is-type = $(call seq,$(__ndk_modules.$1.type),$2) |
| |
| module-get-type = $(__ndk_modules.$1.type) |
| |
| # Retrieve built location of module $1 |
| module-get-built = $(__ndk_modules.$1.BUILT_MODULE) |
| |
| # Returns $(true) is module $1 is of a given type |
| module-is-static-library = $(call module-is-type,$1,static-library) |
| module-is-shared-library = $(call module-is-type,$1,shared-library) |
| module-is-executable = $(call module-is-type,$1,executable) |
| module-is-installable = $(if $(filter shared-library executable prebuilt-shared-library,$(call module-get-type,$1)),$(true),$(false)) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : module-get-export |
| # Arguments: 1: module name |
| # 2: export variable name without LOCAL_EXPORT_ prefix (e.g. 'CFLAGS') |
| # Returns : Exported value |
| # Usage : $(call module-get-export,<modulename>,<varname>) |
| # Rationale: Return the recorded value of LOCAL_EXPORT_$2, if any, for module $1 |
| # ----------------------------------------------------------------------------- |
| module-get-export = $(__ndk_modules.$1.EXPORT_$2) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : module-get-listed-export |
| # Arguments: 1: list of module names |
| # 2: export variable name without LOCAL_EXPORT_ prefix (e.g. 'CFLAGS') |
| # Returns : Exported values |
| # Usage : $(call module-get-listed-export,<module-list>,<varname>) |
| # Rationale: Return the recorded value of LOCAL_EXPORT_$2, if any, for modules |
| # listed in $1. |
| # ----------------------------------------------------------------------------- |
| module-get-listed-export = $(strip \ |
| $(foreach __listed_module,$1,\ |
| $(call module-get-export,$(__listed_module),$2)\ |
| )) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : modules-restore-locals |
| # Arguments: 1: module name |
| # Returns : None |
| # Usage : $(call module-restore-locals,<modulename>) |
| # Rationale: Restore the recorded LOCAL_XXX definitions for a given module. |
| # ----------------------------------------------------------------------------- |
| module-restore-locals = \ |
| $(foreach __local,$(modules-LOCALS),\ |
| $(eval LOCAL_$(__local) := $(__ndk_modules.$1.$(__local)))\ |
| ) |
| |
| # Dump all module information. Only use this for debugging |
| modules-dump-database = \ |
| $(info Modules: $(__ndk_modules)) \ |
| $(foreach __mod,$(__ndk_modules),\ |
| $(info $(space)$(space)$(__mod):)\ |
| $(foreach __field,$(modules-fields),\ |
| $(info $(space)$(space)$(space)$(space)$(__field): $(__ndk_modules.$(__mod).$(__field)))\ |
| )\ |
| )\ |
| $(info --- end of list) |
| |
| |
| # ----------------------------------------------------------------------------- |
| # Function : module-add-static-depends |
| # Arguments: 1: module name |
| # 2: list/set of static library modules this module depends on. |
| # Returns : None |
| # Usage : $(call module-add-static-depends,<modulename>,<list of module names>) |
| # Rationale: Record that a module depends on a set of static libraries. |
| # Use module-get-static-dependencies to retrieve final list. |
| # ----------------------------------------------------------------------------- |
| module-add-static-depends = \ |
| $(call module-add-depends-any,$1,$2,depends) \ |
| |
| # ----------------------------------------------------------------------------- |
| # Function : module-add-shared-depends |
| # Arguments: 1: module name |
| # 2: list/set of shared library modules this module depends on. |
| # Returns : None |
| # Usage : $(call module-add-shared-depends,<modulename>,<list of module names>) |
| # Rationale: Record that a module depends on a set of shared libraries. |
| # Use modulge-get-shared-dependencies to retrieve final list. |
| # ----------------------------------------------------------------------------- |
| module-add-shared-depends = \ |
| $(call module-add-depends-any,$1,$2,depends) \ |
| |
| module-add-prebuilt-depends = \ |
| $(call module-add-depends-any,$1,$2,depends) \ |
| |
| # Used internally by module-add-static-depends and module-add-shared-depends |
| # NOTE: this function must not modify the existing dependency order when new depends are added. |
| # |
| module-add-depends-any = \ |
| $(eval __ndk_modules.$1.$3 += $(filter-out $(__ndk_modules.$1.$3),$(call strip-lib-prefix,$2))) |
| |
| # Used to recompute all dependencies once all module information has been recorded. |
| # |
| modules-compute-dependencies = \ |
| $(foreach __module,$(__ndk_modules),\ |
| $(call module-compute-depends,$(__module))\ |
| ) |
| |
| module-compute-depends = \ |
| $(call module-add-static-depends,$1,$(__ndk_modules.$1.STATIC_LIBRARIES))\ |
| $(call module-add-shared-depends,$1,$(__ndk_modules.$1.SHARED_LIBRARIES))\ |
| $(call module-add-prebuilt-depends,$1,$(__ndk_modules.$1.PREBUILTS)) |
| |
| module-get-installed = $(__ndk_modules.$1.INSTALLED) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : modules-get-all-dependencies |
| # Arguments: 1: list of module names |
| # Returns : List of all the modules $1 depends on transitively. |
| # Usage : $(call modules-all-get-dependencies,<list of module names>) |
| # Rationale: This computes the closure of all module dependencies starting from $1 |
| # ----------------------------------------------------------------------------- |
| module-get-all-dependencies = \ |
| $(strip $(call modules-get-closure,$1,depends)) |
| |
| modules-get-closure = \ |
| $(eval __closure_deps := $(strip $1)) \ |
| $(eval __closure_wq := $(__closure_deps)) \ |
| $(eval __closure_field := $(strip $2)) \ |
| $(call modules-closure)\ |
| $(__closure_deps) |
| |
| # Used internally by modules-get-dependencies |
| # Note the tricky use of conditional recursion to work around the fact that |
| # the GNU Make language does not have any conditional looping construct |
| # like 'while'. |
| # |
| modules-closure = \ |
| $(eval __closure_mod := $(call first,$(__closure_wq))) \ |
| $(eval __closure_wq := $(call rest,$(__closure_wq))) \ |
| $(eval __closure_new := $(filter-out $(__closure_deps),$(__ndk_modules.$(__closure_mod).$(__closure_field))))\ |
| $(eval __closure_deps += $(__closure_new)) \ |
| $(eval __closure_wq := $(strip $(__closure_wq) $(__closure_new)))\ |
| $(if $(__closure_wq),$(call modules-closure)) \ |
| |
| # Return the C++ extension of a given module |
| # |
| module-get-cpp-extension = $(strip \ |
| $(if $(__ndk_modules.$1.CPP_EXTENSION),\ |
| $(__ndk_modules.$1.CPP_EXTENSION),\ |
| .cpp\ |
| )) |
| |
| # Return the list of C++ sources of a given module |
| # |
| module-get-c++-sources = \ |
| $(filter %$(call module-get-cpp-extension,$1),$(__ndk_modules.$1.SRC_FILES)) |
| |
| # Returns true if a module has C++ sources |
| # |
| module-has-c++ = $(strip $(call module-get-c++-sources,$1)) |
| |
| # Add C++ dependencies to any module that has C++ sources. |
| # $1: list of C++ runtime static libraries (if any) |
| # $2: list of C++ runtime shared libraries (if any) |
| # |
| modules-add-c++-dependencies = \ |
| $(foreach __module,$(__ndk_modules),\ |
| $(if $(call module-has-c++,$(__module)),\ |
| $(call ndk_log,Module '$(__module)' has C++ sources)\ |
| $(call module-add-c++-deps,$(__module),$1,$2),\ |
| )\ |
| ) |
| |
| # Add standard C++ dependencies to a given module |
| # |
| # $1: module name |
| # $2: list of C++ runtime static libraries (if any) |
| # $3: list of C++ runtime shared libraries (if any) |
| # |
| module-add-c++-deps = \ |
| $(eval __ndk_modules.$1.STATIC_LIBRARIES += $(2))\ |
| $(eval __ndk_modules.$1.SHARED_LIBRARIES += $(3)) |
| |
| |
| # ============================================================================= |
| # |
| # Utility functions |
| # |
| # ============================================================================= |
| |
| # ----------------------------------------------------------------------------- |
| # Function : parent-dir |
| # Arguments: 1: path |
| # Returns : Parent dir or path of $1, with final separator removed. |
| # ----------------------------------------------------------------------------- |
| parent-dir = $(patsubst %/,%,$(dir $1)) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : check-user-define |
| # Arguments: 1: name of variable that must be defined by the user |
| # 2: name of Makefile where the variable should be defined |
| # 3: name/description of the Makefile where the check is done, which |
| # must be included by $2 |
| # Returns : None |
| # ----------------------------------------------------------------------------- |
| check-user-define = $(if $(strip $($1)),,\ |
| $(call __ndk_error,Missing $1 before including $3 in $2)) |
| |
| # ----------------------------------------------------------------------------- |
| # This is used to check that LOCAL_MODULE is properly defined by an Android.mk |
| # file before including one of the $(BUILD_SHARED_LIBRARY), etc... files. |
| # |
| # Function : check-user-LOCAL_MODULE |
| # Arguments: 1: name/description of the included build Makefile where the |
| # check is done |
| # Returns : None |
| # Usage : $(call check-user-LOCAL_MODULE, BUILD_SHARED_LIBRARY) |
| # ----------------------------------------------------------------------------- |
| check-defined-LOCAL_MODULE = \ |
| $(call check-user-define,LOCAL_MODULE,$(local-makefile),$(1)) \ |
| $(if $(call seq,$(words $(LOCAL_MODULE)),1),,\ |
| $(call __ndk_info,LOCAL_MODULE definition in $(local-makefile) must not contain space)\ |
| $(call __ndk_error,Please correct error. Aborting)\ |
| ) |
| |
| # ----------------------------------------------------------------------------- |
| # This is used to check that LOCAL_MODULE_FILENAME, if defined, is correct. |
| # |
| # Function : check-user-LOCAL_MODULE_FILENAME |
| # Returns : None |
| # Usage : $(call check-user-LOCAL_MODULE_FILENAME) |
| # ----------------------------------------------------------------------------- |
| check-LOCAL_MODULE_FILENAME = \ |
| $(if $(strip $(LOCAL_MODULE_FILENAME)),\ |
| $(if $(call seq,$(words $(LOCAL_MODULE_FILENAME)),1),,\ |
| $(call __ndk_info,$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain spaces)\ |
| $(call __ndk_error,Plase correct error. Aborting)\ |
| )\ |
| $(if $(filter %.a %.so,$(LOCAL_MODULE_FILENAME)),\ |
| $(call __ndk_info,$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_MODULE_FILENAME should not include file extensions)\ |
| )\ |
| ) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : handle-module-filename |
| # Arguments : 1: default file prefix |
| # 2: file suffix |
| # Returns : None |
| # Usage : $(call handle-module-filename,<prefix>,<suffix>) |
| # Rationale : To be used to check and or set the module's filename through |
| # the LOCAL_MODULE_FILENAME variable. |
| # ----------------------------------------------------------------------------- |
| handle-module-filename = $(eval $(call ev-handle-module-filename,$1,$2)) |
| |
| |
| # $1: default file prefix |
| # $2: default file suffix |
| define ev-handle-module-filename |
| LOCAL_MODULE_FILENAME := $$(strip $$(LOCAL_MODULE_FILENAME)) |
| ifdef LOCAL_MODULE_FILENAME |
| ifneq ($$(words $$(LOCAL_MODULE_FILENAME)),1) |
| $$(call __ndk_info,$$(LOCAL_MAKEFILE):$$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain any space) |
| $$(call __ndk_error,Aborting) |
| endif |
| ifneq ($$(filter %.a %.so,$$(LOCAL_MODULE_FILENAME)),) |
| $$(call __ndk_info,$$(LOCAL_MAKEFILE):$$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain a file extension) |
| $$(call __ndk_error,Aborting) |
| endif |
| else |
| LOCAL_MODULE_FILENAME := $1$(LOCAL_MODULE) |
| endif |
| LOCAL_MODULE_FILENAME := $$(LOCAL_MODULE_FILENAME)$2 |
| endef |
| |
| # ----------------------------------------------------------------------------- |
| # Function : handle-module-built |
| # Returns : None |
| # Usage : $(call handle-module-built) |
| # Rationale : To be used to automatically compute the location of the generated |
| # binary file, and the directory where to place its object files. |
| # ----------------------------------------------------------------------------- |
| handle-module-built = \ |
| $(eval LOCAL_BUILT_MODULE := $(TARGET_OUT)/$(LOCAL_MODULE_FILENAME))\ |
| $(eval LOCAL_OBJS_DIR := $(TARGET_OBJS)/$(LOCAL_MODULE)) |
| |
| # ----------------------------------------------------------------------------- |
| # Strip any 'lib' prefix in front of a given string. |
| # |
| # Function : strip-lib-prefix |
| # Arguments: 1: module name |
| # Returns : module name, without any 'lib' prefix if any |
| # Usage : $(call strip-lib-prefix,$(LOCAL_MODULE)) |
| # ----------------------------------------------------------------------------- |
| strip-lib-prefix = $(1:lib%=%) |
| |
| # ----------------------------------------------------------------------------- |
| # This is used to strip any lib prefix from LOCAL_MODULE, then check that |
| # the corresponding module name is not already defined. |
| # |
| # Function : check-user-LOCAL_MODULE |
| # Arguments: 1: path of Android.mk where this LOCAL_MODULE is defined |
| # Returns : None |
| # Usage : $(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE)) |
| # ----------------------------------------------------------------------------- |
| check-LOCAL_MODULE = \ |
| $(eval LOCAL_MODULE := $$(call strip-lib-prefix,$$(LOCAL_MODULE))) |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : my-dir |
| # Returns : the directory of the current Makefile |
| # Usage : $(my-dir) |
| # ----------------------------------------------------------------------------- |
| my-dir = $(call parent-dir,$(lastword $(MAKEFILE_LIST))) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : all-makefiles-under |
| # Arguments: 1: directory path |
| # Returns : a list of all makefiles immediately below some directory |
| # Usage : $(call all-makefiles-under, <some path>) |
| # ----------------------------------------------------------------------------- |
| all-makefiles-under = $(wildcard $1/*/Android.mk) |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : all-subdir-makefiles |
| # Returns : list of all makefiles in subdirectories of the current Makefile's |
| # location |
| # Usage : $(all-subdir-makefiles) |
| # ----------------------------------------------------------------------------- |
| all-subdir-makefiles = $(call all-makefiles-under,$(call my-dir)) |
| |
| # ============================================================================= |
| # |
| # Source file tagging support. |
| # |
| # Each source file listed in LOCAL_SRC_FILES can have any number of |
| # 'tags' associated to it. A tag name must not contain space, and its |
| # usage can vary. |
| # |
| # For example, the 'debug' tag is used to sources that must be built |
| # in debug mode, the 'arm' tag is used for sources that must be built |
| # using the 32-bit instruction set on ARM platforms, and 'neon' is used |
| # for sources that must be built with ARM Advanced SIMD (a.k.a. NEON) |
| # support. |
| # |
| # More tags might be introduced in the future. |
| # |
| # LOCAL_SRC_TAGS contains the list of all tags used (initially empty) |
| # LOCAL_SRC_FILES contains the list of all source files. |
| # LOCAL_SRC_TAG.<tagname> contains the set of source file names tagged |
| # with <tagname> |
| # LOCAL_SRC_FILES_TAGS.<filename> contains the set of tags for a given |
| # source file name |
| # |
| # Tags are processed by a toolchain-specific function (e.g. TARGET-compute-cflags) |
| # which will call various functions to compute source-file specific settings. |
| # These are currently stored as: |
| # |
| # LOCAL_SRC_FILES_TARGET_CFLAGS.<filename> contains the list of |
| # target-specific C compiler flags used to compile a given |
| # source file. This is set by the function TARGET-set-cflags |
| # defined in the toolchain's setup.mk script. |
| # |
| # LOCAL_SRC_FILES_TEXT.<filename> contains the 'text' that will be |
| # displayed along the label of the build output line. For example |
| # 'thumb' or 'arm ' with ARM-based toolchains. |
| # |
| # ============================================================================= |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : clear-all-src-tags |
| # Returns : remove all source file tags and associated data. |
| # Usage : $(clear-all-src-tags) |
| # ----------------------------------------------------------------------------- |
| clear-all-src-tags = \ |
| $(foreach __tag,$(LOCAL_SRC_TAGS), \ |
| $(eval LOCAL_SRC_TAG.$(__tag) := $(empty)) \ |
| ) \ |
| $(foreach __src,$(LOCAL_SRC_FILES), \ |
| $(eval LOCAL_SRC_FILES_TAGS.$(__src) := $(empty)) \ |
| $(eval LOCAL_SRC_FILES_TARGET_CFLAGS.$(__src) := $(empty)) \ |
| $(eval LOCAL_SRC_FILES_TEXT.$(__src) := $(empty)) \ |
| ) \ |
| $(eval LOCAL_SRC_TAGS := $(empty_set)) |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : tag-src-files |
| # Arguments: 1: list of source files to tag |
| # 2: tag name (must not contain space) |
| # Usage : $(call tag-src-files,<list-of-source-files>,<tagname>) |
| # Rationale: Add a tag to a list of source files |
| # ----------------------------------------------------------------------------- |
| tag-src-files = \ |
| $(eval LOCAL_SRC_TAGS := $(call set_insert,$2,$(LOCAL_SRC_TAGS))) \ |
| $(eval LOCAL_SRC_TAG.$2 := $(call set_union,$1,$(LOCAL_SRC_TAG.$2))) \ |
| $(foreach __src,$1, \ |
| $(eval LOCAL_SRC_FILES_TAGS.$(__src) += $2) \ |
| ) |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : get-src-files-with-tag |
| # Arguments: 1: tag name |
| # Usage : $(call get-src-files-with-tag,<tagname>) |
| # Return : The list of source file names that have been tagged with <tagname> |
| # ----------------------------------------------------------------------------- |
| get-src-files-with-tag = $(LOCAL_SRC_TAG.$1) |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : get-src-files-without-tag |
| # Arguments: 1: tag name |
| # Usage : $(call get-src-files-without-tag,<tagname>) |
| # Return : The list of source file names that have NOT been tagged with <tagname> |
| # ----------------------------------------------------------------------------- |
| get-src-files-without-tag = $(filter-out $(LOCAL_SRC_TAG.$1),$(LOCAL_SRC_FILES)) |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : set-src-files-target-cflags |
| # Arguments: 1: list of source files |
| # 2: list of compiler flags |
| # Usage : $(call set-src-files-target-cflags,<sources>,<flags>) |
| # Rationale: Set or replace the set of compiler flags that will be applied |
| # when building a given set of source files. This function should |
| # normally be called from the toolchain-specific function that |
| # computes all compiler flags for all source files. |
| # ----------------------------------------------------------------------------- |
| set-src-files-target-cflags = $(foreach __src,$1,$(eval LOCAL_SRC_FILES_TARGET_CFLAGS.$(__src) := $2)) |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : add-src-files-target-cflags |
| # Arguments: 1: list of source files |
| # 2: list of compiler flags |
| # Usage : $(call add-src-files-target-cflags,<sources>,<flags>) |
| # Rationale: A variant of set-src-files-target-cflags that can be used |
| # to append, instead of replace, compiler flags for specific |
| # source files. |
| # ----------------------------------------------------------------------------- |
| add-src-files-target-cflags = $(foreach __src,$1,$(eval LOCAL_SRC_FILES_TARGET_CFLAGS.$(__src) += $2)) |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : get-src-file-target-cflags |
| # Arguments: 1: single source file name |
| # Usage : $(call get-src-file-target-cflags,<source>) |
| # Rationale: Return the set of target-specific compiler flags that must be |
| # applied to a given source file. These must be set prior to this |
| # call using set-src-files-target-cflags or add-src-files-target-cflags |
| # ----------------------------------------------------------------------------- |
| get-src-file-target-cflags = $(LOCAL_SRC_FILES_TARGET_CFLAGS.$1) |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : set-src-files-text |
| # Arguments: 1: list of source files |
| # 2: text |
| # Usage : $(call set-src-files-text,<sources>,<text>) |
| # Rationale: Set or replace the 'text' associated to a set of source files. |
| # The text is a very short string that complements the build |
| # label. For example, it will be either 'thumb' or 'arm ' for |
| # ARM-based toolchains. This function must be called by the |
| # toolchain-specific functions that processes all source files. |
| # ----------------------------------------------------------------------------- |
| set-src-files-text = $(foreach __src,$1,$(eval LOCAL_SRC_FILES_TEXT.$(__src) := $2)) |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : get-src-file-text |
| # Arguments: 1: single source file |
| # Usage : $(call get-src-file-text,<source>) |
| # Rationale: Return the 'text' associated to a given source file when |
| # set-src-files-text was called. |
| # ----------------------------------------------------------------------------- |
| get-src-file-text = $(LOCAL_SRC_FILES_TEXT.$1) |
| |
| # This should only be called for debugging the source files tagging system |
| dump-src-file-tags = \ |
| $(info LOCAL_SRC_TAGS := $(LOCAL_SRC_TAGS)) \ |
| $(info LOCAL_SRC_FILES = $(LOCAL_SRC_FILES)) \ |
| $(foreach __tag,$(LOCAL_SRC_TAGS),$(info LOCAL_SRC_TAG.$(__tag) = $(LOCAL_SRC_TAG.$(__tag)))) \ |
| $(foreach __src,$(LOCAL_SRC_FILES),$(info LOCAL_SRC_FILES_TAGS.$(__src) = $(LOCAL_SRC_FILES_TAGS.$(__src)))) \ |
| $(info WITH arm = $(call get-src-files-with-tag,arm)) \ |
| $(info WITHOUT arm = $(call get-src-files-without-tag,arm)) \ |
| $(foreach __src,$(LOCAL_SRC_FILES),$(info LOCAL_SRC_FILES_TARGET_CFLAGS.$(__src) = $(LOCAL_SRC_FILES_TARGET_CFLAGS.$(__src)))) \ |
| $(foreach __src,$(LOCAL_SRC_FILES),$(info LOCAL_SRC_FILES_TEXT.$(__src) = $(LOCAL_SRC_FILES_TEXT.$(__src)))) \ |
| |
| |
| # ============================================================================= |
| # |
| # Application.mk support |
| # |
| # ============================================================================= |
| |
| # the list of variables that *must* be defined in Application.mk files |
| NDK_APP_VARS_REQUIRED := |
| |
| # the list of variables that *may* be defined in Application.mk files |
| NDK_APP_VARS_OPTIONAL := APP_OPTIM APP_CPPFLAGS APP_CFLAGS APP_CXXFLAGS \ |
| APP_PLATFORM APP_BUILD_SCRIPT APP_ABI APP_MODULES \ |
| APP_PROJECT_PATH |
| |
| # the list of all variables that may appear in an Application.mk file |
| # or defined by the build scripts. |
| NDK_APP_VARS := $(NDK_APP_VARS_REQUIRED) \ |
| $(NDK_APP_VARS_OPTIONAL) \ |
| APP_DEBUGGABLE \ |
| APP_MANIFEST |
| |
| # ============================================================================= |
| # |
| # Android.mk support |
| # |
| # ============================================================================= |
| |
| # ============================================================================= |
| # |
| # Build commands support |
| # |
| # ============================================================================= |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : hide |
| # Returns : nothing |
| # Usage : $(hide)<make commands> |
| # Rationale: To be used as a prefix for Make build commands to hide them |
| # by default during the build. To show them, set V=1 in your |
| # environment or command-line. |
| # |
| # For example: |
| # |
| # foo.o: foo.c |
| # -->|$(hide) <build-commands> |
| # |
| # Where '-->|' stands for a single tab character. |
| # |
| # ----------------------------------------------------------------------------- |
| ifeq ($(V),1) |
| hide = $(empty) |
| else |
| hide = @ |
| endif |
| |
| # ----------------------------------------------------------------------------- |
| # Template : ev-compile-c-source |
| # Arguments : 1: single C source file name (relative to LOCAL_PATH) |
| # 2: target object file (without path) |
| # Returns : None |
| # Usage : $(eval $(call ev-compile-c-source,<srcfile>,<objfile>) |
| # Rationale : Internal template evaluated by compile-c-source and |
| # compile-s-source |
| # ----------------------------------------------------------------------------- |
| define ev-compile-c-source |
| _SRC:=$$(LOCAL_PATH)/$(1) |
| _OBJ:=$$(LOCAL_OBJS_DIR)/$(2) |
| |
| $$(_OBJ): PRIVATE_SRC := $$(_SRC) |
| $$(_OBJ): PRIVATE_OBJ := $$(_OBJ) |
| $$(_OBJ): PRIVATE_MODULE := $$(LOCAL_MODULE) |
| $$(_OBJ): PRIVATE_ARM_MODE := $$(LOCAL_ARM_MODE) |
| $$(_OBJ): PRIVATE_ARM_TEXT := $$(call get-src-file-text,$1) |
| $$(_OBJ): PRIVATE_CC := $$($$(my)CC) |
| $$(_OBJ): PRIVATE_CFLAGS := $$($$(my)CFLAGS) \ |
| $$(call get-src-file-target-cflags,$(1)) \ |
| $$(LOCAL_C_INCLUDES:%=-I%) \ |
| -I$$(LOCAL_PATH) \ |
| $$(LOCAL_CFLAGS) \ |
| $$(NDK_APP_CFLAGS) \ |
| $$($(my)C_INCLUDES:%=-I%) \ |
| |
| $$(_OBJ): $$(_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK) |
| @mkdir -p $$(dir $$(PRIVATE_OBJ)) |
| @echo "Compile $$(PRIVATE_ARM_TEXT) : $$(PRIVATE_MODULE) <= $$(PRIVATE_SRC)" |
| $(hide) $$(PRIVATE_CC) $$(PRIVATE_CFLAGS) -c \ |
| -MMD -MP -MF $$(PRIVATE_OBJ).d \ |
| $$(PRIVATE_SRC) \ |
| -o $$(PRIVATE_OBJ) |
| |
| LOCAL_OBJECTS += $$(_OBJ) |
| LOCAL_DEPENDENCY_DIRS += $$(dir $$(_OBJ)) |
| endef |
| |
| # ----------------------------------------------------------------------------- |
| # Function : compile-c-source |
| # Arguments : 1: single C source file name (relative to LOCAL_PATH) |
| # Returns : None |
| # Usage : $(call compile-c-source,<srcfile>) |
| # Rationale : Setup everything required to build a single C source file |
| # ----------------------------------------------------------------------------- |
| compile-c-source = $(eval $(call ev-compile-c-source,$1,$(1:%.c=%.o))) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : compile-s-source |
| # Arguments : 1: single Assembly source file name (relative to LOCAL_PATH) |
| # Returns : None |
| # Usage : $(call compile-s-source,<srcfile>) |
| # Rationale : Setup everything required to build a single Assembly source file |
| # ----------------------------------------------------------------------------- |
| compile-s-source = $(eval $(call ev-compile-c-source,$1,$(1:%.S=%.o))) |
| |
| |
| # ----------------------------------------------------------------------------- |
| # Template : ev-compile-cpp-source |
| # Arguments : 1: single C++ source file name (relative to LOCAL_PATH) |
| # 2: target object file (without path) |
| # Returns : None |
| # Usage : $(eval $(call ev-compile-cpp-source,<srcfile>,<objfile>) |
| # Rationale : Internal template evaluated by compile-cpp-source |
| # ----------------------------------------------------------------------------- |
| |
| define ev-compile-cpp-source |
| _SRC:=$$(LOCAL_PATH)/$(1) |
| _OBJ:=$$(LOCAL_OBJS_DIR)/$(2) |
| |
| $$(_OBJ): PRIVATE_SRC := $$(_SRC) |
| $$(_OBJ): PRIVATE_OBJ := $$(_OBJ) |
| $$(_OBJ): PRIVATE_MODULE := $$(LOCAL_MODULE) |
| $$(_OBJ): PRIVATE_ARM_MODE := $$(LOCAL_ARM_MODE) |
| $$(_OBJ): PRIVATE_ARM_TEXT := $$(call get-src-file-text,$1) |
| $$(_OBJ): PRIVATE_CXX := $$($$(my)CXX) |
| $$(_OBJ): PRIVATE_CXXFLAGS := $$($$(my)CXXFLAGS) \ |
| $$(call get-src-file-target-cflags,$(1)) \ |
| $$(LOCAL_C_INCLUDES:%=-I%) \ |
| -I$$(LOCAL_PATH) \ |
| $$(LOCAL_CFLAGS) \ |
| $$(LOCAL_CPPFLAGS) \ |
| $$(LOCAL_CXXFLAGS) \ |
| $$(NDK_APP_CFLAGS) \ |
| $$(NDK_APP_CPPFLAGS) \ |
| $$(NDK_APP_CXXFLAGS) \ |
| $$($(my)C_INCLUDES:%=-I%) \ |
| |
| $$(_OBJ): $$(_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK) |
| @mkdir -p $$(dir $$(PRIVATE_OBJ)) |
| @echo "Compile++ $$(PRIVATE_ARM_TEXT): $$(PRIVATE_MODULE) <= $$(PRIVATE_SRC)" |
| $(hide) $$(PRIVATE_CXX) $$(PRIVATE_CXXFLAGS) -c \ |
| -MMD -MP -MF $$(PRIVATE_OBJ).d \ |
| $$(PRIVATE_SRC) \ |
| -o $$(PRIVATE_OBJ) |
| |
| LOCAL_OBJECTS += $$(_OBJ) |
| LOCAL_DEPENDENCY_DIRS += $$(dir $$(_OBJ)) |
| endef |
| |
| # ----------------------------------------------------------------------------- |
| # Function : compile-cpp-source |
| # Arguments : 1: single C++ source file name (relative to LOCAL_PATH) |
| # Returns : None |
| # Usage : $(call compile-c-source,<srcfile>) |
| # Rationale : Setup everything required to build a single C++ source file |
| # ----------------------------------------------------------------------------- |
| compile-cpp-source = $(eval $(call ev-compile-cpp-source,$1,$(1:%$(LOCAL_CPP_EXTENSION)=%.o))) |
| |
| # ----------------------------------------------------------------------------- |
| # Command : cmd-install-file |
| # Arguments : 1: source file |
| # 2: destination file |
| # Returns : None |
| # Usage : $(call cmd-install-file,<srcfile>,<dstfile>) |
| # Rationale : To be used as a Make build command to copy/install a file to |
| # a given location. |
| # ----------------------------------------------------------------------------- |
| define cmd-install-file |
| @mkdir -p $(dir $2) |
| $(hide) cp -fp $1 $2 |
| endef |
| |
| |
| # |
| # Module imports |
| # |
| |
| # Initialize import list |
| import-init = $(eval __ndk_import_dirs :=) |
| |
| # Add an optional single directory to the list of import paths |
| # |
| import-add-path-optional = \ |
| $(if $(strip $(wildcard $1)),\ |
| $(call ndk_log,Adding import directory: $1)\ |
| $(eval __ndk_import_dirs += $1)\ |
| )\ |
| |
| # Add a directory to the list of import paths |
| # This will warn if the directory does not exist |
| # |
| import-add-path = \ |
| $(if $(strip $(wildcard $1)),\ |
| $(call ndk_log,Adding import directory: $1)\ |
| $(eval __ndk_import_dirs += $1)\ |
| ,\ |
| $(call __ndk_info,WARNING: Ignoring unknown import directory: $1)\ |
| )\ |
| |
| import-find-module = $(strip \ |
| $(eval __imported_module :=)\ |
| $(foreach __import_dir,$(__ndk_import_dirs),\ |
| $(if $(__imported_module),,\ |
| $(call ndk_log, Probing $(__import_dir)/$1/Android.mk)\ |
| $(if $(strip $(wildcard $(__import_dir)/$1/Android.mk)),\ |
| $(eval __imported_module := $(__import_dir)/$1)\ |
| )\ |
| )\ |
| )\ |
| $(__imported_module)\ |
| ) |
| |
| # described in docs/IMPORT-MODULE.TXT |
| # $1: tag name for the lookup |
| # |
| import-module = \ |
| $(call ndk_log,Looking for imported module with tag '$1')\ |
| $(eval __imported_path := $(call import-find-module,$1))\ |
| $(if $(__imported_path),\ |
| $(eval include $(__imported_path)/Android.mk)\ |
| ,\ |
| $(call __ndk_info,$(call local-makefile): Cannot find module with tag '$1' in import path)\ |
| $(call __ndk_info,Are you sure your NDK_MODULE_PATH variable is properly defined ?)\ |
| $(call __ndk_error,Aborting.)\ |
| ) |
| |
| # Only used for debugging |
| # |
| import-debug = \ |
| $(info IMPORT DIRECTORIES:)\ |
| $(foreach __dir,$(__ndk_import_dirs),\ |
| $(info -- $(__dir))\ |
| )\ |