From 7ff36aa9eebcb67eaa10eabbfbe7e043fdc3bb7e Mon Sep 17 00:00:00 2001
From: Ioannis Kappas <ioannis.kappas@gmamil.com>
Date: Sat, 25 Jun 2022 10:50:37 +0100
Subject: [PATCH v6 1/6] java-openjfx-graphics: build all native libs

Outputs native libs to lib/openjfx

Load native libs from lib/opejfx.

Load java-swt native lib using full gnu/store path.
---
 gnu/packages/java.scm | 791 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 697 insertions(+), 94 deletions(-)

diff --git a/gnu/packages/java.scm b/gnu/packages/java.scm
index d2fbf840a0..40b88640a3 100644
--- a/gnu/packages/java.scm
+++ b/gnu/packages/java.scm
@@ -11,6 +11,7 @@
 ;;; Copyright © 2018 Chris Marusich <cmmarusich@gmail.com>
 ;;; Copyright © 2018, 2019, 2020, 2021, 2022 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2019, 2020, 2021 Björn Höfling <bjoern.hoefling@bjoernhoefling.de>
+;;; Copyright © 2020 Alexey Abramov <levenson@mmer.org>
 ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 ;;; Copyright © 2020 Raghav Gururajan <raghavgururajan@disroot.org>
 ;;; Copyright © 2020, 2022 Maxim Cournoyer <maxim.cournoyer@gmail.com>
@@ -65,6 +66,7 @@ (define-module (gnu packages java)
   #:use-module (gnu packages gcc)
   #:use-module (gnu packages gettext)
   #:use-module (gnu packages gl)
+  #:use-module (gnu packages glib)
   #:use-module (gnu packages ghostscript) ;lcms
   #:use-module (gnu packages gnome)
   #:use-module (gnu packages groovy)
@@ -2517,7 +2519,8 @@ (define-public java-openjfx-build
                '(begin
                   ;; Delete included gradle jar
                   (delete-file-recursively "gradle/wrapper")
-                  #t))
+                  ;; Delete third party source code
+                  (delete-file-recursively "modules/graphics/src/main/native-iio/libjpeg")))
               (sha256
                (base32
                 "0yg38mwpivswccv9n96k06x3iv82i4px1a9xg9l8dswzwmfj259f"))
