Add basic VNDK support in Make

Add BOARD_VNDK_VERSION and LOCAL_USE_VNDK to specify the version of the
VNDK that will be used globally, and whether to use the VNDK on a module
basis.

If the board is using the VNDK:

* LOCAL_COPY_HEADERS may only be used by modules defining LOCAL_USE_VNDK
* LOCAL_USE_VNDK modules will compile against the NDK headers and stub
  libraries, but continue to use the platform libc++.
* LOCAL_USE_VNDK modules will not have the global includes like
  system/core/include, but it will use device-specific kernel headers.

This change does not attempt to enforce any linking constraints, that
will come in a later patch.

Test: out/build-aosp_arm.ninja is identical before/after
Change-Id: Icce65d4974f085093d500b5b2516983788fe2905
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 13d20e0..251ac35 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -65,6 +65,8 @@
   my_host_cross :=
 endif
 
+include $(BUILD_SYSTEM)/local_vndk.mk
+
 my_module_tags := $(LOCAL_MODULE_TAGS)
 ifeq ($(my_host_cross),true)
   my_module_tags :=
diff --git a/core/binary.mk b/core/binary.mk
index 765ab36..776a3ff 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -74,8 +74,9 @@
 my_ndk_sysroot :=
 my_ndk_sysroot_include :=
 my_ndk_sysroot_lib :=
-ifdef LOCAL_SDK_VERSION
+ifneq ($(LOCAL_SDK_VERSION)$(LOCAL_USE_VNDK),)
   ifdef LOCAL_IS_HOST_MODULE
+    # LOCAL_USE_VNDK is checked in local_vndk.mk
     $(error $(LOCAL_PATH): LOCAL_SDK_VERSION cannot be used in host module)
   endif
 
@@ -104,9 +105,13 @@
   # missing API levels to existing ones where necessary, but we're not doing
   # that for the generated libraries. Clip the API level to the minimum where
   # appropriate.
-  my_ndk_api := $(LOCAL_SDK_VERSION)
+  ifdef LOCAL_USE_VNDK
+    my_ndk_api := $(BOARD_VNDK_VERSION)
+  else
+    my_ndk_api := $(LOCAL_SDK_VERSION)
+  endif
   ifneq ($(my_ndk_api),current)
-      my_ndk_api := $(call math_max,$(LOCAL_SDK_VERSION),$(my_min_sdk_version))
+      my_ndk_api := $(call math_max,$(my_ndk_api),$(my_min_sdk_version))
   endif
 
   my_ndk_api_def := $(my_ndk_api)
@@ -154,18 +159,20 @@
   my_built_ndk_libs := $(my_ndk_platform_dir)/usr/$(my_ndk_libdir_name)
   my_ndk_sysroot_lib := $(my_ndk_sysroot)/usr/$(my_ndk_libdir_name)
 
-  # The bionic linker now has support for packed relocations and gnu style
-  # hashes (which are much faster!), but shipping to older devices requires
-  # the old style hash. Fortunately, we can build with both and it'll work
-  # anywhere.
-  #
-  # This is not currently supported on MIPS architectures.
-  ifeq (,$(filter mips mips64,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)))
-    my_ldflags += -Wl,--hash-style=both
-  endif
+  ifndef LOCAL_USE_VNDK
+    # The bionic linker now has support for packed relocations and gnu style
+    # hashes (which are much faster!), but shipping to older devices requires
+    # the old style hash. Fortunately, we can build with both and it'll work
+    # anywhere.
+    #
+    # This is not currently supported on MIPS architectures.
+    ifeq (,$(filter mips mips64,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)))
+      my_ldflags += -Wl,--hash-style=both
+    endif
 
-  # We don't want to expose the relocation packer to the NDK just yet.
-  LOCAL_PACK_MODULE_RELOCATIONS := false
+    # We don't want to expose the relocation packer to the NDK just yet.
+    LOCAL_PACK_MODULE_RELOCATIONS := false
+  endif
 
   # Set up the NDK stl variant. Starting from NDK-r5 the c++ stl resides in a separate location.
   # See ndk/docs/CPLUSPLUS-SUPPORT.html
@@ -173,6 +180,7 @@
   my_ndk_stl_shared_lib_fullpath :=
   my_ndk_stl_static_lib :=
   my_ndk_cpp_std_version :=
+  ifndef LOCAL_USE_VNDK
   my_cpu_variant := $(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)CPU_ABI)
   ifeq (mips32r6,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH_VARIANT))
     my_cpu_variant := mips32r6
@@ -260,6 +268,7 @@
   endif
   endif
   endif
+  endif
 endif
 
 ifndef LOCAL_IS_HOST_MODULE
@@ -280,7 +289,7 @@
 my_ldlibs := $(filter $(my_allowed_ldlibs),$(my_ldlibs))
 endif
 
