diff --git a/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalAsmCompileTest.java b/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalAsmCompileTest.java index 75abfd3..31d54da 100644 --- a/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalAsmCompileTest.java +++ b/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalAsmCompileTest.java @@ -49,6 +49,7 @@ void compile () throws IOException val compile = tasks.register("compile") { outputDirectory = layout.buildDirectory.dir("obj") source = layout.projectDirectory.dir("src").asFileTree + target = metal.host } """ ); diff --git a/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalCCompileTest.java b/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalCCompileTest.java index 751124c..0d67846 100644 --- a/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalCCompileTest.java +++ b/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalCCompileTest.java @@ -45,6 +45,7 @@ void compile () throws IOException val compile = tasks.register("compile") { outputDirectory = layout.buildDirectory.dir("obj") source = layout.projectDirectory.dir("src").asFileTree + target = metal.host } """ ); diff --git a/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalCxxCompileTest.java b/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalCxxCompileTest.java index e431019..459e714 100644 --- a/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalCxxCompileTest.java +++ b/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalCxxCompileTest.java @@ -45,6 +45,7 @@ void compile () throws IOException val compile = tasks.register("compile") { outputDirectory = layout.buildDirectory.dir("obj") source = layout.projectDirectory.dir("src").asFileTree + target = metal.host } """ ); diff --git a/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalIxxPrecompileTest.java b/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalIxxPrecompileTest.java index 2bf3dcf..c605e7b 100644 --- a/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalIxxPrecompileTest.java +++ b/plugins/src/functionalTest/java/br/dev/pedrolamarao/gradle/metal/MetalIxxPrecompileTest.java @@ -52,6 +52,7 @@ void compile () throws IOException options = listOf("-std=c++20") outputDirectory = layout.buildDirectory.dir("obj") source = layout.projectDirectory.dir("src").asFileTree + target = metal.host } """ ); diff --git a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalApplicationPlugin.java b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalApplicationPlugin.java index 4c10a95..b2477c8 100644 --- a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalApplicationPlugin.java +++ b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalApplicationPlugin.java @@ -48,6 +48,7 @@ public void apply (Project project) link.getOptions().convention(application.getLinkOptions()); link.getOutput().convention(linkFile); link.setSource(application.getObjectFiles()); + link.getTarget().convention(application.getTarget()); }); tasks.register("run",Exec.class,exec -> diff --git a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalArchive.java b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalArchive.java index 30e74a3..91a98d2 100644 --- a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalArchive.java +++ b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalArchive.java @@ -75,7 +75,6 @@ public abstract class MetalArchive extends SourceTask public MetalArchive () { getArchiver().convention("llvm-ar"); - getTarget().convention(getMetal().map(MetalService::getTarget)); } /** diff --git a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalAsmCompile.java b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalAsmCompile.java index 7bf7638..68ba3c1 100644 --- a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalAsmCompile.java +++ b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalAsmCompile.java @@ -2,10 +2,13 @@ package br.dev.pedrolamarao.gradle.metal; -import org.gradle.api.provider.ListProperty; +import org.gradle.api.provider.Provider; import org.gradle.api.tasks.CacheableTask; import org.gradle.api.tasks.TaskAction; +import java.util.ArrayList; +import java.util.List; + /** * Gradle Metal assembler "compile" task. */ @@ -21,9 +24,18 @@ public MetalAsmCompile () } @Override - protected final void addLanguageOptions (ListProperty list) + Provider> getCommand () { - list.add("--language=assembler"); + return getProviders().provider(() -> + { + final var list = new ArrayList(); + list.add(getMetal().get().locateTool(getCompiler().get()).toString()); + list.add("--target=%s".formatted(getTarget().get())); + list.addAll(getOptions().get()); + list.add("--compile"); + list.add("--language=assembler"); + return list; + }); } /** diff --git a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalAsmPlugin.java b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalAsmPlugin.java index 2e07a05..561bd13 100644 --- a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalAsmPlugin.java +++ b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalAsmPlugin.java @@ -38,37 +38,41 @@ private static void registerMain (Project project, MetalComponentImpl component) final var layout = project.getLayout(); final var tasks = project.getTasks(); - final var buildDirectory = layout.getBuildDirectory(); - final var sourceDirectory = layout.getProjectDirectory().dir("src/main/asm"); - final var commandsElements = configurations.named(Metal.COMMANDS_ELEMENTS); + final var sourceDirectory = layout.getProjectDirectory().dir("src/main/asm"); final var compileTask = tasks.register("compileAsm",MetalAsmCompile.class,task -> { - final var target = task.getTarget(); - final var targets = component.getTargets(); + final var condition = component.getTargets().zip(task.getTarget(), + (allowed,target) -> allowed.isEmpty() || allowed.contains(target) + ); + final var output = task.getProject().getLayout().getBuildDirectory().dir( + task.getTarget().map("obj/main/asm/%s"::formatted) + ); - task.getOutputDirectory().set(buildDirectory.dir("obj/main/asm")); + task.getOutputDirectory().set(output); task.getOptions().convention(component.getCompileOptions()); task.setSource(sourceDirectory); + task.getTarget().convention(component.getTarget()); task.exclude(component.getExcludes()); task.include(component.getIncludes()); - task.onlyIf("target is enabled",it -> - targets.zip(target,(list,item) -> list.isEmpty() || list.contains(item)).get() - ); + task.onlyIf("target is enabled",it -> condition.get()); }); component.getObjectFiles().from(compileTask); final var commandsTask = tasks.register("compileAsmCommands",MetalCompileCommands.class,task -> { - final var output = buildDirectory.file( task.getTarget().map("commands/main/asm/%s/commands.json"::formatted) ); + final var output = task.getProject().getLayout().getBuildDirectory().file( + task.getTarget().map("commands/main/asm/%s/commands.json"::formatted) + ); - task.getCompiler().convention(compileTask.flatMap(MetalCompile::getCompiler)); - task.getOptions().convention(compileTask.flatMap(MetalCompile::getInternalOptions)); - task.getCompileDirectory().convention(compileTask.map(it -> it.getTargetOutputDirectory().get().getAsFile())); - task.setSource(sourceDirectory); + task.getCompileCommand().convention(compileTask.flatMap(MetalCompile::getCommand)); + task.getCompileDirectory().convention(compileTask.flatMap(it -> it.getOutputDirectory().getAsFile())); + task.getDirectory().convention(task.getProject().getProjectDir()); task.getOutput().convention(output); + task.setSource(sourceDirectory); + task.getTarget().convention(component.getTarget()); task.exclude(component.getExcludes()); task.include(component.getIncludes()); @@ -83,37 +87,41 @@ private static void registerTest (Project project, MetalComponentImpl component) final var layout = project.getLayout(); final var tasks = project.getTasks(); - final var buildDirectory = layout.getBuildDirectory(); - final var sourceDirectory = layout.getProjectDirectory().dir("src/test/asm"); - final var commandsElements = configurations.named(Metal.COMMANDS_ELEMENTS); + final var sourceDirectory = layout.getProjectDirectory().dir("src/test/asm"); final var compileTask = tasks.register("compileTestAsm",MetalAsmCompile.class,task -> { - final var target = task.getTarget(); - final var targets = component.getTargets(); + final var condition = component.getTargets().zip(task.getTarget(),(allowed,target) -> + allowed.isEmpty() || allowed.contains(target) + ); + final var output = task.getProject().getLayout().getBuildDirectory().dir( + task.getTarget().map("obj/test/asm/%s"::formatted) + ); - task.getOutputDirectory().set(buildDirectory.dir("obj/test/asm")); + task.getOutputDirectory().set(output); task.getOptions().convention(component.getCompileOptions()); task.setSource(sourceDirectory); + task.getTarget().convention(component.getTarget()); task.exclude(component.getExcludes()); task.include(component.getIncludes()); - task.onlyIf("target is enabled",it -> - targets.zip(target,(list,item) -> list.isEmpty() || list.contains(item)).get() - ); + task.onlyIf("target is enabled",it -> condition.get()); }); component.getObjectFiles().from(compileTask); final var commandsTask = tasks.register("compileTestAsmCommands",MetalCompileCommands.class,task -> { - final var output = buildDirectory.file( task.getTarget().map("commands/test/asm/%s/commands.json"::formatted) ); + final var output = task.getProject().getLayout().getBuildDirectory().file( + task.getTarget().map("commands/test/asm/%s/commands.json"::formatted) + ); - task.getCompiler().convention(compileTask.flatMap(MetalCompile::getCompiler)); - task.getOptions().convention(compileTask.flatMap(MetalCompile::getInternalOptions)); - task.getCompileDirectory().convention(compileTask.map(it -> it.getTargetOutputDirectory().get().getAsFile())); - task.setSource(sourceDirectory); + task.getCompileCommand().convention(compileTask.flatMap(MetalCompile::getCommand)); + task.getCompileDirectory().convention(compileTask.flatMap(it -> it.getOutputDirectory().getAsFile())); + task.getDirectory().convention(task.getProject().getProjectDir()); task.getOutput().convention(output); + task.setSource(sourceDirectory); + task.getTarget().convention(component.getTarget()); task.exclude(component.getExcludes()); task.include(component.getIncludes()); diff --git a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCCompile.java b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCCompile.java index e62a1d0..cd1c98d 100644 --- a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCCompile.java +++ b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCCompile.java @@ -3,10 +3,14 @@ package br.dev.pedrolamarao.gradle.metal; import org.gradle.api.provider.ListProperty; +import org.gradle.api.provider.Provider; import org.gradle.api.tasks.CacheableTask; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.TaskAction; +import java.util.ArrayList; +import java.util.List; + /** * Gradle Metal C compile task. */ @@ -30,10 +34,19 @@ public MetalCCompile () } @Override - protected final void addLanguageOptions (ListProperty list) + Provider> getCommand () { - getIncludePath().get().forEach(path -> list.add("--include-directory=%s".formatted(path))); - list.add("--language=c"); + return getProviders().provider(() -> + { + final var list = new ArrayList(); + list.add(getMetal().get().locateTool(getCompiler().get()).toString()); + list.add("--target=%s".formatted(getTarget().get())); + list.addAll(getOptions().get()); + getIncludePath().get().forEach(path -> list.add("--include-directory=%s".formatted(path))); + list.add("--compile"); + list.add("--language=c"); + return list; + }); } /** diff --git a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCPlugin.java b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCPlugin.java index 600f93c..8767f13 100644 --- a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCPlugin.java +++ b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCPlugin.java @@ -41,11 +41,9 @@ private static void registerMain (Project project, MetalComponentImpl component) final var layout = project.getLayout(); final var tasks = project.getTasks(); - final var buildDirectory = layout.getBuildDirectory(); - final var sourceDirectory = layout.getProjectDirectory().dir("src/main/c"); - final var commandsElements = configurations.named(Metal.COMMANDS_ELEMENTS); final var includeDependencies = configurations.named(Metal.INCLUDABLE_DEPENDENCIES); + final var sourceDirectory = layout.getProjectDirectory().dir("src/main/c"); final var includePath = includeDependencies.map(it -> { final var list = new HashSet(); @@ -54,34 +52,40 @@ private static void registerMain (Project project, MetalComponentImpl component) return list; }); - final var compileTask = tasks.register("compileC",MetalCCompile.class,compile -> + final var compileTask = tasks.register("compileC",MetalCCompile.class,task -> { - final var target = compile.getMetal().map(MetalService::getTarget); - final var targets = component.getTargets(); - - compile.dependsOn(includeDependencies.map(Configuration::getBuildDependencies)); - compile.getIncludePath().convention(includePath); - compile.getOutputDirectory().convention(buildDirectory.dir("obj/main/c")); - compile.getOptions().convention(component.getCompileOptions()); - compile.setSource(sourceDirectory); - - compile.exclude(component.getExcludes()); - compile.include(component.getIncludes()); - compile.onlyIf("target is enabled",it -> - targets.zip(target,(list,item) -> list.isEmpty() || list.contains(item)).get() + final var condition = component.getTargets().zip(task.getTarget(), + (allowed,target) -> allowed.isEmpty() || allowed.contains(target) ); + final var output = task.getProject().getLayout().getBuildDirectory().dir( + task.getTarget().map("obj/main/c/%s"::formatted) + ); + + task.dependsOn(includeDependencies.map(Configuration::getBuildDependencies)); + task.getIncludePath().convention(includePath); + task.getOutputDirectory().convention(output); + task.getOptions().convention(component.getCompileOptions()); + task.setSource(sourceDirectory); + task.getTarget().convention(component.getTarget()); + + task.exclude(component.getExcludes()); + task.include(component.getIncludes()); + task.onlyIf("target is enabled",it -> condition.get()); }); component.getObjectFiles().from(compileTask); final var commandsTask = tasks.register("compileCCommands",MetalCompileCommands.class,task -> { - final var output = buildDirectory.file( task.getTarget().map("commands/main/c/%s/commands.json"::formatted) ); + final var output = task.getProject().getLayout().getBuildDirectory().file( + task.getTarget().map("commands/main/c/%s/commands.json"::formatted) + ); - task.getCompiler().convention(compileTask.flatMap(MetalCompile::getCompiler)); - task.getOptions().convention(compileTask.flatMap(MetalCompile::getInternalOptions)); - task.getCompileDirectory().convention(compileTask.map(it -> it.getTargetOutputDirectory().get().getAsFile())); - task.setSource(sourceDirectory); + task.getCompileCommand().convention(compileTask.flatMap(MetalCompile::getCommand)); + task.getCompileDirectory().convention(compileTask.flatMap(it -> it.getOutputDirectory().getAsFile())); + task.getDirectory().convention(task.getProject().getProjectDir()); task.getOutput().convention(output); + task.setSource(sourceDirectory); + task.getTarget().convention(component.getTarget()); task.exclude(component.getExcludes()); task.include(component.getIncludes()); @@ -96,11 +100,9 @@ private static void registerTest (Project project, MetalComponentImpl component) final var layout = project.getLayout(); final var tasks = project.getTasks(); - final var buildDirectory = layout.getBuildDirectory(); - final var sourceDirectory = layout.getProjectDirectory().dir("src/test/c"); - final var commandsElements = configurations.named(Metal.COMMANDS_ELEMENTS); final var includeDependencies = configurations.named("testIncludeDependencies"); + final var sourceDirectory = layout.getProjectDirectory().dir("src/test/c"); final var includePath = includeDependencies.map(it -> { final var list = new HashSet(); @@ -110,34 +112,40 @@ private static void registerTest (Project project, MetalComponentImpl component) return list; }); - final var compileTask = tasks.register("compileTestC",MetalCCompile.class,compile -> + final var compileTask = tasks.register("compileTestC",MetalCCompile.class,task -> { - final var target = compile.getMetal().map(MetalService::getTarget); - final var targets = component.getTargets(); - - compile.dependsOn(includeDependencies.map(Configuration::getBuildDependencies)); - compile.getIncludePath().convention(includePath); - compile.getOutputDirectory().convention(buildDirectory.dir("obj/test/c")); - compile.getOptions().convention(component.getCompileOptions()); - compile.setSource(sourceDirectory); - - compile.exclude(component.getExcludes()); - compile.include(component.getIncludes()); - compile.onlyIf("target is enabled",it -> - targets.zip(target,(list,item) -> list.isEmpty() || list.contains(item)).get() + final var condition = component.getTargets().zip(task.getTarget(), + (allowed,target) -> allowed.isEmpty() || allowed.contains(target) ); + final var output = task.getProject().getLayout().getBuildDirectory().dir( + task.getTarget().map("obj/test/c/%s"::formatted) + ); + + task.dependsOn(includeDependencies.map(Configuration::getBuildDependencies)); + task.getIncludePath().convention(includePath); + task.getOutputDirectory().convention(output); + task.getOptions().convention(component.getCompileOptions()); + task.setSource(sourceDirectory); + task.getTarget().convention(component.getTarget()); + + task.exclude(component.getExcludes()); + task.include(component.getIncludes()); + task.onlyIf("target is enabled",it -> condition.get()); }); component.getObjectFiles().from(compileTask); final var commandsTask = tasks.register("compileTestCCommands",MetalCompileCommands.class,task -> { - final var output = buildDirectory.file( task.getTarget().map("commands/test/c/%s/commands.json"::formatted) ); + final var output = task.getProject().getLayout().getBuildDirectory().file( + task.getTarget().map("commands/test/c/%s/commands.json"::formatted) + ); - task.getCompiler().convention(compileTask.flatMap(MetalCompile::getCompiler)); - task.getOptions().convention(compileTask.flatMap(MetalCompile::getInternalOptions)); - task.getCompileDirectory().convention(compileTask.map(it -> it.getTargetOutputDirectory().get().getAsFile())); - task.setSource(sourceDirectory); + task.getCompileCommand().convention(compileTask.flatMap(MetalCompile::getCommand)); + task.getCompileDirectory().convention(compileTask.flatMap(it -> it.getOutputDirectory().getAsFile())); + task.getDirectory().convention(task.getProject().getProjectDir()); task.getOutput().convention(output); + task.setSource(sourceDirectory); + task.getTarget().convention(component.getTarget()); task.exclude(component.getExcludes()); task.include(component.getIncludes()); diff --git a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCompile.java b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCompile.java index 15ef79e..3e4a74a 100644 --- a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCompile.java +++ b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCompile.java @@ -2,12 +2,8 @@ package br.dev.pedrolamarao.gradle.metal; -import org.gradle.api.file.Directory; import org.gradle.api.file.DirectoryProperty; -import org.gradle.api.file.ProjectLayout; import org.gradle.api.file.RegularFileProperty; -import org.gradle.api.internal.file.FileOperations; -import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; @@ -59,7 +55,7 @@ public abstract class MetalCompile extends SourceTask * * @return property */ - @Internal + @OutputDirectory public abstract DirectoryProperty getOutputDirectory (); /** @@ -70,35 +66,8 @@ public abstract class MetalCompile extends SourceTask @Input public abstract Property getTarget (); - /** - * Compiler target directory. - * - * @return provider - */ - @OutputDirectory - public Provider getTargetOutputDirectory () - { - return getOutputDirectory().zip(getTarget(),Directory::dir); - } - // services - /** - * FileOperations service. - * - * @return service - */ - @Inject - protected abstract FileOperations getFiles (); - - /** - * ProjectLayout service. - * - * @return service - */ - @Inject - protected abstract ProjectLayout getLayout (); - /** * Gradle Metal service. * @@ -107,14 +76,6 @@ public Provider getTargetOutputDirectory () @ServiceReference protected abstract Property getMetal (); - /** - * ObjectFactory service. - * - * @return service - */ - @Inject - protected abstract ObjectFactory getObjects (); - /** * ProviderFactory service. * @@ -131,47 +92,16 @@ public Provider getTargetOutputDirectory () @Inject protected abstract WorkerExecutor getWorkers (); - // task - - /** - * Constructor. - */ - public MetalCompile () - { - getTarget().convention(getMetal().map(MetalService::getTarget)); - } - - /** - * Add this task's language options to the specified list. - * - * @param list list to receive this task's language options - */ - protected void addLanguageOptions (ListProperty list) { }; - @Internal - Provider> getInternalOptions () - { - return getProviders().provider(() -> - { - final var list = new ArrayList(); - list.add("--target=%s".formatted(getTarget().get())); - list.addAll(getOptions().get()); - list.add("--compile"); - return list; - }); - } + abstract Provider> getCommand (); interface CompileParameter extends WorkParameters { - Property getCompiler (); - - ListProperty getOptions (); + ListProperty getCommand (); DirectoryProperty getOutputDirectory (); RegularFileProperty getSource (); - - Property getTarget (); } static abstract class CompileAction implements WorkAction @@ -187,11 +117,8 @@ public void execute () { final var parameters = getParameters(); - final var compiler = parameters.getCompiler().get(); - final var options = parameters.getOptions().get(); + final var commandBase = parameters.getCommand().get(); final var source = parameters.getSource().getAsFile().get(); - final var target = parameters.getTarget().get(); - final var output = parameters.getOutputDirectory() .file("%X/%s.%s".formatted(hash(source),source.getName(),"o")) .get().getAsFile(); @@ -205,17 +132,11 @@ public void execute () throw new RuntimeException(e); } - final var args = new ArrayList(); - args.add("--target=%s".formatted(target)); - args.addAll(options); - args.add("--compile"); - args.add("--output=%s".formatted(output)); - args.add(source.toString()); + final var command = new ArrayList<>(commandBase); + command.add("--output=%s".formatted(output)); + command.add(source.toString()); - getExec().exec(it -> { - it.executable(compiler); - it.args(args); - }); + getExec().exec(it -> it.commandLine(command)); } } @@ -226,22 +147,16 @@ public void compile () { final var workers = getWorkers().noIsolation(); - final var compiler = getMetal().get().locateTool(getCompiler().get()); - final var options = getOptions(); - final var target = getTarget().get(); - - final var outputDirectory = getTargetOutputDirectory().get(); + final var options = getCommand(); + final var outputDirectory = getOutputDirectory(); getSource().forEach(source -> { - workers.submit(CompileAction.class, parameters -> + workers.submit(CompileAction.class,parameters -> { - parameters.getCompiler().set(compiler.toString()); + parameters.getCommand().set(options); parameters.getOutputDirectory().set(outputDirectory); - parameters.getOptions().set(options); - addLanguageOptions(parameters.getOptions()); parameters.getSource().set(source); - parameters.getTarget().set(target); }); }); } diff --git a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCompileCommands.java b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCompileCommands.java index fa3cadf..cc173ea 100644 --- a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCompileCommands.java +++ b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCompileCommands.java @@ -3,7 +3,6 @@ import org.gradle.api.file.RegularFileProperty; import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.Property; -import org.gradle.api.services.ServiceReference; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.OutputFile; import org.gradle.api.tasks.SourceTask; @@ -13,7 +12,6 @@ import java.io.IOException; import java.nio.file.Files; import java.util.stream.Collectors; -import java.util.stream.Stream; import static br.dev.pedrolamarao.gradle.metal.MetalCompile.hash; import static java.nio.charset.StandardCharsets.UTF_8; @@ -26,31 +24,31 @@ public abstract class MetalCompileCommands extends SourceTask // properties /** - * Compiler output directory. + * Compiler base directory. * * @return property */ @Input - public abstract Property getCompileDirectory (); + public abstract Property getDirectory (); /** - * Compiler tool. + * Compiler output directory. * * @return property */ @Input - public abstract Property getCompiler (); + public abstract Property getCompileDirectory (); /** - * Compiler options. + * Compile command. * * @return property */ @Input - public abstract ListProperty getOptions (); + public abstract ListProperty getCompileCommand (); /** - * Generated commands database file. + * Output file. * * @return property */ @@ -67,14 +65,6 @@ public abstract class MetalCompileCommands extends SourceTask // services - /** - * Gradle Metal service. - * - * @return service - */ - @ServiceReference - protected abstract Property getMetal (); - // task /** @@ -82,7 +72,6 @@ public abstract class MetalCompileCommands extends SourceTask */ public MetalCompileCommands () { - getTarget().convention(getMetal().map(MetalService::getTarget)); } private static final String template = @@ -102,21 +91,19 @@ public MetalCompileCommands () @TaskAction public void generate () throws IOException { - final var tool = getMetal().get().locateTool(getCompiler().get()); - final var directory = getProject().getProjectDir(); - final var options = getOptions().get(); - final var output = getOutput().get(); - - try (var writer = Files.newBufferedWriter(output.getAsFile().toPath(),UTF_8)) { + final var directory = getDirectory().get().toString().replace("\\","\\\\"); + final var compileDirectory = getCompileDirectory().get(); + final var arguments = getCompileCommand().get().stream() + .collect(Collectors.joining("\", \"", "\"", "\"")) + .replace("\\","\\\\"); + final var taskOutput = getOutput().get(); + + try (var writer = Files.newBufferedWriter(taskOutput.getAsFile().toPath(),UTF_8)) { final String[] comma = {""}; writer.write("[\n"); getSource().forEach(file -> { - final var arguments = Stream.concat(Stream.of(tool.toString()),options.stream()) - .collect(Collectors.joining("\", \"", "\"", "\"")); - - final var compileOutput = - new File(directory,"%X/%s.%s".formatted(hash(file),file.getName(),"o")); + final var output = new File(compileDirectory,"%X/%s.%s".formatted(hash(file),file.getName(),"o")); try { // ARGH @@ -125,10 +112,10 @@ public void generate () throws IOException writer.write( template.formatted( - arguments.replace("\\","\\\\"), - directory.toString().replace("\\","\\\\"), + arguments, + directory, file.toString().replace("\\","\\\\"), - compileOutput.toString().replace("\\","\\\\") + output.toString().replace("\\","\\\\") ) ); } diff --git a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCxxCompile.java b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCxxCompile.java index 0947ebd..1aa84a1 100644 --- a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCxxCompile.java +++ b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCxxCompile.java @@ -42,18 +42,12 @@ public MetalCxxCompile () } @Override - protected final void addLanguageOptions (ListProperty list) - { - getImportPath().get().forEach(path -> list.add("-fprebuilt-module-path=%s".formatted(path))); - getIncludePath().get().forEach(path -> list.add("--include-directory=%s".formatted(path))); - } - - @Override - Provider> getInternalOptions () + Provider> getCommand () { return getProviders().provider(() -> { final var list = new ArrayList(); + list.add(getMetal().get().locateTool(getCompiler().get()).toString()); list.add("--target=%s".formatted(getTarget().get())); list.addAll(getOptions().get()); getImportPath().get().forEach(path -> list.add("-fprebuilt-module-path=%s".formatted(path))); diff --git a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCxxPlugin.java b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCxxPlugin.java index 48e2391..467760d 100644 --- a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCxxPlugin.java +++ b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalCxxPlugin.java @@ -43,7 +43,6 @@ private static void registerMain (Project project, MetalComponentImpl component) final var objects = project.getObjects(); final var tasks = project.getTasks(); - final var buildDirectory = layout.getBuildDirectory(); final var projectDirectory = layout.getProjectDirectory(); final var commandsElements = configurations.named(Metal.COMMANDS_ELEMENTS); @@ -64,42 +63,47 @@ private static void registerMain (Project project, MetalComponentImpl component) return list; }); - final var precompileTask = tasks.register("precompileIxx",MetalIxxPrecompile.class,precompile -> + final var precompileTask = tasks.register("precompileIxx",MetalIxxPrecompile.class,task -> { - final var target = precompile.getTarget(); - final var targets = component.getTargets(); + final var condition = component.getTargets().zip(task.getTarget(), + (allowed,target) -> allowed.isEmpty() || allowed.contains(target) + ); + final var output = task.getProject().getLayout().getBuildDirectory().dir( + task.getTarget().map("bmi/main/ixx/%s"::formatted) + ); + final var source = task.getProject().getLayout().getProjectDirectory().dir("src/main/ixx"); - precompile.dependsOn( + task.dependsOn( includeDependencies.map(Configuration::getBuildDependencies), importDependencies.map(Configuration::getBuildDependencies) ); - precompile.getImportPath().convention(importPath); - precompile.getIncludePath().convention(includePath); - precompile.getOutputDirectory().convention(buildDirectory.dir("bmi/main/ixx")); - precompile.getOptions().convention(component.getCompileOptions()); - precompile.setSource(layout.getProjectDirectory().dir("src/main/ixx")); - - precompile.exclude(component.getExcludes()); - precompile.include(component.getIncludes()); - precompile.onlyIf("target is enabled",it -> - targets.zip(target,(list,item) -> list.isEmpty() || list.contains(item)).get() - ); + task.getImportPath().convention(importPath); + task.getIncludePath().convention(includePath); + task.getOutputDirectory().convention(output); + task.getOptions().convention(component.getCompileOptions()); + task.setSource(source); + task.getTarget().convention(component.getTarget()); + + task.exclude(component.getExcludes()); + task.include(component.getIncludes()); + task.onlyIf("target is enabled",it -> condition.get()); }); importableElements.configure(it -> - it.getOutgoing().artifact(precompileTask.map(MetalIxxPrecompile::getTargetOutputDirectory),it2 -> - it2.builtBy(precompileTask) - ) + it.getOutgoing().artifact(precompileTask) ); final var precommandsTask = tasks.register("precompileIxxCommands",MetalCompileCommands.class,task -> { - final var output = buildDirectory.file( task.getTarget().map("commands/main/ixx/%s/commands.json"::formatted) ); + final var output = task.getProject().getLayout().getBuildDirectory().file( + task.getTarget().map("commands/main/ixx/%s/commands.json"::formatted) + ); - task.getCompiler().convention(precompileTask.flatMap(MetalCompile::getCompiler)); - task.getOptions().convention(precompileTask.flatMap(MetalCompile::getInternalOptions)); + task.getCompileCommand().convention(precompileTask.flatMap(MetalCompile::getCommand)); task.getCompileDirectory().convention(precompileTask.flatMap(it -> it.getOutputDirectory().getAsFile())); - task.setSource(projectDirectory.dir("src/main/ixx")); + task.getDirectory().convention(task.getProject().getProjectDir()); task.getOutput().convention(output); + task.setSource(projectDirectory.dir("src/main/ixx")); + task.getTarget().convention(component.getTarget()); task.exclude(component.getExcludes()); task.include(component.getIncludes()); @@ -109,7 +113,7 @@ private static void registerMain (Project project, MetalComponentImpl component) final var compileImports = precompileTask.zip(importPath,(precompile,dependencies) -> { final var list = new ArrayList(); - list.add(precompile.getTargetOutputDirectory().get().toString()); + list.add(precompile.getOutputDirectory().get().toString()); list.addAll(dependencies); return list; }); @@ -118,34 +122,40 @@ private static void registerMain (Project project, MetalComponentImpl component) compileSources.from(layout.getProjectDirectory().dir("src/main/cxx")); compileSources.from(precompileTask); - final var compileTask = tasks.register("compileCxx",MetalCxxCompile.class,compile -> + final var compileTask = tasks.register("compileCxx",MetalCxxCompile.class,task -> { - final var target = compile.getTarget(); - final var targets = component.getTargets(); - - compile.getImportPath().convention(compileImports); - compile.getIncludePath().convention(includePath); - compile.getOutputDirectory().convention(buildDirectory.dir("obj/main/cxx")); - compile.getOptions().convention(component.getCompileOptions()); - compile.setSource(compileSources); - - compile.exclude(component.getExcludes()); - compile.include(component.getIncludes()); - compile.onlyIf("target is enabled",it -> - targets.zip(target,(list,item) -> list.isEmpty() || list.contains(item)).get() + final var condition = component.getTargets().zip(task.getTarget(), + (allowed,target) -> allowed.isEmpty() || allowed.contains(target) ); + final var output = task.getProject().getLayout().getBuildDirectory().dir( + task.getTarget().map("obj/main/cxx/%s"::formatted) + ); + + task.getImportPath().convention(compileImports); + task.getIncludePath().convention(includePath); + task.getOutputDirectory().convention(output); + task.getOptions().convention(component.getCompileOptions()); + task.setSource(compileSources); + task.getTarget().convention(component.getTarget()); + + task.exclude(component.getExcludes()); + task.include(component.getIncludes()); + task.onlyIf("target is enabled",it -> condition.get()); }); component.getObjectFiles().from(compileTask); final var commandsTask = tasks.register("compileCxxCommands",MetalCompileCommands.class,task -> { - final var output = buildDirectory.file( task.getTarget().map("commands/main/cxx/%s/commands.json"::formatted) ); + final var output = task.getProject().getLayout().getBuildDirectory().file( + task.getTarget().map("commands/main/cxx/%s/commands.json"::formatted) + ); - task.getCompiler().convention(compileTask.flatMap(MetalCompile::getCompiler)); - task.getOptions().convention(compileTask.flatMap(MetalCompile::getInternalOptions)); + task.getCompileCommand().convention(compileTask.flatMap(MetalCompile::getCommand)); task.getCompileDirectory().convention(compileTask.flatMap(it -> it.getOutputDirectory().getAsFile())); - task.setSource(compileSources); + task.getDirectory().convention(task.getProject().getProjectDir()); task.getOutput().convention(output); + task.setSource(compileSources); + task.getTarget().convention(component.getTarget()); task.exclude(component.getExcludes()); task.include(component.getIncludes()); @@ -161,7 +171,6 @@ private static void registerTest (Project project, MetalComponentImpl component) final var objects = project.getObjects(); final var tasks = project.getTasks(); - final var buildDirectory = layout.getBuildDirectory(); final var projectDirectory = layout.getProjectDirectory(); final var commandsElements = configurations.named(Metal.COMMANDS_ELEMENTS); @@ -170,7 +179,7 @@ private static void registerTest (Project project, MetalComponentImpl component) final var importPath = importDependencies.map(it -> { final var list = new HashSet(); - list.add(tasks.named("precompileIxx",MetalIxxPrecompile.class).get().getTargetOutputDirectory().get().toString()); + list.add(tasks.named("precompileIxx",MetalIxxPrecompile.class).get().getOutputDirectory().get().toString()); it.getElements().get().forEach(element -> list.add(element.toString())); return list; }); @@ -182,37 +191,44 @@ private static void registerTest (Project project, MetalComponentImpl component) return list; }); - final var precompileTask = tasks.register("precompileTestIxx",MetalIxxPrecompile.class,precompile -> + final var precompileTask = tasks.register("precompileTestIxx",MetalIxxPrecompile.class,task -> { - final var target = precompile.getTarget(); - final var targets = component.getTargets(); + final var condition = component.getTargets().zip(task.getTarget(), + (allowed,target) -> allowed.isEmpty() || allowed.contains(target) + ); + final var output = task.getProject().getLayout().getBuildDirectory().dir( + task.getTarget().map("bmi/test/ixx/%s"::formatted) + ); + final var source = task.getProject().getLayout().getProjectDirectory().dir("src/test/ixx"); - precompile.dependsOn( + task.dependsOn( includeDependencies.map(Configuration::getBuildDependencies), importDependencies.map(Configuration::getBuildDependencies) ); - precompile.getImportPath().convention(importPath); - precompile.getIncludePath().convention(includePath); - precompile.getOutputDirectory().convention(buildDirectory.dir("bmi/test/ixx")); - precompile.getOptions().convention(component.getCompileOptions()); - precompile.setSource(layout.getProjectDirectory().dir("src/test/ixx")); - - precompile.exclude(component.getExcludes()); - precompile.include(component.getIncludes()); - precompile.onlyIf("target is enabled",it -> - targets.zip(target,(list,item) -> list.isEmpty() || list.contains(item)).get() - ); + task.getImportPath().convention(importPath); + task.getIncludePath().convention(includePath); + task.getOutputDirectory().convention(output); + task.getOptions().convention(component.getCompileOptions()); + task.setSource(source); + task.getTarget().convention(component.getTarget()); + + task.exclude(component.getExcludes()); + task.include(component.getIncludes()); + task.onlyIf("target is enabled",it -> condition.get()); }); final var precommandsTask = tasks.register("precompileTestIxxCommands",MetalCompileCommands.class,task -> { - final var output = buildDirectory.file( task.getTarget().map("commands/test/ixx/%s/commands.json"::formatted) ); + final var output = task.getProject().getLayout().getBuildDirectory().file( + task.getTarget().map("commands/test/ixx/%s/commands.json"::formatted) + ); - task.getCompiler().convention(precompileTask.flatMap(MetalCompile::getCompiler)); - task.getOptions().convention(precompileTask.flatMap(MetalCompile::getInternalOptions)); + task.getCompileCommand().convention(precompileTask.flatMap(MetalCompile::getCommand)); task.getCompileDirectory().convention(precompileTask.flatMap(it -> it.getOutputDirectory().getAsFile())); - task.setSource(projectDirectory.dir("src/test/ixx")); + task.getDirectory().convention(task.getProject().getProjectDir()); task.getOutput().convention(output); + task.setSource(projectDirectory.dir("src/test/ixx")); + task.getTarget().convention(component.getTarget()); task.exclude(component.getExcludes()); task.include(component.getIncludes()); @@ -222,8 +238,8 @@ private static void registerTest (Project project, MetalComponentImpl component) final var compileImports = precompileTask.zip(importPath,(precompile,dependencies) -> { final var list = new ArrayList(); - list.add(tasks.named("precompileIxx",MetalIxxPrecompile.class).get().getTargetOutputDirectory().get().toString()); - list.add(precompile.getTargetOutputDirectory().get().toString()); + list.add(tasks.named("precompileIxx",MetalIxxPrecompile.class).get().getOutputDirectory().get().toString()); + list.add(precompile.getOutputDirectory().get().toString()); list.addAll(dependencies); return list; }); @@ -232,35 +248,41 @@ private static void registerTest (Project project, MetalComponentImpl component) compileSources.from(layout.getProjectDirectory().dir("src/test/cxx")); compileSources.from(precompileTask); - final var compileTask = tasks.register("compileTestCxx",MetalCxxCompile.class,compile -> + final var compileTask = tasks.register("compileTestCxx",MetalCxxCompile.class,task -> { - final var target = compile.getTarget(); - final var targets = component.getTargets(); - - compile.dependsOn(tasks.named("precompileIxx")); // TODO - compile.getImportPath().convention(compileImports); - compile.getIncludePath().convention(includePath); - compile.getOutputDirectory().convention(buildDirectory.dir("obj/test/cxx")); - compile.getOptions().convention(component.getCompileOptions()); - compile.setSource(compileSources); - - compile.exclude(component.getExcludes()); - compile.include(component.getIncludes()); - compile.onlyIf("target is enabled",it -> - targets.zip(target,(list,item) -> list.isEmpty() || list.contains(item)).get() + final var condition = component.getTargets().zip(task.getTarget(), + (allowed,target) -> allowed.isEmpty() || allowed.contains(target) ); + final var output = task.getProject().getLayout().getBuildDirectory().dir( + task.getTarget().map("obj/test/cxx/%s"::formatted) + ); + + task.dependsOn(tasks.named("precompileIxx")); // TODO + task.getImportPath().convention(compileImports); + task.getIncludePath().convention(includePath); + task.getOutputDirectory().convention(output); + task.getOptions().convention(component.getCompileOptions()); + task.setSource(compileSources); + task.getTarget().convention(component.getTarget()); + + task.exclude(component.getExcludes()); + task.include(component.getIncludes()); + task.onlyIf("target is enabled",it -> condition.get()); }); component.getObjectFiles().from(compileTask); final var commandsTask = tasks.register("compileTestCxxCommands",MetalCompileCommands.class,task -> { - final var output = buildDirectory.file( task.getTarget().map("commands/test/cxx/%s/commands.json"::formatted) ); + final var output = task.getProject().getLayout().getBuildDirectory().file( + task.getTarget().map("commands/test/cxx/%s/commands.json"::formatted) + ); - task.getCompiler().convention(compileTask.flatMap(MetalCompile::getCompiler)); - task.getOptions().convention(compileTask.flatMap(MetalCompile::getInternalOptions)); + task.getCompileCommand().convention(compileTask.flatMap(MetalCompile::getCommand)); task.getCompileDirectory().convention(compileTask.flatMap(it -> it.getOutputDirectory().getAsFile())); - task.setSource(compileSources); + task.getDirectory().convention(task.getProject().getProjectDir()); task.getOutput().convention(output); + task.setSource(compileSources); + task.getTarget().convention(component.getTarget()); task.exclude(component.getExcludes()); task.include(component.getIncludes()); diff --git a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalIxxPrecompile.java b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalIxxPrecompile.java index e3110fa..9db2b11 100644 --- a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalIxxPrecompile.java +++ b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalIxxPrecompile.java @@ -7,6 +7,7 @@ import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.Property; +import org.gradle.api.provider.Provider; import org.gradle.api.services.ServiceReference; import org.gradle.api.tasks.CacheableTask; import org.gradle.api.tasks.Input; @@ -57,7 +58,7 @@ public abstract class MetalIxxPrecompile extends MetalCompile * @return property */ @Inject - public abstract ExecOperations getExec (); + protected abstract ExecOperations getExec (); /** * FileOperations service. @@ -75,6 +76,24 @@ public abstract class MetalIxxPrecompile extends MetalCompile @Inject protected abstract ObjectFactory getObjects (); + @Override + Provider> getCommand () + { + return getProviders().provider(() -> + { + final var list = new ArrayList(); + list.add(getMetal().get().locateTool(getCompiler().get()).toString()); + list.add("--target=%s".formatted(getTarget().get())); + list.addAll(getOptions().get()); + getImportPath().get().forEach(path -> list.add("-fprebuilt-module-path=%s".formatted(path))); + list.add("-fprebuilt-module-path=%s".formatted(getOutputDirectory().get())); + getIncludePath().get().forEach(path -> list.add("--include-directory=%s".formatted(path))); + list.add("--precompile"); + list.add("--language=c++-module"); + return list; + }); + } + // task /** @@ -83,7 +102,6 @@ public abstract class MetalIxxPrecompile extends MetalCompile public MetalIxxPrecompile () { getCompiler().convention("clang++"); - getTarget().convention(getMetal().map(MetalService::getTarget)); } /** @@ -265,29 +283,13 @@ List scan () throws IOException, ClassNotFoundException @TaskAction public void precompile () throws Exception { - final var metal = getMetal().get(); - - final var compiler = metal.locateTool(getCompiler().get()); - final var target = getTarget().get(); - - final var outputDirectory = getTargetOutputDirectory().get().getAsFile().toPath(); + final var outputDirectory = getOutputDirectory().get().getAsFile().toPath(); // discover dependencies from sources final var modules = scan(); - // remove old objects - getFiles().delete(outputDirectory); - Files.createDirectories(outputDirectory); - // prepare compile arguments - final var baseArgs = new ArrayList(); - baseArgs.add("--target=%s".formatted(target)); - baseArgs.addAll(getOptions().get()); - getIncludePath().get().forEach(dir -> baseArgs.add("--include-directory=%s".formatted(dir))); - getImportPath().get().forEach(dir -> baseArgs.add("-fprebuilt-module-path=%s".formatted(dir))); - baseArgs.add("-fprebuilt-module-path=%s".formatted(outputDirectory)); - baseArgs.add("--precompile"); - baseArgs.add("--language=c++-module"); + final var commandBase = new ArrayList<>(getCommand().get()); // compile objects from sources for (var module : modules) @@ -296,14 +298,11 @@ public void precompile () throws Exception final var output = outputDirectory.resolve( moduleName.replace(":","-") + ".pcm" ); // finish compile arguments - final var compileArgs = new ArrayList<>(baseArgs); - compileArgs.add("--output=%s".formatted(output)); - compileArgs.add(module.source().toString()); + final var command = new ArrayList<>(commandBase); + command.add("--output=%s".formatted(output)); + command.add(module.source().toString()); - getExec().exec(it -> { - it.executable(compiler); - it.args(compileArgs); - }); + getExec().exec(it -> it.commandLine(command)); } } } diff --git a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalLibraryPlugin.java b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalLibraryPlugin.java index 0ee13fa..5ba1709 100644 --- a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalLibraryPlugin.java +++ b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalLibraryPlugin.java @@ -55,6 +55,7 @@ public void apply (Project project) archive.getOutput().convention(archiveFile); archive.setSource(library.getObjectFiles()); + archive.getTarget().convention(library.getTarget()); }); linkableElements.configure(it -> it.getOutgoing().artifact(archiveTask)); @@ -78,6 +79,7 @@ public void apply (Project project) link.getOptions().convention(test.getLinkOptions()); link.getOutput().convention(linkFile); link.setSource(test.getObjectFiles()); + link.getTarget().convention(test.getTarget()); }); final var runTestTask = tasks.register("runTest", Exec.class, exec -> diff --git a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalLink.java b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalLink.java index c65da12..17af407 100644 --- a/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalLink.java +++ b/plugins/src/main/java/br/dev/pedrolamarao/gradle/metal/MetalLink.java @@ -101,7 +101,6 @@ public abstract class MetalLink extends SourceTask public MetalLink () { getLinker().convention("clang++"); - getTarget().convention(getMetal().map(MetalService::getTarget)); } /**