Bug 1093242 - Produce and upload geckolibs artifacts for Android API v11+ opt builds. r=gps
authorNick Alexander <nalexander@mozilla.com>
Tue, 17 Feb 2015 17:23:23 -0800
changeset 230066 19343180c28835fff941092e05e76e421129c2c2
parent 230065 cc01cf09928cfae75fd2b067cca3063331488a4a
child 230067 8eef92e67922b2800fe95efe0d5e635ce365e925
push id28306
push userkwierso@gmail.com
push dateSat, 21 Feb 2015 02:06:27 +0000
treeherdermozilla-central@45a77b0aba15 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps
bugs1093242
milestone38.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1093242 - Produce and upload geckolibs artifacts for Android API v11+ opt builds. r=gps The Android ARchive contains the compiled Gecko libraries that Firefox for Android interfaces to. It does not contain the Gecko resources (the omnijar, omni.ja) nor the compiled Java code (classes.dex). This also uploads metadata and sha1 hashes for future consumption by Maven and/or Ivy dependency managers. In some brave future world, we'll work out exactly what that looks like; for now, this solves a storage problem (each .aar file is ~20MB) and it's possible to point Gradle directly at the uploaded Ivy metadata and artifacts.
configure.in
mobile/android/config/mozconfigs/android-api-11/nightly
mobile/android/geckoview_library/geckolibs/AndroidManifest.xml
mobile/android/geckoview_library/geckolibs/classes.jar
python/mozbuild/mozbuild/action/package_geckolibs_aar.py
python/mozbuild/mozbuild/util.py
toolkit/mozapps/installer/upload-files.mk
--- a/configure.in
+++ b/configure.in
@@ -8530,16 +8530,17 @@ AC_SUBST(MOZ_D3DCOMPILER_XP_CAB)
 
 AC_SUBST(MOZ_METRO)
 
 AC_SUBST(MOZ_ANDROID_HISTORY)
 AC_SUBST(MOZ_WEBSMS_BACKEND)
 AC_SUBST(MOZ_ANDROID_BEAM)
 AC_SUBST(MOZ_LOCALE_SWITCHER)
 AC_SUBST(MOZ_DISABLE_GECKOVIEW)
+AC_SUBST(MOZ_ANDROID_GECKOLIBS_AAR)
 AC_SUBST(MOZ_ANDROID_READING_LIST_SERVICE)
 AC_SUBST(MOZ_ANDROID_SEARCH_ACTIVITY)
 AC_SUBST(MOZ_ANDROID_SHARE_OVERLAY)
 AC_SUBST(MOZ_ANDROID_TAB_QUEUE)
 AC_SUBST(MOZ_ANDROID_MLS_STUMBLER)
 AC_SUBST(MOZ_ANDROID_DOWNLOADS_INTEGRATION)
 AC_SUBST(ENABLE_STRIP)
 AC_SUBST(PKG_SKIP_STRIP)
--- a/mobile/android/config/mozconfigs/android-api-11/nightly
+++ b/mobile/android/config/mozconfigs/android-api-11/nightly
@@ -10,9 +10,11 @@ ac_add_options --with-branding=mobile/an
 
 # This will overwrite the default of stripping everything and keep the symbol table.
 # This is useful for profiling with eideticker. See bug 788680
 STRIP_FLAGS="--strip-debug"
 
 export MOZILLA_OFFICIAL=1
 export MOZ_TELEMETRY_REPORTING=1
 
