Skip to content

Commit

Permalink
(multi-os-engine/multi-os-engine#162) Make reflection collector a sep…
Browse files Browse the repository at this point in the history
…arated task
  • Loading branch information
Noisyfox committed Jan 21, 2022
1 parent e1b8bce commit 11154d3
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 87 deletions.
3 changes: 3 additions & 0 deletions src/main/java/org/moe/gradle/MoePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.moe.gradle.tasks.NatJGen;
import org.moe.gradle.tasks.NativeImage;
import org.moe.gradle.tasks.ProGuard;
import org.moe.gradle.tasks.ReflectionCollect;
import org.moe.gradle.tasks.ResourcePackager;
import org.moe.gradle.tasks.StartupProvider;
import org.moe.gradle.tasks.TestClassesProvider;
Expand Down Expand Up @@ -151,6 +152,8 @@ public void apply(Project project) {
asList(SOURCE_SET, MODE), MoePlugin.this);
addRule(ClassValidate.class, "Validate classes.",
asList(SOURCE_SET, MODE), MoePlugin.this);
addRule(ReflectionCollect.class, "Collect reflection config.",
asList(SOURCE_SET, MODE), MoePlugin.this);
addRule(NativeImage.class, "AOT compile using GraalVM native-image.",
asList(SOURCE_SET, MODE, ARCH, PLATFORM), MoePlugin.this);
ResourcePackager.addRule(this);
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/moe/gradle/tasks/XcodeBuild.java
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,10 @@ protected void run() {
excludes.add(classValidateTask.getOutputDir());
excludes.add(classValidateTask.getLogFile());

final ReflectionCollect reflectionCollectTask = nativeImageTask.getReflectionCollectTaskDep();
excludes.add(reflectionCollectTask.getOutputDir());
excludes.add(reflectionCollectTask.getLogFile());

final ProGuard proGuardTask = classValidateTask.getProGuardTaskDep();
excludes.add(proGuardTask.getOutJar());
excludes.add(proGuardTask.getComposedCfgFile());
Expand Down
85 changes: 0 additions & 85 deletions src/main/kotlin/org/moe/gradle/tasks/ClassValidate.kt
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
package org.moe.gradle.tasks

import com.dd.plist.NSDictionary
import com.dd.plist.NSString
import com.dd.plist.PropertyListParser
import org.gradle.api.GradleException
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.SourceSet
import org.moe.generator.project.writer.XcodeEditor
import org.moe.gradle.MoePlugin
import org.moe.gradle.anns.IgnoreUnused
import org.moe.gradle.anns.NotNull
import org.moe.gradle.anns.Nullable
import org.moe.gradle.options.ProGuardOptions
import org.moe.gradle.utils.FileUtils
import org.moe.gradle.utils.Mode
import org.moe.tools.classvalidator.ClassValidator
import org.moe.tools.classvalidator.ReflectionCollector
import java.io.File
import java.nio.file.Paths

Expand Down Expand Up @@ -64,27 +55,10 @@ open class ClassValidate : AbstractBaseTask() {
this.outputDir = outputDir
}

private var appMainClassName: String? = null

@Input
@Nullable
fun getAppMainClassName(): String? {
return getOrConvention(appMainClassName, CONVENTION_APP_MAIN_CLASS_NAME)
}

@IgnoreUnused
fun setAppMainClassName(appMainClassName: String?) {
this.appMainClassName = appMainClassName
}

val classesOutputDir: File
@Internal
get() = getOutputDir().resolve(ClassValidator.OUTPUT_CLASSES)

val reflectionConfigFile: File
@Internal
get() = getOutputDir().resolve(ReflectionCollector.OUTPUT_REFLECTION)

override fun run() {
// Clean output dir
FileUtils.deleteFileOrFolder(getOutputDir())
Expand All @@ -97,40 +71,6 @@ open class ClassValidate : AbstractBaseTask() {
+ getInputFiles().toSet(),
outputDir = getOutputDir().absoluteFile.toPath(),
)

// Collect platform reflection settings
// TODO: Move this to a separate task
// val libraryJars: MutableSet<File> = linkedSetOf(moeSDK.coreJar)
// moeExtension.platformJar?.let {
// libraryJars.add(it)
// }
when (moeExtension.proguard.levelRaw) {
ProGuardOptions.LEVEL_ALL -> {
// Nothing to be done here, should be handled by [ClassValidator] above
}
else -> {
throw GradleException("Only proguardLevel 'all' is supported atm.")
}
}
// when (moeExtension.proguardLevelRaw) {
// MoeExtension.PROGUARD_LEVEL_APP -> {
//// libraryJars.add(moeSDK.coreJar)
// moeExtension.platformJar?.let {
// libraryJars.add(it)
// }
// }
// MoeExtension.PROGUARD_LEVEL_PLATFORM -> {
//// libraryJars.add(moeSDK.coreJar)
// }
// }
ReflectionCollector.process(
mainClassName = getAppMainClassName(),
inputFiles = setOf(classesOutputDir), // Use the output of the validator as input
outputDir = getOutputDir().absoluteFile.toPath(),
classpath = getClasspathFiles().toSet()
// Add input to classpath
+ setOf(classesOutputDir)
)
}

@get:Internal
Expand All @@ -157,37 +97,12 @@ open class ClassValidate : AbstractBaseTask() {
addConvention(CONVENTION_INPUT_FILES) { setOf(proGuardTask.outJar) }
addConvention(CONVENTION_CLASSPATH_FILES) { setOf(proGuardTask.libraryJars) }
addConvention(CONVENTION_OUTPUT_DIR) { resolvePathInBuildDir(out, "output") }
addConvention(CONVENTION_APP_MAIN_CLASS_NAME) {
try {
// Figure out the app main class from Info.plist
val xcode = moeExtension.xcode
val target = if (SourceSet.MAIN_SOURCE_SET_NAME == sourceSet.name) {
xcode.mainTarget
} else {
xcode.testTarget
}
target?.let {
val xcodeFile = project.file(xcode.project)
val xcodeEditor = XcodeEditor(xcodeFile)
val infoPlistFile = xcodeEditor.getInfoPlist(target, mode.xcodeCompatibleName)

val rootDict = PropertyListParser.parse(infoPlistFile.readBytes()) as NSDictionary
val mainClass = rootDict["MOE.Main.Class"] as NSString

mainClass.content
}
} catch (e: Exception) {
project.logger.warn("Unable to get the MOE.Main.Class from Info.plist, app may not work properly", e)
null
}
}
addConvention(CONVENTION_LOG_FILE) { resolvePathInBuildDir(out, "ClassValidate.log") }
}

companion object {
private const val CONVENTION_INPUT_FILES = "inputFiles"
private const val CONVENTION_CLASSPATH_FILES = "classpathFiles"
private const val CONVENTION_OUTPUT_DIR = "outputDir"
private const val CONVENTION_APP_MAIN_CLASS_NAME = "appMainClassName"
}
}
11 changes: 9 additions & 2 deletions src/main/kotlin/org/moe/gradle/tasks/NativeImage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ open class NativeImage : AbstractBaseTask() {
lateinit var classValidateTaskDep: ClassValidate
private set

@get:Internal
lateinit var reflectionCollectTaskDep: ReflectionCollect
private set

private lateinit var mode: Mode
private lateinit var arch: Arch
private lateinit var platform: MoePlatform
Expand Down Expand Up @@ -245,6 +249,9 @@ open class NativeImage : AbstractBaseTask() {
val classValidateTask = moePlugin.getTaskBy(ClassValidate::class.java, sourceSet, mode)
classValidateTaskDep = classValidateTask
dependsOn(classValidateTask)
val reflectionCollectTask = moePlugin.getTaskBy(ReflectionCollect::class.java, sourceSet, mode)
reflectionCollectTaskDep = reflectionCollectTask
dependsOn(reflectionCollectTask)

val resourceTask = moePlugin.getTaskByName<Jar>(MoePlugin.getTaskName(ResourcePackager::class.java, sourceSet, mode))
dependsOn(resourceTask)
Expand Down Expand Up @@ -285,14 +292,14 @@ open class NativeImage : AbstractBaseTask() {
addConvention(CONVENTION_JNI_CONFIG_FILES) {
listOfNotNull(
moeSDK.jniConfigBaseFile,
classValidateTaskDep.reflectionConfigFile,
reflectionCollectTaskDep.reflectionConfigFile,
project.file("jni-config.json").takeIf { it.exists() && it.isFile },
).toSet()
}
addConvention(CONVENTION_REFLECTION_CONFIG_FILES) {
listOfNotNull(
moeSDK.reflectionConfigBaseFile,
classValidateTaskDep.reflectionConfigFile,
reflectionCollectTaskDep.reflectionConfigFile,
project.file("reflection-config.json").takeIf { it.exists() && it.isFile },
testClassesProviderTaskDep?.reflectionConfigFile,
).toSet()
Expand Down
179 changes: 179 additions & 0 deletions src/main/kotlin/org/moe/gradle/tasks/ReflectionCollect.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package org.moe.gradle.tasks

import com.dd.plist.NSDictionary
import com.dd.plist.NSString
import com.dd.plist.PropertyListParser
import org.gradle.api.GradleException
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.SourceSet
import org.moe.generator.project.writer.XcodeEditor
import org.moe.gradle.MoePlugin
import org.moe.gradle.anns.IgnoreUnused
import org.moe.gradle.anns.NotNull
import org.moe.gradle.anns.Nullable
import org.moe.gradle.options.ProGuardOptions
import org.moe.gradle.utils.FileUtils
import org.moe.gradle.utils.Mode
import org.moe.tools.classvalidator.ReflectionCollector
import java.io.File
import java.nio.file.Paths

open class ReflectionCollect : AbstractBaseTask() {

private var inputFiles: Set<Any>? = null

@InputFiles
@NotNull
fun getInputFiles(): ConfigurableFileCollection {
return project.files(getOrConvention(inputFiles, CONVENTION_INPUT_FILES))
}

@IgnoreUnused
fun setInputFiles(inputFiles: Collection<Any>?) {
this.inputFiles = inputFiles?.toSet()
}

private var classpathFiles: Set<Any>? = null

@InputFiles
@NotNull
fun getClasspathFiles(): ConfigurableFileCollection {
return project.files(getOrConvention(classpathFiles, CONVENTION_CLASSPATH_FILES))
}

@IgnoreUnused
fun setClasspathFiles(classpathFiles: Collection<Any>?) {
this.classpathFiles = classpathFiles?.toSet()
}

private var outputDir: File? = null

@Input
@NotNull
fun getOutputDir(): File {
return project.file(getOrConvention(outputDir, CONVENTION_OUTPUT_DIR))
}

@IgnoreUnused
fun setOutputDir(outputDir: File) {
this.outputDir = outputDir
}

private var appMainClassName: String? = null

@Input
@Nullable
fun getAppMainClassName(): String? {
return getOrConvention(appMainClassName, CONVENTION_APP_MAIN_CLASS_NAME)
}

@IgnoreUnused
fun setAppMainClassName(appMainClassName: String?) {
this.appMainClassName = appMainClassName
}

val reflectionConfigFile: File
@OutputFile
get() = getOutputDir().resolve(ReflectionCollector.OUTPUT_REFLECTION)

override fun run() {
// Delete output file
FileUtils.deleteFileOrFolder(reflectionConfigFile)

// Collect platform reflection settings
// TODO: Move this to a separate task
// val libraryJars: MutableSet<File> = linkedSetOf(moeSDK.coreJar)
// moeExtension.platformJar?.let {
// libraryJars.add(it)
// }
when (moeExtension.proguard.levelRaw) {
ProGuardOptions.LEVEL_ALL -> {
// Nothing to be done here, should be handled by [ClassValidator] above
}
else -> {
throw GradleException("Only proguardLevel 'all' is supported atm.")
}
}
// when (moeExtension.proguardLevelRaw) {
// MoeExtension.PROGUARD_LEVEL_APP -> {
//// libraryJars.add(moeSDK.coreJar)
// moeExtension.platformJar?.let {
// libraryJars.add(it)
// }
// }
// MoeExtension.PROGUARD_LEVEL_PLATFORM -> {
//// libraryJars.add(moeSDK.coreJar)
// }
// }
ReflectionCollector.process(
mainClassName = getAppMainClassName(),
inputFiles = getInputFiles().toSet(),
outputDir = getOutputDir().absoluteFile.toPath(),
classpath = getClasspathFiles().toSet()
// Add input to classpath
+ getInputFiles().toSet(),
)
}

@get:Internal
lateinit var classValidateTaskDep: ClassValidate
private set

protected fun setupMoeTask(
@NotNull sourceSet: SourceSet,
@NotNull mode: Mode,
) {
setSupportsRemoteBuild(false)

// Construct default output path
val out = Paths.get(MoePlugin.MOE, sourceSet.name, "reflection", mode.name)

description = "Collect reflection config (sourceset: ${sourceSet.name}, mode: ${mode.name})."

// Add dependencies
val classValidateTask = moePlugin.getTaskBy(ClassValidate::class.java, sourceSet, mode)
classValidateTaskDep = classValidateTask
dependsOn(classValidateTask)

// Update convention mapping
addConvention(CONVENTION_INPUT_FILES) { setOf(classValidateTask.classesOutputDir) }
addConvention(CONVENTION_CLASSPATH_FILES) { setOf(classValidateTask.getClasspathFiles()) }
addConvention(CONVENTION_OUTPUT_DIR) { resolvePathInBuildDir(out) }
addConvention(CONVENTION_APP_MAIN_CLASS_NAME) {
try {
// Figure out the app main class from Info.plist
val xcode = moeExtension.xcode
val target = if (SourceSet.MAIN_SOURCE_SET_NAME == sourceSet.name) {
xcode.mainTarget
} else {
xcode.testTarget
}
target?.let {
val xcodeFile = project.file(xcode.project)
val xcodeEditor = XcodeEditor(xcodeFile)
val infoPlistFile = xcodeEditor.getInfoPlist(target, mode.xcodeCompatibleName)

val rootDict = PropertyListParser.parse(infoPlistFile.readBytes()) as NSDictionary
val mainClass = rootDict["MOE.Main.Class"] as NSString

mainClass.content
}
} catch (e: Exception) {
project.logger.warn("Unable to get the MOE.Main.Class from Info.plist, app may not work properly", e)
null
}
}
addConvention(CONVENTION_LOG_FILE) { resolvePathInBuildDir(out, "ReflectionCollect.log") }
}

companion object {
private const val CONVENTION_INPUT_FILES = "inputFiles"
private const val CONVENTION_CLASSPATH_FILES = "classpathFiles"
private const val CONVENTION_OUTPUT_DIR = "outputDir"
private const val CONVENTION_APP_MAIN_CLASS_NAME = "appMainClassName"
}
}

0 comments on commit 11154d3

Please sign in to comment.