Skip to content

Commit

Permalink
Simplify (#75)
Browse files Browse the repository at this point in the history
* Move target convention from task to project.

* Remove implicit "target output directory" convention.

* Add getCommand to get the task command line.
  • Loading branch information
pedrolamarao authored Feb 21, 2024
1 parent 90e9795 commit 162e095
Show file tree
Hide file tree
Showing 17 changed files with 291 additions and 328 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ void compile () throws IOException
val compile = tasks.register<MetalAsmCompile>("compile") {
outputDirectory = layout.buildDirectory.dir("obj")
source = layout.projectDirectory.dir("src").asFileTree
target = metal.host
}
"""
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ void compile () throws IOException
val compile = tasks.register<MetalCCompile>("compile") {
outputDirectory = layout.buildDirectory.dir("obj")
source = layout.projectDirectory.dir("src").asFileTree
target = metal.host
}
"""
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ void compile () throws IOException
val compile = tasks.register<MetalCxxCompile>("compile") {
outputDirectory = layout.buildDirectory.dir("obj")
source = layout.projectDirectory.dir("src").asFileTree
target = metal.host
}
"""
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
"""
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ public abstract class MetalArchive extends SourceTask
public MetalArchive ()
{
getArchiver().convention("llvm-ar");
getTarget().convention(getMetal().map(MetalService::getTarget));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -21,9 +24,18 @@ public MetalAsmCompile ()
}

@Override
protected final void addLanguageOptions (ListProperty<String> list)
Provider<List<String>> getCommand ()
{
list.add("--language=assembler");
return getProviders().provider(() ->
{
final var list = new ArrayList<String>();
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;
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -30,10 +34,19 @@ public MetalCCompile ()
}

@Override
protected final void addLanguageOptions (ListProperty<String> list)
Provider<List<String>> getCommand ()
{
getIncludePath().get().forEach(path -> list.add("--include-directory=%s".formatted(path)));
list.add("--language=c");
return getProviders().provider(() ->
{
final var list = new ArrayList<String>();
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;
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>();
Expand All @@ -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());
Expand All @@ -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<String>();
Expand All @@ -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());
Expand Down
Loading

0 comments on commit 162e095

Please sign in to comment.