Bug 1119520 - Add opt-in Gradle build mode for mobile/android. r?gps
Opt-in by adding --enable-gradle-mobile-android-builds.
Gradle dependencies (including the Android-Gradle plugin) are assumed
to be present. Local developers will fetch them from the jcentral
repository.
Android-specific Maven dependencies are shipped as "extras" with the
Android SDK, and should be found automatically by the Android-Gradle
plugin.
MozReview-Commit-ID: 966XgddWgEu
--- a/configure.in
+++ b/configure.in
@@ -3765,16 +3765,17 @@ MOZ_PEERCONNECTION=
MOZ_SRTP=
MOZ_WEBRTC_SIGNALING=
MOZ_WEBRTC_ASSERT_ALWAYS=1
MOZ_WEBRTC_HARDWARE_AEC_NS=
MOZ_SCTP=
MOZ_ANDROID_OMX=
MOZ_MEDIA_NAVIGATOR=
MOZ_OMX_PLUGIN=
+MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE=
MOZ_VPX_ERROR_CONCEALMENT=
MOZ_WEBSPEECH=1
MOZ_WEBSPEECH_MODELS=
MOZ_WEBSPEECH_POCKETSPHINX=
MOZ_WEBSPEECH_TEST_BACKEND=1
VPX_AS=
VPX_ASFLAGS=
VPX_AS_CONVERSION=
@@ -5373,18 +5374,36 @@ MOZ_ARG_ENABLE_BOOL(omx-plugin,
MOZ_OMX_PLUGIN=1,
MOZ_OMX_PLUGIN=)
if test -n "$MOZ_OMX_PLUGIN"; then
if test "$OS_TARGET" = "Android"; then
dnl Only allow building OMX plugin on Gonk (B2G) or Android
AC_DEFINE(MOZ_OMX_PLUGIN)
else
- dnl fail if we're not building on Gonk or Android
- AC_MSG_ERROR([OMX media plugin can only be built on B2G or Android])
+ dnl fail if we're not building on Gonk or Android
+ AC_MSG_ERROR([OMX media plugin can only be built on B2G or Android])
+ fi
+fi
+
+dnl ========================================================
+dnl = Enable building mobile/android with Gradle
+dnl ========================================================
+MOZ_ARG_ENABLE_BOOL(gradle-mobile-android-builds,
+[ --enable-gradle-mobile-android-builds Enable building mobile/android with Gradle],
+ MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE=1,
+ MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE=)
+
+if test -n "$MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE"; then
+ if test "$OS_TARGET" = "Android" -a x"$MOZ_WIDGET_TOOLKIT" != x"gonk"; then
+ dnl Only allow building mobile/android with Gradle.
+ AC_DEFINE(MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE)
+ else
+ dnl fail if we're not building mobile/android.
+ AC_MSG_ERROR([Can only build mobile/android with Gradle])
fi
fi
dnl system libvpx Support
dnl ========================================================
MOZ_ARG_WITH_BOOL(system-libvpx,
[ --with-system-libvpx Use system libvpx (located with pkgconfig)],
MOZ_NATIVE_LIBVPX=1)
@@ -8914,16 +8933,17 @@ AC_SUBST(MOZ_FFVPX)
AC_SUBST(FFVPX_AS)
AC_SUBST_LIST(FFVPX_ASFLAGS)
AC_SUBST(MOZ_FMP4)
AC_SUBST(MOZ_EME)
AC_SUBST(MOZ_DIRECTSHOW)
AC_SUBST(MOZ_ANDROID_OMX)
AC_SUBST(MOZ_APPLEMEDIA)
AC_SUBST(MOZ_OMX_PLUGIN)
+AC_SUBST(MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE)
AC_SUBST(MOZ_VPX_ERROR_CONCEALMENT)
AC_SUBST(VPX_AS)
AC_SUBST_LIST(VPX_ASFLAGS)
AC_SUBST(VPX_AS_CONVERSION)
AC_SUBST(VPX_ASM_SUFFIX)
AC_SUBST(VPX_X86_ASM)
AC_SUBST(VPX_ARM_ASM)
AC_SUBST(VPX_NEED_OBJ_INT_EXTRACT)
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -1,12 +1,18 @@
# 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/.
+# We call mach -> Make -> gradle -> mach, which races to find and
+# create .mozconfig files and to generate targets.
+ifdef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
+.NOTPARALLEL:
+endif
+
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) \
@@ -196,19 +202,31 @@ library_jars := \
# See https://bugzilla.mozilla.org/show_bug.cgi?id=1233238#c19 for symptoms and
# more discussion.
ifdef MOZ_INSTALL_TRACKING
library_jars += $(ANDROID_SDK)/optional/org.apache.http.legacy.jar
endif # MOZ_INSTALL_TRACKING
library_jars := $(subst $(NULL) ,:,$(strip $(library_jars)))
+gradle_dir := $(topobjdir)/gradle/build/mobile/android
+
+ifdef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
+.gradle.deps: .aapt.deps FORCE
+ @$(TOUCH) $@
+ $(topsrcdir)/mach gradle --no-daemon --offline app:dexAutomationDebug app:assembleAutomationDebugAndroidTest -x lint
+
+classes.dex: .gradle.deps
+ $(REPORT_BUILD)
+ cp $(gradle_dir)/app/intermediates/dex/automation/debug/classes.dex $@
+else
classes.dex: .proguard.deps
$(REPORT_BUILD)
$(DX) --dex --output=classes.dex jars-proguarded
+endif
ifdef MOZ_DISABLE_PROGUARD
PROGUARD_PASSES=0
else
ifdef MOZ_DEBUG
PROGUARD_PASSES=1
else
ifndef MOZILLA_OFFICIAL
@@ -496,18 +514,23 @@ endef
# 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/))
+ifdef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
+.aapt.nodeps: FORCE
+ cp $(gradle_dir)/app/intermediates/res/resources-automation-debug.ap_ gecko-nodeps.ap_
+else
+# .aapt.nodeps: $(CURDIR)/AndroidManifest.xml FORCE
+$(eval $(call aapt_command,.aapt.nodeps,$(CURDIR)/AndroidManifest.xml FORCE,gecko-nodeps.ap_,gecko-nodeps/,gecko-nodeps/))
+endif
# 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
@@ -527,34 +550,47 @@ update-generated-wrappers:
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: $(ABS_DIST)/fennec/$(OMNIJAR_NAME)
+ifndef MOZILLA_OFFICIAL
+# Local developers update omni.ja during their builds. There's a
+# chicken-and-egg problem here.
+gradle-omnijar: $(abspath $(DIST)/fennec/$(OMNIJAR_NAME))
+else
+# In automation, omni.ja is built only during packaging.
+gradle-omnijar:
+endif
.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)
+ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
+libs:: jni-stubs.inc GeneratedJNIWrappers.cpp
@(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)
+endif
+
+libs:: $(CURDIR)/fennec_ids.txt
+
+libs:: classes.dex
+ $(INSTALL) classes.dex $(FINAL_TARGET)
--- a/mobile/android/mach_commands.py
+++ b/mobile/android/mach_commands.py
@@ -16,26 +16,16 @@ from mozbuild.base import (
)
from mach.decorators import (
CommandArgument,
CommandProvider,
Command,
)
-SUCCESS = '''
-You should be ready to build with Gradle and import into IntelliJ! Test with
-
- ./mach gradle build
-
-and in IntelliJ select File > Import project... and choose
-
- {topobjdir}/mobile/android/gradle
-'''
-
# NOTE python/mach/mach/commands/commandinfo.py references this function
# by name. If this function is renamed or removed, that file should
# be updated accordingly as well.
def REMOVED(cls):
"""Command no longer exists! Use the Gradle configuration rooted in the top source directory instead.
See https://developer.mozilla.org/en-US/docs/Simple_Firefox_for_Android_build#Developing_Firefox_for_Android_in_Android_Studio_or_IDEA_IntelliJ.
--- a/mobile/android/moz.build
+++ b/mobile/android/moz.build
@@ -26,13 +26,14 @@ DIRS += [
'geckoview_library',
]
if CONFIG['MOZ_ANDROID_PACKAGE_INSTALL_BOUNCER']:
DIRS += ['bouncer'] # No ordering implied with respect to base.
DIRS += ['../../xulrunner/tools/redit']
-TEST_DIRS += [
- 'tests',
-]
+if not CONFIG['MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE']:
+ TEST_DIRS += [
+ 'tests',
+ ]
SPHINX_TREES['fennec'] = 'docs'
--- a/python/mozbuild/mozbuild/mozconfig.py
+++ b/python/mozbuild/mozbuild/mozconfig.py
@@ -102,17 +102,17 @@ class MozconfigLoader(ProcessExecutionMi
MozconfigFindException will be raised if there is a bad state,
including conditions from #3 above.
"""
# Check for legacy methods first.
if 'MOZ_MYCONFIG' in env:
raise MozconfigFindException(MOZ_MYCONFIG_ERROR)
- env_path = env.get('MOZCONFIG', None)
+ env_path = env.get('MOZCONFIG', None) or None
if env_path is not None:
if not os.path.isabs(env_path):
potential_roots = [self.topsrcdir, os.getcwd()]
# Attempt to eliminate duplicates for e.g.
# self.topsrcdir == os.curdir.
potential_roots = set(os.path.abspath(p) for p in potential_roots)
existing = [root for root in potential_roots
if os.path.exists(os.path.join(root, env_path))]
--- a/testing/instrumentation/Makefile.in
+++ b/testing/instrumentation/Makefile.in
@@ -9,15 +9,17 @@ include $(topsrcdir)/config/rules.mk
# Fennec and all instrumentation tests need to be signed with the same
# key, which means release signing them all.
include $(topsrcdir)/config/android-common.mk
stage-package:
$(NSINSTALL) -D $(_DEST_DIR)
+ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
$(call RELEASE_SIGN_ANDROID_APK,\
$(DEPTH)/mobile/android/tests/background/junit3/background-junit3-debug-unsigned-unaligned.apk,\
$(_DEST_DIR)/background-junit3.apk)
$(call RELEASE_SIGN_ANDROID_APK,\
$(DEPTH)/mobile/android/tests/browser/junit3/browser-junit3-debug-unsigned-unaligned.apk,\
$(_DEST_DIR)/browser-junit3.apk)
+endif
@(cd $(DEPTH)/_tests/ && tar $(TAR_CREATE_FLAGS) - instrumentation) | (cd $(PKG_STAGE) && tar -xf -)
--- a/testing/mochitest/Makefile.in
+++ b/testing/mochitest/Makefile.in
@@ -102,21 +102,25 @@ GMP_TEST_PLUGIN_DIRS := \
$(_DEST_DIR):
$(NSINSTALL) -D $@
# On Android only, include a release signed Robocop APK in the test package.
ifeq ($(MOZ_BUILD_APP),mobile/android)
include $(topsrcdir)/config/android-common.mk
+ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
+robocop_apk := $(topobjdir)/mobile/android/tests/browser/robocop/robocop-debug-unsigned-unaligned.apk
+else
+robocop_apk := $(topobjdir)/gradle/build/mobile/android/app/outputs/apk/app-automation-debug-androidTest-unaligned.apk
+endif
+
stage-package-android:
$(NSINSTALL) -D $(_DEST_DIR)
- $(call RELEASE_SIGN_ANDROID_APK,\
- $(DEPTH)/mobile/android/tests/browser/robocop/robocop-debug-unsigned-unaligned.apk,\
- $(_DEST_DIR)/robocop.apk)
+ $(call RELEASE_SIGN_ANDROID_APK,$(robocop_apk),$(_DEST_DIR)/robocop.apk)
stage-package: stage-package-android
endif
stage-package:
$(NSINSTALL) -D $(PKG_STAGE)/mochitest && $(NSINSTALL) -D $(PKG_STAGE)/bin/plugins && $(NSINSTALL) -D $(DIST)/plugins
cp $(DEPTH)/mozinfo.json $(PKG_STAGE)/mochitest
@cp $(DEPTH)/mozinfo.json $(PKG_STAGE)/mochitest
--- a/toolkit/mozapps/installer/upload-files.mk
+++ b/toolkit/mozapps/installer/upload-files.mk
@@ -320,23 +320,28 @@ ifeq ($(MOZ_BUILD_APP),mobile/android)
UPLOAD_EXTRA_FILES += robocop.apk
UPLOAD_EXTRA_FILES += fennec_ids.txt
UPLOAD_EXTRA_FILES += geckoview_library/geckoview_library.zip
UPLOAD_EXTRA_FILES += geckoview_library/geckoview_assets.zip
# Robocop/Robotium tests, Android Background tests, and Fennec need to
# be signed with the same key, which means release signing them all.
-ROBOCOP_PATH = $(topobjdir)/mobile/android/tests/browser/robocop
+ifndef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
+robocop_apk := $(topobjdir)/mobile/android/tests/browser/robocop/robocop-debug-unsigned-unaligned.apk
+else
+robocop_apk := $(topobjdir)/gradle/build/mobile/android/app/outputs/apk/app-automation-debug-androidTest-unaligned.apk
+endif
+
# Normally, $(NSINSTALL) would be used instead of cp, but INNER_ROBOCOP_PACKAGE
# is used in a series of commands that run under a "cd something", while
# $(NSINSTALL) is relative.
INNER_ROBOCOP_PACKAGE= \
cp $(GECKO_APP_AP_PATH)/fennec_ids.txt $(ABS_DIST) && \
- $(call RELEASE_SIGN_ANDROID_APK,$(ROBOCOP_PATH)/robocop-debug-unsigned-unaligned.apk,$(ABS_DIST)/robocop.apk)
+ $(call RELEASE_SIGN_ANDROID_APK,$(robocop_apk),$(ABS_DIST)/robocop.apk)
endif
else
INNER_ROBOCOP_PACKAGE=echo 'Testing is disabled - No Android Robocop for you'
endif
ifdef MOZ_ANDROID_PACKAGE_INSTALL_BOUNCER
UPLOAD_EXTRA_FILES += bouncer.apk
@@ -465,16 +470,25 @@ OMNIJAR_NAME := $(notdir $(OMNIJAR_NAME)
# and the res/ directory is taken from the ap_ as part of the regular
# packaging.
PKG_SUFFIX = .apk
INNER_SZIP_LIBRARIES = \
$(if $(ALREADY_SZIPPED),,$(foreach lib,$(SZIP_LIBRARIES),host/bin/szip $(MOZ_SZIP_FLAGS) $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/$(lib) && )) true
+ifdef MOZ_BUILD_MOBILE_ANDROID_WITH_GRADLE
+INNER_CHECK_R_TXT=echo 'No R.txt checking for you!'
+else
+INNER_CHECK_R_TXT=\
+ ((test ! -f $(GECKO_APP_AP_PATH)/R.txt && echo "*** Warning: The R.txt that is being packaged might not agree with the R.txt that was built. This is normal during l10n repacks.") || \
+ diff $(GECKO_APP_AP_PATH)/R.txt $(GECKO_APP_AP_PATH)/gecko-nodeps/R.txt >/dev/null || \
+ (echo "*** Error: The R.txt that was built and the R.txt that is being packaged are not the same. Rebuild mobile/android/base and re-package." && exit 1))
+endif
+
# Insert $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/classes.dex into
# $(ABS_DIST)/gecko.ap_, producing $(ABS_DIST)/gecko.apk.
INNER_MAKE_APK = \
( cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && \
unzip -o $(ABS_DIST)/gecko.ap_ && \
rm $(ABS_DIST)/gecko.ap_ && \
$(ZIP) -r9D $(ABS_DIST)/gecko.ap_ assets && \
$(ZIP) $(if $(ALREADY_SZIPPED),-0 ,$(if $(MOZ_ENABLE_SZIP),-0 ))$(ABS_DIST)/gecko.ap_ $(ASSET_SO_LIBRARIES) && \
@@ -485,32 +499,30 @@ INNER_MAKE_APK = \
rm -f $(ABS_DIST)/gecko.apk && \
cp $(ABS_DIST)/gecko.ap_ $(ABS_DIST)/gecko.apk && \
$(ZIP) -j0 $(ABS_DIST)/gecko.apk $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/classes.dex && \
cp $(ABS_DIST)/gecko.apk $(ABS_DIST)/gecko-unsigned-unaligned.apk && \
$(RELEASE_JARSIGNER) $(ABS_DIST)/gecko.apk && \
$(ZIPALIGN) -f -v 4 $(ABS_DIST)/gecko.apk $(PACKAGE)
ifeq ($(MOZ_BUILD_APP),mobile/android)
-INNER_MAKE_PACKAGE = \
+INNER_MAKE_PACKAGE = \
$(INNER_SZIP_LIBRARIES) && \
make -C $(GECKO_APP_AP_PATH) gecko-nodeps.ap_ && \
cp $(GECKO_APP_AP_PATH)/gecko-nodeps.ap_ $(ABS_DIST)/gecko.ap_ && \
- ( (test ! -f $(GECKO_APP_AP_PATH)/R.txt && echo "*** Warning: The R.txt that is being packaged might not agree with the R.txt that was built. This is normal during l10n repacks.") || \
- diff $(GECKO_APP_AP_PATH)/R.txt $(GECKO_APP_AP_PATH)/gecko-nodeps/R.txt >/dev/null || \
- (echo "*** Error: The R.txt that was built and the R.txt that is being packaged are not the same. Rebuild mobile/android/base and re-package." && exit 1)) && \
+ $(INNER_CHECK_R_TXT) && \
$(INNER_MAKE_APK) && \
$(INNER_ROBOCOP_PACKAGE) && \
$(INNER_INSTALL_BOUNCER_PACKAGE) && \
$(INNER_MAKE_GECKOLIBS_AAR) && \
$(INNER_MAKE_GECKOVIEW_LIBRARY)
endif
ifeq ($(MOZ_BUILD_APP),mobile/android/b2gdroid)
-INNER_MAKE_PACKAGE = \
+INNER_MAKE_PACKAGE = \
$(INNER_SZIP_LIBRARIES) && \
cp $(topobjdir)/mobile/android/b2gdroid/app/classes.dex $(ABS_DIST)/classes.dex && \
cp $(topobjdir)/mobile/android/b2gdroid/app/b2gdroid-unsigned-unaligned.apk $(ABS_DIST)/gecko.ap_ && \
$(INNER_MAKE_APK)
endif
# Language repacks root the resources contained in assets/omni.ja
# under assets/, but the repacks expect them to be rooted at /.