-ifdef LOCAL_SDK_VERSION
+ifneq ($(LOCAL_SDK_VERSION)$(LOCAL_USE_VNDK),)
   my_all_ndk_libraries := \
       $(NDK_MIGRATED_LIBS) $(addprefix lib,$(NDK_PREBUILT_SHARED_LIBRARIES))
   my_ndk_shared_libraries := \
@@ -489,17 +498,30 @@
 ## Define PRIVATE_ variables from global vars
 ###########################################################
 ifndef LOCAL_IS_HOST_MODULE
-ifdef LOCAL_SDK_VERSION
+ifdef LOCAL_USE_VNDK
+my_target_global_c_includes := \
+    $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)PROJECT_INCLUDES)
+my_target_global_c_system_includes := \
+    $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)PROJECT_SYSTEM_INCLUDES) \
+    $(my_ndk_sysroot_include)
+else ifdef LOCAL_SDK_VERSION
 my_target_global_c_includes :=
 my_target_global_c_system_includes := $(my_ndk_stl_include_path) $(my_ndk_sysroot_include)
-else
+else ifdef BOARD_VNDK_VERSION
 my_target_global_c_includes := $(SRC_HEADERS) \
     $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)PROJECT_INCLUDES) \
     $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)C_INCLUDES)
 my_target_global_c_system_includes := $(SRC_SYSTEM_HEADERS) \
     $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)PROJECT_SYSTEM_INCLUDES) \
     $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)C_SYSTEM_INCLUDES)
-endif # LOCAL_SDK_VERSION
+else
+my_target_global_c_includes := $(SRC_HEADERS) \
+    $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)PROJECT_INCLUDES) \
+    $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)C_INCLUDES)
+my_target_global_c_system_includes := $(SRC_SYSTEM_HEADERS) $(TARGET_OUT_HEADERS) \
+    $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)PROJECT_SYSTEM_INCLUDES) \
+    $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)C_SYSTEM_INCLUDES)
+endif
 
 ifeq ($(my_clang),true)
 my_target_global_cflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)CLANG_$(my_prefix)GLOBAL_CFLAGS)
@@ -1339,7 +1361,7 @@
 ## they may cusomize their install path with LOCAL_MODULE_PATH
 ##########################################################
 # Get the list of INSTALLED libraries as module names.
-ifdef LOCAL_SDK_VERSION
+ifneq ($(LOCAL_SDK_VERSION)$(LOCAL_USE_VNDK),)
   installed_shared_library_module_names := \
       $(my_shared_libraries)
 else
@@ -1508,7 +1530,7 @@
 so_suffix := $($(my_prefix)SHLIB_SUFFIX)
 a_suffix := $($(my_prefix)STATIC_LIB_SUFFIX)
 
-ifdef LOCAL_SDK_VERSION
+ifneq ($(LOCAL_SDK_VERSION)$(LOCAL_USE_VNDK),)
 built_shared_libraries := \
     $(addprefix $($(LOCAL_2ND_ARCH_VAR_PREFIX)$(my_prefix)OUT_INTERMEDIATE_LIBRARIES)/, \
       $(addsuffix $(so_suffix), \
@@ -1690,7 +1712,7 @@
 # One last verification check for ldlibs
 ifndef LOCAL_IS_HOST_MODULE
 my_allowed_ldlibs :=
-ifdef LOCAL_SDK_VERSION
+ifneq ($(LOCAL_SDK_VERSION)$(LOCAL_USE_VNDK),)
   my_allowed_ldlibs := $(addprefix -l,$(NDK_PREBUILT_SHARED_LIBRARIES))
 endif
 
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index faf18e3..b9c28b1 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -216,6 +216,7 @@
 LOCAL_COPY_TO_INTERMEDIATE_LIBRARIES:=
 LOCAL_LOGTAGS_FILES:=
 LOCAL_RECORDED_MODULE_TYPE:=
+LOCAL_USE_VNDK:=
 
 # arch specific variables
 LOCAL_SRC_FILES_$(TARGET_ARCH):=
diff --git a/core/config.mk b/core/config.mk
index 2fcf1fe..a4b0cea 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -687,7 +687,7 @@
 HOST_PROJECT_INCLUDES :=
 HOST_PROJECT_SYSTEM_INCLUDES := $(HOST_OUT_HEADERS)
 TARGET_PROJECT_INCLUDES :=
-TARGET_PROJECT_SYSTEM_INCLUDES := $(TARGET_OUT_HEADERS) \
+TARGET_PROJECT_SYSTEM_INCLUDES := \
 		$(TARGET_DEVICE_KERNEL_HEADERS) $(TARGET_BOARD_KERNEL_HEADERS) \
 		$(TARGET_PRODUCT_KERNEL_HEADERS)
 
diff --git a/core/copy_headers.mk b/core/copy_headers.mk
index 417a76c..a4fd2ed 100644
--- a/core/copy_headers.mk
+++ b/core/copy_headers.mk
@@ -1,3 +1,4 @@
+ifneq (,$(strip $(LOCAL_COPY_HEADERS)))
 ###########################################################
 ## Copy headers to the install tree
 ###########################################################
@@ -8,6 +9,25 @@
   my_prefix := TARGET_
 endif
 
+# Modules linking against the SDK do not have the include path to use
+# COPY_HEADERS, so prevent them from exporting any either.
+ifdef LOCAL_SDK_VERSION
+$(shell echo $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): Modules using LOCAL_SDK_VERSION may not use LOCAL_COPY_HEADERS >&2)
+$(error done)
+endif
+
+include $(BUILD_SYSTEM)/local_vndk.mk
+
+# If we're using the VNDK, only vendor modules using the VNDK may use
+# LOCAL_COPY_HEADERS. Platform libraries will not have the include path
+# present.
+ifdef BOARD_VNDK_VERSION
+ifndef LOCAL_USE_VNDK
+$(shell echo $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): Only vendor modules using LOCAL_USE_VNDK may use LOCAL_COPY_HEADERS >&2)
+$(error done)
+endif
+endif
+
 # Create a rule to copy each header, and make the
 # all_copied_headers phony target depend on each
 # destination header.  copy-one-header defines the
