Skip to content

Commit

Permalink
Separate cxx and ixx languages (#19)
Browse files Browse the repository at this point in the history
* Ignore file if doesn't exist.

* Move getOutputDirectory and getTargetDirectory to MetalCompileTask.

* Inject Gradle services.

* Fix output extension.

* Separate cxx and ixx plugins.

* Finish consolidating configurations in MetalBasePlugin.
  • Loading branch information
pedrolamarao authored Sep 29, 2023
1 parent 701bed1 commit 904c055
Show file tree
Hide file tree
Showing 26 changed files with 221 additions and 261 deletions.
4 changes: 3 additions & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ Plugins:
* `br.dev.pedrolamarao.metal.archive`: creates a conventional "main" archive with tasks
* `br.dev.pedrolamarao.metal.asm`: adds assembler sources to "main" component (at `src/main/asm`) with tasks
* `br.dev.pedrolamarao.metal.c`: adds C sources to "main" component (at `src/main/c`) with tasks
* `br.dev.pedrolamarao.metal.cxx`: adds C++ sources to "main" component (at `src/main/cxx`) with tasks
* `br.dev.pedrolamarao.metal.cpp`: adds CPP sources to "main" component (at `src/main/cxx`) with tasks
* `br.dev.pedrolamarao.metal.cxx`: adds C++ module implementation sources to "main" component (at `src/main/cxx`) with tasks
* `br.dev.pedrolamarao.metal.ixx`: adds C++ module interface sources to "main" component (at `src/main/cxx`) with tasks
Under construction:

Expand Down
6 changes: 5 additions & 1 deletion plugins/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ gradlePlugin {
}
create("commands") {
id = "br.dev.pedrolamarao.metal.commands"
implementationClass = "br.dev.pedrolamarao.gradle.metal.base.MetalRootPlugin"
implementationClass = "br.dev.pedrolamarao.gradle.metal.base.MetalCommandsPlugin"
}
create("cpp") {
id = "br.dev.pedrolamarao.metal.cpp"
Expand All @@ -44,6 +44,10 @@ gradlePlugin {
id = "br.dev.pedrolamarao.metal.prebuilt"
implementationClass = "br.dev.pedrolamarao.gradle.metal.base.MetalPrebuiltPlugin"
}
create("ixx") {
id = "br.dev.pedrolamarao.metal.ixx"
implementationClass = "br.dev.pedrolamarao.gradle.metal.ixx.MetalIxxPlugin"
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ int greet (int argc, char * argv[])
final var buildGradleKts =
"""
plugins {
id("br.dev.pedrolamarao.metal.cxx")
id("br.dev.pedrolamarao.metal.ixx")
}
metal {
Expand Down Expand Up @@ -162,6 +162,7 @@ int greet (int argc, char * argv[])
"""
plugins {
id("br.dev.pedrolamarao.metal.cxx")
id("br.dev.pedrolamarao.metal.ixx")
}
metal {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,23 @@

package br.dev.pedrolamarao.gradle.metal.asm;

import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.stream.Collectors;

import static java.nio.charset.StandardCharsets.UTF_8;

public abstract class MetalAsmCommandsTask extends MetalAsmCompileBaseTask
{
@Input
public abstract Property<File> getObjectDirectory ();

@OutputFile
public abstract RegularFileProperty getOutputFile ();

static final String template =
"""
{
Expand Down Expand Up @@ -64,7 +60,8 @@ public void generate () throws IOException
});

// aggregate fields
try (var writer = Files.newBufferedWriter(getOutputFile().get().getAsFile().toPath(),StandardCharsets.UTF_8)) {
final var output = getTargetDirectory().map(it -> it.file("compile_commands.json")).get();
try (var writer = Files.newBufferedWriter(output.getAsFile().toPath(),UTF_8)) {
writer.write("[\n");
writer.write( String.join(",\n",list) );
writer.write("]");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,13 @@

package br.dev.pedrolamarao.gradle.metal.asm;

import org.gradle.api.file.Directory;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;
import org.gradle.process.ExecOperations;
import org.gradle.workers.WorkAction;
import org.gradle.workers.WorkParameters;
import org.gradle.workers.WorkerExecutor;

import javax.inject.Inject;
import java.io.File;
Expand All @@ -23,23 +18,6 @@

public abstract class MetalAsmCompileTask extends MetalAsmCompileBaseTask
{
final WorkerExecutor workerExecutor;

@OutputDirectory
public abstract DirectoryProperty getOutputDirectory ();

@Internal
Provider<Directory> getOutputTargetDirectory ()
{
return getOutputDirectory().flatMap(it -> it.dir(getTarget().orElse("default")));
}

@Inject
public MetalAsmCompileTask (WorkerExecutor workerExecutor)
{
this.workerExecutor = workerExecutor;
}

public interface CompileParameters extends WorkParameters
{
DirectoryProperty getBaseDirectory ();
Expand All @@ -53,13 +31,8 @@ public interface CompileParameters extends WorkParameters

public static abstract class CompileAction implements WorkAction<CompileParameters>
{
final ExecOperations execOperations;

@Inject
public CompileAction (ExecOperations execOperations)
{
this.execOperations = execOperations;
}
public abstract ExecOperations getExec ();

@Override
public void execute ()
Expand All @@ -80,7 +53,7 @@ public void execute ()
try
{
Files.createDirectories(outputPath.getParent());
execOperations.exec(it -> it.commandLine(compileArgs));
getExec().exec(it -> it.commandLine(compileArgs));
}
catch (IOException e) { throw new RuntimeException(e); }
}
Expand All @@ -90,8 +63,8 @@ public void execute ()
public void compile ()
{
final var baseDirectory = getProject().getProjectDir();
final var outputDirectory = getOutputTargetDirectory();
final var workers = workerExecutor.noIsolation();
final var outputDirectory = getTargetDirectory();
final var workers = getWorkers().noIsolation();

// prepare arguments
final var compileArgs = toCompileArguments(File::toString);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,26 @@ static MetalAsmSources createSources (Project project, String name)
final var objects = project.getObjects();
final var tasks = project.getTasks();

// prepare configuration
final var commandsDirectory = layout.getBuildDirectory().dir("db/%s/asm".formatted(name));
final var compileOptions = objects.listProperty(String.class);
final var includables = configurations.named(INCLUDABLE_DEPENDENCIES);
final var sources = objects.sourceDirectorySet(name,name);
sources.srcDir(layout.getProjectDirectory().dir("src/%s/asm".formatted(name)));
final var objectDirectory = layout.getBuildDirectory().dir("obj/%s/asm".formatted(name));

// register commands database task
final var commandsTask = tasks.register("commands-%s-asm".formatted(name), MetalAsmCommandsTask.class, task ->
{
task.getCompileOptions().set(compileOptions);
task.getIncludables().from(includables);
task.getObjectDirectory().set(objectDirectory.map(Directory::getAsFile));
task.getOutputFile().set(layout.getBuildDirectory().file("db/%s/asm/compile_commands.json".formatted(name)));
task.getOutputDirectory().set(commandsDirectory);
task.setSource(sources);
});
configurations.named(COMMANDS_ELEMENTS).configure(it -> it.getOutgoing().artifact(commandsTask));

// register compile task
final var compileTask = tasks.register("compile-%s-asm".formatted(name), MetalAsmCompileTask.class, task ->
{
task.getCompileOptions().set(compileOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,24 @@ public void apply (Project project)
configuration.setVisible(false);
});

project.getConfigurations().resolvable(IMPORTABLE_DEPENDENCIES, configuration -> {
configuration.attributes(it -> it.attribute(MetalCapability.ATTRIBUTE, MetalCapability.IMPORTABLE));
configuration.extendsFrom(nativeImplementation.get());
});

project.getConfigurations().consumable(MetalBasePlugin.IMPORTABLE_ELEMENTS, configuration -> {
configuration.attributes(it -> it.attribute(MetalCapability.ATTRIBUTE, MetalCapability.IMPORTABLE));
});

project.getConfigurations().resolvable(MetalBasePlugin.INCLUDABLE_DEPENDENCIES, configuration -> {
configuration.attributes(it -> it.attribute(MetalCapability.ATTRIBUTE, MetalCapability.INCLUDABLE));
configuration.extendsFrom(nativeImplementation.get());
});

project.getConfigurations().consumable(MetalBasePlugin.INCLUDABLE_ELEMENTS, configuration -> {
configuration.attributes(it -> it.attribute(MetalCapability.ATTRIBUTE, MetalCapability.INCLUDABLE));
});

configurations.resolvable(LINKABLE_DEPENDENCIES, configuration -> {
configuration.attributes(it -> it.attribute(MetalCapability.ATTRIBUTE, MetalCapability.LINKABLE));
configuration.extendsFrom(nativeImplementation.get());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import java.util.ArrayList;
import java.util.List;

public class MetalRootPlugin implements Plugin<Project>
public class MetalCommandsPlugin implements Plugin<Project>
{
@Override
public void apply (Project project)
Expand All @@ -32,7 +32,7 @@ public void apply (Project project)
}

final var list = new ArrayList<>();
commandsDependencies.forEach(file -> {
commandsDependencies.getAsFileTree().forEach(file -> {
final var parsed = (List<?>) new groovy.json.JsonSlurper().parse(file);
list.addAll(parsed);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,34 @@
package br.dev.pedrolamarao.gradle.metal.base;

import org.gradle.api.file.Directory;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.workers.WorkerExecutor;

import javax.inject.Inject;
import java.nio.file.Path;

public abstract class MetalCompileTask extends MetalSourceTask
{
@Input
public abstract ListProperty<String> getCompileOptions ();

@Internal
public abstract DirectoryProperty getOutputDirectory ();

@OutputDirectory
public Provider<Directory> getTargetDirectory ()
{
return getOutputDirectory().flatMap(it -> it.dir(getTarget().orElse("default")));
}

@Inject
public abstract WorkerExecutor getWorkers ();

protected static Path toOutputPath (Path base, Path source, Path output, String extension)
{
final var hash = hash(base.relativize(source));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ protected void configure (Project project, MetalComponent component)

project.getLogger().info("gradle-metal: creating main component: {}",component);

// if cpp plugin then create cpp sources

plugins.withPlugin("br.dev.pedrolamarao.metal.cpp",plugin ->
{
final var metal = project.getExtensions().getByType(MetalExtension.class);
Expand All @@ -24,6 +26,8 @@ protected void configure (Project project, MetalComponent component)
project.getLogger().info("gradle-metal: creating main sources: {}",sources);
});

// if asm plugin then create asm sources

plugins.withPlugin("br.dev.pedrolamarao.metal.asm",plugin ->
{
final var metal = project.getExtensions().getByType(MetalExtension.class);
Expand All @@ -33,6 +37,8 @@ protected void configure (Project project, MetalComponent component)
project.getLogger().info("gradle-metal: creating main sources: {}",sources);
});

// if c plugin then create c sources

plugins.withPlugin("br.dev.pedrolamarao.metal.c",plugin ->
{
final var metal = project.getExtensions().getByType(MetalExtension.class);
Expand All @@ -42,19 +48,29 @@ protected void configure (Project project, MetalComponent component)
project.getLogger().info("gradle-metal: creating main sources: {}",sources);
});

// if cxx plugin then create cxx sources

plugins.withPlugin("br.dev.pedrolamarao.metal.cxx",plugin ->
{
final var metal = project.getExtensions().getByType(MetalExtension.class);
final var ixx = (NamedDomainObjectContainer<?>) metal.getExtensions().getByName("ixx");
final var ixxSources = (MetalIxxSources) ixx.create("main");
final var cxx = (NamedDomainObjectContainer<?>) metal.getExtensions().getByName("cxx");
final var cxxSources = (MetalCxxSources) cxx.create("main");
cxxSources.importable(ixxSources.getOutputDirectory());
cxxSources.source(ixxSources.getOutputs());
component.source(cxxSources.getOutputs());
project.getLogger().info("gradle-metal: creating main sources: {}",cxxSources);
final var sources = (MetalCxxSources) cxx.create("main");
component.source(sources.getOutputs());
project.getLogger().info("gradle-metal: creating main sources: {}",sources);
});

// if ixx plugin then create ixx sources

plugins.withPlugin("br.dev.pedrolamarao.metal.ixx",plugin ->
{
final var metal = project.getExtensions().getByType(MetalExtension.class);
final var ixx = (NamedDomainObjectContainer<?>) metal.getExtensions().getByName("ixx");
final var sources = (MetalIxxSources) ixx.create("main");
project.getLogger().info("gradle-metal: creating main sources: {}",sources);
});

// if cpp sources then wire to other sources' includables

project.afterEvaluate(it ->
{
final var metal = it.getExtensions().getByType(MetalExtension.class);
Expand Down Expand Up @@ -83,6 +99,32 @@ protected void configure (Project project, MetalComponent component)
cxx.includable( cpp.getSources().getSourceDirectories() );
project.getLogger().info("gradle-metal: wiring sources: {} -> {}",cpp,cxx);
}

final var ixxContainer = (NamedDomainObjectContainer<?>) metal.getExtensions().findByName("ixx");
if (ixxContainer != null) {
final var ixx = (MetalIxxSources) ixxContainer.getByName("main");
ixx.includable( cpp.getSources().getSourceDirectories() );
project.getLogger().info("gradle-metal: wiring sources: {} -> {}",cpp,ixx);
}
});

// if ixx sources then wire to other sources' importables

project.afterEvaluate(it ->
{
final var metal = it.getExtensions().getByType(MetalExtension.class);

final var ixxContainer = (NamedDomainObjectContainer<?>) metal.getExtensions().findByName("ixx");
if (ixxContainer == null) return;
final var ixx = (MetalIxxSources) ixxContainer.getByName("main");

final var cxxContainer = (NamedDomainObjectContainer<?>) metal.getExtensions().findByName("cxx");
if (cxxContainer != null) {
final var cxx = (MetalCxxSources) cxxContainer.getByName("main");
cxx.importable( ixx.getOutputDirectory() );
cxx.source( ixx.getOutputs() );
project.getLogger().info("gradle-metal: wiring sources: {} -> {}",ixx,cxx);
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public Provider<RegularFile> getOutput ()
{
final var target = getTarget().orElse("default").get();
final var name = getProject().getName();
return getOutputDirectory().map(it -> it.file("%s/%s.lib".formatted(target,name)));
return getOutputDirectory().map(it -> it.file("%s/%s.exe".formatted(target,name)));
}

@Internal
Expand Down
Loading

0 comments on commit 904c055

Please sign in to comment.