@@ -2570,8 +2573,7 @@ (define-public java-openjfx-base
                (delete-file
                  "javafx/beans/property/adapter/ReadOnlyJavaBeanPropertyBuilder_General_Test.java")
                ;; This one fails
-               (delete-file "com/sun/javafx/runtime/VersionInfoTest.java"))
-             #t)))))
+               (delete-file "com/sun/javafx/runtime/VersionInfoTest.java")))))))
     (propagated-inputs
      (list java-openjfx-build))
     (description "OpenJFX is a client application platform for desktop,
@@ -2580,107 +2582,690 @@ (define-public java-openjfx-base
 applications.  This package contains base classes for the OpenJFX
 distribution.")))
 
+;; The graphics module is needed for any graphical JavaFX application. It
+;; requires the base module and includes the scene graph, layout, css, prism,
+;; windowing, etc. This is a fairly complicated module. There are many
+;; different types of native components that all need to be compiled.
+;;
+;; All the bellow steps were taken by inspecting build.gradel and  ./gradlew build --info
+;; result.
 (define-public java-openjfx-graphics
   (package (inherit java-openjfx-build)
     (name "java-openjfx-graphics")
     (arguments
      `(#:jar-name "java-openjfx-graphics.jar"
        #:source-dir "modules/graphics/src/main/java"
-       #:tests? #f; require X
        #:test-dir "modules/graphics/src/test"
+       #:test-include (list "**/*Test.*")
+       #:modules ((guix build ant-build-system)
+                  (guix build utils)
+                  (srfi srfi-1)
+                  (srfi srfi-26)
+                  (ice-9 regex)
+                  (ice-9 match))
        #:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'copy-missing-file
-           (lambda* (#:key inputs #:allow-other-keys)
-             (let ((target "modules/graphics/src/main/native-prism-sw/JNativeSurface.c"))
-               (copy-file (assoc-ref inputs "JNativeSurface.c") target)
-               ;; XXX: looks like the missing file we found isn't *quite*
-               ;; compatible...
-               (substitute* target
-                 (("case TYPE_INT_ARGB:") "")))))
-         (add-after 'build 'build-native
-           (lambda* (#:key inputs outputs #:allow-other-keys)
-             (let ((jdk (assoc-ref inputs "jdk"))
-                   (class-file->class-name
-                    (lambda (class-file)
-                      (string-map (lambda (c)
-                                    (if (char=? c #\/) #\. c))
-                                  (string-drop-right class-file
-                                                     (string-length ".class"))))))
-               (setenv "CPPFLAGS"
-                       (string-append "-DINLINE=inline "
-                                      "-DLINUX "
-                                      "-I" jdk "/include "
-                                      "-I" jdk "/include/linux "
-                                      "-I " (getcwd) "/build/classes/include "
-                                      "-I " (getcwd) "/modules/graphics/src/main/native-prism-sw"))
-
-               ;; Instructions have been adapted from buildSrc/linux.gradle
-               (with-directory-excursion "build/classes"
-                 ;; Build prism
-                 (mkdir-p "include")
-
-                 ;; Generate headers for prism
-                 (apply invoke "javah" "-d" "include" "-cp" "."
-                        (map class-file->class-name
-                             (append (find-files "com/sun/prism/impl" "\\.class$")
-                                     (find-files "com/sun/prism" "PresentableState.*\\.class$"))))
-
-                 ;; ...then for prism_sw
-                 (apply invoke "javah" "-d" "include" "-cp" "."
-                        (map class-file->class-name
-                             (find-files "com/sun/pisces" "\\.class$")))
-
-                 ;; ...and for prism_es2
-                 (apply invoke "javah" "-d" "include" "-cp" "."
-                        (map class-file->class-name
-                             (find-files "com/sun/prism/es2" "\\.class$")))))
-
-             (with-directory-excursion "netbeans/native-prism"
-               (invoke "make" "CONF=Release"))
-             (with-directory-excursion "netbeans/native-prism-sw"
-               (invoke "make" "CONF=Release"))
-             ;; TODO: This fails due to unknown EGL procedure names
-             #;
-             (with-directory-excursion "netbeans/native-prism-es2"
-               (invoke "make" "CONF=Release"))
+       (let* ((javac/h-flags
+               '(;; When javac is compiling code it doesn't link
+                 ;; against rt.jar by default. Instead it uses special
+                 ;; symbol file lib/ct.sym with class stubs.
+                 ;; Surprisingly this file contains many but not *all*
+                 ;; of internal classes.
+                 "-XDignore.symbol.file"
+                 ;; It's an internal option for JDK 1.7+ that prevents
+                 ;; the compiler from sharing a table that will never
+                 ;; be reused. When shared, it can't be garbage
+                 ;; collected, continues to accumulate data, and
+                 ;; therefore wastes memory.
+                 "-XDuseUnsharedTable=true"))
+              (common-flags
+               '("-fno-strict-aliasing" "-fPIC" "-fno-omit-frame-pointer" ;; optimization flags
+                 "-fstack-protector"
+                 "-W" "-Wall" "-Wno-unused" "-Wno-parentheses"))
+              (link-flags
+               `("-static-libgcc" "-static-libstdc++" "-shared" ,@common-flags
+                 "-z" "relro"
+                 "-Wl,--gc-sections"))
+              (java-aux-class?
+               (lambda (class)
+                 (string-match "\\$[0-9]+\\.class" class)))
+              (java-list-classes
+               (lambda (path)
+                 ;; For each .java file we need to figure out what
+                 ;; class the .java file belongs in and convert it to a
+                 ;; class name.
+                 (filter-map
+                  (lambda (class)
+                    (let* ((rx (make-regexp (string-append path file-name-separator-string "?")))
+                           (class (string-drop-right class (string-length ".class")))
+                           (class (match:suffix (regexp-exec rx class))))
+                      (if (java-aux-class? class)
+                          #f
+                          (string-join (string-split class #\/) "."))))
+                  (find-files path "\\.class$")))))
+         (modify-phases %standard-phases
 
-             (let* ((out (assoc-ref outputs "out"))
-                    (dir ,(match (%current-system)
-                            ("i686-linux"
-                             "i386")
-                            ((or "armhf-linux" "aarch64-linux")
-                             "arm")
-                            ((or "x86_64-linux")
-                             "amd64")
-                            (_ "unknown")))
-                    (target (string-append out "/share/" dir "/")))
-               (mkdir-p target)
-               (for-each (lambda (file)
-                           (let ((new-name
-                                  (string-append "lib"
-                                                 (string-map
-                                                  (lambda (c)
-                                                    (if (char=? c #\-) #\_ c))
-                                                  (string-drop (basename file)
-                                                               (string-length "libnative-"))))))
-                             (copy-file file
-                                        (string-append target new-name))))
-                         (find-files "netbeans" "\\.so$"))))))))
-    (propagated-inputs
-     (list java-openjfx-base java-swt))
-    ;; XXX: for unknown reasons
-    ;; modules/graphics/src/main/native-prism-sw/JNativeSurface.c is missing
-    ;; in this revision.
+           (replace 'build
+             (lambda* (#:key outputs #:allow-other-keys)
+               ;; add native libs path to the java.library.path property. Used
+               ;; by the openjfx NativeLibLoader at runtime to locate its
+               ;; libraries.
+               (let ((lib (string-append (assoc-ref outputs "out")
+                                         "/lib/openjfx/")))
+                 (substitute* "modules/graphics/src/main/java/com/sun/glass/utils/NativeLibLoader.java"
+                   (((regexp-quote "static {") all)
+                    (string-append
+                     all
+                     "\nString jlp = \""lib"\"+File.pathSeparator+System.getProperty(\"java.library.path\");\n"
+                     "System.setProperty(\"java.library.path\", jlp);\n"))))
+
+               ;; Do not mix different classes. There will be more stuff in build/classes
+               (invoke "ant" "compile" "-Dclasses.dir=modules/graphics/build/classes/java/main")))
+
+           ;; The Decora and Prism JSL files have to be generated in a very specific set of steps.
+           ;;      1) Compile the *Compile.java classes. These live in src/main/jsl-* and will be
+           ;;         output to $buildDir/classes/jsl-compilers/* (where * == decora or prism).
+           ;;      2) Generate source files from the JSL files contained in src/main/jsl-*. These
+           ;;         will be output to $buildDir/generated-src/jsl-*
+           ;;      3) Compile the JSL Java sources in $buildDir/generated-src/jsl-* and put the output
+           ;;         into classes/jsl-*
+           ;;      4) Compile the native JSL sources in $buildDir/generated-src/jsl-* and put the obj
+           ;;         files into native/jsl-* and the resulting library into libs/jsl-*.dll|so|dylib
+           ;;      5) Modify the jar step to include classes/jsl-*
+           ;; The native library must be copied over during SDK creation time in the "sdk" task. In
+           ;; addition to these steps, the clean task is created. Note that I didn't bother to create
+           ;; a new task for each of the decora files, preferring instead just to create a rule?? Also
+           ;; need "clean" tasks for each compile task.
+           (add-after 'build 'compile-prism-compilers
+             (lambda _
+               (let ((prism-compilers-classes "modules/graphics/build/classes/jsl-compilers/prism")
+                     (prism-src "modules/graphics/src/main/jsl-prism/"))
+                 (mkdir-p prism-compilers-classes)
+
+                 (apply invoke "javac" "-d" prism-compilers-classes
+                        (append javac/h-flags (find-files prism-src "\\.java"))))))
+
+           (add-after 'compile-prism-compilers 'generate-prism-shaders
+             (lambda _
+               (let ((prism-compilers-classes "modules/graphics/build/classes/jsl-compilers/prism")
+                     (prism-src "modules/graphics/src/main/jsl-prism/")
+                     (prism-gen-src "modules/graphics/build/generated-src/jsl-prism"))
+                 (mkdir-p prism-gen-src)
+                 (for-each (lambda (file)
+                             (apply invoke "java"
+                                    "-cp" (string-join (list
+                                                        ;; For CompileJSL
+                                                        prism-compilers-classes
+                                                        ;; jsl files are there
+                                                        prism-src
+                                                        (getenv "CLASSPATH"))
+                                                       ":")
+                                    "CompileJSL"
+                                    "-i" prism-src
+                                    "-o" prism-gen-src
+                                    "-t"
+                                    "-pkg" "com/sun/prism"
+                                    "-d3d"
+                                    "-es2"
+                                    "-name" (list file)))
+                           (find-files prism-src "\\.jsl$")))))
+
+           (add-after 'generate-prism-shaders 'compile-prism-shaders
+             (lambda _
+               (let* ((classes "modules/graphics/build/classes/java/main")
+                      (prism-classes "modules/graphics/build/classes/jsl-prism")
+                      (prism-gen-src "modules/graphics/build/generated-src/jsl-prism")
+                      (prism-gen-shaders-src (string-append prism-gen-src "/com/sun/prism/shader")))
+                 (mkdir-p prism-classes)
+                 (apply invoke "javac"
+                        "-d" prism-classes
+                        "-cp" (string-append classes ":" (getenv "CLASSPATH"))
+                        (append javac/h-flags (find-files prism-gen-shaders-src))))))
+
+           (add-after 'compile-prism-shaders 'compile-decora-compilers
+             (lambda _
+               (let ((classes "modules/graphics/build/classes/java/main")
+                     (decora-compilers-classes "modules/graphics/build/classes/jsl-compilers/decora")
+                     (decora-src "modules/graphics/src/main/jsl-decora/"))
+                 (mkdir-p decora-compilers-classes)
+                 (apply invoke "javac"
+                        "-d" decora-compilers-classes
+                        "-cp" (string-append classes ":" (getenv "CLASSPATH"))
+                        (append javac/h-flags (find-files decora-src "\\.java"))))))
+
+           (add-after 'compile-decora-compilers 'generate-decora-shaders
+             (lambda _
+               (let ((classes "modules/graphics/build/classes/java/main")
+                     (decora-classes "modules/graphics/build/classes/jsl-decora/")
+                     (decora-compilers-classes "modules/graphics/build/classes/jsl-compilers/decora")
+                     (decora-gen-src "modules/graphics/build/generated-src/jsl-decora")
+                     (decora-src "modules/graphics/src/main/jsl-decora/")
+                     (decora-components '([(file-name . "ColorAdjust")
+                                           (generator . "CompileJSL")
+                                           (outputs . "-all")]
+                                          [(file-name . "Brightpass")
+                                           (generator . "CompileJSL")
+                                           (outputs . "-all")]
+                                          [(file-name . "SepiaTone")
+                                           (generator . "CompileJSL")
+                                           (outputs . "-all")]
+                                          [(file-name . "PerspectiveTransform")
+                                           (generator . "CompileJSL")
+                                           (outputs . "-all")]
+                                          [(file-name . "DisplacementMap")
+                                           (generator . "CompileJSL")
+                                           (outputs . "-all")]
+                                          [(file-name . "InvertMask")
+                                           (generator . "CompileJSL")
+                                           (outputs . "-all")]
+                                          [(file-name . "Blend")
+                                           (generator . "CompileBlend")
+                                           (outputs . "-all")]
+                                          [(file-name . "PhongLighting")
+                                           (generator . "CompilePhong")
+                                           (outputs . "-all")]
+                                          [(file-name . "LinearConvolve")
+                                           (generator . "CompileLinearConvolve")
+                                           (outputs . "-hw")]
+                                          [(file-name . "LinearConvolveShadow")
+                                           (generator . "CompileLinearConvolve")
+                                           (outputs . "-hw")])))
+                 (mkdir-p decora-gen-src)
+                 (for-each (match-lambda
+                             ((('file-name . file-name)
+                               ('generator . generator)
+                               ('outputs . outputs))
+                              (apply invoke "java"
+                                     "-cp" (string-join (cons* classes
+                                                               decora-src
+                                                               ;; CompileJSL
+                                                               decora-compilers-classes
+                                                               decora-classes
+                                                               ;; We need resources from the build
+                                                               "buildSrc/src/main/resources"
+                                                               (list (getenv "CLASSPATH")))
+                                                        ":")
+                                     generator
+                                     "-i" decora-src
+                                     "-o" decora-gen-src
+                                     "-t"
+                                     "-pkg" "com/sun/scenario/effect"
+                                     outputs
+                                     (list file-name))))
+                           decora-components))))
+
+           (add-after 'generate-decora-shaders 'compile-decora-shaders
+             (lambda _
+               (let ((classes "modules/graphics/build/classes/java/main")
+                     (decora-classes "modules/graphics/build/classes/jsl-decora/")
+                     (decora-gen-src "modules/graphics/build/generated-src/jsl-decora"))
+                 (mkdir-p decora-classes)
+                 (apply invoke "javac"
+                        "-d" decora-classes
+                        "-cp" classes
+                        (append javac/h-flags (find-files decora-gen-src "\\.java$"))))))
+
+           (add-after 'compile-decora-shaders 'compile-decora-native-lib
+             (lambda* (#:key inputs #:allow-other-keys)
+               (let* ((classes "modules/graphics/build/classes/java/main")
+                      (decora-gen-headers "modules/graphics/build/generated-src/headers/jsl-decora")
+                      (decora-gen-src "modules/graphics/build/generated-src/jsl-decora")
+                      (decora-native-lib "modules/graphics/build/libs/jsl-decora/linux/libdecora_sse.so")
+                      (decora-native-obj "modules/graphics/build/native/jsl-decora/linux")
+                      (decora-native-src "modules/graphics/src/main/native-decora")
+                      (decora-src "modules/graphics/src/main/jsl-decora/")
+                      (decora-classes "modules/graphics/build/classes/jsl-decora/")
+                      (jdk (assoc-ref inputs "jdk"))
+                      (cc-flags
+                       `(,@common-flags "-c" "-ffunction-sections" "-fdata-sections"
+                                        "-I" ,(string-append jdk "/include")
+                                        "-I" ,(string-append jdk "/include/linux")))
+                      (decora-cc-flags `(,@cc-flags "-ffast-math")))
+                 (mkdir-p decora-gen-headers)
+                 (apply invoke "javah"
+                        "-d" decora-gen-headers
+                        "-cp" (string-join (list classes decora-classes) ":")
+                        (append javac/h-flags
+                                (filter (cut string-prefix? "com.sun.scenario.effect.impl.sw.sse" <>)
+                                        (append (java-list-classes classes)
+                                                (java-list-classes decora-classes)))))
+                 (mkdir-p decora-native-obj)
+                 (for-each (lambda (cc)
+                             (apply invoke "gcc"
+                                    "-I" decora-gen-headers
+                                    "-I" decora-gen-src
+                                    "-I" decora-native-src
+                                    "-o" (string-append decora-native-obj  "/" (basename cc ".cc") ".obj")
+                                    (append decora-cc-flags (list cc))))
+                           (append (find-files decora-gen-src "\\.cc$")
+                                   (find-files decora-native-src "\\.cc$")))
+                 (mkdir-p (dirname decora-native-lib))
+                 (apply invoke "g++" "-o" decora-native-lib
+                        (append link-flags (find-files decora-native-obj "\\.obj$"))))))
+
+           (add-after 'compile-decora-native-lib 'compile-linux-font-native-lib
+             (lambda* (#:key inputs #:allow-other-keys)
+               (let* ((classes "modules/graphics/build/classes/java/main")
+                      (font-gen-headers "modules/graphics/build/generated-src/headers/font/linux")
+                      (font-native-lib "modules/graphics/build/libs/font/linux/libjavafx_font.so")
+                      (font-native-obj "modules/graphics/build/native/font/linux")
+                      (font-native-src "modules/graphics/src/main/native-font")
+                      ;;
+                      (jdk (assoc-ref inputs "jdk"))
+                      (cc-flags
+                       `(,@common-flags "-c" "-ffunction-sections" "-fdata-sections"
+                                        "-I" ,(string-append jdk "/include")
+                                        "-I" ,(string-append jdk "/include/linux")))
+                      (font-cc-flags `("-DJFXFONT_PLUS" ,@cc-flags)))
+                 (mkdir-p font-gen-headers)
+                 (apply invoke "javah"
+                        "-d" font-gen-headers
+                        "-cp" classes
+                        (append javac/h-flags
+                                (filter (lambda (class)
+                                          (or (string-prefix? "com.sun.javafx.font" class)
+                                              (string-prefix? "com.sun.javafx.text" class)))
+                                        (java-list-classes classes))))
+                 (mkdir-p font-native-obj)
+                 (for-each (lambda (cc)
+                             (apply invoke "gcc"
+                                    "-I" font-gen-headers
+                                    "-I" font-native-src
+                                    "-o" (string-append font-native-obj "/"
+                                                        (basename cc ".c") ".obj")
+                                    (append font-cc-flags (list cc))))
+                           (find-files font-native-src "\\.c$"))
+                 (mkdir-p (dirname font-native-lib))
+                 (apply invoke "g++"
+                        "-o" font-native-lib
+                        (append link-flags
+                                (find-files font-native-obj "\\.obj$"))))))
+
+           (add-after 'compile-linux-font-native-lib 'compile-linux-font-freetype
+             (lambda* (#:key inputs #:allow-other-keys)
+               (let* ((classes "modules/graphics/build/classes/java/main")
+                      ;;
+                      (font-freetype-gen-headers "modules/graphics/build/generated-src/headers/fontFreetype/linux")
+                      (font-freetype-native-lib "modules/graphics/build/libs/fontFreetype/linux/libjavafx_font_freetype.so")
+                      (font-freetype-native-obj "modules/graphics/build/native/fontFreetype/linux")
+                      (font-freetype-native-src "modules/graphics/src/main/native-font/freetype.c")
+                      (jdk (assoc-ref inputs "jdk"))
+                      (cc-flags
+                       `(,@common-flags "-c" "-ffunction-sections" "-fdata-sections"
+                                        "-I" ,(string-append jdk "/include")
+                                        "-I" ,(string-append jdk "/include/linux")))
+                      (font-freetype-cc-flags `("-DJFXFONT_PLUS" "-D_ENABLE_PANGO"
+                                                "$(pkg-config --cflags freetype2)" ,@cc-flags))
+                      (font-freetype-link-flags `("$(pkg-config --libs freetype2)" ,@link-flags)))
+                 (mkdir-p font-freetype-gen-headers)
+                 (apply invoke "javah"
+                        "-d" font-freetype-gen-headers
+                        "-cp" classes
+                        (append javac/h-flags
+                                (filter (cut string-prefix? "com.sun.javafx.font.freetype.OSFreetype" <>)
+                                        (java-list-classes classes))))
+                 (mkdir-p font-freetype-native-obj)
+                 (invoke "bash" "-c"
+                         (string-join `("gcc"
+                                        ,@font-freetype-cc-flags
+                                        "-I" ,font-freetype-gen-headers
+                                        "-I" ,(dirname font-freetype-native-src)
+                                        "-o" ,(string-append font-freetype-native-obj "/"
+                                                             (basename font-freetype-native-src ".c") ".obj")
+                                        ,font-freetype-native-src)))
+                 (mkdir-p (dirname font-freetype-native-lib))
+                 (invoke "bash" "-c"
+                         (string-join `("g++"
+                                        "-o" ,font-freetype-native-lib
+                                        ,@font-freetype-link-flags
+                                        ,@(find-files font-freetype-native-obj "\\.obj$")))))))
+
+           (add-after 'compile-linux-font-freetype 'compile-linux-font-pango-lib
+             (lambda* (#:key inputs #:allow-other-keys)
+               (let* ((classes "modules/graphics/build/classes/java/main")
+                      (font-pango-gen-headers "modules/graphics/build/generated-src/headers/fontPango/linux")
+                      (font-pango-native-lib "modules/graphics/build/libs/fontPango/linux/libjavafx_font_pango.so")
+                      (font-pango-native-obj "modules/graphics/build/native/fontPango/linux")
+                      (font-pango-native-src "modules/graphics/src/main/native-font/pango.c")
+                      (jdk (assoc-ref inputs "jdk"))
+                      (cc-flags
+                       `(,@common-flags "-c" "-ffunction-sections" "-fdata-sections"
+                                        "-I" ,(string-append jdk "/include")
+                                        "-I" ,(string-append jdk "/include/linux")))
+                      (font-pango-cc-flags `("-DJFXFONT_PLUS" "-D_ENABLE_PANGO"
+                                             "$(pkg-config --cflags pangoft2)" ,@cc-flags))
+                      (font-pango-link-flags `("$(pkg-config --libs pangoft2)" ,@link-flags)))
+                 (mkdir-p font-pango-gen-headers)
+                 (apply invoke "javah"
+                        "-d" font-pango-gen-headers
+                        "-cp" classes
+                        (append javac/h-flags
+                                (filter (cut string-prefix? "com.sun.javafx.font.freetype.OSPango" <>)
+                                        (java-list-classes classes))))
+                 (mkdir-p font-pango-native-obj)
+                 (invoke "bash" "-c"
+                         (string-join `("gcc"
+                                        ,@font-pango-cc-flags
+                                        "-I" ,font-pango-gen-headers
+                                        "-I" ,(dirname font-pango-native-src)
+                                        "-o" ,(string-append font-pango-native-obj "/"
+                                                             (basename font-pango-native-src ".c") ".obj")
+                                        ,font-pango-native-src)))
+                 (mkdir-p (dirname font-pango-native-lib))
+                 (invoke "bash" "-c"
+                         (string-join `("g++"
+                                        ,@font-pango-link-flags
+                                        "-o" ,font-pango-native-lib
+                                        ,@(find-files font-pango-native-obj "\\.obj$")))))))
+
+           (add-after 'compile-linux-font-pango-lib 'compile-linux-glass-lib
+             (lambda* (#:key inputs outputs #:allow-other-keys)
+               (let* ((classes "modules/graphics/build/classes/java/main")
+                      ;; glass
+                      (glass-gen-headers "modules/graphics/build/generated-src/headers/glass/linux")
+                      (glass-native-lib "modules/graphics/build/libs/glass/linux/libglass.so")
+                      (glass-native-obj "modules/graphics/build/native/glass/linux/glass")
+                      (glass-native-src "modules/graphics/src/main/native-glass/gtk")
+                      (jdk (assoc-ref inputs "jdk"))
+                      (cc-flags
+                       `(,@common-flags "-c" "-ffunction-sections" "-fdata-sections"
+                                        "-I" ,(string-append jdk "/include")
+                                        "-I" ,(string-append jdk "/include/linux")))
+                      (glass-cc-flags
+                       `(,@cc-flags
+                         "$(pkg-config --cflags glib-2.0 gtk+-2.0 xtst)"
+                         "-Wno-deprecated-declarations"
+                         "-Werror"
+                         "-Wno-cast-function-type"
+                         ))
+                      (glass-link-flags
+                       `(,@link-flags
+                         "$(pkg-config --libs x11 gtk+-2.0)" "-ldl"))
+                      ;; glass-gtk2
+                      (gtk (assoc-ref inputs "gtk"))
+                      (glass-gtk2-native-obj "modules/graphics/build/native/glass/linux/glassgtk2")
+                      (glass-gtk2-native-src glass-native-src)
+                      (glass-gtk2-native-lib "modules/graphics/build/libs/glass/linux/libglassgtk2.so")
+                      (glass-gtk2-cc-flags
+                       `(,@cc-flags
+                         "$(pkg-config --cflags gtk+-2.0 xtst)"
+                         ;; XX: GTimeVal has been deprecated in GLIB since
+                         ;; version 2.62. GTimeVal s not year-2038-safe. Gtk
+                         ;; 2.24 uses GTimeVal so our build is also failing.
+                         "-Wno-deprecated-declarations"
+                         "-Werror"
+                         "-Wno-cast-function-type"
+                         ))
+                      (glass-gtk2-link-flags
+                       `(,@link-flags "$(pkg-config --libs gtk+-2.0 xtst)")))
+                 ;; glass
+                 (mkdir-p glass-gen-headers)
+                 (apply invoke "javah"
+                        "-d" glass-gen-headers
+                        "-cp" (string-append classes ":" (getenv "CLASSPATH"))
+                        (append javac/h-flags
+                                (filter (lambda (class)
+                                          (or (string-prefix? "com.sun.glass.events" class)
+                                              (string-prefix? "com.sun.glass.ui.gtk" class)
+                                              (string-prefix? "com.sun.glass.ui" class)))
+                                        (java-list-classes classes))))
+                 (mkdir-p glass-native-obj)
+                 (for-each (lambda (c)
+                             (invoke "bash" "-c"
+                                     (string-join `("gcc"
+                                                    ,@glass-cc-flags
+                                                    "-I" ,glass-gen-headers
+                                                    "-I" ,glass-native-src
+                                                    "-o" ,(string-append glass-native-obj "/"
+                                                                         (basename c ".c") ".obj")
+                                                    ,c))))
+                           (find-files glass-native-src "\\.c$"))
+                 (mkdir-p (dirname glass-native-lib))
+                 (invoke "bash" "-c"
+                         (string-join `("g++"
+                                        ,@glass-link-flags
+                                        "-o" ,glass-native-lib
+                                        ,@(find-files glass-native-obj "\\.obj$"))))
+                 ;; gtk2
+                 (mkdir-p glass-gtk2-native-obj)
+                 (for-each (lambda (cpp)
+                             (invoke "bash" "-c"
+                                     (string-join `("gcc"
+                                                    ,@glass-gtk2-cc-flags
+                                                    "-I" ,glass-gen-headers
+                                                    "-o" ,(string-append glass-gtk2-native-obj "/"
+                                                                         (basename cpp ".cpp") ".obj")
+                                                    ,cpp))))
+                           (find-files glass-gtk2-native-src "\\.cpp$"))
+                 (mkdir-p (dirname glass-gtk2-native-lib))
+                 (invoke "bash" "-c"
+                         (string-join `("g++"
+                                        ,@glass-gtk2-link-flags
+                                        "-o" ,glass-gtk2-native-lib
+                                        ,@(find-files glass-gtk2-native-obj "\\.obj$")))))))
+
+           (add-after 'compile-linux-glass-lib  'compile-linux-iio
+             (lambda* (#:key inputs #:allow-other-keys)
+               (let* ((classes "modules/graphics/build/classes/java/main")
+                      (iio-gen-headers "modules/graphics/build/generated-src/headers/iio/linux")
+                      (iio-native-lib "modules/graphics/build/libs/iio/linux/libjavafx_iio.so")
+                      (iio-native-obj "modules/graphics/build/native/iio/linux")
+                      (iio-native-src "modules/graphics/src/main/native-iio")
+                      (jdk (assoc-ref inputs "jdk"))
+                      (cc-flags
+                       `(,@common-flags "-c" "-ffunction-sections" "-fdata-sections"
+                                        "-I" ,(string-append jdk "/include")
+                                        "-I" ,(string-append jdk "/include/linux")))
+                      (iio-cc-flags cc-flags)
+                      (iio-link-flags `(,@link-flags "$(pkg-config --libs libjpeg)")))
+                 (mkdir-p iio-gen-headers)
+                 (apply invoke "javah"
+                        "-d" iio-gen-headers
+                        "-cp" (string-append classes ":" (getenv "CLASSPATH"))
+                        (append javac/h-flags
+                                (filter (cut string-prefix? "com.sun.javafx.iio" <>)
+                                        (java-list-classes classes))))
+                 (mkdir-p iio-native-obj)
+                 (for-each (lambda (c)
+                             (invoke "bash" "-c"
+                                     (string-join `("gcc"
+                                                    ,@iio-cc-flags
+                                                    "-I" ,iio-gen-headers
+                                                    "-o" ,(string-append iio-native-obj "/"
+                                                                         (basename c ".c") ".obj")
+                                                    ,c))))
+                           (find-files iio-native-src "\\.c$"))
+                 (mkdir-p (dirname iio-native-lib))
+                 (invoke "bash" "-c"
+                         (string-join `("g++"
+                                        ,@iio-link-flags
+                                        "-o" ,iio-native-lib
+                                        ,@(find-files iio-native-obj "\\.obj$")))))))
+
+           (add-after 'compile-linux-iio 'compile-linux-prism
+             (lambda* (#:key inputs #:allow-other-keys)
+               (let* ((classes "modules/graphics/build/classes/java/main")
+                      (prism-gen-headers "modules/graphics/build/generated-src/headers/prism/linux")
+                      (prism-native-lib "modules/graphics/build/libs/prism/linux/libprism_common.so")
+                      (prism-native-obj "modules/graphics/build/native/prism/linux")
+                      (prism-native-src "modules/graphics/src/main/native-prism")
+                      (jdk (assoc-ref inputs "jdk"))
+                      (cc-flags
+                       `(,@common-flags "-c" "-ffunction-sections" "-fdata-sections"
+                                        "-I" ,(string-append jdk "/include")
+                                        "-I" ,(string-append jdk "/include/linux")))
+                      (prism-cc-flags `(,@cc-flags "-DINLINE=inline"))
+                      (prism-link-flags link-flags))
+                 (mkdir-p prism-gen-headers)
+                 (apply invoke "javah"
+                        "-d" prism-gen-headers
+                        "-cp" (string-append classes ":" (getenv "CLASSPATH"))
+                        (append javac/h-flags
+                                (filter (lambda (class)
+                                          (or (string-prefix? "com.sun.prism.impl" class)
+                                              (string-prefix? "com.sun.prism.PresentableState" class)))
+                                        (java-list-classes classes))))
+                 (mkdir-p prism-native-obj)
+                 (for-each (lambda (c)
+                             (invoke "bash" "-c"
+                                     (string-join `("gcc"
+                                                    ,@prism-cc-flags
+                                                    "-I" ,prism-gen-headers
+                                                    "-I" ,prism-native-src
+                                                    "-o" ,(string-append prism-native-obj "/"
+                                                                         (basename c ".c") ".obj")
+                                                    ,c))))
+                           (find-files prism-native-src "\\.c$"))
+                 (mkdir-p (dirname prism-native-lib))
+                 (invoke "bash" "-c"
+                         (string-join `("g++"
+                                        ,@prism-link-flags
+                                        "-o" ,prism-native-lib
+                                        ,@(find-files prism-native-obj "\\.obj$")))))))
+
+           (add-after 'compile-linux-prism 'compile-linux-prism-es2
+             (lambda* (#:key inputs #:allow-other-keys)
+               (let* ((classes "modules/graphics/build/classes/java/main")
+                      (prism-es2-gen-headers "modules/graphics/build/generated-src/headers/prismES2/linux")
+                      (prism-es2-native-lib "modules/graphics/build/libs/prism/linux/libprism_es2.so")
+                      (prism-es2-native-obj "modules/graphics/build/native/prismES2/linux")
+                      (prism-es2-native-src "modules/graphics/src/main/native-prism-es2")
+                      (jdk (assoc-ref inputs "jdk"))
+                      (cc-flags
+                       `(,@common-flags "-c" "-ffunction-sections" "-fdata-sections"
+                                        "-I" ,(string-append jdk "/include")
+                                        "-I" ,(string-append jdk "/include/linux")))
+                      (prism-es2-cc-flags `("-DLINUX" ,@cc-flags))
+                      (prism-es2-link-flags
+                       `(,@link-flags "$(pkg-config --libs x11 xxf86vm gl fontconfig)"))
+                      ;; We need all *.c files in the root and only those
+                      ;; which are in a specific directories.
+                      (filter-src
+                       (lambda (abs _)
+                         (or (regexp-exec (make-regexp (string-append prism-es2-native-src "/[[:alnum:]]+\\.c$"))
+                                          abs)
+                             (regexp-exec (make-regexp (string-append prism-es2-native-src "/(x11/|GL/).*\\.c$"))
+                                          abs)))))
+                 (mkdir-p prism-es2-gen-headers)
+                 (apply invoke "javah"
+                        "-d" prism-es2-gen-headers
+                        "-cp" (string-append classes ":" (getenv "CLASSPATH"))
+                        (append javac/h-flags
+                                (filter (cut string-prefix? "com.sun.prism.es2" <>)
+                                        (java-list-classes classes))))
+                 (mkdir-p prism-es2-native-obj)
+                 (for-each (lambda (c)
+                             (apply invoke "gcc"
+                                    "-I" prism-es2-gen-headers
+                                    "-I" prism-es2-native-src
+                                    "-I" (string-append prism-es2-native-src "/GL")
+                                    "-I" (string-append prism-es2-native-src "/x11")
+                                    "-o" (string-append prism-es2-native-obj "/" (basename c ".c") ".obj")
+                                    (append prism-es2-cc-flags (list c))))
+                           (find-files prism-es2-native-src filter-src))
+                 (mkdir-p (dirname prism-es2-native-lib))
+                 (invoke "bash" "-c"
+                         (string-join `("g++"
+                                        ,@prism-es2-link-flags
+                                        "-o" ,prism-es2-native-lib
+                                        ,@(find-files prism-es2-native-obj "\\.obj$")))))))
+
+           (add-after 'compile-linux-prism-es2 'compile-linux-prism-sw
+             (lambda* (#:key inputs #:allow-other-keys)
+               (let* ((classes "modules/graphics/build/classes/java/main")
+                      (prism-sw-gen-headers "modules/graphics/build/generated-src/headers/prismSW/linux")
+                      (prism-sw-native-lib "modules/graphics/build/libs/prism/linux/libprism_sw.so")
+                      (prism-sw-native-obj "modules/graphics/build/native/prismSW/linux")
+                      (prism-sw-native-src "modules/graphics/src/main/native-prism-sw")
+                      (jdk (assoc-ref inputs "jdk"))
+                      (cc-flags
+                       `(,@common-flags "-c" "-ffunction-sections" "-fdata-sections"
+                                        "-I" ,(string-append jdk "/include")
+                                        "-I" ,(string-append jdk "/include/linux")))
+                      ;;
+                      (prism-sw-cc-flags `(,@cc-flags "-DINLINE=inline"))
+                      (prism-sw-link-flags link-flags))
+                 (mkdir-p prism-sw-gen-headers)
+                 (apply invoke "javah"
+                        "-d" prism-sw-gen-headers
+                        "-cp" (string-append classes ":" (getenv "CLASSPATH"))
+                        (append javac/h-flags
+                                (filter (cut string-prefix? "com.sun.pisces" <>)
+                                        (java-list-classes classes))))
+                 (mkdir-p prism-sw-native-obj)
+                 (for-each (lambda (c)
+                             (invoke "bash" "-c"
+                                     (string-join `("gcc"
+                                                    ,@prism-sw-cc-flags
+                                                    "-I" ,prism-sw-gen-headers
+                                                    "-I" ,prism-sw-native-src
+                                                    "-o" ,(string-append prism-sw-native-obj "/"
+                                                                         (basename c ".c") ".obj")
+                                                    ,c))))
+                           (find-files prism-sw-native-src "\\.c$"))
+                 (mkdir-p (dirname prism-sw-native-lib))
+                 (apply invoke "g++" "-o" prism-sw-native-lib
+                        (append prism-sw-link-flags (find-files prism-sw-native-obj "\\.obj$"))))))
+
+           (add-after 'compile-linux-prism-sw 'build-jar
+             (lambda _
+               (let* ((module (string-append "modules/graphics"))
+                      (decora (string-append module "/build/classes/jsl-decora"))
+                      (prism (string-append module "/build/classes/jsl-prism"))
+                      (resources (string-append module "/src/main/resources"))
+                      (classes (string-append module "/build/classes/java/main")))
+                 (copy-recursively decora classes)
+                 (copy-recursively prism classes)
+                 (copy-recursively resources classes)
+
+                 (invoke "ant" "jar" (string-append "-Dclasses.dir=" classes)))))
+
+           (add-before 'check 'copy-classes
+             (lambda _
+             (copy-recursively "modules/graphics/build/classes/java/main" "build/classes")
+             (substitute* "build.xml"
+               (("<junit.*haltonfailure=\"yes\">" all)
+                (string-append
+                 all
+                 "<sysproperty key=\"java.library.path\" value=\""
+                 (string-join '("modules/graphics/build/libs/prism/linux/"
+                                "modules/graphics/build/libs/font/linux/"
+                                "modules/graphics/build/libs/fontFreetype/linux/"
+                                "modules/graphics/build/libs/fontPango/linux/"
+                                "modules/graphics/build/libs/iio/linux/")
+                              ":")
+                  "\"/>"
+                  "<sysproperty key=\"javafx.toolkit\" value=\"com.sun.javafx.pgstub.StubToolkit\"/>")))))
+
+
+           (add-after 'install 'install-native
+             (lambda* (#:key outputs #:allow-other-keys)
+               (let ((lib (string-append (assoc-ref outputs "out") "/lib/openjfx")))
+                 (for-each (lambda (file)
+                             (install-file file lib))
+                           (find-files "." "\\.so$")))))))))
     (native-inputs
-     `(("JNativeSurface.c"
-        ,(origin
-           (method url-fetch)
-           (uri "https://raw.githubusercontent.com/openjdk/jfx/8u20-b02\
-/modules/graphics/src/main/native-prism-sw/JNativeSurface.c")
-           (sha256
-            (base32
-             "1kp15wbnd6rn0nciczp5ibq0ikby2yysvx1gnz5fa05vl2mm8mbm"))))))
+     (list antlr3
+           java-stringtemplate
+           gcc
+           icedtea-8
+           pkg-config
+           java-junit))
+    (inputs
+     (list freetype
+           fontconfig
+           glib
+           zlib
+           gtk+-2
+           libjpeg-turbo
+           libxtst
+           mesa
+           pango
+           libpng
+           libxxf86vm
+           libx11))
+    (propagated-inputs
+     (list java-openjfx-base
+           java-swt))
     (description "OpenJFX is a client application platform for desktop,
 mobile and embedded systems built on Java.  Its goal is to produce a
 modern, efficient, and fully featured toolkit for developing rich client
@@ -3519,6 +4104,9 @@ (define-public java-swt
      `(#:jar-name "swt.jar"
        #:jdk ,icedtea-8
        #:tests? #f ; no "check" target
+       #:modules ((guix build ant-build-system)
+                  (guix build utils)
+                  (ice-9 regex))
        #:phases
        (modify-phases %standard-phases
          (replace 'unpack
@@ -3528,6 +4116,21 @@ (define-public java-swt
              (chdir "swt")
              (mkdir "src")
              (invoke "unzip" "src.zip" "-d" "src")))
+         ;; explicitly load native library from gnu/store if it can't be found
+         ;; by the standard means.
+         (add-before 'configure 'engrave-swt-path
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let ((lib (string-append (assoc-ref outputs "out")
+                                       "/lib")))
+               (substitute* "src/org/eclipse/swt/internal/Library.java"
+                 (((regexp-quote "/* Failed to find the library */") all)
+                  (string-append
+                   "if (path != null) {
+                     path = new File (\"" lib "\").getAbsolutePath ();
+                     if (load (path + SEPARATOR + mappedName1, message)) return;
+                     if (mapName && load (path + SEPARATOR + mappedName2, message)) return;
+                    }\n\n"
+                     all))))))
          ;; The classpath contains invalid icecat jars.  Since we don't need
          ;; anything other than the JDK on the classpath, we can simply unset
          ;; it.
-- 
2.34.0

