gecko-dev/mobile/android/base/Makefile.in
Nick Alexander b27086641f Bug 1208793 - Part 1: Fix gradle-targets dependencies. r=sebastian
We were both lazy and incomplete before.  Lazy because .aapt.deps is a
sentinel, and doesn't necessarily see relevant changes, due to
timestamps and deletions.  Incomplete because we never forced
generated Java code to be fresh.

--HG--
extra : commitid : JXLe9uWqjhN
extra : rebase_source : 8eaa2d012915ad59d5cd03d7e4a6552ae4db13c1
extra : histedit_source : 231ca7ad88e7965424a8c8a3e80dac68a32980a7
2015-10-19 17:01:26 -07:00

496 lines
19 KiB
Makefile

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
MOZ_APP_BUILDID=$(shell cat $(DEPTH)/config/buildid)
# Set the appropriate version code, based on the existance of the
# MOZ_APP_ANDROID_VERSION_CODE variable.
ifdef MOZ_APP_ANDROID_VERSION_CODE
ANDROID_VERSION_CODE:=$(MOZ_APP_ANDROID_VERSION_CODE)
else
ANDROID_VERSION_CODE:=$(shell $(PYTHON) \
$(topsrcdir)/python/mozbuild/mozbuild/android_version_code.py \
--verbose \
--with-android-cpu-arch=$(ANDROID_CPU_ARCH) \
$(if $(MOZ_ANDROID_MIN_SDK_VERSION),--with-android-min-sdk=$(MOZ_ANDROID_MIN_SDK_VERSION)) \
$(if $(MOZ_ANDROID_MAX_SDK_VERSION),--with-android-max-sdk=$(MOZ_ANDROID_MAX_SDK_VERSION)) \
$(MOZ_APP_BUILDID))
endif
DEFINES += \
-DANDROID_VERSION_CODE=$(ANDROID_VERSION_CODE) \
-DMOZ_ANDROID_SHARED_ID="$(MOZ_ANDROID_SHARED_ID)" \
-DMOZ_ANDROID_SHARED_ACCOUNT_TYPE="$(MOZ_ANDROID_SHARED_ACCOUNT_TYPE)" \
-DMOZ_ANDROID_SHARED_FXACCOUNT_TYPE="$(MOZ_ANDROID_SHARED_FXACCOUNT_TYPE)" \
-DMOZ_APP_BUILDID=$(MOZ_APP_BUILDID) \
$(NULL)
GARBAGE += \
classes.dex \
gecko.ap_ \
res/values/strings.xml \
res/raw/browsersearch.json \
res/raw/suggestedsites.json \
.aapt.deps \
javah.out \
jni-stubs.inc \
GeneratedJNINatives.h \
GeneratedJNIWrappers.cpp \
GeneratedJNIWrappers.h \
$(NULL)
GARBAGE_DIRS += classes db jars res sync services generated
# The bootclasspath is functionally identical to the classpath, but allows the
# classes given to redefine classes in core packages, such as java.lang.
# android.jar is here as it provides Android's definition of the Java Standard
# Library. The compatability lib here tweaks a few of the core classes to paint
# over changes in behaviour between versions.
JAVA_BOOTCLASSPATH := \
$(ANDROID_SDK)/android.jar \
$(NULL)
JAVA_BOOTCLASSPATH := $(subst $(NULL) ,:,$(strip $(JAVA_BOOTCLASSPATH)))
JAVA_CLASSPATH += \
$(ANDROID_SUPPORT_ANNOTATIONS_JAR_LIB) \
$(ANDROID_SUPPORT_V4_AAR_LIB) \
$(ANDROID_SUPPORT_V4_AAR_INTERNAL_LIB) \
$(ANDROID_APPCOMPAT_V7_AAR_LIB) \
$(ANDROID_RECYCLERVIEW_V7_AAR_LIB) \
$(NULL)
# If native devices are enabled, add Google Play Services and some of the v7
# compat libraries.
ifdef MOZ_NATIVE_DEVICES
JAVA_CLASSPATH += \
$(ANDROID_PLAY_SERVICES_BASE_AAR_LIB) \
$(ANDROID_PLAY_SERVICES_BASEMENT_AAR_LIB) \
$(ANDROID_PLAY_SERVICES_CAST_AAR_LIB) \
$(ANDROID_MEDIAROUTER_V7_AAR_LIB) \
$(ANDROID_MEDIAROUTER_V7_AAR_INTERNAL_LIB) \
$(NULL)
endif
JAVA_CLASSPATH := $(subst $(NULL) ,:,$(strip $(JAVA_CLASSPATH)))
# Library jars that we're bundling: these are subject to Proguard before inclusion
# into classes.dex.
java_bundled_libs := \
$(ANDROID_SUPPORT_V4_AAR_LIB) \
$(ANDROID_SUPPORT_V4_AAR_INTERNAL_LIB) \
$(ANDROID_APPCOMPAT_V7_AAR_LIB) \
$(ANDROID_RECYCLERVIEW_V7_AAR_LIB) \
$(NULL)
ifdef MOZ_NATIVE_DEVICES
java_bundled_libs += \
$(ANDROID_PLAY_SERVICES_BASE_AAR_LIB) \
$(ANDROID_PLAY_SERVICES_BASEMENT_AAR_LIB) \
$(ANDROID_PLAY_SERVICES_CAST_AAR_LIB) \
$(ANDROID_MEDIAROUTER_V7_AAR_LIB) \
$(ANDROID_MEDIAROUTER_V7_AAR_INTERNAL_LIB) \
$(NULL)
endif
java_bundled_libs := $(subst $(NULL) ,:,$(strip $(java_bundled_libs)))
# All the jars we're compiling from source. (not to be confused with
# java_bundled_libs, which holds the jars which we're including as binaries).
ALL_JARS = \
constants.jar \
gecko-R.jar \
gecko-browser.jar \
gecko-mozglue.jar \
gecko-thirdparty.jar \
gecko-util.jar \
sync-thirdparty.jar \
../javaaddons/javaaddons-1.0.jar \
$(NULL)
ifdef MOZ_WEBRTC
ALL_JARS += webrtc.jar
endif
ifdef MOZ_ANDROID_SEARCH_ACTIVITY
ALL_JARS += search-activity.jar
endif
ifdef MOZ_ANDROID_MLS_STUMBLER
ALL_JARS += ../stumbler/stumbler.jar
endif
ifdef MOZ_INSTALL_TRACKING
ALL_JARS += gecko-thirdparty-adjust_sdk.jar
endif
# The list of jars in Java classpath notation (colon-separated).
all_jars_classpath := $(subst $(NULL) ,:,$(strip $(ALL_JARS)))
include $(topsrcdir)/config/config.mk
library_jars := \
$(ANDROID_SDK)/android.jar \
$(NULL)
library_jars := $(subst $(NULL) ,:,$(strip $(library_jars)))
classes.dex: .proguard.deps
$(REPORT_BUILD)
$(DX) --dex --output=classes.dex jars-proguarded
ifdef MOZ_DISABLE_PROGUARD
PROGUARD_PASSES=0
else
ifdef MOZ_DEBUG
PROGUARD_PASSES=1
else
ifndef MOZILLA_OFFICIAL
PROGUARD_PASSES=1
else
PROGUARD_PASSES=6
endif
endif
endif
proguard_config_dir=$(topsrcdir)/mobile/android/config/proguard
# This stanza ensures that the set of GeckoView classes does not depend on too
# much of Fennec, where "too much" is defined as the set of potentially
# non-GeckoView classes that GeckoView already depended on at a certain point in
# time. The idea is to set a high-water mark that is not to be crossed.
classycle_jar := $(topsrcdir)/mobile/android/build/classycle/classycle-1.4.1.jar
.geckoview.deps: geckoview.ddf $(classycle_jar) $(ALL_JARS)
$(JAVA) -cp $(classycle_jar) \
classycle.dependency.DependencyChecker \
-mergeInnerClasses \
-dependencies=@$< \
$(ALL_JARS)
@$(TOUCH) $@
# First, we delete debugging information from libraries. Having line-number
# information for libraries for which we lack the source isn't useful, so this
# saves us a bit of space. Importantly, Proguard has a bug causing it to
# sometimes corrupt this information if present (which it does for some of the
# included libraries). This corruption prevents dex from completing, so we need
# to get rid of it. This prevents us from seeing line numbers in stack traces
# for stack frames inside libraries.
#
# This step can occur much earlier than the main Proguard pass: it needs only
# gecko-R.jar to have been compiled (as that's where the library R.java files
# end up), but it does block the main Proguard pass.
.bundled.proguard.deps: gecko-R.jar $(proguard_config_dir)/strip-libs.cfg
$(REPORT_BUILD)
@$(TOUCH) $@
$(JAVA) \
-Xmx512m -Xms128m \
-jar $(ANDROID_SDK_ROOT)/tools/proguard/lib/proguard.jar \
@$(proguard_config_dir)/strip-libs.cfg \
-injars $(subst ::,:,$(java_bundled_libs))\
-outjars bundled-jars-nodebug \
-libraryjars $(library_jars):gecko-R.jar
# We touch the target file before invoking Proguard so that Proguard's
# outputs are fresher than the target, preventing a subsequent
# invocation from thinking Proguard's outputs are stale. This is safe
# because Make removes the target file if any recipe command fails.
.proguard.deps: .geckoview.deps .bundled.proguard.deps $(ALL_JARS) $(proguard_config_dir)/proguard.cfg
$(REPORT_BUILD)
@$(TOUCH) $@
$(JAVA) \
-Xmx512m -Xms128m \
-jar $(ANDROID_SDK_ROOT)/tools/proguard/lib/proguard.jar \
@$(proguard_config_dir)/proguard.cfg \
-optimizationpasses $(PROGUARD_PASSES) \
-injars $(subst ::,:,$(all_jars_classpath)):bundled-jars-nodebug \
-outjars jars-proguarded \
-libraryjars $(library_jars)
CLASSES_WITH_JNI= \
org.mozilla.gecko.GeckoAppShell \
org.mozilla.gecko.GeckoJavaSampler \
org.mozilla.gecko.GeckoSmsManager \
org.mozilla.gecko.gfx.NativePanZoomController \
$(NULL)
jni-stubs.inc: gecko-browser.jar constants.jar gecko-mozglue.jar gecko-util.jar sync-thirdparty.jar
$(JAVAH) -o javah.out -bootclasspath $(JAVA_BOOTCLASSPATH) -classpath $(subst $(NULL) $(NULL),:,$^) $(CLASSES_WITH_JNI)
$(PYTHON) $(topsrcdir)/mobile/android/base/jni-generator.py javah.out $@
ANNOTATION_PROCESSOR_JAR_FILES := $(DEPTH)/build/annotationProcessors/annotationProcessors.jar
# This annotation processing step also generates
# GeneratedJNIWrappers.h and GeneratedJNINatives.h
GeneratedJNIWrappers.cpp: $(ANNOTATION_PROCESSOR_JAR_FILES)
GeneratedJNIWrappers.cpp: $(ALL_JARS)
$(JAVA) -classpath constants.jar:$(JAVA_BOOTCLASSPATH):$(JAVA_CLASSPATH):$(ANNOTATION_PROCESSOR_JAR_FILES) org.mozilla.gecko.annotationProcessors.AnnotationProcessor $(ALL_JARS)
manifest := \
AndroidManifest.xml.in \
fennec_ids.txt.in \
$(NULL)
PP_TARGETS += manifest
# Certain source files need to be preprocessed. This special rule
# generates these files into generated/org/mozilla/gecko for
# consumption by the build system and IDEs.
# The list in moz.build looks like
# 'preprocessed/org/mozilla/gecko/AppConstants.java'. The list in
# constants_PP_JAVAFILES looks like
# 'generated/preprocessed/org/mozilla/gecko/AppConstants.java'. We
# need to write AppConstants.java.in to
# generated/preprocessed/org/mozilla/gecko.
preprocessed := $(addsuffix .in,$(subst generated/preprocessed/org/mozilla/gecko/,,$(filter generated/preprocessed/org/mozilla/gecko/%,$(constants_PP_JAVAFILES))))
preprocessed_PATH := generated/preprocessed/org/mozilla/gecko
preprocessed_KEEP_PATH := 1
preprocessed_FLAGS := --marker='//\\\#'
ifdef MOZ_INSTALL_TRACKING
ifdef MOZ_INSTALL_TRACKING_ADJUST_SDK_APP_TOKEN
# The value of MOZ_INSTALL_TRACKING_ADJUST_SDK_APP_TOKEN is sensitive: we don't
# want to expose it in build logs. Following the model set by
# toolkit/components/urlformatter/Makefile.in, we expose it to AppConstants.java
# quietly here. Be aware that the included line's marker needs to agree with
# --marker above.
adjust_sdk_app_token:
@echo '//#define MOZ_INSTALL_TRACKING_ADJUST_SDK_APP_TOKEN $(MOZ_INSTALL_TRACKING_ADJUST_SDK_APP_TOKEN)' > $@
export:: adjust_sdk_app_token
preprocessed_FLAGS += -I adjust_sdk_app_token
endif # MOZ_INSTALL_TRACKING
endif # MOZ_INSTALL_TRACKING_ADJUST_SDK_APP_TOKEN
GARBAGE += adjust_sdk_app_token
PP_TARGETS += preprocessed
include $(topsrcdir)/config/rules.mk
not_android_res_files := \
*.mkdir.done* \
*.DS_Store* \
*\#* \
*.rej \
*.orig \
$(NULL)
# This uses the fact that Android resource directories list all
# resource files one subdirectory below the parent resource directory.
android_res_files := $(filter-out $(not_android_res_files),$(wildcard $(addsuffix /*,$(wildcard $(addsuffix /*,$(ANDROID_RES_DIRS))))))
$(ANDROID_GENERATED_RESFILES): $(call mkdir_deps,$(sort $(dir $(ANDROID_GENERATED_RESFILES))))
# [Comment 1/3] We don't have correct dependencies for strings.xml at
# this point, so we always recursively invoke the submake to check the
# dependencies. Sigh. And, with multilocale builds, there will be
# multiple strings.xml files, and we need to rebuild gecko.ap_ if any
# of them change. But! mobile/android/base/locales does not have
# enough information to actually build res/values/strings.xml during a
# language repack. So rather than adding rules into the main
# makefile, and trying to work around the lack of information, we
# force a rebuild of gecko.ap_ during packaging. See below.
# Since the sub-Make is forced, it doesn't matter that we touch the
# target file before the command. If in the future we stop forcing
# the sub-Make, touching the target file first is better, because the
# sub-Make outputs will be fresher than the target, and not require
# rebuilding. This is all safe because Make removes the target file
# if any recipe command fails. It is crucial that the sub-Make touch
# the target files (those depending on .locales.deps) only when there
# contents have changed; otherwise, this will force rebuild them as
# part of every build.
.locales.deps: FORCE
$(TOUCH) $@
$(MAKE) -C locales
# This .deps pattern saves an invocation of the sub-Make: the single
# invocation generates strings.xml, browsersearch.json, and
# suggestedsites.json. The trailing semi-colon defines an empty
# recipe: defining no recipe at all causes Make to treat the target
# differently, in a way that defeats our dependencies.
res/values/strings.xml: .locales.deps ;
res/raw/browsersearch.json: .locales.deps ;
res/raw/suggestedsites.json: .locales.deps ;
all_resources = \
$(abspath $(CURDIR)/AndroidManifest.xml) \
$(android_res_files) \
$(ANDROID_GENERATED_RESFILES) \
$(NULL)
# For GeckoView, we want a zip of an Android res/ directory that
# merges the contents of all the ANDROID_RES_DIRS. The inner res/
# directory must have the Android resource two-layer hierarchy.
# The following helper zips files in a directory into a zip file while
# maintaining the directory structure rooted below the directory.
# (adding or creating said file as appropriate). For example, if the
# dir contains dir/subdir/file, calling with directory dir would
# create a zip containing subdir/file. Note: the trailing newline is
# necessary.
# $(1): zip file to add to (or create).
# $(2): directory to zip contents of.
define zip_directory_with_relative_paths
cd $(2) && zip -q $(1) -r * -x $(subst *,\*,$(not_android_res_files))
endef
ifndef MOZ_DISABLE_GECKOVIEW
# We delete the archive before updating so that resources removed from
# the filesystem are removed from the archive.
geckoview_resources.zip: $(all_resources) $(GLOBAL_DEPS)
$(REPORT_BUILD)
$(RM) -rf $@
$(foreach dir,$(ANDROID_RES_DIRS),$(call zip_directory_with_relative_paths,$(CURDIR)/$@,$(dir)))
endif
# All of generated/org/mozilla/gecko/R.java, gecko.ap_, and R.txt are
# produced by aapt; this saves aapt invocations. The trailing
# semi-colon defines an empty recipe; defining no recipe at all causes
# Make to treat the target differently, in a way that defeats our
# dependencies.
generated/org/mozilla/gecko/R.java: .aapt.deps ;
# If native devices are enabled, add Google Play Services, build their resources
generated/android/support/v4/R.java: .aapt.deps ;
generated/android/support/v7/appcompat/R.java: .aapt.deps ;
generated/android/support/v7/mediarouter/R.java: .aapt.deps ;
generated/android/support/v7/recyclerview/R.java: .aapt.deps ;
generated/com/google/android/gms/R.java: .aapt.deps ;
generated/com/google/android/gms/base/R.java: .aapt.deps ;
generated/com/google/android/gms/cast/R.java: .aapt.deps ;
gecko.ap_: .aapt.deps ;
R.txt: .aapt.deps ;
# [Comment 2/3] This tom-foolery provides a target that forces a
# rebuild of gecko.ap_. This is used during packaging to ensure that
# resources are fresh. The alternative would be complicated; see
# [Comment 1/3].
gecko-nodeps/R.java: .aapt.nodeps ;
gecko-nodeps.ap_: .aapt.nodeps ;
gecko-nodeps/R.txt: .aapt.nodeps ;
# This ignores the default set of resources ignored by aapt, plus
# files starting with '#'. (Emacs produces temp files named #temp#.)
# This doesn't actually set the environment variable; it's used as a
# parameter in the aapt invocation below. Consider updating
# not_android_res_files as well.
ANDROID_AAPT_IGNORE := !.svn:!.git:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~:\#*:*.rej:*.orig
# 1: target file.
# 2: dependencies.
# 3: name of ap_ file to write.
# 4: directory to write R.java into.
# 5: directory to write R.txt into.
# We touch the target file before invoking aapt so that aapt's outputs
# are fresher than the target, preventing a subsequent invocation from
# thinking aapt's outputs are stale. This is safe because Make
# removes the target file if any recipe command fails.
CONSTRAINED_AAPT_CONFIGURATIONS := hdpi
define aapt_command
$(1): $$(call mkdir_deps,$(filter-out ./,$(dir $(3) $(4) $(5)))) $(2)
@$$(TOUCH) $$@
$$(AAPT) package -f -m \
-M AndroidManifest.xml \
-I $(ANDROID_SDK)/android.jar \
$(if $(MOZ_ANDROID_MAX_SDK_VERSION),--max-res-version $(MOZ_ANDROID_MAX_SDK_VERSION),) \
--auto-add-overlay \
$$(addprefix -S ,$$(ANDROID_RES_DIRS)) \
$$(addprefix -A ,$$(ANDROID_ASSETS_DIRS)) \
$(if $(ANDROID_EXTRA_PACKAGES),--extra-packages $$(subst $$(NULL) ,:,$$(strip $$(ANDROID_EXTRA_PACKAGES)))) \
$(if $(ANDROID_EXTRA_RES_DIRS),$$(addprefix -S ,$$(ANDROID_EXTRA_RES_DIRS))) \
--custom-package org.mozilla.gecko \
--non-constant-id \
-F $(3) \
-J $(4) \
--output-text-symbols $(5) \
$(if $(MOZ_ANDROID_RESOURCE_CONSTRAINED),-c $(CONSTRAINED_AAPT_CONFIGURATIONS),) \
--ignore-assets "$$(ANDROID_AAPT_IGNORE)"
endef
# [Comment 3/3] The first of these rules is used during regular
# builds. The second writes an ap_ file that is only used during
# packaging. It doesn't write the normal ap_, or R.java, since we
# don't want the packaging step to write anything that would make a
# further no-op build do work. See also
# toolkit/mozapps/installer/packager.mk.
# .aapt.deps: $(all_resources)
$(eval $(call aapt_command,.aapt.deps,$(all_resources),gecko.ap_,generated/,./))
# .aapt.nodeps: $(abspath $(CURDIR)/AndroidManifest.xml) FORCE
$(eval $(call aapt_command,.aapt.nodeps,$(abspath $(CURDIR)/AndroidManifest.xml) FORCE,gecko-nodeps.ap_,gecko-nodeps/,gecko-nodeps/))
# Override the Java settings with some specific android settings
include $(topsrcdir)/config/android-common.mk
update-generated-wrappers:
@cp $(CURDIR)/jni-stubs.inc $(topsrcdir)/mozglue/android
@cp $(CURDIR)/GeneratedJNIWrappers.cpp $(CURDIR)/GeneratedJNIWrappers.h $(CURDIR)/GeneratedJNINatives.h $(topsrcdir)/widget/android
@echo Updated generated JNI code
.PHONY: update-generated-wrappers
# This target is only used by IDE integrations. It rebuilds resources
# that end up in omni.ja, does most of the packaging step, and then
# updates omni.ja in place. If you're not using an IDE, you should be
# using |mach build mobile/android && mach package|.
$(abspath $(DIST)/fennec/$(OMNIJAR_NAME)): FORCE
$(REPORT_BUILD)
$(MAKE) -C ../locales
$(MAKE) -C ../chrome
$(MAKE) -C ../components
$(MAKE) -C ../modules
$(MAKE) -C ../app
$(MAKE) -C ../themes/core
$(MAKE) -C ../installer stage-package
$(MKDIR) -p $(@D)
rsync --update $(DIST)/fennec/$(notdir $(OMNIJAR_NAME)) $@
$(RM) $(DIST)/fennec/$(notdir $(OMNIJAR_NAME))
# Targets built very early during a Gradle build.
gradle-targets: $(foreach f,$(constants_PP_JAVAFILES),$(f))
gradle-targets: $(abspath AndroidManifest.xml)
gradle-targets: $(ANDROID_GENERATED_RESFILES)
gradle-omnijar: $(abspath $(DIST)/fennec/$(OMNIJAR_NAME))
.PHONY: gradle-targets gradle-omnijar
ifndef MOZ_DISABLE_GECKOVIEW
libs:: geckoview_resources.zip
$(INSTALL) geckoview_resources.zip $(FINAL_TARGET)
endif
# GeneratedJNIWrappers.cpp target also generates
# GeneratedJNIWrappers.h and GeneratedJNINatives.h
libs:: classes.dex jni-stubs.inc GeneratedJNIWrappers.cpp $(CURDIR)/fennec_ids.txt
$(INSTALL) classes.dex $(FINAL_TARGET)
@(diff jni-stubs.inc $(topsrcdir)/mozglue/android/jni-stubs.inc >/dev/null && \
diff GeneratedJNIWrappers.cpp $(topsrcdir)/widget/android/GeneratedJNIWrappers.cpp >/dev/null && \
diff GeneratedJNIWrappers.h $(topsrcdir)/widget/android/GeneratedJNIWrappers.h >/dev/null && \
diff GeneratedJNINatives.h $(topsrcdir)/widget/android/GeneratedJNINatives.h >/dev/null) || \
(echo '*****************************************************' && \
echo '*** Error: The generated JNI code has changed ***' && \
echo '* To update generated code in the tree, please run *' && \
echo && \
echo ' make -C $(CURDIR) update-generated-wrappers' && \
echo && \
echo '* Repeat the build, and check in any changes. *' && \
echo '*****************************************************' && \
exit 1)