| # 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 build/gmsl/gmsl |
| |
| # This is the Android NDK version number as a list of three items: |
| # major, minor, revision |
| # |
| ndk_version := 1 0 0 |
| |
| # Used to output warnings and error from the library, it's possible to |
| # disable any warnings or errors by overriding these definitions |
| # manually or by setting GMSL_NO_WARNINGS or GMSL_NO_ERRORS |
| |
| __ndk_name := Android NDK |
| __ndk_info = $(info $(__ndk_name): $1 $2 $3 $4 $5) |
| __ndk_warning = $(warning $(__ndk_name): $1 $2 $3 $4 $5) |
| __ndk_error = $(error $(__ndk_name): $1 $2 $3 $4 $5) |
| |
| ifdef NDK_NO_WARNINGS |
| __ndk_warning := |
| endif |
| ifdef NDK_NO_ERRORS |
| __ndk_error := |
| endif |
| |
| # 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 |
| |
| # ----------------------------------------------------------------------------- |
| # Function : ndk_log |
| # Arguments: 1: text to print when NDK_LOG is defined |
| # Returns : None |
| # Usage : $(call ndk_log,<some text>) |
| # ----------------------------------------------------------------------------- |
| ifdef NDK_LOG |
| ndk_log = $(info $(__ndk_name): $1) |
| else |
| ndk_log := |
| 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)\ |
| )\ |
| ) |
| |
| # ----------------------------------------------------------------------------- |
| # 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 = $(eval __ndk_modules := $(empty_set)) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : modules-add |
| # Arguments: 1: module name |
| # 2: path to Android.mk where the module is defined |
| # 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. |
| # ----------------------------------------------------------------------------- |
| modules-add = \ |
| $(if $(call set_is_member,$(__ndk_modules),$1),\ |
| $(call __ndk_info,Trying to define local module '$1' in $2.)\ |
| $(call __ndk_info,But this module was already defined by $(__ndk_modules.$1).)\ |
| $(call __ndk_error,Aborting.)\ |
| )\ |
| $(eval __ndk_modules := $(call set_insert,$(__ndk_modules),$1))\ |
| $(eval __ndk_modules.$1 := $2)\ |
| |
| # ----------------------------------------------------------------------------- |
| # 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)\ |
| ) |
| |
| # ----------------------------------------------------------------------------- |
| # 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)))\ |
| $(call modules-add,$(LOCAL_MODULE),$1) |
| |
| # ----------------------------------------------------------------------------- |
| # Macro : my-dir |
| # Returns : the directory of the current Makefile |
| # Usage : $(my-dir) |
| # ----------------------------------------------------------------------------- |
| my-dir = $(patsubst %/,%,$(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)) |
| |
| |
| # ============================================================================= |
| # |
| # Application.mk support |
| # |
| # ============================================================================= |
| |
| # the list of variables that *must* be defined in Application.mk files |
| NDK_APP_VARS_REQUIRED := APP_MODULES APP_PROJECT_PATH |
| |
| # the list of variables that *may* be defined in Application.mk files |
| NDK_APP_VARS_OPTIONAL := APP_OPTIM APP_CPPFLAGS APP_CFLAGS APP_CXXFLAGS |
| |
| # the list of all variables that may appear in an Application.mk file |
| NDK_APP_VARS := $(NDK_APP_VARS_REQUIRED) $(NDK_APPS_VARS_OPTIONAL) |
| |
| # ============================================================================= |
| # |
| # Android.mk support |
| # |
| # ============================================================================= |
| |
| |
| # ============================================================================= |
| # |
| # Generated files support |
| # |
| # ============================================================================= |
| |
| |
| # ----------------------------------------------------------------------------- |
| # Function : host-static-library-path |
| # Arguments : 1: library module name (e.g. 'foo') |
| # Returns : location of generated host library name (e.g. '..../libfoo.a) |
| # Usage : $(call host-static-library-path,<modulename>) |
| # ----------------------------------------------------------------------------- |
| host-static-library-path = $(HOST_OUT)/lib$1.a |
| |
| # ----------------------------------------------------------------------------- |
| # Function : host-executable-path |
| # Arguments : 1: executable module name (e.g. 'foo') |
| # Returns : location of generated host executable name (e.g. '..../foo) |
| # Usage : $(call host-executable-path,<modulename>) |
| # ----------------------------------------------------------------------------- |
| host-executable-path = $(HOST_OUT)/$1$(HOST_EXE) |
| |
| # ----------------------------------------------------------------------------- |
| # Function : static-library-path |
| # Arguments : 1: library module name (e.g. 'foo') |
| # Returns : location of generated static library name (e.g. '..../libfoo.a) |
| # Usage : $(call static-library-path,<modulename>) |
| # ----------------------------------------------------------------------------- |
| static-library-path = $(TARGET_OUT)/lib$1.a |
| |
| # ----------------------------------------------------------------------------- |
| # Function : shared-library-path |
| # Arguments : 1: library module name (e.g. 'foo') |
| # Returns : location of generated shared library name (e.g. '..../libfoo.so) |
| # Usage : $(call shared-library-path,<modulename>) |
| # ----------------------------------------------------------------------------- |
| shared-library-path = $(TARGET_OUT)/lib$1.so |
| |
| # ----------------------------------------------------------------------------- |
| # Function : executable-path |
| # Arguments : 1: executable module name (e.g. 'foo') |
| # Returns : location of generated exectuable name (e.g. '..../foo) |
| # Usage : $(call executable-path,<modulename>) |
| # ----------------------------------------------------------------------------- |
| executable-path = $(TARGET_OUT)/$1 |
| |
| # ============================================================================= |
| # |
| # 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 := $$(LOCAL_ARM_TEXT) |
| $$(_OBJ): PRIVATE_CC := $$($$(my)CC) |
| $$(_OBJ): PRIVATE_CFLAGS := $$($$(my)CFLAGS) \ |
| $$($$(my)_$(LOCAL_ARM_MODE)_$(LOCAL_BUILD_MODE)_CFLAGS) \ |
| -I$$(LOCAL_PATH) \ |
| -I$$(OBJS_DIR) \ |
| $$(LOCAL_CFLAGS) \ |
| $$(NDK_APP_CPPFLAGS) \ |
| $$(NDK_APP_CFLAGS) \ |
| $$(LOCAL_ARM_CFLAGS) |
| |
| $$(_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.tmp \ |
| $$(PRIVATE_SRC) \ |
| -o $$(PRIVATE_OBJ) |
| $$(call cmd-process-deps,$$(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-s-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 := $$(LOCAL_ARM_TEXT) |
| $$(_OBJ): PRIVATE_CXX := $$($$(my)CXX) |
| $$(_OBJ): PRIVATE_CXXFLAGS := $$($$(my)CXXFLAGS) \ |
| $$($$(my)_$(LOCAL_ARM_MODE)_$(LOCAL_BUILD_MODE)_CFLAGS) \ |
| -I$$(LOCAL_PATH) \ |
| -I$$(OBJS_DIR) \ |
| $$(LOCAL_CFLAGS) \ |
| $$(NDK_APP_CPPFLAGS) \ |
| $$(NDK_APP_CXXFLAGS) \ |
| $$(LOCAL_ARM_CFLAGS) |
| |
| $$(_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.tmp \ |
| $$(PRIVATE_SRC) \ |
| -o $$(PRIVATE_OBJ) |
| $$(call cmd-process-deps,$$(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-process-deps |
| # Arguments : 1: object file path |
| # Returns : None |
| # Usage : $(call cmd-process-deps,<objectfile>) |
| # Rationale : To be used as a Make build command to process the dependencies |
| # generated by the compiler (in <obj>.d.tmp) into ones suited |
| # for our build system. See the comments in build/core/mkdeps.sh |
| # for more details. |
| # ----------------------------------------------------------------------------- |
| cmd-process-deps = $(hide) $(BUILD_SYSTEM)/mkdeps.sh $(1) $(1).d.tmp $(1).d |
| |
| # ----------------------------------------------------------------------------- |
| # 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 |