xref: /aosp_15_r20/external/ow2-asm/build.gradle (revision 2835e6bb194a25e32dae2cc0628d8f988b82bfc0)
1// ASM: a very small and fast Java bytecode manipulation framework
2// Copyright (c) 2000-2011 INRIA, France Telecom
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions
7// are met:
8// 1. Redistributions of source code must retain the above copyright
9//    notice, this list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright
11//    notice, this list of conditions and the following disclaimer in the
12//    documentation and/or other materials provided with the distribution.
13// 3. Neither the name of the copyright holders nor the names of its
14//    contributors may be used to endorse or promote products derived from
15//    this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27// THE POSSIBILITY OF SUCH DAMAGE.
28
29buildscript {
30  repositories { mavenCentral() }
31  dependencies { classpath 'org.netbeans.tools:sigtest-maven-plugin:1.5' }
32}
33
34plugins { id 'com.github.sherter.google-java-format' version '0.9' apply false }
35plugins { id 'me.champeau.jmh' version '0.6.8' apply false }
36plugins { id 'org.sonarqube' version '4.3.1.3277' apply false }
37
38description = 'ASM, a very small and fast Java bytecode manipulation framework'
39
40apply plugin: 'java-platform'
41dependencies {
42  constraints {
43    api project(':asm'), project(':asm-tree'), project(':asm-analysis')
44    api project(':asm-util'), project(':asm-commons')
45  }
46}
47
48allprojects {
49  group = 'org.ow2.asm'
50  version = '9.6' + (rootProject.hasProperty('release') ? '' : '-SNAPSHOT')
51}
52
53subprojects {
54  repositories { mavenCentral() }
55  apply plugin: 'java-library'
56  apply plugin: 'jacoco'
57  sourceCompatibility = '1.8'
58  targetCompatibility = '1.8'
59  test { useJUnitPlatform() }
60  ext.provides = []  // The provided java packages, e.g. ['org.objectweb.asm']
61  ext.requires = []  // The required Gradle projects, e.g. [':asm-test']
62  ext.transitiveRequires = { ->
63    return requires.collect{project(it)}
64        .collect{it.transitiveRequires().plus(it.provides[0])}.flatten() as Set
65  }
66  ext.transitiveImports = { ->
67    return requires.collect{project(it)}
68        .collect{it.transitiveImports().plus(it.provides)}.flatten() as Set
69  }
70  ext.depends = []   // The external dependencies, e.g. ['junit:junit:4.12']
71  // Some external dependencies (such as Jacoco) depend transitively on ASM, and
72  // without this rule Gradle can mix ASM jars of different versions (e.g.
73  // asm-6.0.jar with the asm-tree.jar built locally).
74  configurations.all { resolutionStrategy { preferProjectModules() } }
75}
76
77// -----------------------------------------------------------------------------
78// Project descriptions
79// -----------------------------------------------------------------------------
80
81project(':asm') {
82  description = parent.description
83  provides = ['org.objectweb.asm', 'org.objectweb.asm.signature']
84}
85
86project(':asm-analysis') {
87  description = "Static code analysis API of ${parent.description}"
88  provides = ['org.objectweb.asm.tree.analysis']
89  requires = [':asm-tree']
90}
91
92project(':asm-commons') {
93  description = "Usefull class adapters based on ${parent.description}"
94  provides = ['org.objectweb.asm.commons']
95  requires = [':asm', ':asm-tree']
96  dependencies { testImplementation project(':asm-util') }
97}
98
99project(':asm-test') {
100  description = "Utilities for testing ${parent.description}"
101  provides = ['org.objectweb.asm.test']
102  depends = ['org.junit.jupiter:junit-jupiter-api:5.9.1',
103      'org.junit.jupiter:junit-jupiter-params:5.9.1']
104}
105
106project(':asm-tree') {
107  description = "Tree API of ${parent.description}"
108  provides = ['org.objectweb.asm.tree']
109  requires = [':asm']
110}
111
112project(':asm-util') {
113  description = "Utilities for ${parent.description}"
114  provides = ['org.objectweb.asm.util']
115  requires = [':asm', ':asm-tree', ':asm-analysis']
116  dependencies { testImplementation 'org.codehaus.janino:janino:3.1.9' }
117}
118
119// Use "gradle benchmarks:jmh [-PjmhInclude='<regex>']" to run the benchmarks.
120project(':benchmarks') {
121  description = "Benchmarks for ${rootProject.description}"
122  apply plugin: 'me.champeau.jmh'
123  dependencies {
124    implementation files('libs/csg-bytecode-1.0.0.jar', 'libs/jclasslib.jar')
125    jmh project(':asm'), project(':asm-tree')
126  }
127  depends = [
128    'kawa:kawa:1.7',
129    'net.sf.jiapi:jiapi-reflect:0.5.2',
130    'net.sourceforge.serp:serp:1.15.1',
131    'org.apache.bcel:bcel:6.0',
132    'org.aspectj:aspectjweaver:1.8.10',
133    'org.cojen:cojen:2.2.5',
134    'org.javassist:javassist:3.21.0-GA',
135    'org.mozilla:rhino:1.7.7.1'
136  ]
137  ['4.0', '5.0.1', '6.0', '7.0', '8.0.1', '9.0'].each { version ->
138    configurations.create("asm${version}")
139    dependencies.add("asm${version}", "org.ow2.asm:asm:${version}@jar")
140    dependencies.add("asm${version}", "org.ow2.asm:asm-tree:${version}@jar")
141    task "asm${version}"(type: Copy) {
142      from configurations."asm${version}".collect{zipTree(it)}
143      into "${buildDir}/asm${version}"
144      duplicatesStrategy = DuplicatesStrategy.INCLUDE  // module-info.class
145    }
146    classes.dependsOn "asm${version}"
147  }
148  configurations.create('input-classes-java8')
149  dependencies.add('input-classes-java8', 'io.vavr:vavr:0.10.0@jar')
150  task copyInputClasses(type: Copy) {
151    from configurations.'input-classes-java8'.collect{zipTree(it)}
152    into "${buildDir}/input-classes-java8"
153  }
154  classes.dependsOn copyInputClasses
155  jmh {
156    jvmArgsAppend = ["-Duser.dir=${rootDir}"]
157    resultFormat = 'CSV'
158    profilers = ['org.objectweb.asm.benchmarks.MemoryProfiler']
159    if (rootProject.hasProperty('jmhInclude')) {
160      includes = [jmhInclude]
161    }
162  }
163}
164
165project(':tools') {
166  description = "Tools used to build ${parent.description}"
167}
168
169project(':tools:retrofitter') {
170  description = "JDK 1.5 class retrofitter based on ${rootProject.description}"
171  sourceCompatibility = '1.9'
172  targetCompatibility = '1.9'
173  // TODO: this compiles asm twice (here and in :asm).
174  sourceSets.main.java.srcDirs += project(':asm').sourceSets.main.java.srcDirs
175}
176
177// -----------------------------------------------------------------------------
178// Project tasks creation and configuration
179// -----------------------------------------------------------------------------
180
181// All projects are checked with googleJavaFormat, Checkstyle and PMD,
182// and tested with :asm-test and JUnit.
183subprojects {
184  apply plugin: 'com.github.sherter.google-java-format'
185  googleJavaFormat.toolVersion = '1.15.0'
186  googleJavaFormat.exclude 'src/resources/java/**/*'
187
188  // Check the coding style with Checkstyle. Fail in case of error or warning.
189  apply plugin: 'checkstyle'
190  checkstyle.configFile = file("${rootDir}/tools/checkstyle.xml")
191  checkstyle.maxErrors = 0
192  checkstyle.maxWarnings = 0
193
194  // Check the code with PMD.
195  apply plugin: 'pmd'
196  pmd.ruleSets = []
197  pmd.ruleSetFiles = files("${rootDir}/tools/pmd.xml")
198  pmd.consoleOutput = true
199  pmdMain.dependsOn ':asm:jar'
200  pmdTest.dependsOn ':asm:jar'
201
202  dependencies {
203    requires.each { projectName -> api project(projectName) }
204    depends.each { artifactName -> api artifactName }
205    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1',
206        'org.junit.jupiter:junit-jupiter-params:5.9.1'
207    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.1'
208    testImplementation project(':asm-test')
209  }
210
211  // Produce byte-for-byte reproducible archives.
212  tasks.withType(AbstractArchiveTask).configureEach {
213    preserveFileTimestamps = false
214    reproducibleFileOrder = true
215    dirMode = 0775
216    fileMode = 0664
217  }
218}
219
220// Configure the projects with a non-empty 'provides' property. They must be
221// checked for code coverage and backward compatibility, retrofited to Java 1.5,
222// and packaged with generated module-info classes.
223configure(subprojects.findAll{it.provides}) {
224  // Code coverage configuration.
225  jacoco.toolVersion = '0.8.10'
226  jacocoTestReport {
227    reports { xml.required = true }
228    classDirectories.setFrom(sourceSets.main.output.classesDirs)
229  }
230  jacocoTestCoverageVerification {
231    classDirectories.setFrom(sourceSets.main.output.classesDirs)
232    violationRules.rule { limit { minimum = 0.95; counter = 'INSTRUCTION' } }
233    dependsOn ':asm:jar'
234    dependsOn ':asm-tree:jar'
235    dependsOn ':asm-commons:jar'
236  }
237  check.dependsOn jacocoTestCoverageVerification
238
239  // Retrofit the code in-place to Java 1.5 and generate a module-info class
240  // from the code content, in compileJava.doLast.
241  if (name != 'asm-test') {
242    compileJava.dependsOn ':tools:retrofitter:classes'
243    compileJava.doLast {
244      def path = project(':tools:retrofitter').sourceSets.main.runtimeClasspath
245      def loader = new URLClassLoader(path.collect {f -> f.toURL()} as URL[])
246      def retrofitter =
247          loader.loadClass('org.objectweb.asm.tools.Retrofitter').newInstance()
248      def classes = sourceSets.main.output.classesDirs.singleFile
249      def requires = transitiveRequires() as List
250      retrofitter.retrofit(classes, "${version}")
251      retrofitter.verify(classes, "${version}", provides, requires)
252    }
253  }
254
255  // Create one backward compatibility checking task for each 'sigtest-*' file
256  // in test/resources, and make the 'check' task depend on all these tasks.
257  if (file('src/test/resources/').exists()) {
258    file('src/test/resources/').eachFileMatch(~/sigtest-.*/) { f ->
259      task "${f.name}"(dependsOn: 'classes') {
260        inputs.files(f, sourceSets.main.java)
261        outputs.file("${buildDir}/${f.name}")
262        doLast {
263          def sigtest = new com.sun.tdk.signaturetest.SignatureTest()
264          def args = ['-ApiVersion', version, '-Backward', '-Static',
265              '-Mode', 'bin', '-FileName', f, '-Classpath',
266              project(':tools').file('jdk8-api.jar').path + File.pathSeparator +
267              sourceSets.main.output.classesDirs.asPath, '-Package'] + provides
268          outputs.getFiles()[0].withPrintWriter { printWriter ->
269            sigtest.run(args as String[], printWriter, null)
270          }
271          if (!sigtest.isPassed()) throw new GradleException()
272        }
273      }
274      check.dependsOn f.name
275    }
276    // Define a task to create a sigtest file for the current version.
277    task "buildSigtest"(dependsOn: 'classes') {
278      inputs.files(sourceSets.main.java)
279      outputs.file("src/test/resources/sigtest-${version}.txt")
280      doLast {
281        def setup = new com.sun.tdk.signaturetest.Setup()
282        def args = ['-ApiVersion', version, '-FileName', outputs.getFiles()[0],
283            '-Classpath', project(':tools').file('jdk8-api.jar').path +
284            File.pathSeparator + sourceSets.main.output.classesDirs.asPath +
285            File.pathSeparator + sourceSets.main.compileClasspath.asPath,
286            '-Package'] + provides
287        setup.run(args as String[], new PrintWriter(System.err, true), null)
288        if (!setup.isPassed()) throw new GradleException()
289      }
290    }
291  }
292
293  jar.manifest.attributes(
294    'Implementation-Title': project.description,
295    'Implementation-Version': "${version}")
296  // Package the project as an OSGi bundle. Exclude the asm-test project (the
297  // DefaultPackage class prevents it from being a proper bundle).
298  if (name != 'asm-test') {
299    def imports = transitiveImports()
300    jar.manifest.attributes(
301      'Bundle-DocURL': 'http://asm.ow2.org',
302      'Bundle-License': 'BSD-3-Clause;link=https://asm.ow2.io/LICENSE.txt',
303      'Bundle-ManifestVersion': 2,
304      'Bundle-Name': provides[0],
305      'Bundle-RequiredExecutionEnvironment': 'J2SE-1.5',
306      'Bundle-SymbolicName': provides[0],
307      'Bundle-Version': "${version}",
308      'Export-Package':
309          provides.collect{"${it};version=\"${version}\""}.join(',') +
310              (imports ? ";uses:=\"${imports.join(',')}\"" : ""))
311    if (imports) {
312      jar.manifest.attributes(
313        'Import-Package':
314            imports.collect{"${it};version=\"${version}\""}.join(','),
315        'Module-Requires':
316            transitiveRequires().collect{"${it};transitive=true"}.join(','))
317    }
318  }
319
320  // Apply the SonarQube plugin to monitor the code quality of the project.
321  // Use with 'gradlew sonar -Dsonar.host.url=https://sonarqube.ow2.org'.
322  apply plugin: 'org.sonarqube'
323  sonar {
324    properties { property 'sonar.projectKey', "ASM:${project.name}" }
325  }
326
327  // Add a task to generate a private javadoc and add it as a dependency of the
328  // 'check' task.
329  task privateJavadoc(type: Javadoc) {
330    source = sourceSets.main.allJava
331    classpath = configurations.compileClasspath
332    destinationDir = file("${javadoc.destinationDir}-private")
333    options.memberLevel = JavadocMemberLevel.PRIVATE
334    options.addBooleanOption('Xdoclint:all,-missing', true)
335  }
336  check.dependsOn privateJavadoc
337
338  // Add tasks to generate the Javadoc and a source jar, to be uploaded to Maven
339  // together with the main jar (containing the compiled code).
340  task javadocJar(type: Jar, dependsOn: 'javadoc') {
341    from javadoc.destinationDir
342    archiveClassifier = 'javadoc'
343  }
344  task sourcesJar(type: Jar, dependsOn: 'classes') {
345    from sourceSets.main.allSource
346    archiveClassifier = 'sources'
347  }
348  java {
349    withJavadocJar()
350    withSourcesJar()
351  }
352}
353
354// Configure the root project, and those with a non-empty 'provides' property,
355// to be published in Maven with a POM.
356configure([rootProject] + subprojects.findAll { it.provides }) {
357  apply plugin: 'maven-publish'
358  apply plugin: 'signing'
359  publishing {
360    repositories {
361      maven {
362        def baseUrl = 'https://repository.ow2.org/nexus/'
363        def releasesUrl = baseUrl + 'service/local/staging/deploy/maven2'
364        def snapshotsUrl = baseUrl + 'content/repositories/snapshots'
365        name = 'nexus'
366        url = rootProject.hasProperty('release') ? releasesUrl : snapshotsUrl
367        credentials {
368          username System.env.NEXUS_USER_NAME
369          password System.env.NEXUS_PASSWORD
370        }
371      }
372    }
373    publications {
374      maven(MavenPublication) {
375        def isRoot = project == rootProject
376        artifactId (isRoot ? 'asm-bom' : project.name)
377        from (isRoot ? components.javaPlatform : components.java)
378        pom.withXml {
379          def parent = asNode().appendNode('parent')
380          parent.appendNode('groupId', 'org.ow2')
381          parent.appendNode('artifactId', 'ow2')
382          parent.appendNode('version', '1.5.1')
383        }
384        pom {
385          name = artifactId
386          description = project.description
387          packaging 'jar'
388          inceptionYear = '2000'
389          licenses {
390            license {
391              name = 'BSD-3-Clause'
392              url = 'https://asm.ow2.io/license.html'
393            }
394          }
395          url = 'http://asm.ow2.io/'
396          mailingLists {
397            mailingList {
398              name = 'ASM Users List'
399              subscribe = 'https://mail.ow2.org/wws/subscribe/asm'
400              post = '[email protected]'
401              archive = 'https://mail.ow2.org/wws/arc/asm/'
402            }
403            mailingList {
404              name = 'ASM Team List'
405              subscribe = 'https://mail.ow2.org/wws/subscribe/asm-team'
406              post = '[email protected]'
407              archive = 'https://mail.ow2.org/wws/arc/asm-team/'
408            }
409          }
410          issueManagement {
411            url = 'https://gitlab.ow2.org/asm/asm/issues'
412          }
413          scm {
414            connection = 'scm:git:https://gitlab.ow2.org/asm/asm/'
415            developerConnection = 'scm:git:https://gitlab.ow2.org/asm/asm/'
416            url = 'https://gitlab.ow2.org/asm/asm/'
417          }
418          developers {
419            developer {
420              name = 'Eric Bruneton'
421              id = 'ebruneton'
422              email = '[email protected]'
423              roles = ['Creator', 'Java Developer']
424            }
425            developer {
426              name = 'Eugene Kuleshov'
427              id = 'eu'
428              email = '[email protected]'
429              roles = ['Java Developer']
430            }
431            developer {
432              name = 'Remi Forax'
433              id = 'forax'
434              email = '[email protected]'
435              roles = ['Java Developer']
436            }
437          }
438          organization {
439            name = 'OW2'
440            url = 'http://www.ow2.org/'
441          }
442        }
443      }
444    }
445  }
446  signing {
447    required rootProject.hasProperty('release')
448    sign publishing.publications.maven
449  }
450  tasks.withType(GenerateModuleMetadata) { enabled = false }
451}
452