From f87320fae871930359648552b95866a6967e4329 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Tue, 1 Nov 2022 21:36:41 +0000 Subject: [PATCH] Add multi project optimisation option to allow opt into shared tiny remapper. (#747) * Add multi project optimisation option to allow opting into shared tiny remapper. * Review feedback and fixes --- .../fabricmc/loom/LoomGradleExtension.java | 8 ++++++++ .../mixin/AnnotationProcessorInvoker.java | 10 +++++++--- .../extension/LoomGradleExtensionImpl.java | 10 ++++++++++ .../loom/task/AbstractRemapJarTask.java | 8 ++++++++ .../loom/task/PrepareJarRemapTask.java | 9 +++++---- .../net/fabricmc/loom/task/RemapJarTask.java | 20 ++++++++++++++++++- .../loom/task/RemapTaskConfiguration.java | 17 +++------------- .../task/service/TinyRemapperService.java | 2 +- .../net/fabricmc/loom/util/Constants.java | 6 ++++++ .../loom/util/gradle/GradleUtils.java | 15 ++++++++++++++ .../test/integration/FabricAPITest.groovy | 3 +++ .../test/util/GradleProjectTestTrait.groovy | 5 +++++ 12 files changed, 90 insertions(+), 23 deletions(-) diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java index 8d93e47b..aa74bab0 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java +++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java @@ -108,4 +108,12 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI { boolean refreshDeps(); void setRefreshDeps(boolean refreshDeps); + + /** + * If true, multi-project optimisation mode is enabled. This mode makes builds with many Loom projects + * much faster by increasing sharing and disabling some functionality. + * + *

You can enable it by setting the Gradle property {@code fabric.loom.multiProjectOptimisation} to {@code true}. + */ + boolean multiProjectOptimisation(); } diff --git a/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java b/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java index 7e3c3815..d0417961 100644 --- a/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java +++ b/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java @@ -62,6 +62,7 @@ public abstract class AnnotationProcessorInvoker { private static final Pattern MSG_VALUE_PATTERN = Pattern.compile("^(note|warning|error|disabled)$"); protected final Project project; + private final LoomGradleExtension loomExtension; protected final MixinExtension mixinExtension; protected final Map invokerTasks; private final Collection apConfigurations; @@ -70,7 +71,8 @@ public abstract class AnnotationProcessorInvoker { Collection apConfigurations, Map invokerTasks) { this.project = project; - this.mixinExtension = LoomGradleExtension.get(project).getMixin(); + this.loomExtension = LoomGradleExtension.get(project); + this.mixinExtension = loomExtension.getMixin(); this.apConfigurations = apConfigurations; this.invokerTasks = invokerTasks; } @@ -111,8 +113,10 @@ public abstract class AnnotationProcessorInvoker { args.put("MSG_" + key, value); }); - // Ensure that all of the mixin mappings have been generated before we create the mixin mappings. - runBeforePrepare(project, task); + if (loomExtension.multiProjectOptimisation()) { + // Ensure that all of the mixin mappings have been generated before we create the mixin mappings. + runBeforePrepare(project, task); + } project.getLogger().debug("Outputting refmap to dir: " + getRefmapDestinationDir(task) + " for compile task: " + task); args.forEach((k, v) -> passArgument(task, k, v)); diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java index b56d06d0..0c2d7c8e 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java @@ -36,6 +36,7 @@ import org.cadixdev.mercury.Mercury; import org.gradle.api.Project; import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.FileCollection; +import org.gradle.api.provider.Provider; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.mappings.intermediate.IntermediateMappingsProvider; @@ -48,8 +49,10 @@ import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.IntermediaryMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.NamedMinecraftProvider; +import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.download.Download; import net.fabricmc.loom.util.download.DownloadBuilder; +import net.fabricmc.loom.util.gradle.GradleUtils; public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implements LoomGradleExtension { private final Project project; @@ -68,6 +71,7 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen private IntermediaryMinecraftProvider intermediaryMinecraftProvider; private InstallerData installerData; private boolean refreshDeps; + private Provider multiProjectOptimisation; public LoomGradleExtensionImpl(Project project, LoomFiles files) { super(project, files); @@ -87,6 +91,7 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen }); refreshDeps = project.getGradle().getStartParameter().isRefreshDependencies() || Boolean.getBoolean("loom.refresh"); + multiProjectOptimisation = GradleUtils.getBooleanPropertyProvider(project, Constants.Properties.MULTI_PROJECT_OPTIMISATION); if (refreshDeps) { project.getLogger().lifecycle("Refresh dependencies is in use, loom will be significantly slower."); @@ -237,6 +242,11 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen this.refreshDeps = refreshDeps; } + @Override + public boolean multiProjectOptimisation() { + return multiProjectOptimisation.getOrElse(false); + } + @Override protected void configureIntermediateMappingsProviderInternal(T provider) { provider.getMinecraftVersion().set(getProject().provider(() -> getMinecraftProvider().minecraftVersion())); diff --git a/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java b/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java index 57f7dcdc..f1948b59 100644 --- a/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/AbstractRemapJarTask.java @@ -56,7 +56,9 @@ import org.gradle.workers.WorkAction; import org.gradle.workers.WorkParameters; import org.gradle.workers.WorkQueue; import org.gradle.workers.WorkerExecutor; +import org.jetbrains.annotations.ApiStatus; +import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.task.service.JarManifestService; import net.fabricmc.loom.util.ZipReprocessorUtil; @@ -228,4 +230,10 @@ public abstract class AbstractRemapJarTask extends Jar { return s; }; } + + @ApiStatus.Internal + @Internal + protected LoomGradleExtension getLoomExtension() { + return LoomGradleExtension.get(getProject()); + } } diff --git a/src/main/java/net/fabricmc/loom/task/PrepareJarRemapTask.java b/src/main/java/net/fabricmc/loom/task/PrepareJarRemapTask.java index 360f88ef..ab4c69c0 100644 --- a/src/main/java/net/fabricmc/loom/task/PrepareJarRemapTask.java +++ b/src/main/java/net/fabricmc/loom/task/PrepareJarRemapTask.java @@ -39,7 +39,6 @@ import org.gradle.workers.WorkerExecutor; import net.fabricmc.loom.task.service.TinyRemapperService; import net.fabricmc.loom.util.service.UnsafeWorkQueueHelper; -import net.fabricmc.tinyremapper.TinyRemapper; /** * The prepare remap task runs before all other jar remap tasks, should be used to setup tiny remapper. @@ -97,10 +96,12 @@ public abstract class PrepareJarRemapTask extends AbstractLoomTask { @Override public void execute() { - final TinyRemapper tinyRemapper = tinyRemapperService.getTinyRemapperForInputs(); final Path inputFile = getParameters().getInputFile().getAsFile().get().toPath(); - - tinyRemapper.readInputsAsync(tinyRemapperService.getOrCreateTag(inputFile), inputFile); + prepare(tinyRemapperService, inputFile); } } + + static void prepare(TinyRemapperService tinyRemapperService, Path inputFile) { + tinyRemapperService.getTinyRemapperForInputs().readInputsAsync(tinyRemapperService.getOrCreateTag(inputFile), inputFile); + } } diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java index 7b300db6..8a379417 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java @@ -27,6 +27,7 @@ package net.fabricmc.loom.task; import java.io.IOException; import java.io.Serializable; import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -106,7 +107,9 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { getUseMixinAP().set(LoomGradleExtension.get(getProject()).getMixin().getUseLegacyMixinAp()); - setupPreparationTask(); + if (getLoomExtension().multiProjectOptimisation()) { + setupPreparationTask(); + } } private void setupPreparationTask() { @@ -134,6 +137,7 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { params.getTinyRemapperBuildServiceUuid().set(UnsafeWorkQueueHelper.create(tinyRemapperService.get())); params.getRemapClasspath().from(getClasspath()); + params.getMultiProjectOptimisation().set(getLoomExtension().multiProjectOptimisation()); final boolean mixinAp = getUseMixinAP().get(); params.getUseMixinExtension().set(!mixinAp); @@ -181,6 +185,7 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { ConfigurableFileCollection getRemapClasspath(); Property getUseMixinExtension(); + Property getMultiProjectOptimisation(); record RefmapData(List mixinConfigs, String refmapName) implements Serializable { } ListProperty getMixinData(); @@ -203,6 +208,10 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { try { LOGGER.info("Remapping {} to {}", inputFile, outputFile); + if (!getParameters().getMultiProjectOptimisation().get()) { + prepare(); + } + tinyRemapper = tinyRemapperService.getTinyRemapperForRemapping(); remap(); @@ -217,6 +226,10 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { modifyJarManifest(); rewriteJar(); + if (!getParameters().getMultiProjectOptimisation().get()) { + tinyRemapperService.close(); + } + LOGGER.debug("Finished remapping {}", inputFile); } catch (Exception e) { try { @@ -229,6 +242,11 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { } } + private void prepare() { + final Path inputFile = getParameters().getInputFile().getAsFile().get().toPath(); + PrepareJarRemapTask.prepare(tinyRemapperService, inputFile); + } + private void remap() throws IOException { try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(outputFile).build()) { outputConsumer.addNonClassFiles(inputFile); diff --git a/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java b/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java index 63702a32..c74d0a9c 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java +++ b/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java @@ -49,7 +49,7 @@ public class RemapTaskConfiguration { final TaskContainer tasks = project.getTasks(); final LoomGradleExtension extension = LoomGradleExtension.get(project); - if (getBooleanProperty(project, "fabric.loom.dontRemap")) { + if (GradleUtils.getBooleanProperty(project, Constants.Properties.DONT_REMAP)) { extension.getUnmappedModCollection().from(project.getTasks().getByName(JavaPlugin.JAR_TASK_NAME)); return; } @@ -81,7 +81,7 @@ public class RemapTaskConfiguration { trySetupSourceRemapping(project); - if (getBooleanProperty(project, "fabric.loom.disableRemappedVariants")) { + if (GradleUtils.getBooleanProperty(project, Constants.Properties.DISABLE_REMAPPED_VARIANTS)) { return; } @@ -132,7 +132,7 @@ public class RemapTaskConfiguration { tasks.named(BasePlugin.ASSEMBLE_TASK_NAME).configure(task -> task.dependsOn(remapSourcesTask)); - if (getBooleanProperty(project, "fabric.loom.disableRemappedVariants")) { + if (GradleUtils.getBooleanProperty(project, "fabric.loom.disableRemappedVariants")) { return; } @@ -155,15 +155,4 @@ public class RemapTaskConfiguration { } }); } - - private static boolean getBooleanProperty(Project project, String key) { - return project.getProviders().gradleProperty(key).map(string -> { - try { - return Boolean.parseBoolean(string); - } catch (final IllegalArgumentException ex) { - return false; - } - }) - .getOrElse(false); - } } diff --git a/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java b/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java index 298cdd46..ced8f239 100644 --- a/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java +++ b/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java @@ -73,7 +73,7 @@ public class TinyRemapperService implements SharedService { joiner.add("kotlin-" + kotlinClasspathService.version()); } - if (remapJarTask.getRemapperIsolation().get()) { + if (remapJarTask.getRemapperIsolation().get() || !extension.multiProjectOptimisation()) { joiner.add(project.getPath()); } diff --git a/src/main/java/net/fabricmc/loom/util/Constants.java b/src/main/java/net/fabricmc/loom/util/Constants.java index f5e694ea..78eb818d 100644 --- a/src/main/java/net/fabricmc/loom/util/Constants.java +++ b/src/main/java/net/fabricmc/loom/util/Constants.java @@ -137,4 +137,10 @@ public class Constants { public static final String INJECTED_INTERFACE = "loom:injected_interfaces"; public static final String PROVIDED_JAVADOC = "loom:provided_javadoc"; } + + public static final class Properties { + public static final String MULTI_PROJECT_OPTIMISATION = "fabric.loom.multiProjectOptimisation"; + public static final String DONT_REMAP = "fabric.loom.dontRemap"; + public static final String DISABLE_REMAPPED_VARIANTS = "fabric.loom.disableRemappedVariants"; + } } diff --git a/src/main/java/net/fabricmc/loom/util/gradle/GradleUtils.java b/src/main/java/net/fabricmc/loom/util/gradle/GradleUtils.java index 88accb25..6361d235 100644 --- a/src/main/java/net/fabricmc/loom/util/gradle/GradleUtils.java +++ b/src/main/java/net/fabricmc/loom/util/gradle/GradleUtils.java @@ -28,6 +28,7 @@ import java.util.function.Consumer; import org.gradle.api.Project; import org.gradle.api.invocation.Gradle; +import org.gradle.api.provider.Provider; public final class GradleUtils { private GradleUtils() { @@ -52,4 +53,18 @@ public final class GradleUtils { } }); } + + public static Provider getBooleanPropertyProvider(Project project, String key) { + return project.getProviders().gradleProperty(key).map(string -> { + try { + return Boolean.parseBoolean(string); + } catch (final IllegalArgumentException ex) { + return false; + } + }); + } + + public static boolean getBooleanProperty(Project project, String key) { + return getBooleanPropertyProvider(project, key).getOrElse(false); + } } diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/FabricAPITest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/FabricAPITest.groovy index 8f909d79..f5be694f 100644 --- a/src/test/groovy/net/fabricmc/loom/test/integration/FabricAPITest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/integration/FabricAPITest.groovy @@ -49,6 +49,8 @@ class FabricAPITest extends Specification implements GradleProjectTestTrait { patch: "fabric_api" ) + gradle.enableMultiProjectOptimisation() + // Set the version to something constant gradle.buildGradle.text = gradle.buildGradle.text.replace('project.version + "+" + (ENV.GITHUB_RUN_NUMBER ? "" : "local-") + getBranch()', "\"$API_VERSION\"") @@ -61,6 +63,7 @@ class FabricAPITest extends Specification implements GradleProjectTestTrait { def serverResult = server.run() then: result.task(":build").outcome == SUCCESS + result.task(":prepareRemapJar").outcome == SUCCESS new File(gradle.mavenLocalDir, "net/fabricmc/fabric-api/fabric-biome-api-v1/9.0.17/fabric-biome-api-v1-9.0.17.jar").exists() new File(gradle.mavenLocalDir, "net/fabricmc/fabric-api/fabric-biome-api-v1/9.0.17/fabric-biome-api-v1-9.0.17-sources.jar").exists() diff --git a/src/test/groovy/net/fabricmc/loom/test/util/GradleProjectTestTrait.groovy b/src/test/groovy/net/fabricmc/loom/test/util/GradleProjectTestTrait.groovy index 2fdc5d4a..01d4e5b5 100644 --- a/src/test/groovy/net/fabricmc/loom/test/util/GradleProjectTestTrait.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/util/GradleProjectTestTrait.groovy @@ -26,6 +26,7 @@ package net.fabricmc.loom.test.util import groovy.transform.Immutable import net.fabricmc.loom.test.LoomTestConstants +import net.fabricmc.loom.util.Constants import net.fabricmc.loom.util.ZipUtils import org.apache.commons.io.FileUtils import org.gradle.testkit.runner.BuildResult @@ -310,5 +311,9 @@ trait GradleProjectTestTrait { } """ } + + void enableMultiProjectOptimisation() { + getGradleProperties() << "\n${Constants.Properties.MULTI_PROJECT_OPTIMISATION}=true" + } } } \ No newline at end of file