gen_aar_gradle_script.py 8.2 KB

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