Skip to content

Commit dfab9a7

Browse files
committed
Make distribution tasks configuration-cache-friendly
1 parent 794f427 commit dfab9a7

File tree

5 files changed

+140
-82
lines changed

5 files changed

+140
-82
lines changed

build.gradle

Lines changed: 75 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ buildscript {
1313
}
1414

1515
import org.gradle.api.file.RelativePath
16+
import java.nio.file.Files
17+
import java.nio.file.StandardCopyOption
1618

1719
// Set the license for IDEs that understand this
1820
ext.license = file("$rootDir/source-file-header-template.txt")
@@ -25,7 +27,7 @@ allprojects {
2527
mavenCentral()
2628
google()
2729
}
28-
tasks.withType(Jar) {
30+
tasks.withType(Jar).configureEach {
2931
duplicatesStrategy = 'include'
3032
}
3133
}
@@ -47,7 +49,7 @@ subprojects {
4749
toolVersion = libs.versions.spotbugs.get()
4850
}
4951

50-
tasks.withType(com.github.spotbugs.snom.SpotBugsTask ) {
52+
tasks.withType(com.github.spotbugs.snom.SpotBugsTask).configureEach {
5153
reports {
5254
html.required = !project.hasProperty("xml-reports")
5355
xml.required = project.hasProperty("xml-reports")
@@ -63,39 +65,57 @@ tasks.register('run') {
6365

6466
defaultTasks 'run'
6567

68+
def fileSystemOperations = services.get(FileSystemOperations)
69+
def libDistDir = layout.buildDirectory.dir('libDist')
70+
def libDistArchives = subprojects.collectMany { subproject ->
71+
if (subproject.hasProperty('mainClassName')) {
72+
return []
73+
}
74+
subproject.tasks.withType(Jar).matching { task ->
75+
task.name == 'jar' ||
76+
task.name == 'sourcesJar' ||
77+
(buildJavaDoc == "true" && task.name == 'javadocJar')
78+
}.collect { archiveTask ->
79+
[
80+
projectName: subproject.name,
81+
archiveFile: archiveTask.archiveFile,
82+
archiveClassifier: archiveTask.archiveClassifier,
83+
archiveExtension: archiveTask.archiveExtension,
84+
]
85+
}
86+
}
87+
6688
def libDist = tasks.register('libDist') {
67-
dependsOn(subprojects.collect { it.tasks.named('build') })
89+
dependsOn(libDistArchives.collect { it.archiveFile })
6890
description = 'Builds and copies the engine binaries, sources and javadoc to build/libDist'
91+
inputs.files(libDistArchives.collect { it.archiveFile })
92+
outputs.dir(libDistDir)
6993

7094
doLast {
71-
File libFolder = mkdir("$buildDir/libDist/lib")
72-
File sourceFolder = mkdir("$buildDir/libDist/sources")
73-
File javadocFolder = mkdir("$buildDir/libDist/javadoc")
74-
subprojects.each {project ->
75-
if(!project.hasProperty('mainClassName')){
76-
project.tasks.withType(Jar).each {archiveTask ->
77-
String classifier = archiveTask.archiveClassifier.get()
78-
String ext = archiveTask.archiveExtension.get()
79-
File archiveFile = archiveTask.archiveFile.get().asFile
80-
if (classifier == "sources") {
81-
copy {
82-
from archiveFile
83-
into sourceFolder
84-
rename {project.name + '-' + classifier + '.' + ext}
85-
}
86-
} else if (classifier == "javadoc") {
87-
copy {
88-
from archiveFile
89-
into javadocFolder
90-
rename {project.name + '-' + classifier + '.' + ext}
91-
}
92-
} else{
93-
copy {
94-
from archiveFile
95-
into libFolder
96-
rename {project.name + '.' + ext}
97-
}
98-
}
95+
File libFolder = libDistDir.get().dir('lib').asFile
96+
File sourceFolder = libDistDir.get().dir('sources').asFile
97+
File javadocFolder = libDistDir.get().dir('javadoc').asFile
98+
libDistArchives.each { archive ->
99+
String classifier = archive.archiveClassifier.get()
100+
String ext = archive.archiveExtension.get()
101+
File archiveFile = archive.archiveFile.get().asFile
102+
if (classifier == "sources") {
103+
fileSystemOperations.copy {
104+
from archiveFile
105+
into sourceFolder
106+
rename {archive.projectName + '-' + classifier + '.' + ext}
107+
}
108+
} else if (classifier == "javadoc") {
109+
fileSystemOperations.copy {
110+
from archiveFile
111+
into javadocFolder
112+
rename {archive.projectName + '-' + classifier + '.' + ext}
113+
}
114+
} else{
115+
fileSystemOperations.copy {
116+
from archiveFile
117+
into libFolder
118+
rename {archive.projectName + '.' + ext}
99119
}
100120
}
101121
}
@@ -145,7 +165,13 @@ def mergedJavadocSubprojects = [
145165
":jme3-plugins",
146166
":jme3-terrain",
147167
]
168+
def mergedJavadocClasspath = providers.provider {
169+
mergedJavadocSubprojects.collectMany { projectPath ->
170+
project(projectPath).sourceSets.main.compileClasspath.files as List<File>
171+
}
172+
}
148173
tasks.register('mergedJavadoc', Javadoc) {
174+
dependsOn mergedJavadocSubprojects.collect { project(it).tasks.named('classes') }
149175
description = 'Creates Javadoc from all the projects.'
150176
title = 'jMonkeyEngine3'
151177
destinationDir = file("dist/javadoc")
@@ -157,7 +183,7 @@ tasks.register('mergedJavadoc', Javadoc) {
157183

158184
options.overview = file("javadoc-overview.html")
159185
source = mergedJavadocSubprojects.collect { project(it).sourceSets.main.allJava }
160-
classpath = files(mergedJavadocSubprojects.collect { project(it).sourceSets.main.compileClasspath })
186+
classpath = files(mergedJavadocClasspath)
161187
}
162188

163189
def cleanMergedJavadoc = tasks.register('cleanMergedJavadoc', Delete) {
@@ -197,45 +223,40 @@ gradle.rootProject.ext.set("usePrebuildNatives", buildNativeProjects!="true");
197223

198224
if (skipPrebuildLibraries != "true" && buildNativeProjects != "true") {
199225
File nativesSnapshotPropF = file('natives-snapshot.properties')
226+
String prebuildNativesUrlTemplate = PREBUILD_NATIVES_URL
200227

201228
if (nativesSnapshotPropF.exists()) {
202-
def readNativesConfig = {
203-
Properties nativesSnapshotProp = new Properties()
204-
nativesSnapshotPropF.withInputStream { nativesSnapshotProp.load(it) }
205-
206-
String nativesSnapshot = nativesSnapshotProp.getProperty("natives.snapshot")
207-
if (!nativesSnapshot) {
208-
throw new GradleException("Missing 'natives.snapshot' in ${nativesSnapshotPropF}")
209-
}
229+
Properties nativesSnapshotProp = new Properties()
230+
nativesSnapshotPropF.withInputStream { nativesSnapshotProp.load(it) }
210231

211-
[
212-
snapshot: nativesSnapshot,
213-
url: PREBUILD_NATIVES_URL.replace('${natives.snapshot}', nativesSnapshot),
214-
zipFile: layout.buildDirectory.file("${nativesSnapshot}-natives.zip"),
215-
nativeDir: layout.buildDirectory.dir("native"),
216-
]
232+
String nativesSnapshot = nativesSnapshotProp.getProperty("natives.snapshot")
233+
if (!nativesSnapshot) {
234+
throw new GradleException("Missing 'natives.snapshot' in ${nativesSnapshotPropF}")
217235
}
218236

219-
def nativesZipFile = providers.provider { readNativesConfig().zipFile.get().asFile }
237+
String nativesUrl = prebuildNativesUrlTemplate.replace('${natives.snapshot}', nativesSnapshot)
238+
File nativesZipFile = layout.buildDirectory.file("${nativesSnapshot}-natives.zip").get().asFile
220239
def nativesPath = layout.buildDirectory.dir("native")
221240

222241
def getNativesZipFile = tasks.register('getNativesZipFile') {
242+
inputs.property('nativesUrl', nativesUrl)
223243
outputs.file(nativesZipFile)
224244
doFirst {
225-
def nativesConfig = readNativesConfig()
226-
File target = nativesConfig.zipFile.get().asFile
227-
println("Use natives snapshot: ${nativesConfig.url}")
228-
println("Download natives from ${nativesConfig.url} to ${target}")
229-
target.getParentFile().mkdirs()
230-
ant.get(src: nativesConfig.url, dest: target)
245+
println("Use natives snapshot: ${nativesUrl}")
246+
println("Download natives from ${nativesUrl} to ${nativesZipFile}")
247+
nativesZipFile.getParentFile().mkdirs()
248+
File tempFile = new File(nativesZipFile.parentFile, "${nativesZipFile.name}.part")
249+
tempFile.delete()
250+
ant.get(src: nativesUrl, dest: tempFile)
251+
Files.move(tempFile.toPath(), nativesZipFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
231252
}
232253
}
233254

234255
def extractPrebuiltNatives = tasks.register('extractPrebuiltNatives', Sync) {
235256
dependsOn(getNativesZipFile)
236257
into(nativesPath)
237258
from({
238-
zipTree(readNativesConfig().zipFile.get().asFile)
259+
zipTree(nativesZipFile)
239260
}) {
240261
eachFile { details ->
241262
def segments = details.relativePath.segments

gradle.properties

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ includeBranchInVersion = false
1515
# specify if JavaDoc should be built
1616
buildJavaDoc = false
1717

18+
# Gradle performance defaults
19+
org.gradle.parallel=true
20+
org.gradle.caching=true
21+
org.gradle.configuration-cache=true
22+
1823
# specify if SDK and Native libraries get built
1924
buildNativeProjects = false
2025
buildAndroidExamples = false

jme3-android-native/build.gradle

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,14 @@ ext {
3333
apply from: file('openalsoft.gradle')
3434
apply from: file('decode.gradle')
3535
apply from: file('bufferallocator.gradle')
36+
37+
def androidCompileJava = project(':jme3-android').tasks.named('compileJava')
38+
tasks.named('copyJmeHeadersOpenAL') {
39+
dependsOn androidCompileJava
40+
}
41+
tasks.named('copyJmeHeadersDecode') {
42+
dependsOn androidCompileJava
43+
}
44+
tasks.named('copyJmeHeadersBufferAllocator') {
45+
dependsOn androidCompileJava
46+
}

jme3-examples/build.gradle

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,23 @@ ext.mainClassName = examplesMainClassName
33

44
def androidProject = project(':jme3-android')
55
def androidNativeProject = project(':jme3-android-native')
6+
def androidProjectName = androidProject.name
7+
def androidNativeProjectName = androidNativeProject.name
8+
def fileSystemOperations = services.get(FileSystemOperations)
9+
def compileClasspath = configurations.compileClasspath
10+
def compileClasspathArtifacts = providers.provider {
11+
compileClasspath.resolvedConfiguration.resolvedArtifacts.collect { artifact ->
12+
[
13+
file: artifact.file,
14+
fileName: artifact.classifier != null ?
15+
"${artifact.name}-${artifact.classifier}.${artifact.extension}" :
16+
"${artifact.name}.${artifact.extension}",
17+
]
18+
}
19+
}
620

7-
task run(dependsOn: 'build', type:JavaExec) {
21+
tasks.register('run', JavaExec) {
22+
dependsOn sourceSets.main.runtimeClasspath
823
mainClass = examplesMainClassName
924
classpath = sourceSets.main.runtimeClasspath
1025

@@ -49,45 +64,48 @@ jar.doFirst{
4964
// 'Implementation-Vendor' : vendor,
5065
'Main-Class' : examplesMainClassName,
5166
// Add dependencies to manifest, remove version
52-
'Class-Path' : configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.collect {
53-
'lib/' +
54-
it.name +
55-
(it.classifier != null ? '-' + it.classifier : '') +
56-
'.' + it.extension }.join(' ')
67+
'Class-Path' : compileClasspathArtifacts.get().collect { 'lib/' + it.fileName }.join(' ')
5768
)
5869
}
5970
}
6071

61-
task dist (dependsOn: ['build', ':jme3-android:jar', ':jme3-android-native:jar']) {
72+
tasks.register('dist') {
73+
dependsOn 'build', ':jme3-android:jar', ':jme3-android-native:jar'
74+
def examplesJar = tasks.named('jar', Jar).flatMap { it.archiveFile }
75+
def androidJar = androidProject.tasks.named('jar', Jar).flatMap { it.archiveFile }
76+
def androidNativeJar = androidNativeProject.tasks.named('jar', Jar).flatMap { it.archiveFile }
77+
def distDir = rootProject.layout.projectDirectory.dir('dist')
78+
79+
inputs.files(compileClasspathArtifacts.map { artifacts -> artifacts.collect { it.file } })
80+
inputs.files(examplesJar, androidJar, androidNativeJar)
81+
outputs.dir(distDir)
82+
6283
doLast {
6384
// Copy all dependencies to ../dist/lib, remove versions from jar files
64-
configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.each { artifact ->
65-
copy {
85+
compileClasspathArtifacts.get().each { artifact ->
86+
fileSystemOperations.copy {
87+
duplicatesStrategy = DuplicatesStrategy.INCLUDE
6688
from artifact.file
67-
into '../dist/lib'
68-
if(artifact.classifier != null){
69-
rename { "${artifact.name}-${artifact.classifier}.${artifact.extension}" }
70-
} else{
71-
rename { "${artifact.name}.${artifact.extension}" }
72-
}
89+
into distDir.dir('lib')
90+
rename { artifact.fileName }
7391
}
7492
}
75-
copy {
76-
from tasks.named('jar').flatMap { it.archiveFile }
77-
into '../dist'
93+
fileSystemOperations.copy {
94+
from examplesJar
95+
into distDir
7896
rename { "jMonkeyEngine3.jar" }
7997
}
8098

8199
// Copy android packages, remove version
82-
copy {
83-
from androidProject.tasks.named('jar').flatMap { it.archiveFile }
84-
into '../dist/opt/android'
85-
rename { androidProject.name + ".jar" }
100+
fileSystemOperations.copy {
101+
from androidJar
102+
into distDir.dir('opt/android')
103+
rename { androidProjectName + ".jar" }
86104
}
87-
copy {
88-
from androidNativeProject.tasks.named('jar').flatMap { it.archiveFile }
89-
into '../dist/opt/android'
90-
rename { androidNativeProject.name + ".jar" }
105+
fileSystemOperations.copy {
106+
from androidNativeJar
107+
into distDir.dir('opt/android')
108+
rename { androidNativeProjectName + ".jar" }
91109
}
92110
}
93111
}

jme3-ios-native/build.gradle

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@ def deleteXcframework = tasks.register('deleteXcframework', Delete) {
44
delete 'template/META-INF/robovm/ios/libs/jme3-ios-native.xcframework'
55
}
66

7+
def iosDeviceDerivedDataPath = layout.buildDirectory.dir('derivedData/ios')
8+
def iosSimulatorDerivedDataPath = layout.buildDirectory.dir('derivedData/ios-simulator')
9+
710
def buildNativeLibIos = tasks.register('buildNativeLibIos', Exec) {
811
executable "xcodebuild"
9-
args 'archive', '-project', 'jme3-ios-native.xcodeproj', '-scheme', 'jme3-ios-native', '-configuration', 'release', '-destination', 'generic/platform=iOS', '-archivePath', 'build/archives/jme3-ios-native_iOS', 'SKIP_INSTALL=NO', 'BUILD_LIBRARY_FOR_DISTRIBUTION=YES'
12+
args 'archive', '-project', 'jme3-ios-native.xcodeproj', '-scheme', 'jme3-ios-native', '-configuration', 'release', '-destination', 'generic/platform=iOS', '-derivedDataPath', iosDeviceDerivedDataPath.get().asFile.absolutePath, '-archivePath', 'build/archives/jme3-ios-native_iOS', 'SKIP_INSTALL=NO', 'BUILD_LIBRARY_FOR_DISTRIBUTION=YES'
1013
}
1114

1215
def buildNativeLibSimulator = tasks.register('buildNativeLibSimulator', Exec) {
1316
executable "xcodebuild"
14-
args 'archive', '-project', 'jme3-ios-native.xcodeproj', '-scheme', 'jme3-ios-native', '-configuration', 'release', '-destination', 'generic/platform=iOS Simulator', '-archivePath', 'build/archives/jme3-ios-native_iOS-Simulator', 'SKIP_INSTALL=NO', 'BUILD_LIBRARY_FOR_DISTRIBUTION=YES'
17+
args 'archive', '-project', 'jme3-ios-native.xcodeproj', '-scheme', 'jme3-ios-native', '-configuration', 'release', '-destination', 'generic/platform=iOS Simulator', '-derivedDataPath', iosSimulatorDerivedDataPath.get().asFile.absolutePath, '-archivePath', 'build/archives/jme3-ios-native_iOS-Simulator', 'SKIP_INSTALL=NO', 'BUILD_LIBRARY_FOR_DISTRIBUTION=YES'
1518
}
1619

1720
def buildNativeLib = tasks.register('buildNativeLib', Exec) {

0 commit comments

Comments
 (0)