gen_aar_gradle_script.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. import argparse
  2. import os
  3. import tarfile
  4. FLAT_DIRS_REPO_TEMPLATE='flatDir {{ dirs {dirs} }}\n'
  5. MAVEN_REPO_TEMPLATE='maven {{ url "{repo}" }}\n'
  6. KEYSTORE_TEMLATE='signingConfigs {{ debug {{ storeFile file("{keystore}") }} }}\n'
  7. DO_NOT_STRIP = '''\
  8. packagingOptions {
  9. doNotStrip "*/arm64-v8a/*.so"
  10. doNotStrip "*/armeabi-v7a/*.so"
  11. doNotStrip "*/x86_64/*.so"
  12. doNotStrip "*/x86/*.so"
  13. }
  14. '''
  15. AAR_TEMPLATE = """\
  16. ext.jniLibsDirs = [
  17. {jni_libs_dirs}
  18. ]
  19. ext.resDirs = [
  20. {res_dirs}
  21. ]
  22. ext.assetsDirs = [
  23. {assets_dirs}
  24. ]
  25. ext.javaDirs = [
  26. {java_dirs}
  27. ]
  28. def aidlDirs = [
  29. {aidl_dirs}
  30. ]
  31. ext.bundles = [
  32. {bundles}
  33. ]
  34. ext.androidArs = [
  35. {aars}
  36. ]
  37. ext.compileOnlyAndroidArs = [
  38. {compile_only_aars}
  39. ]
  40. def minVersion = 21
  41. def compileVersion = 30
  42. def targetVersion = 30
  43. def buildVersion = '30.0.3'
  44. import com.android.build.gradle.LibraryPlugin
  45. import java.nio.file.Files
  46. import java.nio.file.Paths
  47. import java.util.regex.Matcher
  48. import java.util.regex.Pattern
  49. import java.util.zip.ZipFile
  50. apply plugin: 'com.github.dcendents.android-maven'
  51. buildDir = "$projectDir/build"
  52. if (!ext.has("packageSuffix"))
  53. ext.packageSuffix = ""
  54. buildscript {{
  55. // repositories {{
  56. // jcenter()
  57. // mavenCentral()
  58. // }}
  59. repositories {{
  60. {maven_repos}
  61. }}
  62. dependencies {{
  63. classpath 'com.android.tools.build:gradle:4.0.2'
  64. classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
  65. }}
  66. }}
  67. apply plugin: LibraryPlugin
  68. repositories {{
  69. // flatDir {{
  70. // dirs System.env.PKG_ROOT + '/bundle'
  71. // }}
  72. // maven {{
  73. // url "http://maven.google.com/"
  74. // }}
  75. // maven {{
  76. // url "http://artifactory.yandex.net/artifactory/public/"
  77. // }}
  78. {flat_dirs_repo}
  79. {maven_repos}
  80. }}
  81. android {{
  82. {keystore}
  83. compileSdkVersion compileVersion
  84. buildToolsVersion buildVersion
  85. defaultConfig {{
  86. minSdkVersion minVersion
  87. targetSdkVersion targetVersion
  88. consumerProguardFiles '{proguard_rules}'
  89. }}
  90. sourceSets {{
  91. main {{
  92. manifest.srcFile '{manifest}'
  93. jniLibs.srcDirs = jniLibsDirs
  94. res.srcDirs = resDirs
  95. assets.srcDirs = assetsDirs
  96. java.srcDirs = javaDirs
  97. aidl.srcDirs = aidlDirs
  98. }}
  99. // We don't use this feature, so we set it to nonexisting directory
  100. androidTest.setRoot('bundle/tests')
  101. }}
  102. {do_not_strip}
  103. dependencies {{
  104. for (bundle in bundles)
  105. compile("$bundle") {{
  106. transitive = true
  107. }}
  108. for (bundle in androidArs)
  109. compile(bundle) {{
  110. transitive = true
  111. }}
  112. for (bundle in compileOnlyAndroidArs)
  113. compileOnly(bundle)
  114. }}
  115. android.libraryVariants.all {{ variant ->
  116. def suffix = variant.buildType.name.capitalize()
  117. def sourcesJarTask = project.tasks.create(name: "sourcesJar${{suffix}}", type: Jar) {{
  118. classifier = 'sources'
  119. from android.sourceSets.main.java.srcDirs
  120. include '**/*.java'
  121. eachFile {{ fcd ->
  122. def segments = fcd.relativePath.segments
  123. if (segments[0] == 'impl') {{
  124. fcd.relativePath = new RelativePath(true, segments.drop(1))
  125. }}
  126. }}
  127. includeEmptyDirs = false
  128. }}
  129. def manifestFile = android.sourceSets.main.manifest.srcFile
  130. def manifestXml = new XmlParser().parse(manifestFile)
  131. def packageName = manifestXml['@package']
  132. def groupName = packageName.tokenize('.')[0..-2].join('.')
  133. def androidNs = new groovy.xml.Namespace("http://schemas.android.com/apk/res/android")
  134. def packageVersion = manifestXml.attributes()[androidNs.versionName]
  135. def writePomTask = project.tasks.create(name: "writePom${{suffix}}") {{
  136. pom {{
  137. project {{
  138. groupId groupName
  139. version packageVersion
  140. packaging 'aar'
  141. }}
  142. }}.writeTo("$buildDir/${{rootProject.name}}$packageSuffix-pom.xml")
  143. }}
  144. tasks["bundle${{suffix}}Aar"].dependsOn sourcesJarTask
  145. tasks["bundle${{suffix}}Aar"].dependsOn writePomTask
  146. }}
  147. }}
  148. """
  149. def gen_build_script(args):
  150. def wrap(items):
  151. return ',\n '.join('"{}"'.format(x) for x in items)
  152. bundles = []
  153. bundles_dirs = set(args.flat_repos)
  154. for bundle in args.bundles:
  155. dir_name, base_name = os.path.split(bundle)
  156. assert(len(dir_name) > 0 and len(base_name) > 0)
  157. name, ext = os.path.splitext(base_name)
  158. assert(len(name) > 0 and ext == '.aar')
  159. bundles_dirs.add(dir_name)
  160. bundles.append('com.yandex:{}@aar'.format(name))
  161. if len(bundles_dirs) > 0:
  162. flat_dirs_repo = FLAT_DIRS_REPO_TEMPLATE.format(dirs=wrap(bundles_dirs))
  163. else:
  164. flat_dirs_repo = ''
  165. maven_repos = ''.join(MAVEN_REPO_TEMPLATE.format(repo=repo) for repo in args.maven_repos)
  166. if args.keystore:
  167. keystore = KEYSTORE_TEMLATE.format(keystore=args.keystore)
  168. else:
  169. keystore = ''
  170. if args.do_not_strip:
  171. do_not_strip = DO_NOT_STRIP
  172. else:
  173. do_not_strip = ''
  174. return AAR_TEMPLATE.format(
  175. aars=wrap(args.aars),
  176. compile_only_aars=wrap(args.compile_only_aars),
  177. aidl_dirs=wrap(args.aidl_dirs),
  178. assets_dirs=wrap(args.assets_dirs),
  179. bundles=wrap(bundles),
  180. do_not_strip=do_not_strip,
  181. flat_dirs_repo=flat_dirs_repo,
  182. java_dirs=wrap(args.java_dirs),
  183. jni_libs_dirs=wrap(args.jni_libs_dirs),
  184. keystore=keystore,
  185. manifest=args.manifest,
  186. maven_repos=maven_repos,
  187. proguard_rules=args.proguard_rules,
  188. res_dirs=wrap(args.res_dirs),
  189. )
  190. if __name__ == '__main__':
  191. parser = argparse.ArgumentParser()
  192. parser.add_argument('--aars', nargs='*', default=[])
  193. parser.add_argument('--compile-only-aars', nargs='*', default=[])
  194. parser.add_argument('--aidl-dirs', nargs='*', default=[])
  195. parser.add_argument('--assets-dirs', nargs='*', default=[])
  196. parser.add_argument('--bundle-name', nargs='?', default='default-bundle-name')
  197. parser.add_argument('--bundles', nargs='*', default=[])
  198. parser.add_argument('--do-not-strip', action='store_true')
  199. parser.add_argument('--flat-repos', nargs='*', default=[])
  200. parser.add_argument('--java-dirs', nargs='*', default=[])
  201. parser.add_argument('--jni-libs-dirs', nargs='*', default=[])
  202. parser.add_argument('--keystore', default=None)
  203. parser.add_argument('--manifest', required=True)
  204. parser.add_argument('--maven-repos', nargs='*', default=[])
  205. parser.add_argument('--output-dir', required=True)
  206. parser.add_argument('--peers', nargs='*', default=[])
  207. parser.add_argument('--proguard-rules', nargs='?', default=None)
  208. parser.add_argument('--res-dirs', nargs='*', default=[])
  209. args = parser.parse_args()
  210. if args.proguard_rules is None:
  211. args.proguard_rules = os.path.join(args.output_dir, 'proguard-rules.txt')
  212. with open(args.proguard_rules, 'w') as f:
  213. pass
  214. for index, jsrc in enumerate(filter(lambda x: x.endswith('.jsrc'), args.peers)):
  215. jsrc_dir = os.path.join(args.output_dir, 'jsrc_{}'.format(str(index)))
  216. os.makedirs(jsrc_dir)
  217. with tarfile.open(jsrc, 'r') as tar:
  218. tar.extractall(path=jsrc_dir)
  219. args.java_dirs.append(jsrc_dir)
  220. args.build_gradle = os.path.join(args.output_dir, 'build.gradle')
  221. args.settings_gradle = os.path.join(args.output_dir, 'settings.gradle')
  222. args.gradle_properties = os.path.join(args.output_dir, 'gradle.properties')
  223. content = gen_build_script(args)
  224. with open(args.build_gradle, 'w') as f:
  225. f.write(content)
  226. with open(args.gradle_properties, 'w') as f:
  227. f.write('android.useAndroidX=true')
  228. if args.bundle_name:
  229. with open(args.settings_gradle, 'w') as f:
  230. f.write('rootProject.name = "{}"'.format(args.bundle_name))