gen_aar_gradle_script.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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. compileOptions {{
  86. sourceCompatibility 1.8
  87. targetCompatibility 1.8
  88. }}
  89. defaultConfig {{
  90. minSdkVersion minVersion
  91. targetSdkVersion targetVersion
  92. consumerProguardFiles '{proguard_rules}'
  93. }}
  94. sourceSets {{
  95. main {{
  96. manifest.srcFile '{manifest}'
  97. jniLibs.srcDirs = jniLibsDirs
  98. res.srcDirs = resDirs
  99. assets.srcDirs = assetsDirs
  100. java.srcDirs = javaDirs
  101. aidl.srcDirs = aidlDirs
  102. }}
  103. // We don't use this feature, so we set it to nonexisting directory
  104. androidTest.setRoot('bundle/tests')
  105. }}
  106. {do_not_strip}
  107. dependencies {{
  108. for (bundle in bundles)
  109. compile("$bundle") {{
  110. transitive = true
  111. }}
  112. for (bundle in androidArs)
  113. compile(bundle) {{
  114. transitive = true
  115. }}
  116. for (bundle in compileOnlyAndroidArs)
  117. compileOnly(bundle)
  118. }}
  119. android.libraryVariants.all {{ variant ->
  120. def suffix = variant.buildType.name.capitalize()
  121. def sourcesJarTask = project.tasks.create(name: "sourcesJar${{suffix}}", type: Jar) {{
  122. classifier = 'sources'
  123. from android.sourceSets.main.java.srcDirs
  124. include '**/*.java'
  125. eachFile {{ fcd ->
  126. def segments = fcd.relativePath.segments
  127. if (segments[0] == 'impl') {{
  128. fcd.relativePath = new RelativePath(true, segments.drop(1))
  129. }}
  130. }}
  131. includeEmptyDirs = false
  132. }}
  133. def manifestFile = android.sourceSets.main.manifest.srcFile
  134. def manifestXml = new XmlParser().parse(manifestFile)
  135. def packageName = manifestXml['@package']
  136. def groupName = packageName.tokenize('.')[0..-2].join('.')
  137. def androidNs = new groovy.xml.Namespace("http://schemas.android.com/apk/res/android")
  138. def packageVersion = manifestXml.attributes()[androidNs.versionName]
  139. def writePomTask = project.tasks.create(name: "writePom${{suffix}}") {{
  140. pom {{
  141. project {{
  142. groupId groupName
  143. version packageVersion
  144. packaging 'aar'
  145. }}
  146. }}.writeTo("$buildDir/${{rootProject.name}}$packageSuffix-pom.xml")
  147. }}
  148. tasks["bundle${{suffix}}Aar"].dependsOn sourcesJarTask
  149. tasks["bundle${{suffix}}Aar"].dependsOn writePomTask
  150. }}
  151. }}
  152. """
  153. def gen_build_script(args):
  154. def wrap(items):
  155. return ',\n '.join('"{}"'.format(x) for x in items)
  156. bundles = []
  157. bundles_dirs = set(args.flat_repos)
  158. for bundle in args.bundles:
  159. dir_name, base_name = os.path.split(bundle)
  160. assert len(dir_name) > 0 and len(base_name) > 0
  161. name, ext = os.path.splitext(base_name)
  162. assert len(name) > 0 and ext == '.aar'
  163. bundles_dirs.add(dir_name)
  164. bundles.append('com.yandex:{}@aar'.format(name))
  165. if len(bundles_dirs) > 0:
  166. flat_dirs_repo = FLAT_DIRS_REPO_TEMPLATE.format(dirs=wrap(bundles_dirs))
  167. else:
  168. flat_dirs_repo = ''
  169. maven_repos = ''.join(MAVEN_REPO_TEMPLATE.format(repo=repo) for repo in args.maven_repos)
  170. if args.keystore:
  171. keystore = KEYSTORE_TEMLATE.format(keystore=args.keystore)
  172. else:
  173. keystore = ''
  174. if args.do_not_strip:
  175. do_not_strip = DO_NOT_STRIP
  176. else:
  177. do_not_strip = ''
  178. return AAR_TEMPLATE.format(
  179. aars=wrap(args.aars),
  180. compile_only_aars=wrap(args.compile_only_aars),
  181. aidl_dirs=wrap(args.aidl_dirs),
  182. assets_dirs=wrap(args.assets_dirs),
  183. bundles=wrap(bundles),
  184. do_not_strip=do_not_strip,
  185. flat_dirs_repo=flat_dirs_repo,
  186. java_dirs=wrap(args.java_dirs),
  187. jni_libs_dirs=wrap(args.jni_libs_dirs),
  188. keystore=keystore,
  189. manifest=args.manifest,
  190. maven_repos=maven_repos,
  191. proguard_rules=args.proguard_rules,
  192. res_dirs=wrap(args.res_dirs),
  193. )
  194. if __name__ == '__main__':
  195. parser = argparse.ArgumentParser()
  196. parser.add_argument('--aars', nargs='*', default=[])
  197. parser.add_argument('--compile-only-aars', nargs='*', default=[])
  198. parser.add_argument('--aidl-dirs', nargs='*', default=[])
  199. parser.add_argument('--assets-dirs', nargs='*', default=[])
  200. parser.add_argument('--bundle-name', nargs='?', default='default-bundle-name')
  201. parser.add_argument('--bundles', nargs='*', default=[])
  202. parser.add_argument('--do-not-strip', action='store_true')
  203. parser.add_argument('--flat-repos', nargs='*', default=[])
  204. parser.add_argument('--java-dirs', nargs='*', default=[])
  205. parser.add_argument('--jni-libs-dirs', nargs='*', default=[])
  206. parser.add_argument('--keystore', default=None)
  207. parser.add_argument('--manifest', required=True)
  208. parser.add_argument('--maven-repos', nargs='*', default=[])
  209. parser.add_argument('--output-dir', required=True)
  210. parser.add_argument('--peers', nargs='*', default=[])
  211. parser.add_argument('--proguard-rules', nargs='?', default=None)
  212. parser.add_argument('--res-dirs', nargs='*', default=[])
  213. args = parser.parse_args()
  214. if args.proguard_rules is None:
  215. args.proguard_rules = os.path.join(args.output_dir, 'proguard-rules.txt')
  216. with open(args.proguard_rules, 'w') as f:
  217. pass
  218. for index, jsrc in enumerate(filter(lambda x: x.endswith('.jsrc'), args.peers)):
  219. jsrc_dir = os.path.join(args.output_dir, 'jsrc_{}'.format(str(index)))
  220. os.makedirs(jsrc_dir)
  221. with tarfile.open(jsrc, 'r') as tar:
  222. tar.extractall(path=jsrc_dir)
  223. args.java_dirs.append(jsrc_dir)
  224. args.build_gradle = os.path.join(args.output_dir, 'build.gradle')
  225. args.settings_gradle = os.path.join(args.output_dir, 'settings.gradle')
  226. args.gradle_properties = os.path.join(args.output_dir, 'gradle.properties')
  227. content = gen_build_script(args)
  228. with open(args.build_gradle, 'w') as f:
  229. f.write(content)
  230. with open(args.gradle_properties, 'w') as f:
  231. f.write('android.useAndroidX=true')
  232. if args.bundle_name:
  233. with open(args.settings_gradle, 'w') as f:
  234. f.write('rootProject.name = "{}"'.format(args.bundle_name))