Hello,
I am using one of the recent nightly builds of gradle, and I am trying to create a plugin for transforming yacc grammars to C/C++ source code. In the build.gradle file, I would like to be able to have something like:
model {
 components {
            mylibrary(NativeLibrarySpec) {
                binaries.all {
                    cppCompiler.args Config.includePaths(project,"mylibrary")
                }
                sources {
                    cpp {
                        source {
                            include '**/*.cc'
                        }
                      yacc {
                        source { include '**/*.y' }
                    }
                }
            }
        }
    }
but I am having trouble figuring out how to register the LanguageSourceSet factory from the plugin class. I think DefaultPolymorphicDomainObjectContainer is looking for a registered factory for YaccLanguageSourceSet when the ‘yacc’ name is encountered. The error I get is:
Cannot create a LanguageSourceSet named ‘yacc’ because this container does not support creating elements by name alone. Please specify which subtype of LanguageSourceSet to create. Known subtypes are: CppSourceSet, JvmResourceSet, YaccLanguageSourceSet
I have used the Scala plugin as a model for how to structure the plugin et al. but right now I am just trying to figure out how to have a plugin which gets a SourceSet from the build.gradle file on a per-cpp-library basis. FWIW my plugin code is below. I know the JVM compilation model is wrong for YACC, but the scala plugin seemed to be well ordered and I am really just trying to get a ‘*.y’ SourceSet where I can (1) pass it through bison and then (2) add the output to the C/C++ SourceSet.
I have a lot of these transformational plugins to do, e.g. XML to C++, XML to LaTeX, etc. so I am really trying to do it right.
Thanks very much for any advice or tips Darrell
class YaccLanguagePlugin implements Plugin<Project> {
      def void apply(Project project) {
        project.getPluginManager().apply(ComponentModelBasePlugin.class);
        project.getPluginManager().apply(JvmResourcesPlugin.class);
    }
      /**
     * Model rules.
     */
    @SuppressWarnings("UnusedDeclaration")
    static class Rules extends RuleSource {
          @Model
        YaccToolChain yaccToolChain(ServiceRegistry serviceRegistry) {
            return serviceRegistry.get(YaccToolChain.class);
        }
          @LanguageType
        void registerLanguage(LanguageTypeBuilder<YaccLanguageSourceSet> builder) {
            builder.setLanguageName("yacc");
            builder.defaultImplementation(DefaultYaccLanguageSourceSet.class);
        }
          @Mutate
        void registerLanguageTransform(LanguageTransformContainer languages, ServiceRegistry serviceRegistry) {
            languages.add(new Yacc());
        }
    }
      private static class Yacc implements LanguageTransform<YaccLanguageSourceSet, JvmByteCode> {
        public Class<YaccLanguageSourceSet> getSourceSetType() {
            return YaccLanguageSourceSet.class;
        }
          public Map<String, Class<?>> getBinaryTools() {
            return Collections.emptyMap();
        }
          public Class<JvmByteCode> getOutputType() {
            return JvmByteCode.class;
        }
          public SourceTransformTaskConfig getTransformTask() {
            return new SourceTransformTaskConfig() {
                public String getTaskPrefix() {
                    return "compile";
                }
                  public Class<? extends DefaultTask> getTaskType() {
                    return PlatformYaccCompile.class;
                }
                  public void configureTask(Task task, BinarySpec binarySpec, LanguageSourceSet sourceSet) {
                    PlatformYaccCompile compile = (PlatformYaccCompile) task;
                    YaccLanguageSourceSet yaccSourceSet = (YaccLanguageSourceSet) sourceSet;
                    JvmBinarySpec binary = (JvmBinarySpec) binarySpec;
                    JavaPlatform javaPlatform = binary.getTargetPlatform();
                    // TODO RG resolve the yacc platform from the binary
                      compile.setPlatform(new DefaultYaccPlatform("2.10.4"));
                    File analysisFile = new File(task.getTemporaryDir(), String.format("compilerAnalysis/%s.analysis", task.getName()));
                    compile.getYaccCompileOptions().getIncrementalOptions().setAnalysisFile(analysisFile);
                      compile.setDescription(String.format("Compiles %s.", yaccSourceSet));
                    compile.setDestinationDir(binary.getClassesDir());
                      compile.setSource(yaccSourceSet.getSource());
                    compile.setClasspath(yaccSourceSet.getCompileClasspath().getFiles());
                    compile.setTargetCompatibility(javaPlatform.getTargetCompatibility().toString());
                    compile.setSourceCompatibility(javaPlatform.getTargetCompatibility().toString());
                      compile.dependsOn(yaccSourceSet);
                    binary.getTasks().getJar().dependsOn(compile);
                }
            };
        }
          public boolean applyToBinary(BinarySpec binary) {
            return binary instanceof JvmBinarySpec;
        }
    }
}
