| # | |
| # Copyright (c) 2014-2017 Nest Labs, Inc. | |
| # All rights reserved. | |
| # | |
| # 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. | |
| # | |
| # | |
| # Description: | |
| # This file implements a glue makefile for building the Weave SDK | |
| # for Android devices and simulators for multiple architectures. | |
| # | |
| # This was largely directed and inspired by two Android NDK | |
| # documents: | |
| # | |
| # * Android NDK Programmer's Guide: Standalone Toolchain | |
| # * Android NDK Programmer's Guide: C++ Support | |
| # | |
| # | |
| # Command-line Configurable Options | |
| # | |
| ANDROID_ROOT ?= /usr/local/android | |
| ANDROID_HOME ?= $(ANDROID_ROOT)/android-sdk-linux-r23.0.2 | |
| ANDROID_NDK_HOME ?= $(ANDROID_ROOT)/android-ndk-r10 | |
| ANDROID_API ?= $(ANDROID_RELEASE) | |
| ANDROID_ABI ?= armeabi-v7a arm64-v8a x86 x86_64 | |
| ANDROID_STL ?= $(ANDROID_CXX) | |
| DEBUG ?= 0 | |
| ENABLE_TARGETED_LISTEN ?= 0 | |
| # Deprecated -- Use ANDROID_API | |
| ANDROID_RELEASE ?= 22 | |
| # Deprecated -- Use ANDROID_STL | |
| ANDROID_CXX ?= system | |
| # | |
| # Android C++ Runtime (STL) Selection | |
| # | |
| ANDROID_STLROOT = $(ANDROID_NDK_HOME)/sources/cxx-stl | |
| ANDROID_STL_INCLUDE_DIRS_libc++ = $(ANDROID_STLROOT)/llvm-libc++/include \ | |
| $(ANDROID_STLROOT)/llvm-libc++abi/include \ | |
| $(ANDROID_NDK_HOME)/sources/android/support/include | |
| ANDROID_STL_INCLUDE_DIRS_gnustl = $(ANDROID_STLROOT)/gnu-libstdc++/4.9/include | |
| ANDROID_STL_INCLUDE_DIRS_system = $(ANDROID_STLROOT)/system/include | |
| ANDROID_STL_INCLUDES = $(foreach dir,$(ANDROID_STL_INCLUDE_DIRS_$(ANDROID_STL)),-isystem $(dir)) | |
| # | |
| # Tools and Executables | |
| # | |
| android-ndk-which = $(shell $(AbsTopSourceDir)/build/scripts/android-ndk-which --ndk-home $(ANDROID_NDK_HOME) $(1) $(TARGET_ABI)) | |
| AR = $(call android-ndk-which,ar) | |
| AS = $(call android-ndk-which,as) | |
| CPP = $(call android-ndk-which,cpp) | |
| CC = $(call android-ndk-which,gcc) | |
| CXX = $(call android-ndk-which,g++) | |
| LD = $(call android-ndk-which,ld) | |
| STRIP = $(call android-ndk-which,strip) | |
| NM = $(call android-ndk-which,nm) | |
| RANLIB = $(call android-ndk-which,ranlib) | |
| OBJCOPY = $(call android-ndk-which,objcopy) | |
| ECHO = @echo | |
| MAKE = make | |
| MKDIR_P = mkdir -p | |
| LN_S = ln -s | |
| RM_F = rm -f | |
| INSTALL = /usr/bin/install | |
| # | |
| # Common C/C++ Defines | |
| # | |
| DEFINES += -D__ANDROID_API__=$(ANDROID_API) \ | |
| -DWEAVE_CONFIG_ENABLE_TARGETED_LISTEN=$(ENABLE_TARGETED_LISTEN) \ | |
| -DWEAVE_PROGRESS_LOGGING=$(DEBUG) \ | |
| -DWEAVE_ERROR_LOGGING=$(DEBUG) \ | |
| -DWEAVE_DETAIL_LOGGING=$(DEBUG) | |
| ifeq ($(DEBUG),1) | |
| DEFINES = -DDEBUG=$(DEBUG) -UNDEBUG | |
| else | |
| DEFINES = -DNDEBUG=1 -UDEBUG | |
| endif | |
| # | |
| # Common C/C++ Includes | |
| # | |
| INCLUDES += -isystem $(ANDROID_NDK_HOME)/sysroot/usr/include \ | |
| $(ANDROID_STL_INCLUDES) | |
| # | |
| # Compilation/Build Flags | |
| # | |
| CPPFLAGS = --sysroot=$(ABI_SYSROOT) $(DEFINES) $(INCLUDES) $(ABI_CPPFLAGS) | |
| CFLAGS = $(CPPFLAGS) -ffunction-sections -funwind-tables $(ABI_CFLAGS) | |
| CXXFLAGS = $(CPPFLAGS) -fno-rtti $(ABI_CXXFLAGS) | |
| LDFLAGS = --sysroot=$(ABI_SYSROOT) -Wl,--gc-sections $(ABI_LDFLAGS) | |
| INSTALLFLAGS = -p | |
| ifndef BuildJobs | |
| BuildJobs := $(shell getconf _NPROCESSORS_ONLN) | |
| endif | |
| JOBSFLAG := -j$(BuildJobs) | |
| # | |
| # Common Weave configure options | |
| # | |
| CONFIGURE_OPTIONS = --disable-cocoa \ | |
| --disable-docs \ | |
| --enable-java \ | |
| --disable-python \ | |
| --enable-shared \ | |
| --disable-tests \ | |
| --disable-tools | |
| ifeq ($(DEBUG),1) | |
| CONFIGURE_OPTIONS += --enable-debug --enable-optimization=no | |
| else | |
| CONFIGURE_OPTIONS += | |
| endif | |
| # | |
| # Directories | |
| # | |
| TopSourceDir := $(dir $(shell readlink $(firstword $(MAKEFILE_LIST)))) | |
| AbsTopSourceDir := $(dir $(realpath $(firstword $(MAKEFILE_LIST)))) | |
| BuildPath = build | |
| TopBuildDir = $(BuildPath) | |
| AbsTopBuildDir = $(PWD)/$(TopBuildDir) | |
| ResultPath = output | |
| TopResultDir = $(ResultPath) | |
| AbsTopResultDir = $(PWD)/$(TopResultDir) | |
| # NB: Regardless of where JAVA_HOME points, always use the JNI headers from the Android NDK, | |
| # and only include the top-most directory (include), not the system directory (include/linux). | |
| # Because the NDK mixes the JNI headers in with the linux headers, listing the system | |
| # directory in the -I flags will result in strange compilation errors. And unlike the standard | |
| # Java jni.h, the jni.h that comes with the Android NDK does not depend on any system-specific | |
| # JNI header files (e.g. jni_md.h). Thus only the top-level include directory is needed. | |
| JNI_INCLUDE_DIRS = $(ABI_SYSROOT)/usr/include | |
| # | |
| # ABI-specific Configurations | |
| # | |
| ABI_CONFIG_TUPLE_armeabi = arm-unknown-linux-android | |
| ABI_SYSROOT_armeabi = $(ANDROID_NDK_HOME)/platforms/android-$(ANDROID_API)/arch-arm | |
| ABI_CPPFLAGS_armeabi = -march=armv5te -mtune=xscale -msoft-float -isystem $(ANDROID_NDK_HOME)/sysroot/usr/include/arm-linux-androideabi | |
| ABI_CFLAGS_armeabi = -fstack-protector | |
| ABI_CXXFLAGS_armeabi = -I$(ANDROID_NDK_HOME)/platforms/android-$(ANDROID_API)/arch-arm/usr/include | |
| ABI_LDFLAGS_armeabi = -march=armv5te -mtune=xscale -msoft-float | |
| ABI_CONFIG_TUPLE_armeabi-v7a = armv7-unknown-linux-android | |
| ABI_SYSROOT_armeabi-v7a = $(ANDROID_NDK_HOME)/platforms/android-$(ANDROID_API)/arch-arm | |
| ABI_CPPFLAGS_armeabi-v7a = -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -isystem $(ANDROID_NDK_HOME)/sysroot/usr/include/arm-linux-androideabi | |
| ABI_CFLAGS_armeabi-v7a = -fstack-protector | |
| ABI_CXXFLAGS_armeabi-v7a = -I$(ANDROID_NDK_HOME)/platforms/android-$(ANDROID_API)/arch-arm/usr/include | |
| ABI_LDFLAGS_armeabi-v7a = -march=armv7-a -Wl,--fix-cortex-a8 | |
| ABI_CONFIG_TUPLE_arm64-v8a = arm64-unknown-linux-android | |
| ABI_SYSROOT_arm64-v8a = $(ANDROID_NDK_HOME)/platforms/android-$(ANDROID_API)/arch-arm64 | |
| ABI_CPPFLAGS_arm64-v8a = -march=armv8-a -isystem $(ANDROID_NDK_HOME)/sysroot/usr/include/aarch64-linux-android | |
| ABI_CFLAGS_arm64-v8a = -fstack-protector | |
| ABI_CXXFLAGS_arm64-v8a = -I$(ANDROID_NDK_HOME)/platforms/android-$(ANDROID_API)/arch-arm64/usr/include | |
| ABI_LDFLAGS_arm64-v8a = -march=armv8-a | |
| ABI_CONFIG_TUPLE_x86 = x86-unknown-linux-android | |
| ABI_SYSROOT_x86 = $(ANDROID_NDK_HOME)/platforms/android-$(ANDROID_API)/arch-x86 | |
| ABI_CPPFLAGS_x86 = -march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32 -isystem $(ANDROID_NDK_HOME)/sysroot/usr/include/i686-linux-android | |
| ABI_CFLAGS_x86 = | |
| ABI_CXXFLAGS_x86 = -I$(ANDROID_NDK_HOME)/platforms/android-$(ANDROID_API)/arch-x86/usr/include | |
| ABI_LDFLAGS_x86 = -march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32 | |
| ABI_CONFIG_TUPLE_x86_64 = x86_64-unknown-linux-android | |
| ABI_SYSROOT_x86_64 = $(ANDROID_NDK_HOME)/platforms/android-$(ANDROID_API)/arch-x86_64 | |
| ABI_CPPFLAGS_x86_64 = -march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel -isystem $(ANDROID_NDK_HOME)/sysroot/usr/include/x86_64-linux-android | |
| ABI_CFLAGS_x86_64 = | |
| ABI_CXXFLAGS_x86_64 = -I$(ANDROID_NDK_HOME)/platforms/android-$(ANDROID_API)/arch-x86_64/usr/include | |
| ABI_LDFLAGS_x86_64 = -march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel | |
| # | |
| # configure-action <abi> | |
| # | |
| # Steps to configure the Weave SDK for a specific Android ABI. | |
| # | |
| # abi - The target ABI. | |
| # | |
| define configure-action | |
| $(ECHO) " CONFIG $(ABI_CONFIG_TUPLE_$(1))..." | |
| (cd $(BuildPath)/$(ABI_CONFIG_TUPLE_$(1)) && $(AbsTopSourceDir)/configure \ | |
| CPP="$(CPP)" CC="$(CC)" CXX="$(CXX)" OBJC="$(OBJC)" OBJCXX="$(OBJCXX)" AR="$(AR)" RANLIB="$(RANLIB)" NM="$(NM)" STRIP="$(STRIP)" \ | |
| INSTALL="$(INSTALL) $(INSTALLFLAGS)" \ | |
| CPPFLAGS="$(CPPFLAGS)" \ | |
| CFLAGS="$(CFLAGS)" \ | |
| CXXFLAGS="$(CXXFLAGS)" \ | |
| OBJCFLAGS="$(OBJCFLAGS)" \ | |
| OBJCXXFLAGS="$(OBJCXXFLAGS)" \ | |
| LDFLAGS="$(LDFLAGS)" \ | |
| JAVA_HOME="$(JAVA_HOME)" \ | |
| JNI_INCLUDE_DIRS="$(JNI_INCLUDE_DIRS)" \ | |
| --build=$(shell $(AbsTopSourceDir)/third_party/nlbuild-autotools/repo/autoconf/config.guess) \ | |
| --host=$(ABI_CONFIG_TUPLE_$(1)) \ | |
| --with-sysroot=$(ABI_SYSROOT) \ | |
| --with-libtool-sysroot=$(ABI_SYSROOT) \ | |
| --with-weave-project-includes=$(AbsTopSourceDir)/build/config/android \ | |
| --prefix=/ \ | |
| --exec-prefix=/$(ABI_CONFIG_TUPLE_$(1)) \ | |
| $(CONFIGURE_OPTIONS)) | |
| endef # configure-action | |
| # | |
| # build-action <abi> | |
| # | |
| # Steps to generate the Weave SDK intermediate build products for the specified Android ABI. | |
| # | |
| # abi - The target ABI. | |
| # | |
| define build-action | |
| $(ECHO) " BUILD $(ABI_CONFIG_TUPLE_$(1))" | |
| $(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(ABI_CONFIG_TUPLE_$(1)) --no-print-directory all | |
| endef # build-action | |
| # | |
| # stage-action <abi> | |
| # | |
| # Steps to stage (install) the Weave SDK final build products for the specified | |
| # specified Android ABI. | |
| # | |
| # abi - The target ABI. | |
| # | |
| define stage-action | |
| $(ECHO) " STAGE $(ABI_CONFIG_TUPLE_$(1))" | |
| $(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(ABI_CONFIG_TUPLE_$(1)) --no-print-directory DESTDIR=$(AbsTopResultDir) install | |
| endef # stage-action | |
| # | |
| # pretty-action <abi> | |
| # | |
| # Steps to pretty-ify the Weave SDK source code for the specified Android ABI. | |
| # | |
| # abi - The target ABI. | |
| # | |
| define pretty-action | |
| $(ECHO) " PRETTY $(1)" | |
| $(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(ABI_CONFIG_TUPLE_$(1)) --no-print-directory pretty | |
| endef # pretty-action | |
| # | |
| # pretty-check-action <abi> | |
| # | |
| # Steps to pretty-check (lint) the Weave SDK source code for the specified | |
| # Android ABI. | |
| # | |
| # abi - The target ABI. | |
| # | |
| define pretty-check-action | |
| $(ECHO) " PRETTY $(1)" | |
| $(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(ABI_CONFIG_TUPLE_$(1)) --no-print-directory pretty-check | |
| endef # pretty-check-action | |
| # | |
| # clean-action <abi> | |
| # | |
| # Steps to clean (delete) the Weave SDK final build products for the specified | |
| # specified Android ABI. | |
| # | |
| # abi - The target ABI. | |
| # | |
| define clean-action | |
| $(ECHO) " CLEAN $(1)" | |
| @$(RM_F) -r $(BuildPath)/$(ABI_CONFIG_TUPLE_$(1)) | |
| endef # clean-action | |
| # | |
| # ABI_template <abi> | |
| # | |
| # Define macros, targets and rules to configure, build, and stage the | |
| # Weave SDK for a single Android ABI. | |
| # | |
| # abi - The architecture to instantiate the template for. | |
| # | |
| define ABI_template | |
| CONFIGURE_TARGETS += configure-$(1) | |
| BUILD_TARGETS += do-build-$(1) | |
| STAGE_TARGETS += stage-$(1) | |
| PRETTY_TARGETS += pretty-$(1) | |
| PRETTY_CHECK_TARGETS += pretty-check-$(1) | |
| CLEAN_TARGETS += clean-$(1) | |
| BUILD_DIRS += $(BuildPath)/$(ABI_CONFIG_TUPLE_$(1)) | |
| .PHONY: configure-$(1) do-build-$(1) stage-$(1) pretty-$(1) lint-$(1) pretty-check-$(1) clean-$(1) | |
| configure-$(1): TARGET_ABI=$(1) | |
| configure-$(1): ABI_SYSROOT=$(ABI_SYSROOT_$(1)) | |
| configure-$(1): ABI_CPPFLAGS=$(ABI_CPPFLAGS_$(1)) | |
| configure-$(1): ABI_CFLAGS=$(ABI_CFLAGS_$(1)) | |
| configure-$(1): ABI_CXXFLAGS=$(ABI_CXXFLAGS_$(1)) | |
| configure-$(1): ABI_LDFLAGS=$(ABI_LDFLAGS_$(1)) | |
| configure-$(1): env-check $(BuildPath)/$(ABI_CONFIG_TUPLE_$(1))/config.status | |
| $(BuildPath)/$(ABI_CONFIG_TUPLE_$(1))/config.status: | $(BuildPath)/$(ABI_CONFIG_TUPLE_$(1)) | |
| $$(call configure-action,$(1)) | |
| do-build-$(1): configure-$(1) | |
| do-build-$(1): | |
| $$(call build-action,$(1)) | |
| stage-$(1): do-build-$(1) | |
| stage-$(1): | $(TopResultDir) | |
| $$(call stage-action,$(1)) | |
| pretty-$(1): configure-$(1) | |
| $$(call pretty-action,$(1)) | |
| lint-$(1) pretty-check-$(1): configure-$(1) | |
| $$(call pretty-check-action,$(1)) | |
| clean-$(1): | |
| $$(call clean-action,$(1)) | |
| endef # ABI_template | |
| # | |
| # Rules | |
| # | |
| # Don't allow this top-level makefile's targets to be built in parallel. | |
| .NOTPARALLEL: | |
| .DEFAULT_GOAL := all | |
| .PHONY : all configure build stage pretty lint pretty check clean env-check help | |
| # Instantiate an ABI-specific set of rules to build weave for each target ABI. | |
| $(foreach abi,$(ANDROID_ABI),$(eval $(call ABI_template,$(abi)))) | |
| all: stage | |
| configure: $(CONFIGURE_TARGETS) | |
| build: $(BUILD_TARGETS) | |
| stage: $(STAGE_TARGETS) | |
| pretty: $(PRETTY_TARGETS) | |
| lint pretty-check: $(PRETTY_CHECK_TARGETS) | |
| clean: $(CLEAN_TARGETS) | |
| env-check: | |
| @if [ -z "$(JAVA_HOME)" ]; then \ | |
| echo "JAVA_HOME not set"; \ | |
| false; \ | |
| fi | |
| @if [ \! -d "$(ANDROID_HOME)" ]; then \ | |
| echo "ERROR: Android SDK not found at $(ANDROID_HOME)"; \ | |
| echo "Override the ANDROID_HOME variable to specify an alternate location for the Android SDK"; \ | |
| false; \ | |
| fi | |
| @if [ \! -d "$(ANDROID_NDK_HOME)" ]; then \ | |
| echo "ERROR: Android NDK not found at $(ANDROID_NDK_HOME)"; \ | |
| echo "Override the ANDROID_NDK_HOME variable to specify an alternate location for the Android NDK"; \ | |
| false; \ | |
| fi | |
| @if [ \! -d "$(ANDROID_NDK_HOME)/platforms/android-$(ANDROID_API)" ]; then \ | |
| echo "ERROR: Android API level $(ANDROID_API) not supported by NDK at $(ANDROID_NDK_HOME)"; \ | |
| echo "Override the ANDROID_API variable to select another API level"; \ | |
| false; \ | |
| fi | |
| $(ECHO) "NOTE: JAVA_HOME is '$(JAVA_HOME)' (source: $(origin JAVA_HOME))" | |
| $(ECHO) "NOTE: ANDROID_HOME is '$(ANDROID_HOME)' (source: $(origin ANDROID_HOME))" | |
| $(ECHO) "NOTE: ANDROID_NDK_HOME is '$(ANDROID_NDK_HOME)' (source: $(origin ANDROID_NDK_HOME))" | |
| $(ECHO) "NOTE: ANDROID_API is $(ANDROID_API) (source: $(origin ANDROID_API))" | |
| $(ECHO) "NOTE: ANDROID_ABI is '$(ANDROID_ABI)' (source: $(origin ANDROID_ABI))" | |
| $(ECHO) "NOTE: ANDROID_STL is '$(ANDROID_STL)' (source: $(origin ANDROID_STL))" | |
| $(TopResultDir) $(BUILD_DIRS): | |
| $(ECHO) " MKDIR $@" | |
| @$(MKDIR_P) "$@" | |
| help: | |
| $(ECHO) "" | |
| $(ECHO) "Type 'make -f $(firstword $(MAKEFILE_LIST))' to build Weave for Android for the following" | |
| $(ECHO) "API level and ABIs: " | |
| $(ECHO) "" | |
| $(ECHO) " API Level $(ANDROID_API)" | |
| $(ECHO) " $(ANDROID_ABI)" | |
| $(ECHO) "" | |
| $(ECHO) "To build for a particular API or ABI, override the ANDROID_API and ANDROID_ABI" | |
| $(ECHO) "variables as follows:" | |
| $(ECHO) "" | |
| $(ECHO) " make -f $(firstword $(MAKEFILE_LIST)) ANDROID_API=24 ANDROID_ABI='armv7 x86'" | |
| $(ECHO) "" | |
| $(ECHO) "You may want or need to override the following make variables either on the " | |
| $(ECHO) "command line or in the environment: " | |
| $(ECHO) "" | |
| $(ECHO) " DEBUG Enable Weave debug code and logging (default: $(DEBUG))." | |
| $(ECHO) "" | |
| $(ECHO) " ENABLE_TARGETED_LISTEN Enable Weave support for listening on particular " | |
| $(ECHO) " addresses or interfaces. This allows testing multiple " | |
| $(ECHO) " instances of the Weave stack running on a single host " | |
| $(ECHO) " (default: $(ENABLE_TARGETED_LISTEN))." | |
| $(ECHO) "" | |
| $(ECHO) " JAVA_HOME Directory in which the Java runtime is located." | |
| $(ECHO) "" | |
| $(ECHO) " ANDROID_ROOT Directory where Android NDK and SDK are installed (if " | |
| $(ECHO) " the same) (default: $(ANDROID_ROOT))." | |
| $(ECHO) "" | |
| $(ECHO) " ANDROID_NDK_HOME Directory where Android NDK is installed (default: " | |
| $(ECHO) " $(ANDROID_NDK_HOME))." | |
| $(ECHO) "" | |
| $(ECHO) " ANDROID_HOME Directory where Android SDK is installed (default: " | |
| $(ECHO) " $(ANDROID_HOME))." | |
| $(ECHO) "" | |
| $(ECHO) " ANDROID_API Android NDK API level to build against (default: $(ANDROID_API))." | |
| $(ECHO) "" | |
| $(ECHO) " ANDROID_ABI List of Android ABIs to build for. Choices are: armeabi," | |
| $(ECHO) " armeabi-v7a, arm64-v8a, x86 and x86_64 (default: " | |
| $(ECHO) " $(ANDROID_ABI))." | |
| $(ECHO) "" | |
| $(ECHO) " NOTE: Support for armeabi is deprecated in later SDKs/NDKs." | |
| $(ECHO) "" | |
| $(ECHO) " ANDROID_STL Android NDK C++ runtime to build against. Choices" | |
| $(ECHO) " are libc++, gnustl and system (default: $(ANDROID_CXX))." |