| # 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. |
| # |
| # Module database functions. |
| # |
| |
| # The list of default C++ extensions supported by GCC. |
| default-c++-extensions := .cc .cp .cxx .cpp .CPP .c++ .C |
| |
| # ============================================================================= |
| # |
| # Modules database |
| # |
| # The following declarations are used to manage the list of modules |
| # defined in application's Android.mk files. |
| # |
| # Technical note: |
| # We use __build_modules to hold the list of all modules corresponding |
| # to a given application. |
| # |
| # For each module 'foo', __build_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 := \ |
| ALLOW_UNDEFINED_SYMBOLS \ |
| ASMFLAGS \ |
| BUILT_MODULE_NOT_COPIED \ |
| CFLAGS \ |
| CONLYFLAGS \ |
| CPPFLAGS \ |
| CPP_EXTENSION \ |
| CPP_FEATURES \ |
| CXXFLAGS \ |
| C_INCLUDES \ |
| DISABLE_FORMAT_STRING_CHECKS \ |
| DISABLE_NO_EXECUTE \ |
| DISABLE_RELRO \ |
| EXPORT_ASMFLAGS \ |
| EXPORT_CFLAGS \ |
| EXPORT_CONLYFLAGS \ |
| EXPORT_CPPFLAGS \ |
| EXPORT_C_INCLUDES \ |
| EXPORT_LDFLAGS \ |
| EXPORT_LDLIBS \ |
| FILTER_ASM \ |
| LDFLAGS \ |
| LDLIBS \ |
| MODULE \ |
| MODULE_FILENAME \ |
| PATH \ |
| PCH \ |
| SHARED_LIBRARIES \ |
| SHORT_COMMANDS \ |
| SRC_FILES \ |
| STATIC_LIBRARIES \ |
| THIN_ARCHIVE \ |
| WHOLE_STATIC_LIBRARIES \ |
| |
| # The following are generated by the build scripts themselves |
| |
| # LOCAL_MAKEFILE will contain the path to the Android.mk defining the module |
| modules-LOCALS += MAKEFILE |
| |
| # LOCAL_LDFLAGS will contain the set of final linker flags for the module |
| modules-LOCALS += LDFLAGS |
| |
| # LOCAL_OBJECTS will contain the list of object files generated from the |
| # module's sources, if any. |
| modules-LOCALS += OBJECTS |
| |
| # LOCAL_BUILT_MODULE will contain the location of the symbolic version of |
| # the generated module (i.e. the one containing all symbols used during |
| # native debugging). It is generally under $PROJECT/obj/local/ |
| modules-LOCALS += BUILT_MODULE |
| |
| # LOCAL_OBJS_DIR will contain the location where the object files for |
| # this module will be stored. Usually $PROJECT/obj/local/<module>/obj |
| modules-LOCALS += OBJS_DIR |
| |
| # LOCAL_INSTALLED will contain the location of the installed version |
| # of the module. Usually $PROJECT/libs/<abi>/<prefix><module><suffix> |
| # where <prefix> and <suffix> depend on the module class. |
| modules-LOCALS += INSTALLED |
| |
| # LOCAL_MODULE_CLASS will contain the type of the module |
| # (e.g. STATIC_LIBRARY, SHARED_LIBRARY, etc...) |
| modules-LOCALS += MODULE_CLASS |
| |
| # the list of managed fields per module |
| modules-fields = 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,$(__build_modules),\ |
| $(foreach __field,$(modules-fields),\ |
| $(eval __build_modules.$(__mod).$(__field) := $(empty))\ |
| )\ |
| )\ |
| $(eval __build_modules := $(empty_set)) \ |
| $(eval __build_top_modules := $(empty)) \ |
| $(eval __build_import_list := $(empty)) \ |
| $(eval __build_import_depth := $(empty)) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : modules-clear-local-vars |
| # Arguments: None |
| # Returns : None |
| # Usage : $(call modules-clear-localvars) |
| # Rationale: clears all module-specific LOCAL_XXX variables, with the exception |
| # of LOCAL_PATH. Typically used to implement $(CLEAR_VARS) |
| # ----------------------------------------------------------------------------- |
| modules-clear-local-vars = \ |
| $(call clear-vars, $(filter-out LOCAL_PATH,$(modules-LOCALS:%=LOCAL_%)))\ |
| $(eval LOCAL_PATH := $$(strip $$(LOCAL_PATH))) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : modules-get-list |
| # Arguments: None |
| # Returns : The list of all recorded modules |
| # Usage : $(call modules-get-list) |
| # ----------------------------------------------------------------------------- |
| modules-get-list = $(__build_modules) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : modules-get-top-list |
| # Arguments: None |
| # Returns : The list of all recorded non-imported modules |
| # Usage : $(call modules-get-top-list) |
| # ----------------------------------------------------------------------------- |
| modules-get-top-list = $(__build_top_modules) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : module-add |
| # Arguments: 1: module name |
| # Returns : None |
| # Usage : $(call module-add,<modulename>) |
| # 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 LOCAL_MODULE_CLASS)\ |
| $(if $(call set_is_member,$(__build_modules),$1),\ |
| $(call -build-info,Trying to define local module '$1' in $(LOCAL_MAKEFILE).)\ |
| $(call -build-info,But this module was already defined by $(__build_modules.$1.MAKEFILE).)\ |
| $(call -build-error,Aborting.)\ |
| )\ |
| $(eval __build_modules := $(call set_insert,$(__build_modules),$1))\ |
| $(if $(strip $(__build_import_depth)),,\ |
| $(eval __build_top_modules := $(call set_insert,$(__build_top_modules),$1))\ |
| )\ |
| $(if $(call module-class-is-installable,$(LOCAL_MODULE_CLASS)),\ |
| $(eval LOCAL_INSTALLED := $(BUILD_INSTALL_DIR)/$(notdir $(LOCAL_BUILT_MODULE))),\ |
| $(eval LOCAL_INSTALLED := $(LOCAL_BUILT_MODULE))\ |
| )\ |
| $(foreach __field,STATIC_LIBRARIES WHOLE_STATIC_LIBRARIES SHARED_LIBRARIES,\ |
| $(eval LOCAL_$(__field) := $(call strip-lib-prefix,$(LOCAL_$(__field)))))\ |
| $(foreach __local,$(modules-LOCALS),\ |
| $(eval __build_modules.$1.$(__local) := $(LOCAL_$(__local)))\ |
| )\ |
| $(call module-handle-c++-features,$1) |
| |
| |
| # Retrieve the class of module $1 |
| module-get-class = $(__build_modules.$1.MODULE_CLASS) |
| |
| # Retrieve built location of module $1 |
| module-get-built = $(__build_modules.$1.BUILT_MODULE) |
| |
| # Returns $(true) is module $1 is installable |
| # An installable module is one that will be copied to $PROJECT/libs/<abi>/ |
| # (e.g. shared libraries). |
| # |
| module-is-installable = $(call module-class-is-installable,$(call module-get-class,$1)) |
| |
| # ----------------------------------------------------------------------------- |
| # 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 = $(__build_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) := $(__build_modules.$1.$(__local)))\ |
| ) |
| |
| # Dump all module information. Only use this for debugging |
| modules-dump-database = \ |
| $(info Modules [$(TARGET_ARCH_ABI)]: $(__build_modules)) \ |
| $(foreach __mod,$(__build_modules),\ |
| $(info $(space4)$(__mod):)\ |
| $(foreach __field,$(modules-fields),\ |
| $(eval __fieldval := $(strip $(__build_modules.$(__mod).$(__field))))\ |
| $(if $(__fieldval),\ |
| $(if $(filter 1,$(words $(__fieldval))),\ |
| $(info $(space4)$(space4)$(__field): $(__fieldval)),\ |
| $(info $(space4)$(space4)$(__field): )\ |
| $(foreach __fielditem,$(__fieldval),\ |
| $(info $(space4)$(space4)$(space4)$(__fielditem))\ |
| )\ |
| )\ |
| )\ |
| )\ |
| )\ |
| $(info Top modules: $(__build_top_modules))\ |
| $(info --- end of modules 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) \ |
| |
| # 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 __build_modules.$1.$3 += $(filter-out $(__build_modules.$1.$3),$2)) |
| |
| |
| # ----------------------------------------------------------------------------- |
| # Returns non-empty if a module is a static library |
| # Arguments: 1: module name |
| # Returns : non-empty iff the module is a static library. |
| # Usage : $(if $(call module-is-static-library,<name>),...) |
| # ----------------------------------------------------------------------------- |
| module-is-static-library = $(strip \ |
| $(filter STATIC_LIBRARY PREBUILT_STATIC_LIBRARY,\ |
| $(call module-get-class,$1))) |
| |
| # ----------------------------------------------------------------------------- |
| # Returns non-empty if a module is a shared library |
| # Arguments: 1: module name |
| # Returns : non-empty iff the module is a shared library. |
| # Usage : $(if $(call module-is-shared-library,<name>),...) |
| # ----------------------------------------------------------------------------- |
| module-is-shared-library = $(strip \ |
| $(filter SHARED_LIBRARY PREBUILT_SHARED_LIBRARY,\ |
| $(call module-get-class,$1))) |
| |
| # ----------------------------------------------------------------------------- |
| # Filter a list of module names to retain only the static libraries. |
| # Arguments: 1: module name list |
| # Returns : input list modules which are static libraries. |
| # ----------------------------------------------------------------------------- |
| module-filter-static-libraries = $(call filter-by,$1,module-is-static-library) |
| |
| # ----------------------------------------------------------------------------- |
| # Filter a list of module names to retain only the shared libraries. |
| # Arguments: 1: module name list |
| # Returns : input list modules which are shared libraries. |
| # ----------------------------------------------------------------------------- |
| module-filter-shared-libraries = $(call filter-by,$1,module-is-shared-library) |
| |
| # ----------------------------------------------------------------------------- |
| # Return the LOCAL_STATIC_LIBRARIES for a given module. |
| # Arguments: 1: module name |
| # Returns : List of static library modules. |
| # ----------------------------------------------------------------------------- |
| module-get-static-libs = $(__build_modules.$1.STATIC_LIBRARIES) |
| |
| # ----------------------------------------------------------------------------- |
| # Return the LOCAL_WHOLE_STATIC_LIBRARIES for a given module. |
| # Arguments: 1: module name |
| # Returns : List of whole static library modules. |
| # ----------------------------------------------------------------------------- |
| module-get-whole-static-libs = $(__build_modules.$1.WHOLE_STATIC_LIBRARIES) |
| |
| # ----------------------------------------------------------------------------- |
| # Return all static libraries for a given module. |
| # Arguments: 1: module name |
| # Returns : List of static library modules (whole or not). |
| # ----------------------------------------------------------------------------- |
| module-get-all-static-libs = $(strip \ |
| $(__build_modules.$1.STATIC_LIBRARIES) \ |
| $(__build_modules.$1.WHOLE_STATIC_LIBRARIES)) |
| |
| # ----------------------------------------------------------------------------- |
| # Return the list of LOCAL_SHARED_LIBRARIES for a given module. |
| # Arguments: 1: module name |
| # Returns : List of shared library modules. |
| # ----------------------------------------------------------------------------- |
| module-get-shared-libs = $(__build_modules.$1.SHARED_LIBRARIES) |
| |
| # ----------------------------------------------------------------------------- |
| # Return the list of all libraries a modules depends directly on. |
| # This is the concatenation of its LOCAL_STATIC_LIBRARIES, |
| # LOCAL_WHOLE_STATIC_LIBRARIES, and LOCAL_SHARED_LIBRARIES variables. |
| # Arguments: 1: module name |
| # Returns : List of library modules (static or shared). |
| # ----------------------------------------------------------------------------- |
| module-get-direct-libs = $(strip \ |
| $(__build_modules.$1.STATIC_LIBRARIES) \ |
| $(__build_modules.$1.WHOLE_STATIC_LIBRARIES) \ |
| $(__build_modules.$1.SHARED_LIBRARIES)) |
| |
| |
| # ----------------------------------------------------------------------------- |
| # Computes the full closure of a module and its dependencies. Order is |
| # defined by a breadth-first walk of the graph. |
| # $1 will be the first item in the result. |
| # |
| # Arguments: 1: module name |
| # Returns : List of all modules $1 depends on. |
| # |
| # Note: Do not use this to determine build dependencies. The returned list |
| # is much too large for this. For example consider the following |
| # dependency graph: |
| # |
| # main.exe -> libA.a -> libfoo.so -> libB.a |
| # |
| # This function will return all four modules in the result, while |
| # at link time building main.exe only requires the first three. |
| # |
| # ----------------------------------------------------------------------------- |
| module-get-all-dependencies = $(call -build-mod-get-closure,$1,module-get-depends) |
| |
| # ----------------------------------------------------------------------------- |
| # Compute the list of all static and shared libraries required to link a |
| # given module. |
| # |
| # Note that the result is topologically ordered, i.e. if library A depends |
| # on library B, then A will always appear after B in the result. |
| # |
| # Arguments: 1: module name |
| # Returns : List of all library $1 depends at link time. |
| # |
| # Note: This doesn't differentiate between regular and whole static |
| # libraries. Use module-extract-whole-static-libs to filter the |
| # result returned by this function. |
| # ----------------------------------------------------------------------------- |
| module-get-link-libs = $(strip \ |
| $(eval _build_mod_link_module := $1) \ |
| $(call -build-mod-get-topological-depends,$1,-build-mod-link-deps)) |
| |
| # Special dependency function used by module-get-link-libs. |
| # The rules to follow are the following: |
| # - if $1 is the link module, or if it is a static library, then all |
| # direct dependencies. |
| # - otherwise, the module is a shared library, don't add build deps. |
| -build-mod-link-deps = \ |
| $(if $(call seq,$1,$(_build_mod_link_module))$(call module-is-static-library,$1),\ |
| $(call module-get-direct-libs,$1)) |
| |
| # ----------------------------------------------------------------------------- |
| # This function is used to extract the list of static libraries that need |
| # to be linked as whole, i.e. placed in a special section on the final |
| # link command. |
| # Arguments: $1: module name. |
| # $2: list of all static link-time libraries (regular or whole). |
| # Returns : list of static libraries from '$2' that need to be linked |
| # as whole. |
| # ----------------------------------------------------------------------------- |
| module-extract-whole-static-libs = $(strip \ |
| $(eval _build_mod_whole_all := $(call map,module-get-whole-static-libs,$1 $2))\ |
| $(eval _build_mod_whole_result := $(filter $(_build_mod_whole_all),$2))\ |
| $(_build_mod_whole_result)) |
| |
| # Used to recompute all dependencies once all module information has been recorded. |
| # |
| modules-compute-dependencies = \ |
| $(foreach __module,$(__build_modules),\ |
| $(call module-compute-depends,$(__module))\ |
| ) |
| |
| module-compute-depends = \ |
| $(call module-add-static-depends,$1,$(__build_modules.$1.STATIC_LIBRARIES))\ |
| $(call module-add-static-depends,$1,$(__build_modules.$1.WHOLE_STATIC_LIBRARIES))\ |
| $(call module-add-shared-depends,$1,$(__build_modules.$1.SHARED_LIBRARIES))\ |
| |
| module-get-installed = $(__build_modules.$1.INSTALLED) |
| |
| module-get-depends = $(__build_modules.$1.depends) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : modules-get-all-installable |
| # Arguments: 1: list of module names |
| # Returns : List of all the installable modules $1 depends on transitively. |
| # Usage : $(call modules-all-get-installable,<list of module names>) |
| # Rationale: This computes the closure of all installable module dependencies starting from $1 |
| # ----------------------------------------------------------------------------- |
| # For now, only the closure of LOCAL_SHARED_LIBRARIES is enough |
| modules-get-all-installable = $(strip \ |
| $(foreach __alldep,$(call module-get-all-dependencies,$1),\ |
| $(if $(call module-is-installable,$(__alldep)),$(__alldep))\ |
| )) |
| |
| # Return the C++ extension(s) of a given module |
| # $1: module name |
| module-get-c++-extensions = $(strip \ |
| $(if $(__build_modules.$1.CPP_EXTENSION),\ |
| $(__build_modules.$1.CPP_EXTENSION),\ |
| $(default-c++-extensions)\ |
| )) |
| |
| # Return the list of C++ sources of a given module |
| # |
| module-get-c++-sources = \ |
| $(eval __files := $(__build_modules.$1.SRC_FILES:%.neon=%)) \ |
| $(eval __files := $(__files:%.arm=%)) \ |
| $(eval __extensions := $(call module-get-c++-extensions,$1))\ |
| $(filter $(foreach __extension,$(__extensions),%$(__extension)),$(__files)) |
| |
| # Returns true if a module has C++ sources |
| # |
| module-has-c++-sources = $(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,$(__build_modules),\ |
| $(if $(call module-has-c++-sources,$(__module)),\ |
| $(call -build-log,Module '$(__module)' has C++ sources)\ |
| $(call module-add-c++-deps,$(__module),$1,$2),\ |
| )\ |
| ) |
| |
| |
| # Return the compiler flags used to compile a C++ module |
| # Order matters and should match the one used by the build command |
| module-get-c++-flags = $(strip \ |
| $(__build_modules.$1.CFLAGS) \ |
| $(__build_modules.$1.CPPFLAGS) \ |
| $(__build_modules.$1.CXXFLAGS)) |
| |
| # This function is used to remove certain flags from a module compiler flags |
| # $1: Module name |
| # $2: List of flags to remove |
| # |
| module-filter-out-compiler-flags = \ |
| $(eval __build_modules.$1.CFLAGS := $(filter-out $2,$(__build_modules.$1.CFLAGS)))\ |
| $(eval __build_modules.$1.CONLYFLAGS := $(filter-out $2,$(__build_modules.$1.CONLYFLAGS)))\ |
| $(eval __build_modules.$1.CPPFLAGS := $(filter-out $2,$(__build_modules.$1.CPPFLAGS)))\ |
| $(eval __build_modules.$1.CXXFLAGS := $(filter-out $2,$(__build_modules.$1.CXXFLAGS)))\ |
| $(eval __build_modules.$1.ASMFLAGS := $(filter-out $2,$(__build_modules.$1.ASMFLAGS))) |
| |
| # Return true if a module's compiler flags enable rtti |
| # We just look at -frtti and -fno-rtti on the command-line |
| # and keep the last one of these flags. |
| module-flags-have-rtti = $(strip \ |
| $(filter -frtti,\ |
| $(lastword $(filter -frtti -fno-rtti,$(call module-get-c++-flags,$1)))\ |
| )\ |
| ) |
| |
| # Same with C++ exception support (i.e. -fexceptions and -fno-exceptions) |
| # |
| module-flags-have-exceptions = $(strip \ |
| $(filter -fexceptions,\ |
| $(lastword $(filter -fexceptions -fno-execeptions,$(call module-get-c++-flags,$1)))\ |
| )\ |
| ) |
| |
| # Handle the definition of LOCAL_CPP_FEATURES, i.e.: |
| # |
| # - If it is defined, check that it only contains valid values |
| # - If it is undefined, try to compute its value automatically by |
| # looking at the C++ compiler flags used to build the module |
| # |
| # After this, we remove all features flags from the module's command-line |
| # And add only the correct ones back in LOCAL_CPP_FLAGS |
| # |
| module-handle-c++-features = \ |
| $(if $(strip $(__build_modules.$1.CPP_FEATURES)),\ |
| $(eval __cxxbad := $(filter-out rtti exceptions,$(__build_modules.$1.CPP_FEATURES)))\ |
| $(if $(__cxxbad),\ |
| $(call -build-info,WARNING: Ignoring invalid values in LOCAL_CPP_FEATURES definition in $(__build_modules.$1.MAKEFILE): $(__cxxbad))\ |
| $(eval __build_modules.$1.CPP_FEATURES := $(strip $(filter-out $(__cxxbad),$(__build_modules.$1.CPP_FEATURES))))\ |
| )\ |
| ,\ |
| $(eval __build_modules.$1.CPP_FEATURES := $(strip \ |
| $(if $(call module-flags-have-rtti,$1),rtti) \ |
| $(if $(call module-flags-have-exceptions,$1),exceptions) \ |
| )) \ |
| )\ |
| $(call module-filter-out-compiler-flags,$1,-frtti -fno-rtti -fexceptions -fno-exceptions)\ |
| |
| # Returns true if a module or its dependencies have specific C++ features |
| # (i.e. RTTI or Exceptions) |
| # |
| # $1: module name |
| # $2: list of features (e.g. 'rtti' or 'exceptions') |
| # |
| module-has-c++-features = $(strip \ |
| $(eval __cxxdeps := $(call module-get-all-dependencies,$1))\ |
| $(eval __cxxflags := $(foreach __cxxdep,$(__cxxdeps),$(__build_modules.$(__cxxdep).CPP_FEATURES)))\ |
| $(if $(filter $2,$(__cxxflags)),true,)\ |
| ) |
| |
| # 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 = \ |
| $(if $(call strip,$2),$(call -build-log,Add dependency '$(call strip,$2)' to module '$1'))\ |
| $(eval __build_modules.$1.STATIC_LIBRARIES += $(2))\ |
| $(if $(call strip,$3),$(call -build-log,Add dependency '$(call strip,$3)' to module '$1'))\ |
| $(eval __build_modules.$1.SHARED_LIBRARIES += $(3)) |
| |
| # ----------------------------------------------------------------------------- |
| # 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 -build-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 -build-info,LOCAL_MODULE definition in $(LOCAL_MAKEFILE) must not contain space)\ |
| $(call -build-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 -build-info,$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain spaces)\ |
| $(call -build-error,Plase correct error. Aborting)\ |
| )\ |
| $(if $(filter %$(TARGET_LIB_EXTENSION) %$(TARGET_SONAME_EXTENSION),$(LOCAL_MODULE_FILENAME)),\ |
| $(call -build-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)) |
| |
| # |
| # Check that LOCAL_MODULE_FILENAME is properly defined |
| # - with one single item |
| # - without a library file extension |
| # - with no directory separators |
| # |
| define ev-check-module-filename |
| ifneq (1,$$(words $$(LOCAL_MODULE_FILENAME))) |
| $$(call -build-info,$$(LOCAL_MAKEFILE):$$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain any space) |
| $$(call -build-error,Aborting) |
| endif |
| ifneq (,$$(filter %$$(TARGET_LIB_EXTENSION) %$$(TARGET_SONAME_EXTENSION),$$(LOCAL_MODULE_FILENAME))) |
| $$(call -build-info,$$(LOCAL_MAKEFILE):$$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain a file extension) |
| $$(call -build-error,Aborting) |
| endif |
| ifneq (1,$$(words $$(subst /, ,$$(LOCAL_MODULE_FILENAME)))) |
| $$(call -build-info,$$(LOCAL_MAKEFILE):$$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain directory separators) |
| $$(call -build-error,Aborting) |
| endif |
| endef |
| |
| # |
| # Check the definition of LOCAL_MODULE_FILENAME. If none exists, |
| # infer it from the LOCAL_MODULE name. |
| # |
| # $1: default file prefix |
| # $2: default file suffix |
| # |
| define ev-handle-module-filename |
| LOCAL_MODULE_FILENAME := $$(strip $$(LOCAL_MODULE_FILENAME)) |
| ifndef LOCAL_MODULE_FILENAME |
| LOCAL_MODULE_FILENAME := $1$$(LOCAL_MODULE) |
| endif |
| $$(eval $$(call ev-check-module-filename)) |
| LOCAL_MODULE_FILENAME := $$(LOCAL_MODULE_FILENAME)$2 |
| endef |
| |
| handle-prebuilt-module-filename = $(eval $(call ev-handle-prebuilt-module-filename,$1)) |
| |
| # |
| # Check the definition of LOCAL_MODULE_FILENAME for a _prebuilt_ module. |
| # If none exists, infer it from $(LOCAL_SRC_FILES) |
| # |
| # $1: default file suffix |
| # |
| define ev-handle-prebuilt-module-filename |
| LOCAL_MODULE_FILENAME := $$(strip $$(LOCAL_MODULE_FILENAME)) |
| ifndef LOCAL_MODULE_FILENAME |
| LOCAL_MODULE_FILENAME := $$(notdir $(LOCAL_SRC_FILES)) |
| LOCAL_MODULE_FILENAME := $$(LOCAL_MODULE_FILENAME:%$$(TARGET_LIB_EXTENSION)=%) |
| LOCAL_MODULE_FILENAME := $$(LOCAL_MODULE_FILENAME:%$$(TARGET_SONAME_EXTENSION)=%) |
| endif |
| LOCAL_MODULE_FILENAME := $$(LOCAL_MODULE_FILENAME)$1 |
| $$(eval $$(call ev-check-module-filename)) |
| 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)) |
| |
| # ----------------------------------------------------------------------------- |
| # Compute the real path of a prebuilt file. |
| # |
| # Function : local-prebuilt-path |
| # Arguments: 1: prebuilt path (as listed in $(LOCAL_SRC_FILES)) |
| # Returns : full path. If $1 begins with a /, the path is considered |
| # absolute and returned as-is. Otherwise, $(LOCAL_PATH)/$1 is |
| # returned instead. |
| # Usage : $(call local-prebuilt-path,$(LOCAL_SRC_FILES)) |
| # ----------------------------------------------------------------------------- |
| local-prebuilt-path = $(call local-source-file-path,$1) |
| |
| # ----------------------------------------------------------------------------- |
| # 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))) |
| |
| # |
| # Module imports |
| # |
| |
| # List of module import directories. |
| __build_import_dirs := |
| |
| # Add an optional single directory to the list of import paths |
| # |
| import-add-path-optional = \ |
| $(if $(strip $(wildcard $1)),\ |
| $(call -build-log,Adding import directory: $1)\ |
| $(eval __build_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 -build-log,Adding import directory: $1)\ |
| $(eval __build_import_dirs += $1)\ |
| ,\ |
| $(call -build-info,WARNING: Ignoring unknown import directory: $1)\ |
| )\ |
| |
| import-find-module = $(strip \ |
| $(eval __imported_module :=)\ |
| $(foreach __import_dir,$(__build_import_dirs),\ |
| $(if $(__imported_module),,\ |
| $(call -build-log, Probing $(__import_dir)/$1/Android.mk)\ |
| $(if $(strip $(wildcard $(__import_dir)/$1/Android.mk)),\ |
| $(eval __imported_module := $(__import_dir)/$1)\ |
| )\ |
| )\ |
| )\ |
| $(__imported_module)\ |
| ) |
| |
| BUILD_MODULE_PATH_VARNAME := $(strip $(BUILD_MODULE_PATH_VARNAME)) |
| ifndef BUILD_MODULE_PATH_VARNAME |
| BUILD_MODULE_PATH_VARNAME := BUILD_MODULE_PATH |
| endif |
| |
| BUILD_MODULE_PATH := $(strip $($(BUILD_MODULE_PATH_VARNAME))) |
| ifdef BUILD_MODULE_PATH |
| ifneq ($(words $(BUILD_MODULE_PATH)),1) |
| $(call -build-info,ERROR: You $(BUILD_MODULE_PATH_VARNAME) variable contains spaces) |
| $(call -build-info,Please fix the error and start again.) |
| $(call -build-error,Aborting) |
| endif |
| endif |
| |
| modules-reset-imports = \ |
| $(eval __build_import_dirs :=)\ |
| $(foreach __import_path,$(subst $(BUILD_HOST_DIRSEP),$(space),$(BUILD_MODULE_PATH)),\ |
| $(call import-add-path,$(__import_path))\ |
| ) |
| |
| # described in docs/IMPORT-MODULE.TXT |
| # $1: tag name for the lookup |
| # |
| # Small technical note on __build_import_depth: we use this variable to |
| # record the depth of recursive import-module calls. The variable is |
| # initially empty, and we append a "x" to it each time import-module is |
| # called. I.e. for three recursive calls to import-module, we would get |
| # the values: |
| # |
| # first call: x |
| # second call: xx |
| # third call: xxx |
| # |
| # This is used in module-add to add the top-level modules (i.e. those |
| # that are not added with import-module) to __build_top_modules, corresponding |
| # to the default list of wanted modules (see setup-toolchain.mk). |
| # |
| import-module = \ |
| $(eval __import_tag := $(strip $1))\ |
| $(if $(call seq,$(words $(__import_tag)),1),,\ |
| $(call -build-info,$(LOCAL_MAKEFILE): Cannot import module with spaces in tag: '$(__import_tag)')\ |
| )\ |
| $(if $(call set_is_member,$(__build_import_list),$(__import_tag)),\ |
| $(call -build-log,Skipping duplicate import for module with tag '$(__import_tag)')\ |
| ,\ |
| $(call -build-log,Looking for imported module with tag '$(__import_tag)')\ |
| $(eval __imported_path := $(call import-find-module,$(__import_tag)))\ |
| $(if $(__imported_path),\ |
| $(call -build-log, Found in $(__imported_path))\ |
| $(eval __build_import_depth := $(__build_import_depth)x) \ |
| $(eval __build_import_list := $(call set_insert,$(__build_import_list),$(__import_tag)))\ |
| $(eval include $(__imported_path)/Android.mk)\ |
| $(eval __build_import_depth := $(__build_import_depth:%x=%))\ |
| ,\ |
| $(call -build-info,$(LOCAL_MAKEFILE): Cannot find module with tag '$(__import_tag)' in import path)\ |
| $(call -build-info,Are you sure your $(BUILD_MODULE_PATH_VARNAME) variable is properly defined ?)\ |
| $(call -build-info,The following directories were searched:)\ |
| $(for __import_dir,$(__build_import_dirs),\ |
| $(call -build-info, $(__import_dir))\ |
| )\ |
| $(call -build-error,Aborting.)\ |
| )\ |
| ) |
| |
| # Only used for debugging |
| # |
| import-debug = \ |
| $(info IMPORT DIRECTORIES:)\ |
| $(foreach __dir,$(__build_import_dirs),\ |
| $(info -- $(__dir))\ |
| )\ |
| |
| # |
| # Module classes |
| # |
| _build_module_classes := |
| |
| # Register a new module class |
| # $1: class name (e.g. STATIC_LIBRARY) |
| # $2: optional file prefix (e.g. 'lib') |
| # $3: optional file suffix (e.g. '.so') |
| # |
| module-class-register = \ |
| $(eval _build_module_classes += $1) \ |
| $(eval _build_module_class.$1.FILE_PREFIX := $2) \ |
| $(eval _build_module_class.$1.FILE_SUFFIX := $3) \ |
| $(eval _build_module_class.$1.INSTALLABLE := $(false)) \ |
| |
| # Same a module-class-register, for installable modules |
| # |
| # An installable module is one that will be copied to $PROJECT/libs/<abi>/ |
| # during the build. |
| # |
| # $1: class name |
| # $2: optional file prefix |
| # $3: optional file suffix |
| # |
| module-class-register-installable = \ |
| $(call module-class-register,$1,$2,$3) \ |
| $(eval _build_module_class.$1.INSTALLABLE := $(true)) |
| |
| # Returns $(true) if $1 is a valid/registered LOCAL_MODULE_CLASS value |
| # |
| module-class-check = $(call set_is_member,$(_build_module_classes),$1) |
| |
| # Returns $(true) if $1 corresponds to an installable module class |
| # |
| module-class-is-installable = $(if $(_build_module_class.$1.INSTALLABLE),$(true),$(false)) |
| |
| # |
| # Register valid module classes |
| # |
| |
| # static libraries: |
| # <foo> -> lib<foo>.a by default |
| $(call module-class-register,STATIC_LIBRARY,lib,$(TARGET_LIB_EXTENSION)) |
| |
| # shared libraries: |
| # <foo> -> lib<foo>.so |
| # a shared library is installable. |
| $(call module-class-register-installable,SHARED_LIBRARY,lib,$(TARGET_SONAME_EXTENSION)) |
| |
| # executable |
| # <foo> -> <foo> |
| # an executable is installable. |
| $(call module-class-register-installable,EXECUTABLE,,) |
| |
| # prebuilt shared library |
| # <foo> -> <foo> (we assume it is already well-named) |
| # it is installable |
| $(call module-class-register-installable,PREBUILT_SHARED_LIBRARY,,) |
| |
| # prebuilt static library |
| # <foo> -> <foo> (we assume it is already well-named) |
| $(call module-class-register,PREBUILT_STATIC_LIBRARY,,) |