@@ -26,3 +46,5 @@
  )
 _chFrom :=
 _chTo :=
+
+endif # LOCAL_COPY_HEADERS
diff --git a/core/executable_internal.mk b/core/executable_internal.mk
index 531187c..f51ddb8 100644
--- a/core/executable_internal.mk
+++ b/core/executable_internal.mk
@@ -49,7 +49,7 @@
 my_target_crtbegin_static_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.o
 my_target_crtend_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_android.o
 endif
-ifdef LOCAL_SDK_VERSION
+ifneq ($(LOCAL_SDK_VERSION)$(LOCAL_USE_VNDK),)
 my_target_crtbegin_dynamic_o := $(wildcard $(my_ndk_sysroot_lib)/crtbegin_dynamic.o)
 my_target_crtbegin_static_o := $(wildcard $(my_ndk_sysroot_lib)/crtbegin_static.o)
 my_target_crtend_o := $(wildcard $(my_ndk_sysroot_lib)/crtend_android.o)
diff --git a/core/local_vndk.mk b/core/local_vndk.mk
new file mode 100644
index 0000000..f81249b
--- /dev/null
+++ b/core/local_vndk.mk
@@ -0,0 +1,25 @@
+# Verify LOCAL_USE_VNDK usage, and set LOCAL_SDK_VERSION if necessary
+
+ifdef LOCAL_IS_HOST_MODULE
+  ifdef LOCAL_USE_VNDK
+    $(shell echo $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): Do not use LOCAL_USE_VNDK with host modules >&2)
+    $(error done)
+  endif
+endif
+ifdef LOCAL_USE_VNDK
+  ifneq ($(LOCAL_USE_VNDK),true)
+    $(shell echo '$(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): LOCAL_USE_VNDK must be "true" or empty, not "$(LOCAL_USE_VNDK)"' >&2)
+    $(error done)
+  endif
+
+  ifdef LOCAL_SDK_VERSION
+    $(shell echo $(LOCAL_MODULE_MAKEFILE): $(LOCAL_MODULE): LOCAL_USE_VNDK must not be used with LOCAL_SDK_VERSION >&2)
+    $(error done)
+  endif
+
+  # If we're not using the VNDK, drop all restrictions
+  ifndef BOARD_VNDK_VERSION
+    LOCAL_USE_VNDK:=
+  endif
+endif
+
diff --git a/core/shared_library_internal.mk b/core/shared_library_internal.mk
index eeea50b..6b914c9 100644
--- a/core/shared_library_internal.mk
+++ b/core/shared_library_internal.mk
@@ -52,7 +52,7 @@
 my_target_crtbegin_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
 my_target_crtend_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
 endif
-ifdef LOCAL_SDK_VERSION
+ifneq ($(LOCAL_SDK_VERSION)$(LOCAL_USE_VNDK),)
 my_target_crtbegin_so_o := $(wildcard $(my_ndk_sysroot_lib)/crtbegin_so.o)
 my_target_crtend_so_o := $(wildcard $(my_ndk_sysroot_lib)/crtend_so.o)
 endif
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 995d9ed..1782ce5 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -47,6 +47,7 @@
 	echo '    "DeviceCpuVariant": "$(TARGET_CPU_VARIANT)",'; \
 	echo '    "DeviceAbi": ["$(TARGET_CPU_ABI)", "$(TARGET_CPU_ABI2)"],'; \
 	echo '    "DeviceUsesClang": $(if $(USE_CLANG_PLATFORM_BUILD),$(USE_CLANG_PLATFORM_BUILD),false),'; \
+	echo '    "DeviceVndkVersion": "$(BOARD_VNDK_VERSION)",'; \
 	echo ''; \
 	echo '    "DeviceSecondaryArch": "$(TARGET_2ND_ARCH)",'; \
 	echo '    "DeviceSecondaryArchVariant": "$(TARGET_2ND_ARCH_VARIANT)",'; \