From 3c96b2fba3c24081a6866ce1134c5572dde7ef8f Mon Sep 17 00:00:00 2001 From: Tudor Timi Date: Sun, 26 May 2024 17:20:03 +0200 Subject: [PATCH 1/6] Add property for SV exported header directories to HDVL compile spec --- .../gradle/hdvl/HDVLCompileSpec.java | 1 + .../hdvl/internal/DefaultHDVLCompileSpec.java | 14 +++++++++++++- .../gradle/hdvl/internal/WriteCompileSpecFile.java | 4 +++- 3 files changed, 17 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 ae98bd9..d1aa451 100644 --- a/src/main/java/com/verificationgentleman/gradle/hdvl/HDVLCompileSpec.java +++ b/src/main/java/com/verificationgentleman/gradle/hdvl/HDVLCompileSpec.java @@ -6,4 +6,5 @@ public interface HDVLCompileSpec { Set getSvSourceFiles(); Set getSvPrivateIncludeDirs(); + Set getSvExportedHeaderDirs(); } 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 88ab55c..d185774 100644 --- a/src/main/java/com/verificationgentleman/gradle/hdvl/internal/DefaultHDVLCompileSpec.java +++ b/src/main/java/com/verificationgentleman/gradle/hdvl/internal/DefaultHDVLCompileSpec.java @@ -23,9 +23,15 @@ public class DefaultHDVLCompileSpec implements HDVLCompileSpec { @XmlJavaTypeAdapter(value=FileAdapter.class) private final File[] svPrivateIncludeDirs; - public DefaultHDVLCompileSpec(Set svSourceFiles, Set svPrivateIncludeDirs) { + @XmlElementWrapper + @XmlElement(name="svExportedHeaderDir") + @XmlJavaTypeAdapter(value=FileAdapter.class) + private final File[] svExportedHeaderDirs; + + public DefaultHDVLCompileSpec(Set svSourceFiles, Set svPrivateIncludeDirs, Set svExportedHeaderDirs) { this.svSourceFiles = svSourceFiles.toArray(new File[0]); this.svPrivateIncludeDirs = svPrivateIncludeDirs.toArray(new File[0]); + this.svExportedHeaderDirs = svExportedHeaderDirs.toArray(new File[0]); } // Needed for JAXB @@ -33,6 +39,7 @@ public DefaultHDVLCompileSpec(Set svSourceFiles, Set svPrivateInclud private DefaultHDVLCompileSpec() { this.svSourceFiles = new File[0]; this.svPrivateIncludeDirs = new File[0]; + this.svExportedHeaderDirs = new File[0]; } @Override @@ -44,4 +51,9 @@ public Set getSvSourceFiles() { public Set getSvPrivateIncludeDirs() { return new HashSet<>(Arrays.asList(svPrivateIncludeDirs)); } + + @Override + public Set getSvExportedHeaderDirs() { + return new HashSet<>(Arrays.asList(svExportedHeaderDirs)); + } } 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 25cb135..63cd7d8 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; @@ -42,7 +44,7 @@ public ConfigurableFileCollection getSvSPrivateIncludeDirs() { @TaskAction protected void generate() { DefaultHDVLCompileSpec compileSpec = new DefaultHDVLCompileSpec(getSvSource().getFiles(), - svSPrivateIncludeDirs.getFiles()); + svSPrivateIncludeDirs.getFiles(), Collections.emptySet()); try { JAXBContext jaxbContext = JAXBContext.newInstance(DefaultHDVLCompileSpec.class); Marshaller marshaller = jaxbContext.createMarshaller(); From 8102352da890e8a298ca76643a1ee83443df3c95 Mon Sep 17 00:00:00 2001 From: Tudor Timi Date: Sun, 26 May 2024 17:29:59 +0200 Subject: [PATCH 2/6] Write SV exported header dirs to compile spec --- .../gradle/hdvl/internal/WriteCompileSpecFile.java | 14 +++++++++++--- .../hdvl/systemverilog/SystemVerilogPlugin.java | 1 + 2 files changed, 12 insertions(+), 3 deletions(-) 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 63cd7d8..2847c22 100644 --- a/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteCompileSpecFile.java +++ b/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteCompileSpecFile.java @@ -8,18 +8,19 @@ 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 svSPrivateIncludeDirs; + private final ConfigurableFileCollection svExportedHeaderDirs; + public WriteCompileSpecFile() { destination = getProject().getObjects().fileProperty(); svSourceFiles = getProject().getObjects().fileCollection(); svSPrivateIncludeDirs = getProject().getObjects().fileCollection(); + svExportedHeaderDirs = getProject().getObjects().fileCollection(); } @OutputFile @@ -41,10 +42,17 @@ public ConfigurableFileCollection getSvSPrivateIncludeDirs() { return svSPrivateIncludeDirs; } + @InputFiles + @SkipWhenEmpty + @PathSensitive(PathSensitivity.ABSOLUTE) + public ConfigurableFileCollection getSvExportedHeaderDirs() { + return svExportedHeaderDirs; + } + @TaskAction protected void generate() { DefaultHDVLCompileSpec compileSpec = new DefaultHDVLCompileSpec(getSvSource().getFiles(), - svSPrivateIncludeDirs.getFiles(), Collections.emptySet()); + svSPrivateIncludeDirs.getFiles(), svExportedHeaderDirs.getFiles()); try { JAXBContext jaxbContext = JAXBContext.newInstance(DefaultHDVLCompileSpec.class); Marshaller marshaller = jaxbContext.createMarshaller(); diff --git a/src/main/java/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPlugin.java b/src/main/java/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPlugin.java index cb85ff1..c8ebe40 100644 --- a/src/main/java/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPlugin.java +++ b/src/main/java/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPlugin.java @@ -53,6 +53,7 @@ public void execute(SourceSet sourceSet) { project.getTasks().withType(WriteCompileSpecFile.class, task -> { task.getSvSource().from(svSourceSet.getSv()); task.getSvSPrivateIncludeDirs().from(svSourceSet.getSv().getSourceDirectories()); + task.getSvExportedHeaderDirs().from(svSourceSet.getSvHeaders().getSourceDirectories()); }); project.getTasks().getByName("hdvlSourcesArchive", task -> { Zip hdvlSourcesArchive = (Zip) task; From 3e485c5caa733074a8c18fc479a912fcf8d7593c Mon Sep 17 00:00:00 2001 From: Tudor Timi Date: Sun, 26 May 2024 17:35:53 +0200 Subject: [PATCH 3/6] Also zip SV private headers into HDVL sources archive We still need to implement proper handling of headers in order to get a list of files through the source set. --- .../SystemVerilogPluginSpec.groovy | 19 +++++++++++++++++++ .../systemverilog/SystemVerilogPlugin.java | 5 +++++ 2 files changed, 24 insertions(+) diff --git a/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPluginSpec.groovy b/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPluginSpec.groovy index 602b5bc..1619928 100644 --- a/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPluginSpec.groovy +++ b/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPluginSpec.groovy @@ -945,6 +945,25 @@ class SystemVerilogPluginSpec extends Specification { entries[2].name == 'src/main/sv/private_header.svh' } + def "can produce archive with private header"() { + File mainSvHeaders = testProjectDir.newFolder('src', 'main', 'sv_headers') + new File(mainSvHeaders, "exported_header.svh").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/sv_headers/exported_header.svh' + } + def "can publishing metadata for archive"() { File mainSv = testProjectDir.newFolder('src', 'main', 'sv') new File(mainSv, "main.sv").createNewFile() diff --git a/src/main/java/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPlugin.java b/src/main/java/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPlugin.java index c8ebe40..d2ab51f 100644 --- a/src/main/java/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPlugin.java +++ b/src/main/java/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPlugin.java @@ -66,6 +66,11 @@ public void execute(SourceSet sourceSet) { hdvlSourcesArchive.from(project.files("src/main/sv").getFiles(), it -> { it.into("src/main/sv"); // FIXME Assumes source in conventional location }); + + // FIXME Implement proper handling of SV exported headers + hdvlSourcesArchive.from(project.files("src/main/sv_headers").getFiles(), it -> { + it.into("src/main/sv_headers"); // FIXME Assumes source in conventional location + }); }); } } From 3e0b51bad15a8a748cbe711524eff3754af22f72 Mon Sep 17 00:00:00 2001 From: Tudor Timi Date: Sun, 26 May 2024 17:39:40 +0200 Subject: [PATCH 4/6] Handle SV exported header dirs when consuming HDVL source archives --- .../SystemVerilogPluginSpec.groovy | 60 +++++++++++++++++++ .../hdvl/internal/WriteXrunArgsFile.java | 6 ++ 2 files changed, 66 insertions(+) diff --git a/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPluginSpec.groovy b/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPluginSpec.groovy index 1619928..bafa273 100644 --- a/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPluginSpec.groovy +++ b/src/functTest/groovy/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPluginSpec.groovy @@ -1115,4 +1115,64 @@ class SystemVerilogPluginSpec extends Specification { line.contains('-incdir') && line.endsWith('src/main/sv') } } + + def "can consume source archive with exported header directory"() { + 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') + } + } + } + """ + + File dependencyProjectExportedHeaderDir = new File(dependencyProjectBuildFile.parentFile, 'src/main/sv_headers') + dependencyProjectExportedHeaderDir.mkdir() + File dependencyProjectPrivateHeader = new File(dependencyProjectExportedHeaderDir, 'dependency-project-exported-header.svh') + dependencyProjectPrivateHeader.text = "dummy" + + 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.contains('-incdir') && line.endsWith('src/main/sv_headers') + } + } } 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 7608ebe..6aeebd7 100644 --- a/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteXrunArgsFile.java +++ b/src/main/java/com/verificationgentleman/gradle/hdvl/internal/WriteXrunArgsFile.java @@ -46,6 +46,10 @@ private static DefaultHDVLCompileSpec getCompileSpec(File input) { assert svPrivateIncludeDir.isAbsolute() : "not absolute: " + svPrivateIncludeDir; assert svPrivateIncludeDir.exists() : "doesn't exist: " + svPrivateIncludeDir; } + for (File svExportedHeaderDir : result.getSvExportedHeaderDirs()) { + assert svExportedHeaderDir.isAbsolute() : "not absolute: " + svExportedHeaderDir; + assert svExportedHeaderDir.exists() : "doesn't exist: " + svExportedHeaderDir; + } return result; } catch (JAXBException e) { @@ -55,6 +59,8 @@ private static DefaultHDVLCompileSpec getCompileSpec(File input) { private static void writeXrunArgsFile(File xrunArgsFile, HDVLCompileSpec compileSpec) { try (BufferedWriter writer = new BufferedWriter(new FileWriter(xrunArgsFile, true))) { + for (File svExportedHeaderDir: compileSpec.getSvExportedHeaderDirs()) + writer.write("-incdir " + svExportedHeaderDir + "\n"); writer.write("-makelib worklib\n"); for (File svPrivateIncludeDir: compileSpec.getSvPrivateIncludeDirs()) writer.write(" -incdir " + svPrivateIncludeDir + "\n"); From 6be5a75281331205ecece7f17cc70d161b6d40c4 Mon Sep 17 00:00:00 2001 From: Tudor Timi Date: Sun, 26 May 2024 18:13:19 +0200 Subject: [PATCH 5/6] Only handle SV exported header dirs that actually exist The `getSourceDirectories()` method returns which source directories are specified, but does not check whether they actually exist. Source sets in Gradle are primarily intended for specifying files, but we're trying to also use them for specifying directories, which means that we'll have to invest a bit more effort. --- .../gradle/hdvl/systemverilog/SystemVerilogPlugin.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPlugin.java b/src/main/java/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPlugin.java index d2ab51f..c7ea562 100644 --- a/src/main/java/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPlugin.java +++ b/src/main/java/com/verificationgentleman/gradle/hdvl/systemverilog/SystemVerilogPlugin.java @@ -26,6 +26,8 @@ import org.gradle.api.internal.plugins.DslObject; import org.gradle.api.tasks.bundling.Zip; +import java.io.File; + public class SystemVerilogPlugin implements Plugin { @Override @@ -53,7 +55,7 @@ public void execute(SourceSet sourceSet) { project.getTasks().withType(WriteCompileSpecFile.class, task -> { task.getSvSource().from(svSourceSet.getSv()); task.getSvSPrivateIncludeDirs().from(svSourceSet.getSv().getSourceDirectories()); - task.getSvExportedHeaderDirs().from(svSourceSet.getSvHeaders().getSourceDirectories()); + task.getSvExportedHeaderDirs().from(svSourceSet.getSvHeaders().getSourceDirectories().filter(File::exists)); }); project.getTasks().getByName("hdvlSourcesArchive", task -> { Zip hdvlSourcesArchive = (Zip) task; From 21dca8ade969ecb9b52d427af5bc0e5a37a6aed0 Mon Sep 17 00:00:00 2001 From: Tudor Timi Date: Sun, 26 May 2024 17:55:44 +0200 Subject: [PATCH 6/6] Add exported header to example using published dependency --- .../using-published/some-project/src/main/sv/some_project.sv | 2 ++ .../src/main/sv_headers/some_published_dependency_macros.svh | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 examples/using-published/some-published-dependency/src/main/sv_headers/some_published_dependency_macros.svh 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 0dc52b3..a38db2d 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 @@ -1,10 +1,12 @@ module some_project; import some_published_dependency::*; + `include "some_published_dependency_macros.svh" initial do_stuff(); function automatic void do_stuff(); some_class o = new(); + `some_published_dependency_macro endfunction endmodule diff --git a/examples/using-published/some-published-dependency/src/main/sv_headers/some_published_dependency_macros.svh b/examples/using-published/some-published-dependency/src/main/sv_headers/some_published_dependency_macros.svh new file mode 100644 index 0000000..752a8ab --- /dev/null +++ b/examples/using-published/some-published-dependency/src/main/sv_headers/some_published_dependency_macros.svh @@ -0,0 +1,2 @@ +`define some_published_dependency_macro \ + $display("Hello from macro");