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
This commit is contained in:
modmuss50
2022-11-01 21:36:41 +00:00
committed by GitHub
parent e48a7124f5
commit f87320fae8
12 changed files with 90 additions and 23 deletions

View File

@@ -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.
*
* <p>You can enable it by setting the Gradle property {@code fabric.loom.multiProjectOptimisation} to {@code true}.
*/
boolean multiProjectOptimisation();
}

View File

@@ -62,6 +62,7 @@ public abstract class AnnotationProcessorInvoker<T extends Task> {
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<SourceSet, T> invokerTasks;
private final Collection<Configuration> apConfigurations;
@@ -70,7 +71,8 @@ public abstract class AnnotationProcessorInvoker<T extends Task> {
Collection<Configuration> apConfigurations,
Map<SourceSet, T> 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<T extends Task> {
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));

View File

@@ -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<Boolean> 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 <T extends IntermediateMappingsProvider> void configureIntermediateMappingsProviderInternal(T provider) {
provider.getMinecraftVersion().set(getProject().provider(() -> getMinecraftProvider().minecraftVersion()));

View File

@@ -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());
}
}

View File

@@ -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);
}
}

View File

@@ -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<Boolean> getUseMixinExtension();
Property<Boolean> getMultiProjectOptimisation();
record RefmapData(List<String> mixinConfigs, String refmapName) implements Serializable { }
ListProperty<RefmapData> 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);

View File

@@ -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);
}
}

View File

@@ -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());
}

View File

@@ -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";
}
}

View File

@@ -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<Boolean> 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);
}
}