+MOZ_ANDROID_GECKOLIBS_AAR=1
+
 . "$topsrcdir/mobile/android/config/mozconfigs/common.override"
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview_library/geckolibs/AndroidManifest.xml
@@ -0,0 +1,4 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.mozilla.gecko.libs">
+
+</manifest>
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..09af11bda0c895e33494d4aac83c1171c3267ab8
GIT binary patch
literal 473
zc$^FHW@Zs#-~d9QZXY)WB*4kQ!r<!~;;8HC=cfPf6axb@Lx49s2S|zusw4oXW)UEU
zYxZ^Y^K^3!4$<><`|Nw>w2!y0-bG$-U9EFx&TkGfxMKX^X_20nua2kh#nM$QoHJfZ
z9+^E;E5kxe<jE4Pif5{?Gd~r5EMf%PUhi&k+y-d24T|lIXtr~MY$s&tBPOtkc}LWn
zB!TM1!6q^?i7=r02<BH%aG(N|z(LoF>`)ODZMHaq2H6CVhmak{jbg%XRPP0Nv$BDN
NnSpQ{kmh9s@c<k|S;PPU
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/action/package_geckolibs_aar.py
@@ -0,0 +1,125 @@
+# 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/.
+
+'''
+Script to produce an Android ARchive (.aar) containing the compiled
+Gecko library binaries.  The AAR file is intended for use by local
+developers using Gradle.
+'''
+
+from __future__ import print_function
+
+import argparse
+import hashlib
+import os
+import sys
+
+from mozbuild import util
+from mozpack.copier import Jarrer
+from mozpack.files import (
+    File,
+    FileFinder,
+)
+
+MAVEN_POM_TEMPLATE = r'''
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>{groupId}</groupId>
+  <artifactId>{artifactId}</artifactId>
+  <version>{version}</version>
+  <packaging>{packaging}</packaging>
+</project>
+'''.lstrip()
+
+IVY_XML_TEMPLATE = r'''
+<?xml version="1.0" encoding="UTF-8"?>
+<ivy-module version="2.0">
+  <info organisation="{organisation}" module="{module}" revision="{revision}" status="integration" publication="{publication}"/>
+  <configurations/>
+  <publications>
+    <artifact name="{name}" type="{type}" ext="{ext}"/>
+  </publications>
+  <dependencies/>
+</ivy-module>
+'''.lstrip()
+
+def package_geckolibs_aar(topsrcdir, distdir, output_file):
+    jarrer = Jarrer(optimize=False)
+
+    srcdir = os.path.join(topsrcdir, 'mobile', 'android', 'geckoview_library', 'geckolibs')
+    jarrer.add('AndroidManifest.xml', File(os.path.join(srcdir, 'AndroidManifest.xml')))
+    jarrer.add('classes.jar', File(os.path.join(srcdir, 'classes.jar')))
+
+    jni = FileFinder(os.path.join(distdir, 'fennec', 'lib'))
+    for p, f in jni.find('**/*.so'):
+        jarrer.add(os.path.join('jni', p), f)
+
+    # Include the buildinfo JSON as an asset, to give future consumers at least
+    # a hope of determining where this AAR came from.
+    json = FileFinder(distdir, ignore=['*.mozinfo.json'])
+    for p, f in json.find('*.json'):
+        jarrer.add(os.path.join('assets', p), f)
+
+    # This neatly ignores omni.ja.
+    assets = FileFinder(os.path.join(distdir, 'fennec', 'assets'))
+    for p, f in assets.find('**/*.so'):
+        jarrer.add(os.path.join('assets', p), f)
+
+    jarrer.copy(output_file)
+    return 0
+
+
+def main(args):
+    parser = argparse.ArgumentParser()
+    parser.add_argument(dest='dir',
+                        metavar='DIR',
+                        help='Path to write geckolibs Android ARchive and metadata to.')
+    parser.add_argument('--revision',
+                        help='Revision identifier to write.')
+    parser.add_argument('--topsrcdir',
+                        help='Top source directory.')
+    parser.add_argument('--distdir',
+                        help='Distribution directory (usually $OBJDIR/dist).')
+    args = parser.parse_args(args)
+
+    paths_to_hash = []
+
+    aar = os.path.join(args.dir, 'geckolibs-{revision}.aar').format(revision=args.revision)
+    paths_to_hash.append(aar)
+    package_geckolibs_aar(args.topsrcdir, args.distdir, aar)
+
+    pom = os.path.join(args.dir, 'geckolibs-{revision}.pom').format(revision=args.revision)
+    paths_to_hash.append(pom)
+    with open(pom, 'wt') as f:
+        f.write(MAVEN_POM_TEMPLATE.format(
+            groupId='org.mozilla',
+            artifactId='geckolibs',
+            version=args.revision,
+            packaging='aar',
+        ))
+
+    ivy = os.path.join(args.dir, 'ivy-geckolibs-{revision}.xml').format(revision=args.revision)
+    paths_to_hash.append(ivy)
+    with open(ivy, 'wt') as f:
+        f.write(IVY_XML_TEMPLATE.format(
+            organisation='org.mozilla',
+            module='geckolibs',
+            revision=args.revision,
+            publication=args.revision, # A white lie.
+            name='geckolibs',
+            type='aar',
+            ext='aar',
+        ))
+
+    for p in paths_to_hash:
+        with open("%s.sha1" % p, 'wt') as f:
+            f.write(util.hash_file(p, hasher=hashlib.sha1()))
+
+    return 0
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv[1:]))
--- a/python/mozbuild/mozbuild/util.py
+++ b/python/mozbuild/mozbuild/util.py
@@ -26,22 +26,22 @@ from collections import (
 from StringIO import StringIO
 
 
 if sys.version_info[0] == 3:
     str_type = str
 else:
     str_type = basestring
 
-def hash_file(path):
+def hash_file(path, hasher=None):
     """Hashes a file specified by the path given and returns the hex digest."""
 
-    # If the hashing function changes, this may invalidate lots of cached data.
-    # Don't change it lightly.
-    h = hashlib.sha1()
+    # If the default hashing function changes, this may invalidate
+    # lots of cached data.  Don't change it lightly.
+    h = hasher or hashlib.sha1()
 
     with open(path, 'rb') as fh:
         while True:
             data = fh.read(8192)
 
             if not len(data):
                 break
 
--- a/toolkit/mozapps/installer/upload-files.mk
+++ b/toolkit/mozapps/installer/upload-files.mk
@@ -357,16 +357,38 @@ else
 INNER_MAKE_GECKOVIEW_LIBRARY=echo 'GeckoView library packaging is disabled'
 INNER_MAKE_GECKOVIEW_EXAMPLE=echo 'GeckoView example packaging is disabled'
 endif
 else
 INNER_MAKE_GECKOVIEW_LIBRARY=echo 'GeckoView library packaging is only enabled on Nightly'
 INNER_MAKE_GECKOVIEW_EXAMPLE=echo 'GeckoView example packaging is only enabled on Nightly'
 endif
 
+# Create geckolibs Android ARchive and metadata for download by local
+# developers using Gradle.
+ifdef MOZ_ANDROID_GECKOLIBS_AAR
+UPLOAD_EXTRA_FILES += \
+  geckolibs-$(geckolibs-revision).aar \
+  geckolibs-$(geckolibs-revision).aar.sha1 \
+  geckolibs-$(geckolibs-revision).pom \
+  geckolibs-$(geckolibs-revision).pom.sha1 \
+  ivy-geckolibs-$(geckolibs-revision).xml \
+  ivy-geckolibs-$(geckolibs-revision).xml.sha1 \
+  $(NULL)
+
+INNER_MAKE_GECKOLIBS_AAR= \
+  $(PYTHON) -m mozbuild.action.package_geckolibs_aar \
+    --revision '$(BUILDID)' \
+    --topsrcdir '$(topsrcdir)' \
+    --distdir '$(_ABS_DIST)' \
+    '$(_ABS_DIST)'
+else
+INNER_MAKE_GECKOLIBS_AAR=echo 'Android geckolibs.aar packaging is disabled'
+endif
+
 ifdef MOZ_OMX_PLUGIN
 DIST_FILES += libomxplugin.so libomxplugingb.so libomxplugingb235.so \
               libomxpluginhc.so libomxpluginkk.so
 endif
 
 SO_LIBRARIES := $(filter %.so,$(DIST_FILES))
 # These libraries are placed in the assets/$(ANDROID_CPU_ARCH) directory by packager.py.
 ASSET_SO_LIBRARIES := $(addprefix assets/$(ANDROID_CPU_ARCH)/,$(filter-out libmozglue.so $(MOZ_CHILD_PROCESS_NAME),$(SO_LIBRARIES)))
@@ -433,16 +455,17 @@ INNER_MAKE_PACKAGE	= \
     $(ZIP) -0 $(_ABS_DIST)/gecko.ap_ $(OMNIJAR_DIR)$(OMNIJAR_NAME)) && \
   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) && \
   $(INNER_ROBOCOP_PACKAGE) && \
+  $(INNER_MAKE_GECKOLIBS_AAR) && \
   $(INNER_MAKE_GECKOVIEW_LIBRARY) && \
   $(INNER_MAKE_GECKOVIEW_EXAMPLE)
 
 # Language repacks root the resources contained in assets/omni.ja
 # under assets/, but the repacks expect them to be rooted at /.
 # Therefore, we we move the omnijar back to / so the resources are
 # under the root here, in INNER_UNMAKE_PACKAGE. See comments about
 # OMNIJAR_NAME earlier in this file and in configure.in.