diff --git a/buildSrc/src/main/groovy/io/github/jwharm/javagi/generator/GenerateSources.groovy b/buildSrc/src/main/groovy/io/github/jwharm/javagi/generator/GenerateSources.groovy deleted file mode 100644 index 4915f487..00000000 --- a/buildSrc/src/main/groovy/io/github/jwharm/javagi/generator/GenerateSources.groovy +++ /dev/null @@ -1,97 +0,0 @@ -package io.github.jwharm.javagi.generator - -import io.github.jwharm.javagi.model.Repository -import io.github.jwharm.javagi.model.Module -import org.gradle.api.DefaultTask -import org.gradle.api.file.Directory -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.provider.Property -import org.gradle.api.tasks.* - -import java.nio.file.Path - -/** - * GenerateSources is a Gradle task that will parse a GIR file (and all included GIR files) - * and generate Java source files for the types defined in the GIR file. - */ -abstract class GenerateSources extends DefaultTask { - - @InputDirectory - abstract DirectoryProperty getInputDirectory() - - @OutputDirectory - abstract DirectoryProperty getOutputDirectory() - - @Input - abstract Property getGirFile() - - @Input @Optional - abstract Property getUrlPrefix() - - @Input @Optional - abstract Property getPatch() - - @TaskAction - void execute() { - Conversions.packageNames = PackageNames.map - - Module windows = parse(Platform.WINDOWS, inputDirectory.get(), girFile.get(), - urlPrefix.getOrElse(null), patch.getOrElse(null)) - Module linux = parse(Platform.LINUX, inputDirectory.get(), girFile.get(), - urlPrefix.getOrElse(null), patch.getOrElse(null)) - Module macos = parse(Platform.MACOS, inputDirectory.get(), girFile.get(), - urlPrefix.getOrElse(null), patch.getOrElse(null)) - - Module module = new Merge().merge(windows, linux, macos) - - for (Repository repository : module.repositories.values()) { - if (repository.generate) { - Path basePath = outputDirectory.get().file(repository.namespace.pathName).asFile.toPath() - repository.generate(basePath) - } - } - } - - private static Module parse(Platform platform, Directory sourceDirectory, String girFile, String urlPrefix, Patch patch) { - Module module = new Module(platform) - Directory girPath = sourceDirectory.dir(platform.name().toLowerCase()) - if (! girPath.asFile.exists()) { - System.out.println("Not found: " + girPath) - return null - } - GirParser parser = new GirParser(girPath.asFile.toPath(), module) - - // Parse the GI files into Repository objects - try { - // Parse the file - Repository r = parser.parse(girFile) - - // Check if this one has already been parsed - if (module.repositories.containsKey(r.namespace.name)) { - r = module.repositories.get(r.namespace.name) - } else { - // Add the repository to the module - module.repositories.put(r.namespace.name, r) - } - - r.urlPrefix = urlPrefix - - // Flag unsupported va_list methods so they will not be generated - module.flagVaListFunctions() - - // Apply patch - if (patch != null) { - patch.patch(r) - } - - } catch (IOException ignored) { - // Gir file not found for this platform: This will generate code with UnsupportedPlatformExceptions - } - - // Link the type references to the GIR type definition across the GI repositories - module.link() - - return module - } -} - diff --git a/buildSrc/src/main/groovy/io/github/jwharm/javagi/generator/PackageNames.groovy b/buildSrc/src/main/groovy/io/github/jwharm/javagi/generator/PackageNames.groovy deleted file mode 100644 index 0e798e88..00000000 --- a/buildSrc/src/main/groovy/io/github/jwharm/javagi/generator/PackageNames.groovy +++ /dev/null @@ -1,37 +0,0 @@ -package io.github.jwharm.javagi.generator - -/** - * The PackageNames class defines the mapping between GIR namespaces - * and Java package names. - */ -class PackageNames { - - static Map map = - [ - GLib : 'org.gnome.glib', - GObject : 'org.gnome.gobject', - GModule : 'org.gnome.gmodule', - Gio : 'org.gnome.gio', - cairo : 'org.freedesktop.cairo', - freetype2 : 'org.freedesktop.freetype', - HarfBuzz : 'org.freedesktop.harfbuzz', - Pango : 'org.gnome.pango', - PangoCairo : 'org.gnome.pango.cairo', - GdkPixbuf : 'org.gnome.gdkpixbuf', - Gdk : 'org.gnome.gdk', - Graphene : 'org.gnome.graphene', - Gsk : 'org.gnome.gsk', - Gtk : 'org.gnome.gtk', - GtkSource : 'org.gnome.gtksourceview', - Adw : 'org.gnome.adw', - Soup : 'org.gnome.soup', - JavaScriptCore : 'org.gnome.webkit.jsc', - WebKit : "org.gnome.webkit", - WebKitWebProcessExtension: "org.gnome.webkit.wpe", - Gst : 'org.freedesktop.gstreamer', - GstBase : 'org.freedesktop.gstreamer.base', - GstAudio : 'org.freedesktop.gstreamer.audio', - GstPbutils : 'org.freedesktop.gstreamer.pbutils', - GstVideo : 'org.freedesktop.gstreamer.video' - ] -} diff --git a/buildSrc/src/main/groovy/java-gi.library-conventions.gradle b/buildSrc/src/main/groovy/java-gi.library-conventions.gradle index 527b0b37..12f0f1c2 100644 --- a/buildSrc/src/main/groovy/java-gi.library-conventions.gradle +++ b/buildSrc/src/main/groovy/java-gi.library-conventions.gradle @@ -1,5 +1,5 @@ import org.apache.tools.ant.taskdefs.condition.Os -import io.github.jwharm.javagi.generator.GenerateSources +import io.github.jwharm.javagi.GenerateSources /* Common build settings for Java-GI modules: * diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/GenerateSources.java b/buildSrc/src/main/java/io/github/jwharm/javagi/GenerateSources.java new file mode 100644 index 00000000..8289629e --- /dev/null +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/GenerateSources.java @@ -0,0 +1,122 @@ +/* Java-GI - Java language bindings for GObject-Introspection-based libraries + * Copyright (C) 2022-2023 Jan-Willem Harmannij + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +package io.github.jwharm.javagi; + +import io.github.jwharm.javagi.generator.*; +import io.github.jwharm.javagi.model.Repository; +import io.github.jwharm.javagi.model.Module; +import org.gradle.api.DefaultTask; +import org.gradle.api.file.Directory; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.*; +import org.xml.sax.SAXException; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.nio.file.Path; + +/** + * GenerateSources is a Gradle task that will parse a GIR file (and all included GIR files) + * and generate Java source files for the types defined in the GIR file. + */ +public abstract class GenerateSources extends DefaultTask { + + @InputDirectory + abstract DirectoryProperty getInputDirectory(); + + @OutputDirectory + abstract DirectoryProperty getOutputDirectory(); + + @Input + abstract Property getGirFile(); + + @Input @Optional + abstract Property getUrlPrefix(); + + @Input @Optional + abstract Property getPatch(); + + @TaskAction + void execute() { + try { + Module windows = parse(Platform.WINDOWS, getInputDirectory().get(), getGirFile().get(), + getUrlPrefix().getOrElse(null), getPatch().getOrElse(null)); + Module linux = parse(Platform.LINUX, getInputDirectory().get(), getGirFile().get(), + getUrlPrefix().getOrElse(null), getPatch().getOrElse(null)); + Module macos = parse(Platform.MACOS, getInputDirectory().get(), getGirFile().get(), + getUrlPrefix().getOrElse(null), getPatch().getOrElse(null)); + + Module module = new Merge().merge(windows, linux, macos); + + for (Repository repository : module.repositories.values()) { + if (repository.generate) { + Path basePath = getOutputDirectory().get().file(repository.namespace.pathName).getAsFile().toPath(); + repository.generate(basePath); + } + } + } catch (Exception e) { + throw new TaskExecutionException(this, e); + } + } + + private static Module parse(Platform platform, Directory sourceDirectory, String girFile, String urlPrefix, Patch patch) + throws SAXException, ParserConfigurationException { + Module module = new Module(platform); + Directory girPath = sourceDirectory.dir(platform.name().toLowerCase()); + if (! girPath.getAsFile().exists()) { + System.out.println("Not found: " + girPath); + return null; + } + GirParser parser = new GirParser(girPath.getAsFile().toPath(), module); + + // Parse the GI files into Repository objects + try { + // Parse the file + Repository r = parser.parse(girFile); + + // Check if this one has already been parsed + if (module.repositories.containsKey(r.namespace.name)) { + r = module.repositories.get(r.namespace.name); + } else { + // Add the repository to the module + module.repositories.put(r.namespace.name, r); + } + + r.urlPrefix = urlPrefix; + + // Flag unsupported va_list methods so they will not be generated + module.flagVaListFunctions(); + + // Apply patch + if (patch != null) { + patch.patch(r); + } + + } catch (IOException ignored) { + // Gir file not found for this platform: This will generate code with UnsupportedPlatformExceptions + } + + // Link the type references to the GIR type definition across the GI repositories + module.link(); + + return module; + } +} diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/configuration/PackageNames.java b/buildSrc/src/main/java/io/github/jwharm/javagi/configuration/PackageNames.java new file mode 100644 index 00000000..cf70da50 --- /dev/null +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/configuration/PackageNames.java @@ -0,0 +1,61 @@ +/* Java-GI - Java language bindings for GObject-Introspection-based libraries + * Copyright (C) 2022-2023 Jan-Willem Harmannij + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +package io.github.jwharm.javagi.configuration; + +import java.util.Map; + +import static java.util.Map.entry; + +/** + * The PackageNames class defines the mapping between GIR namespaces + * and Java package names. + */ +public class PackageNames { + + public static Map getMap() { + return Map.ofEntries( + entry("GLib", "org.gnome.glib"), + entry("GObject", "org.gnome.gobject"), + entry("GModule", "org.gnome.gmodule"), + entry("Gio", "org.gnome.gio"), + entry("cairo", "org.freedesktop.cairo"), + entry("freetype2", "org.freedesktop.freetype"), + entry("HarfBuzz", "org.freedesktop.harfbuzz"), + entry("Pango", "org.gnome.pango"), + entry("PangoCairo", "org.gnome.pango.cairo"), + entry("GdkPixbuf", "org.gnome.gdkpixbuf"), + entry("Gdk", "org.gnome.gdk"), + entry("Graphene", "org.gnome.graphene"), + entry("Gsk", "org.gnome.gsk"), + entry("Gtk", "org.gnome.gtk"), + entry("GtkSource", "org.gnome.gtksourceview"), + entry("Adw", "org.gnome.adw"), + entry("Soup", "org.gnome.soup"), + entry("JavaScriptCore", "org.gnome.webkit.jsc"), + entry("WebKit", "org.gnome.webkit"), + entry("WebKitWebProcessExtension", "org.gnome.webkit.wpe"), + entry("Gst", "org.freedesktop.gstreamer"), + entry("GstBase", "org.freedesktop.gstreamer.base"), + entry("GstAudio", "org.freedesktop.gstreamer.audio"), + entry("GstPbutils", "org.freedesktop.gstreamer.pbutils"), + entry("GstVideo", "org.freedesktop.gstreamer.video") + ); + } +} diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/generator/Conversions.java b/buildSrc/src/main/java/io/github/jwharm/javagi/generator/Conversions.java index 54ba7fb3..2d8dd903 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/generator/Conversions.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/generator/Conversions.java @@ -21,27 +21,21 @@ import java.util.Arrays; import java.util.List; -import java.util.Map; import java.util.Objects; +import io.github.jwharm.javagi.configuration.PackageNames; import io.github.jwharm.javagi.model.*; -import io.github.jwharm.javagi.model.Module; /** * Utility functions to convert names and keywords */ public class Conversions { - /** - * Map of namespaces to Java package names - */ - public static Map packageNames; - /** * Convert "Gdk" to "org.gnome.gdk" */ public static String namespaceToJavaPackage(String ns) { - return Objects.requireNonNullElse(packageNames.get(ns), ns); + return Objects.requireNonNullElse(PackageNames.getMap().get(ns), ns); } /** diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/model/Namespace.java b/buildSrc/src/main/java/io/github/jwharm/javagi/model/Namespace.java index 1378cc09..5d645109 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/model/Namespace.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/model/Namespace.java @@ -19,7 +19,7 @@ package io.github.jwharm.javagi.model; -import io.github.jwharm.javagi.generator.Conversions; +import io.github.jwharm.javagi.configuration.PackageNames; import io.github.jwharm.javagi.generator.Platform; import java.util.HashMap; @@ -45,7 +45,7 @@ public Namespace(GirElement parent, String name, String version, String sharedLi this.sharedLibrary = sharedLibrary; this.cIdentifierPrefix = cIdentifierPrefix; this.cSymbolPrefix = cSymbolPrefix; - this.packageName = Conversions.packageNames.get(name); + this.packageName = PackageNames.getMap().get(name); this.globalClassName = (name.equals("GObject") ? "GObjects" : name); this.pathName = packageName.replace('.', '/') + '/'; } diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/operations/GenerateSourcesOperation.java b/buildSrc/src/main/java/io/github/jwharm/javagi/operations/GenerateSourcesOperation.java deleted file mode 100644 index 856116ff..00000000 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/operations/GenerateSourcesOperation.java +++ /dev/null @@ -1,216 +0,0 @@ -/* Java-GI - Java language bindings for GObject-Introspection-based libraries - * Copyright (C) 2022-2023 Jan-Willem Harmannij - * - * SPDX-License-Identifier: LGPL-2.1-or-later - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -package io.github.jwharm.javagi.operations; - -import io.github.jwharm.javagi.generator.*; -import io.github.jwharm.javagi.model.Module; -import io.github.jwharm.javagi.model.Repository; -import org.xml.sax.SAXException; - -import javax.xml.parsers.ParserConfigurationException; -import java.io.IOException; -import java.nio.file.Path; -import java.util.*; - -/** - * Generates Java sources from GIR files - * - * @since 0.5 - */ -public class GenerateSourcesOperation { - private Path sourceDirectory = null; - private Path outputDirectory = null; - private final List sources = new ArrayList<>(); - private static Map packageNames = null; - - /** - * Performs the JavaGI operation. - * @since 0.5 - */ - public void execute() throws Exception { - Conversions.packageNames = packageNames; - Set namespaces = new LinkedHashSet<>(); - - // Parse all platform-specific gir files - Module windows = parse(Platform.WINDOWS); - Module linux = parse(Platform.LINUX); - Module macos = parse(Platform.MACOS); - - // Merge the gir repositories into one cross-platform repository - Module module = new Merge().merge(windows, linux, macos); - - // Generate bindings classes - for (Repository repository : module.repositories.values()) { - if (repository.generate) { - Path basePath = outputDirectory().resolve(repository.namespace.pathName); - repository.generate(basePath); - namespaces.add(repository.namespace.packageName); - } - } - } - - public Module parse(Platform platform) throws ParserConfigurationException, SAXException { - Module module = new Module(platform); - Path girPath = sourceDirectory().resolve(platform.name().toLowerCase()); - if (! girPath.toFile().exists()) { - System.out.println("Not found: " + girPath); - return null; - } - GirParser parser = new GirParser(girPath, module); - - // Parse the GI files into Repository objects - for (var source : sources()) { - try { - // Parse the file - Repository r = parser.parse(source.fileName); - - // Check if this one has already been parsed - if (module.repositories.containsKey(r.namespace.name)) { - r = module.repositories.get(r.namespace.name); - } else { - // Add the repository to the module - module.repositories.put(r.namespace.name, r); - } - - r.urlPrefix = source.urlPrefix; - - // Flag unsupported va_list methods so they will not be generated - module.flagVaListFunctions(); - - // Apply patch - if (source.patch != null) { - source.patch.patch(r); - } - - } catch (IOException ignored) { - // Gir file not found for this platform: This will generate code with UnsupportedPlatformExceptions - } - } - - // Link the type references to the GIR type definition across the GI repositories - module.link(); - - return module; - } - - /** - * Source gir file to parse - * @param fileName the filename of the gir file - * @param urlPrefix URL to prefix before links to images - * @param patch patch to apply to a parsed gi repository before generating classes - */ - public record Source(String fileName, String urlPrefix, Patch patch) {} - - /** - * Provides the source directory that will be used for the JavaGI operation. - * @param directory the source directory - * @return this operation instance - * @since 0.5 - */ - public GenerateSourcesOperation sourceDirectory(Path directory) { - sourceDirectory = directory; - return this; - } - - /** - * Provides the output directory where all output is generated. - * @param directory the output directory - * @return this operation instance - * @since 0.5 - */ - public GenerateSourcesOperation outputDirectory(Path directory) { - outputDirectory = directory; - return this; - } - - /** - * Provides the sources for which bindings are generated. - * @param sources the sources - * @return this operation instance - * @since 0.5 - */ - public GenerateSourcesOperation sources(Source... sources) { - return sources(Arrays.asList(sources)); - } - - /** - * Provides a list of source for which bindings are generated. - * @param sources the sources - * @return this operation instance - * @since 0.5 - */ - public GenerateSourcesOperation sources(List sources) { - this.sources.addAll(sources); - return this; - } - - /** - * Provide the map of namespaces to package names - * @param map the map of namespaces to package names - * @since 0.7 - */ - public static void packageNames(Map map) { - packageNames = map; - } - - /** - * Create a new Source - * @param file the gir filename - * @param urlPrefix the prefix for image link URLs - * @param patches patch to apply before generating bindings - */ - public GenerateSourcesOperation source(String file, String urlPrefix, Patch patches) { - sources(new Source(file, urlPrefix, patches)); - return this; - } - - /** - * Retrieves the source directory that will be used for the - * JavaGI operation. - * @return the source directory, or {@code null} if the directory - * wasn't specified. - * @since 0.5 - */ - public Path sourceDirectory() { - return sourceDirectory; - } - - /** - * Retrieves the list of sources that will be used for the - * JavaGI operation. - *

- * This is a modifiable list that can be retrieved and changed. - * @return the source files - * @since 0.5 - */ - public List sources() { - return sources; - } - - /** - * Retrieves the output directory where all output is generated. - * @return the output directory, or {@code null} if the directory - * wasn't specified. - * @since 0.5 - */ - public Path outputDirectory() { - return outputDirectory; - } -} diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/operations/GlibCompileResourcesOperation.java b/buildSrc/src/main/java/io/github/jwharm/javagi/util/GlibCompileResources.java similarity index 78% rename from buildSrc/src/main/java/io/github/jwharm/javagi/operations/GlibCompileResourcesOperation.java rename to buildSrc/src/main/java/io/github/jwharm/javagi/util/GlibCompileResources.java index 48235197..6b59c5b7 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/operations/GlibCompileResourcesOperation.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/util/GlibCompileResources.java @@ -17,7 +17,7 @@ * License along with this library; if not, see . */ -package io.github.jwharm.javagi.operations; +package io.github.jwharm.javagi.util; import java.io.File; import java.io.FileNotFoundException; @@ -25,23 +25,22 @@ import java.util.Arrays; import java.util.List; -public class GlibCompileResourcesOperation { - - File workDirectory; +/** + * Utility class that runs {@code glib-compile-resources} on all {@code .gresources.xml} + * files in a specific directory. + */ +public class GlibCompileResources { - public GlibCompileResourcesOperation workDirectory(File directory) { - this.workDirectory = directory; - return this; - } + private final File workDirectory; - public File workDirectory() { - return workDirectory; + public GlibCompileResources(File workDirectory) { + this.workDirectory = workDirectory; } private List getCommand() throws FileNotFoundException { List command = new ArrayList<>(); command.add("glib-compile-resources"); - File[] files = workDirectory().listFiles((dir, name) -> name.endsWith(".gresource.xml")); + File[] files = workDirectory.listFiles((dir, name) -> name.endsWith(".gresource.xml")); if (files == null) { throw new FileNotFoundException("No .gresource.xml files found"); } @@ -52,7 +51,7 @@ private List getCommand() throws FileNotFoundException { public void execute() throws Exception { int exitCode = new ProcessBuilder() .inheritIO() - .directory(workDirectory()) + .directory(workDirectory) .command(getCommand()) .start() .waitFor();