Implement module exports + update docs + add a sample.
Change-Id: Ib892ca7d46b69599ce4569d5929f0149bdea8e3f
diff --git a/build/core/build-binary.mk b/build/core/build-binary.mk
index 6582b1f..1de633b 100644
--- a/build/core/build-binary.mk
+++ b/build/core/build-binary.mk
@@ -34,6 +34,7 @@
#
$(call assert-defined,LOCAL_MAKEFILE)
+include $(BUILD_SYSTEM)/import-locals.mk
include $(BUILD_SYSTEM)/build-module.mk
# list of generated object files
diff --git a/build/core/definitions.mk b/build/core/definitions.mk
index 0d8ce50..501c322 100644
--- a/build/core/definitions.mk
+++ b/build/core/definitions.mk
@@ -171,7 +171,7 @@
EXPORT_CFLAGS \
EXPORT_CPPFLAGS \
EXPORT_LDLIBS \
- EXPORT_C_INCLUDES
+ EXPORT_C_INCLUDES \
# The following are generated by the build scripts themselves
modules-LOCALS += \
@@ -255,6 +255,30 @@
module-is-installable = $(call or,$(call module-is-type,$1,shared-library),$(call module-is-type,$1,executable))
# -----------------------------------------------------------------------------
+# 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
@@ -288,7 +312,7 @@
# Use module-get-static-dependencies to retrieve final list.
# -----------------------------------------------------------------------------
module-add-static-depends = \
- $(call modules-add-depends-any,$1,$2,depends) \
+ $(call module-add-depends-any,$1,$2,depends) \
# -----------------------------------------------------------------------------
# Function : module-add-shared-depends
@@ -300,12 +324,12 @@
# Use modulge-get-shared-dependencies to retrieve final list.
# -----------------------------------------------------------------------------
module-add-shared-depends = \
- $(call modules-add-depends-any,$1,$2,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.
#
-modules-add-depends-any = \
+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.
@@ -316,8 +340,8 @@
)
module-compute-depends = \
- $(call modules-add-static-depends,$1,$(call strip-lib-prefix,$(__ndk_modules.$1.STATIC_LIBRARIES)))\
- $(call modules-add-shared-depends,$1,$(call strip-lib-prefix,$(__ndk_modules.$1.SHARED_LIBRARIES)))
+ $(call module-add-static-depends,$1,$(call strip-lib-prefix,$(__ndk_modules.$1.STATIC_LIBRARIES)))\
+ $(call module-add-shared-depends,$1,$(call strip-lib-prefix,$(__ndk_modules.$1.SHARED_LIBRARIES)))
module-get-installed = $(__ndk_modules.$1.INSTALLED)
diff --git a/build/core/import-locals.mk b/build/core/import-locals.mk
new file mode 100644
index 0000000..5e08b1a
--- /dev/null
+++ b/build/core/import-locals.mk
@@ -0,0 +1,61 @@
+# 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.
+#
+# Handle local variable expor/import during the build
+#
+
+$(call assert-defined,LOCAL_MODULE)
+
+# For LOCAL_CFLAGS, LOCAL_CPPFLAGS and LOCAL_C_INCLUDES, we need
+# to use the exported definitions of the closure of all modules
+# we depend on.
+#
+# I.e. If module 'foo' depends on 'bar' which depends on 'zoo',
+# then 'foo' will get the CFLAGS/CPPFLAGS/C_INCLUDES of both 'bar'
+# and 'zoo'
+#
+
+#
+# The imported compiler flags are prepended to their LOCAL_XXXX value
+# (this allows the module to override them).
+#
+all_depends := $(call module-get-all-dependencies,$(LOCAL_MODULE))
+all_depends := $(filter-out $(LOCAL_MODULE),$(all_depends))
+
+imported_CFLAGS := $(call module-get-listed-export,$(all_depends),CFLAGS)
+imported_CPPFLAGS := $(call module-get-listed-export,$(all_depends),CPPFLAGS)
+imported_C_INCLUDES := $(call module-get-listed-export,$(all_depends),C_INCLUDES)
+
+ifdef NDK_DEBUG_IMPORTS
+ $(info Imports for module $(LOCAL_MODULE):)
+ $(info CFLAGS='$(imported_CFLAGS)')
+ $(info CPPFLAGS='$(imported_CPPFLAGS)')
+ $(info C_INCLUDES='$(imported_C_INCLUDES)')
+ $(info All depends='$(all_depends)')
+endif
+
+LOCAL_CFLAGS := $(strip $(imported_CFLAGS) $(LOCAL_CFLAGS))
+LOCAL_CPPFLAGS := $(strip $(imported_CPPFLAGS) $(LOCAL_CPPFLAGS))
+LOCAL_C_INCLUDES := $(strip $(imported_C_INCLUDES) $(LOCAL_C_INCLUDES))
+
+# For LOCAL_LDLIBS, things are a bit different!
+#
+# You want the imported flags to appear _after_ the LOCAL_LDLIBS due to the way Unix
+# linkers work.
+#
+imported_LDLIBS := $(call module-get-listed-export,$(all_depends),LDLIBS)
+
+LOCAL_LDLIBS := $(strip $(LOCAL_LDLIBS) $(imported_LDLIBS))
+
+# We're done here
diff --git a/docs/ANDROID-MK.TXT b/docs/ANDROID-MK.TXT
index 3857385..397e12d 100644
--- a/docs/ANDROID-MK.TXT
+++ b/docs/ANDROID-MK.TXT
@@ -481,3 +481,70 @@
http://en.wikipedia.org/wiki/NX_bit
http://www.gentoo.org/proj/en/hardened/gnu-stack.xml
+
+LOCAL_EXPORT_CFLAGS
+ Define this variable to record a set of C/C++ compiler flags that will
+ be added to the LOCAL_CFLAGS definition of any other module that uses
+ this one with LOCAL_STATIC_LIBRARIES or LOCAL_SHARED_LIBRARIES.
+
+ For example, consider the module 'foo' with the following definition:
+
+ include $(CLEAR_VARS)
+ LOCAL_MODULE := foo
+ LOCAL_SRC_FILES := foo/foo.c
+ LOCAL_EXPORT_CFLAGS := -DFOO=1
+ include $(BUILD_STATIC_LIBRARY)
+
+ And another module, named 'bar' that depends on it as:
+
+ include $(CLEAR_VARS)
+ LOCAL_MODULE := bar
+ LOCAL_SRC_FILES := bar.c
+ LOCAL_CFLAGS := -DBAR=2
+ LOCAL_STATIC_LIBRARIES := foo
+ include $(BUILD_SHARED_LIBRARY)
+
+ Then, the flags '-DFOO=1 -DBAR=2' will be passed to the compiler when
+ building bar.c
+
+ Exported flags are prepended to your module's LOCAL_CFLAGS so you can
+ easily override them. They are also transitive: if 'zoo' depends on
+ 'bar' which depends on 'foo', then 'zoo' will also inherit all flags
+ exported by 'foo'.
+
+ Finally, exported flags are *not* used when building the module that
+ exports them. In the above example, -DFOO=1 would not be passed to the
+ compiler when building foo/foo.c.
+
+LOCAL_EXPORT_CPPFLAGS
+ Same as LOCAL_EXPORT_CFLAGS, but for C++ flags only.
+
+LOCAL_EXPORT_C_INCLUDES
+ Same as LOCAL_EXPORT_CFLAGS, but for C include paths.
+ This can be useful if 'bar.c' wants to include headers
+ that are provided by module 'foo'.
+
+LOCAL_EXPORT_LDLIBS
+ Same as LOCAL_EXPORT_CFLAGS, but for linker flags. Note that the
+ imported linker flags will be appended to your module's LOCAL_LDLIBS
+ though, due to the way Unix linkers work.
+
+ This is typically useful when module 'foo' is a static library and has
+ code that depends on a system library. LOCAL_EXPORT_LDLIBS can then be
+ used to export the dependency. For example:
+
+ include $(CLEAR_VARS)
+ LOCAL_MODULE := foo
+ LOCAL_SRC_FILES := foo/foo.c
+ LOCAL_EXPORT_LDLIBS := -llog
+ include $(BUILD_STATIC_LIBRARY)
+
+ include $(CLEAR_VARS)
+ LOCAL_MODULE := bar
+ LOCAL_SRC_FILES := bar.c
+ LOCAL_STATIC_LIBRARIES := foo
+ include $(BUILD_SHARED_LIBRARY)
+
+ There, libbar.so will be built with a -llog at the end of the linker
+ command to indicate that it depends on the system logging library,
+ because it depends on 'foo'.
diff --git a/docs/CHANGES.TXT b/docs/CHANGES.TXT
index 202220f..88e8cbf 100644
--- a/docs/CHANGES.TXT
+++ b/docs/CHANGES.TXT
@@ -1,6 +1,24 @@
Android NDK ChangeLog:
-------------------------------------------------------------------------------
+android-ndk-r5
+
+IMPORTANT BUG FIXES:
+
+IMPORTANT CHANGES:
+
+- Support for module exports: A module can now define a set of compiler or
+ linker flags that will be automatically 'imported' by any other module that
+ depends on it, through LOCAL_STATIC_LIBRARIES or LOCAL_SHARED_LIBRARIES.
+
+ This is achieved with the help of new Android.mk variables named
+ LOCAL_EXPORT_CFLAGS, LOCAL_EXPORT_CPPFLAGS, LOCAL_EXPORT_C_INCLUDES and
+ LOCAL_EXPORT_LDLIBS. See docs/ANDROID-MK.TXT for mode documentation, and
+ a 'samples/module-exports' for a sample project that uses this.
+
+OTHER FIXES & CHANGES:
+
+-------------------------------------------------------------------------------
android-ndk-r4b
This release fixes a few bugs in r4 scripts. There are no new features.