diff --git a/lib/maven.defs b/lib/maven.defs index bdebe20af6..5c29beda36 100644 --- a/lib/maven.defs +++ b/lib/maven.defs @@ -147,3 +147,31 @@ def maven_jar( source_jar = ':%s__download_src' % name if srcjar else None, visibility = visibility, ) + + +def merge_maven_jars( + name, + srcs, + visibility = []): + + def cmd(jars): + return ('$(location //tools:merge_jars) $OUT ' + + ' '.join(['$(location %s)' % j for j in jars])) + + genrule( + name = '%s__merged_bin' % name, + cmd = cmd(['%s__download_bin' % s for s in srcs]), + out = '%s__merged.jar' % name, + ) + genrule( + name = '%s__merged_src' % name, + cmd = cmd(['%s__download_src' % s for s in srcs]), + # tools/eclipse/project.py requires -src.jar suffix. + out = '%s__merged-src.jar' % name, + ) + prebuilt_jar( + name = name, + binary_jar = ':%s__merged_bin' % name, + source_jar = ':%s__merged_src' % name, + visibility = visibility, + ) diff --git a/tools/BUCK b/tools/BUCK index d9cd42f921..489dffc8e8 100644 --- a/tools/BUCK +++ b/tools/BUCK @@ -5,6 +5,12 @@ python_binary( visibility = ['PUBLIC'], ) +python_binary( + name = 'merge_jars', + main = 'merge_jars.py', + visibility = ['PUBLIC'], +) + python_binary( name = 'pack_war', main = 'pack_war.py', diff --git a/tools/merge_jars.py b/tools/merge_jars.py new file mode 100755 index 0000000000..46016c0d21 --- /dev/null +++ b/tools/merge_jars.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# Copyright (C) 2015 The Android Open Source Project +# +# 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. + +from __future__ import print_function +import collections +import sys +import zipfile + + +if len(sys.argv) < 3: + print('usage: %s ...' % sys.argv[0], file=sys.stderr) + exit(1) + +outfile = sys.argv[1] +infiles = sys.argv[2:] +seen = set() +SERVICES = 'META-INF/services/' + +try: + with zipfile.ZipFile(outfile, 'w') as outzip: + services = collections.defaultdict(lambda: '') + for infile in infiles: + with zipfile.ZipFile(infile) as inzip: + for info in inzip.infolist(): + n = info.filename + if n in seen: + continue + elif n.startswith(SERVICES): + # Concatenate all provider configuration files. + services[n] += inzip.read(n) + continue + outzip.writestr(info, inzip.read(n)) + seen.add(n) + + for n, v in services.iteritems(): + outzip.writestr(n, v) +except Exception as err: + exit('Failed to merge jars: %s' % err)