From a56698bcd97540d430af6563effb974e4c011724 Mon Sep 17 00:00:00 2001 From: Tudor Timi Date: Sat, 1 Jun 2024 16:24:06 +0200 Subject: [PATCH 1/5] Add property for C source files to HDVL compile spec --- .../gradle/hdvl/HDVLCompileSpec.java | 1 + .../hdvl/internal/DefaultHDVLCompileSpec.java | 15 ++++++++++++++- .../hdvl/internal/WriteCompileSpecFile.java | 4 +++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/verificationgentleman/gradle/hdvl/HDVLCompileSpec.java b/src/main/java/com/verificationgentleman/gradle/hdvl/HDVLCompileSpec.java index d1aa451..b986484 100644 --- a/src/main/java/com/verificationgentleman/gradle/hdvl/HDVLCompileSpec.java +++ b/src/main/java/com/verificationgentleman/gradle/hdvl/HDVLCompileSpec.java @@ -7,4 +7,5 @@ public interface HDVLCompileSpec { Set getSvSourceFiles(); Set getSvPrivateIncludeDirs(); Set getSvExportedHeaderDirs(); + Set getCSourceFiles(); } diff --git a/src/main/java/com/verificationgentleman/gradle/hdvl/internal/DefaultHDVLCompileSpec.java b/src/main/java/com/verificationgentleman/gradle/hdvl/internal/DefaultHDVLCompileSpec.java index d185774..ed8ba0c 100644 --- a/src/main/java/com/verificationgentleman/gradle/hdvl/internal/DefaultHDVLCompileSpec.java +++ b/src/main/java/com/verificationgentleman/gradle/hdvl/internal/DefaultHDVLCompileSpec.java @@ -28,10 +28,17 @@ public class DefaultHDVLCompileSpec implements HDVLCompileSpec { @XmlJavaTypeAdapter(value=FileAdapter.class) private final File[] svExportedHeaderDirs; - public DefaultHDVLCompileSpec(Set svSourceFiles, Set svPrivateIncludeDirs, Set svExportedHeaderDirs) { + @XmlElementWrapper + @XmlElement(name="cSourceFile") + @XmlJavaTypeAdapter(value=FileAdapter.class) + private final File[] cSourceFiles; + + public DefaultHDVLCompileSpec(Set svSourceFiles, Set svPrivateIncludeDirs, Set svExportedHeaderDirs, + Set cSourceFiles) { this.svSourceFiles = svSourceFiles.toArray(new File[0]); this.svPrivateIncludeDirs = svPrivateIncludeDirs.toArray(new File[0]); this.svExportedHeaderDirs = svExportedHeaderDirs.toArray(new File[0]); + this.cSourceFiles = cSourceFiles.toArray(new File[0]); } // Needed for JAXB @@ -40,6 +47,7 @@ private DefaultHDVLCompileSpec() { this.svSourceFiles = new File[0]; this.svPrivateIncludeDirs = new File[0]; this.svExportedHeaderDirs = new File[0]; + this.cSourceFiles = new File[0]; } @Override @@ -56,4 +64,9 @@ public Set getSvPrivateIncludeDirs() { public Set getSvExportedHeaderDirs() { return new HashSet<>(Arrays.asList(svExportedHeaderDirs)); } + + @Override + public Set getCSourceFiles() { + return new HashSet<>(Arrays.asList(cSourceFiles)); + } } diff --git a/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteCompileSpecFile.java b/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteCompileSpecFile.java index db37a35..bf45cd8 100644 --- a/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteCompileSpecFile.java +++ b/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteCompileSpecFile.java @@ -8,6 +8,8 @@ import org.gradle.api.file.RegularFileProperty; import org.gradle.api.tasks.*; +import java.util.Collections; + public class WriteCompileSpecFile extends DefaultTask { private final RegularFileProperty destination; @@ -52,7 +54,7 @@ public ConfigurableFileCollection getSvExportedHeaderDirs() { @TaskAction protected void generate() { DefaultHDVLCompileSpec compileSpec = new DefaultHDVLCompileSpec(getSvSource().getFiles(), - svPrivateIncludeDirs.getFiles(), svExportedHeaderDirs.getFiles()); + svPrivateIncludeDirs.getFiles(), svExportedHeaderDirs.getFiles(), Collections.emptySet()); try { JAXBContext jaxbContext = JAXBContext.newInstance(DefaultHDVLCompileSpec.class); Marshaller marshaller = jaxbContext.createMarshaller(); From a90ca0c6171b4fb0235f74d1c27c68fd30a04582 Mon Sep 17 00:00:00 2001 From: Tudor Timi Date: Sat, 1 Jun 2024 16:27:37 +0200 Subject: [PATCH 2/5] Write C source files to compile spec --- .../gradle/hdvl/c/CPlugin.java | 12 +++++++++++- .../gradle/hdvl/internal/WriteCompileSpecFile.java | 13 ++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/verificationgentleman/gradle/hdvl/c/CPlugin.java b/src/main/java/com/verificationgentleman/gradle/hdvl/c/CPlugin.java index 8b3e90b..501192d 100644 --- a/src/main/java/com/verificationgentleman/gradle/hdvl/c/CPlugin.java +++ b/src/main/java/com/verificationgentleman/gradle/hdvl/c/CPlugin.java @@ -16,8 +16,12 @@ package com.verificationgentleman.gradle.hdvl.c; -import com.verificationgentleman.gradle.hdvl.*; +import com.verificationgentleman.gradle.hdvl.AbstractGenArgsFile; +import com.verificationgentleman.gradle.hdvl.HDVLBasePlugin; +import com.verificationgentleman.gradle.hdvl.HDVLPluginExtension; +import com.verificationgentleman.gradle.hdvl.SourceSet; import com.verificationgentleman.gradle.hdvl.c.internal.DefaultCSourceSet; +import com.verificationgentleman.gradle.hdvl.internal.WriteCompileSpecFile; import org.gradle.api.Action; import org.gradle.api.NamedDomainObjectContainer; import org.gradle.api.Plugin; @@ -45,6 +49,12 @@ public void execute(SourceSet sourceSet) { = (AbstractGenArgsFile) project.getTasks().getByName(sourceSet.getGenArgsFileTaskName(toolName)); genArgsFile.setCSource(cSourceSet.getC()); } + + if (sourceSet.getName() == "main") { + project.getTasks().withType(WriteCompileSpecFile.class, task -> { + task.getCSource().from(cSourceSet.getC()); + }); + } } }); } diff --git a/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteCompileSpecFile.java b/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteCompileSpecFile.java index bf45cd8..9c3884b 100644 --- a/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteCompileSpecFile.java +++ b/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteCompileSpecFile.java @@ -8,14 +8,13 @@ import org.gradle.api.file.RegularFileProperty; import org.gradle.api.tasks.*; -import java.util.Collections; - public class WriteCompileSpecFile extends DefaultTask { private final RegularFileProperty destination; private final ConfigurableFileCollection svSourceFiles; private final ConfigurableFileCollection svPrivateIncludeDirs; private final ConfigurableFileCollection svExportedHeaderDirs; + private final ConfigurableFileCollection cSourceFiles; public WriteCompileSpecFile() { @@ -23,6 +22,7 @@ public WriteCompileSpecFile() { svSourceFiles = getProject().getObjects().fileCollection(); svPrivateIncludeDirs = getProject().getObjects().fileCollection(); svExportedHeaderDirs = getProject().getObjects().fileCollection(); + cSourceFiles = getProject().getObjects().fileCollection(); } @OutputFile @@ -51,10 +51,17 @@ public ConfigurableFileCollection getSvExportedHeaderDirs() { return svExportedHeaderDirs; } + @InputFiles + @SkipWhenEmpty + @PathSensitive(PathSensitivity.ABSOLUTE) + public ConfigurableFileCollection getCSource() { + return cSourceFiles; + } + @TaskAction protected void generate() { DefaultHDVLCompileSpec compileSpec = new DefaultHDVLCompileSpec(getSvSource().getFiles(), - svPrivateIncludeDirs.getFiles(), svExportedHeaderDirs.getFiles(), Collections.emptySet()); + svPrivateIncludeDirs.getFiles(), svExportedHeaderDirs.getFiles(), cSourceFiles.getFiles()); try { JAXBContext jaxbContext = JAXBContext.newInstance(DefaultHDVLCompileSpec.class); Marshaller marshaller = jaxbContext.createMarshaller(); From 4da3562879dbba60456bf724828926cd90dc3749 Mon Sep 17 00:00:00 2001 From: Tudor Timi Date: Sat, 1 Jun 2024 16:38:03 +0200 Subject: [PATCH 3/5] Also zip C source files into HDVL sources archive --- .../gradle/hdvl/c/CPluginSpec.groovy | 21 +++++++++++++++++++ .../gradle/hdvl/c/CPlugin.java | 7 +++++++ 2 files changed, 28 insertions(+) diff --git a/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/c/CPluginSpec.groovy b/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/c/CPluginSpec.groovy index 62be3fc..b8068cd 100644 --- a/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/c/CPluginSpec.groovy +++ b/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/c/CPluginSpec.groovy @@ -22,6 +22,8 @@ import org.junit.rules.TemporaryFolder import spock.lang.Ignore import spock.lang.Specification +import java.util.zip.ZipFile + import static org.gradle.testkit.runner.TaskOutcome.NO_SOURCE import static org.gradle.testkit.runner.TaskOutcome.SUCCESS @@ -201,4 +203,23 @@ class CPluginSpec extends Specification { new File(testProjectDir.root, "build/dummy_xrun_args.f").exists() new File(testProjectDir.root, "build/dummy_xrun_args.f").text.contains('dummy.c') } + + def "can produce archive with source file"() { + File mainSv = testProjectDir.newFolder('src', 'main', 'c') + new File(mainSv, "main.c").createNewFile() + + when: + def result = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withPluginClasspath() + .withArguments(':hdvlSourcesArchive') + .build() + + then: + new File(testProjectDir.root, 'build/hdvl-sources.zip').exists() + def zipFile = new ZipFile(new File(testProjectDir.root, 'build/hdvl-sources.zip')) + def entries = zipFile.entries().findAll { !it.directory } + entries.size() == 2 + entries[1].name == 'src/main/c/main.c' + } } diff --git a/src/main/java/com/verificationgentleman/gradle/hdvl/c/CPlugin.java b/src/main/java/com/verificationgentleman/gradle/hdvl/c/CPlugin.java index 501192d..509f418 100644 --- a/src/main/java/com/verificationgentleman/gradle/hdvl/c/CPlugin.java +++ b/src/main/java/com/verificationgentleman/gradle/hdvl/c/CPlugin.java @@ -27,6 +27,7 @@ import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.internal.plugins.DslObject; +import org.gradle.api.tasks.bundling.Zip; public class CPlugin implements Plugin { @@ -54,6 +55,12 @@ public void execute(SourceSet sourceSet) { project.getTasks().withType(WriteCompileSpecFile.class, task -> { task.getCSource().from(cSourceSet.getC()); }); + project.getTasks().getByName("hdvlSourcesArchive", task -> { + Zip hdvlSourcesArchive = (Zip) task; + hdvlSourcesArchive.from(cSourceSet.getC(), it -> { + it.into("src/main/c"); // FIXME Assumes source in conventional location + }); + }); } } }); From 4676092c5a4064cad3e7bf90b68cbadf46815454 Mon Sep 17 00:00:00 2001 From: Tudor Timi Date: Sat, 1 Jun 2024 17:00:25 +0200 Subject: [PATCH 4/5] Handle C source files when consuming HDVL source archives --- .../gradle/hdvl/c/CPluginSpec.groovy | 78 +++++++++++++++++++ .../hdvl/internal/WriteXrunArgsFile.java | 6 ++ 2 files changed, 84 insertions(+) diff --git a/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/c/CPluginSpec.groovy b/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/c/CPluginSpec.groovy index b8068cd..18e2c3a 100644 --- a/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/c/CPluginSpec.groovy +++ b/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/c/CPluginSpec.groovy @@ -22,6 +22,7 @@ import org.junit.rules.TemporaryFolder import spock.lang.Ignore import spock.lang.Specification +import java.nio.file.Files import java.util.zip.ZipFile import static org.gradle.testkit.runner.TaskOutcome.NO_SOURCE @@ -40,6 +41,28 @@ class CPluginSpec extends Specification { """ } + /** + * Creates a new project in a new directory, with a standard layout. + * + * @param name The project name + * @return The build file of the project + */ + def newStandardProject(String name) { + File folder = testProjectDir.newFolder(name) + + File sv = testProjectDir.newFolder(name,'src', 'main', 'c') + new File(sv, "${name}.c").createNewFile() + + File buildFile = new File(folder, "build.gradle") + buildFile << """ + plugins { + id 'com.verificationgentleman.gradle.hdvl.c' + } + """ + + return buildFile + } + def "can successfully import the plugin"() { when: def result = GradleRunner.create() @@ -222,4 +245,59 @@ class CPluginSpec extends Specification { entries.size() == 2 entries[1].name == 'src/main/c/main.c' } + + def "can consume source archive"() { + File dependencyProjectBuildFile = newStandardProject('dependency-project') + dependencyProjectBuildFile << """ + plugins { + id 'maven-publish' + } + + group = "org.example" + version = "1.0.0" + + publishing { + repositories { + maven { + name = 'dummy' + url = layout.buildDirectory.dir('dummy-repo') + } + } + } + """ + + GradleRunner.create() + .withProjectDir(dependencyProjectBuildFile.parentFile) + .withPluginClasspath() + .withArguments(':publish') + .build() + + File mainProjectBuildFile = newStandardProject('main-project') + mainProjectBuildFile << """ + dependencies { + compile 'org.example:dependency-project:1.0.0' + } + + repositories { + maven { + url = layout.projectDirectory.dir('../dependency-project/build/dummy-repo') + } + } + """ + + when: + def result = GradleRunner.create() + .withProjectDir(mainProjectBuildFile.parentFile) + .withPluginClasspath() + .withDebug(true) + .withArguments(':genFullXrunArgsFile') + .build() + + then: + def lines = new File(mainProjectBuildFile.parentFile, 'build/full_xrun_args.f').text.split("\n") + def xrunArgsForDependencyProject = new File(lines[0].split(/\s+/)[1]) + Files.lines(xrunArgsForDependencyProject.toPath()).anyMatch { line -> + line.endsWith 'src/main/c/dependency-project.c' + } + } } diff --git a/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteXrunArgsFile.java b/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteXrunArgsFile.java index 6aeebd7..33a4d9c 100644 --- a/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteXrunArgsFile.java +++ b/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteXrunArgsFile.java @@ -50,6 +50,10 @@ private static DefaultHDVLCompileSpec getCompileSpec(File input) { assert svExportedHeaderDir.isAbsolute() : "not absolute: " + svExportedHeaderDir; assert svExportedHeaderDir.exists() : "doesn't exist: " + svExportedHeaderDir; } + for (File cSourceFile : result.getCSourceFiles()) { + assert cSourceFile.isAbsolute() : "not absolute: " + cSourceFile; + assert cSourceFile.exists() : "doesn't exist: " + cSourceFile; + } return result; } catch (JAXBException e) { @@ -66,6 +70,8 @@ private static void writeXrunArgsFile(File xrunArgsFile, HDVLCompileSpec compile writer.write(" -incdir " + svPrivateIncludeDir + "\n"); for (File svSourceFile : compileSpec.getSvSourceFiles()) writer.write(" " + svSourceFile + "\n"); + for (File cSourceFile : compileSpec.getCSourceFiles()) + writer.write(" " + cSourceFile + "\n"); writer.write("-endlib\n"); } catch (IOException ex) { From bd162631a5fe3fb03d6288c72caa4c5d5f43b28f Mon Sep 17 00:00:00 2001 From: Tudor Timi Date: Sat, 1 Jun 2024 17:02:03 +0200 Subject: [PATCH 5/5] Add C source file to example using published dependency --- .../using-published/some-project/src/main/sv/some_project.sv | 1 + .../using-published/some-published-dependency/build.gradle | 1 + .../some-published-dependency/src/main/c/some_dpi_func.c | 5 +++++ .../src/main/sv/some_published_dependency.sv | 1 + 4 files changed, 8 insertions(+) create mode 100644 examples/using-published/some-published-dependency/src/main/c/some_dpi_func.c diff --git a/examples/using-published/some-project/src/main/sv/some_project.sv b/examples/using-published/some-project/src/main/sv/some_project.sv index a38db2d..6e52e37 100644 --- a/examples/using-published/some-project/src/main/sv/some_project.sv +++ b/examples/using-published/some-project/src/main/sv/some_project.sv @@ -8,5 +8,6 @@ module some_project; function automatic void do_stuff(); some_class o = new(); `some_published_dependency_macro + some_dpi_func(); endfunction endmodule diff --git a/examples/using-published/some-published-dependency/build.gradle b/examples/using-published/some-published-dependency/build.gradle index fe26e9b..f2591ea 100644 --- a/examples/using-published/some-published-dependency/build.gradle +++ b/examples/using-published/some-published-dependency/build.gradle @@ -1,5 +1,6 @@ plugins { id 'com.verificationgentleman.gradle.hdvl.systemverilog' + id 'com.verificationgentleman.gradle.hdvl.c' id 'maven-publish' } diff --git a/examples/using-published/some-published-dependency/src/main/c/some_dpi_func.c b/examples/using-published/some-published-dependency/src/main/c/some_dpi_func.c new file mode 100644 index 0000000..07a9b9c --- /dev/null +++ b/examples/using-published/some-published-dependency/src/main/c/some_dpi_func.c @@ -0,0 +1,5 @@ +#include + +void some_dpi_func() { + printf("Hello from C\n"); +} diff --git a/examples/using-published/some-published-dependency/src/main/sv/some_published_dependency.sv b/examples/using-published/some-published-dependency/src/main/sv/some_published_dependency.sv index c41e751..d42f613 100644 --- a/examples/using-published/some-published-dependency/src/main/sv/some_published_dependency.sv +++ b/examples/using-published/some-published-dependency/src/main/sv/some_published_dependency.sv @@ -1,3 +1,4 @@ package some_published_dependency; `include "some_class.svh" + import "DPI-C" function void some_dpi_func(); endpackage