<?xml version="1.0" encoding="UTF-8"?>
<!--
   - Ant build for GlueGen and corresponding ANT tasks. Also builds
   - JOGL-specific BuildStaticGLInfo and its corresponding ANT task.
   -
   - This build has been tested with ANT 1.6.2 and ANTLR 2.7.4.
   -
   - Public targets:
   -   all:  clean and build GlueGen and GlueGen Ant task
   -   clean:  clean all built
  -->
<project name="GlueGen" basedir="." default="all">

  <import file="gluegen-cpptasks.xml" />
  <import file="jogamp-archivetasks.xml" />
  <import file="jogamp-androidtasks.xml" />
  <import file="jogamp-env.xml" />

  <condition property="rootrel.build" value="build">
    <not>
      <isset property="rootrel.build"/>
    </not>
  </condition>

  <target name="setup.excludes.nsig" unless="gluegen.nsig">
    <property name="gluegen.excludes.nsig" value="com/jogamp/gluegen/runtime/BufferFactoryInternal.java com/jogamp/gluegen/nativesig/**" />
  </target>

  <target name="init.base" depends="jogamp.env.init,gluegen.properties.load.user,gluegen.cpptasks.detect.os,setup.excludes.nsig">
    <!-- Create the classpath for compiling GlueGen.
         This requires the user-defined "antlr.jar" property. -->
    <path id="cc_gluegen.classpath">
      <pathelement location="${antlr.jar}" />
      <pathelement location="${japicmp.jar}" />
    </path>
    <path id="javadoc_gluegen.classpath">
      <pathelement location="${ant.jar}" />
      <pathelement location="${antlr.jar}" />
      <pathelement location="${japicmp.jar}" />
      <pathelement location="${gluegen.jar}" />
    </path>
  </target>

  <target name="init.android" if="android-jars.available" >
    <!-- Create the classpath for compiling Android only stuff. -->
    <path id="android.classpath">
      <pathelement location="${android-min.jar}"/>
    </path>

    <!-- Create the classpath for compiling GlueGen.
         This requires the user-defined "antlr.jar" property. -->
    <path id="cc_gluegen_android.classpath">
      <pathelement location="${antlr.jar}" />
      <pathelement location="${android-min.jar}"/>
    </path>
  </target>

  <target name="init" depends="init.base, init.android">
    <!-- Declare all paths and user defined variables. -->

    <!-- property name="javadoc.link" value="http://java.sun.com/j2se/1.4.2/docs/api/" /-->
    <!-- property name="javadoc.link" value="http://download.oracle.com/javase/1.5.0/docs/api/" /-->
    <!-- property name="javadoc.link" value="http://docs.oracle.com/javase/6/docs/api/" /-->
    <property name="javadoc.link" value="https://docs.oracle.com/javase/8/docs/api/" />

    <!-- The source and build directories. -->
    <property name="project.root"  value=".." />
    <property name="project.root.abs-path"      location="${project.root}" />
    <property name="src.java" value="${project.root}/src/java" />
    <property name="src.antlr" value="${project.root}/src/antlr" />
    <property name="src.jcpp" value="${project.root}/jcpp/src/main/java" />

    <property name="build"    location="${project.root}/${rootrel.build}" />
    <property name="build.abs-path"       location="${build}" />

    <property name="doxygen.root.path"    location="${build}/javadoc" />
    <property name="doxygen.gluegen.public.path" location="${doxygen.root.path}/gluegen/javadoc" />
    <property name="doxygen.gluegen.dev.path" location="${doxygen.root.path}/gluegen/javadoc_dev" />

    <property name="javadoc.root.path"    location="${build}/javadoc" />
    <property name="javadoc.gluegen.path" location="${javadoc.root.path}/gluegen/javadoc" />

    <property name="gluegen.lib.dir" value="${build}/obj"/>
    <property name="gluegen.build.number" value="manual"/>
    <property name="gluegen.build.id"     value="${version.timestamp}"/>
    <mkdir dir="${build}" />
    <exec dir="." executable="git" logError="true" failonerror="false" failifexecutionfails="false"
              output="${build}/localbranch.raw">
        <arg line="branch --no-color"/>
    </exec>
    <exec dir="." executable="sed" logError="true" failonerror="false" failifexecutionfails="false"
              outputproperty="gluegen.build.branch">
        <arg line="-e '/^[^*]/d' -e 's/* \(.*\)/\1/' '${build}/localbranch.raw'"/>
    </exec>
    <property name="gluegen.build.branch" value="manual"/> <!-- fallback -->
    <exec dir="${project.root}" executable="git" logError="true" failonerror="false" failifexecutionfails="false"
              outputproperty="gluegen.build.commit">
        <arg line="rev-parse HEAD"/>
    </exec>
    <property name="gluegen.build.commit" value="manual"/> <!-- fallback -->

    <property name="gluegen.version" value="${jogamp.version.base}-b${gluegen.build.number}-${version.timestamp}" />

    <delete includeEmptyDirs="false">
      <fileset dir="${project.root}" includes="make/GnuCTreeParserTokenTypes.txt make/STDCTokenTypes.txt" />
    </delete>
    <echo message="gluegen.build.branch         ${gluegen.build.branch}"/>
    <echo message="gluegen.build.commit         ${gluegen.build.commit}"/>

    <property name="stub.includes.dir" value="stub_includes" /> <!-- NOTE:  this MUST be relative for FileSet -->

    <!-- The generated source directories. -->
    <property name="src.generated"          value="${build}/gensrc" />
    <property name="src.generated.java"     value="${src.generated}/java" />
    <property name="src.generated.c"        value="${src.generated}/native" />

    <!-- The compiler output directories. -->
    <property name="classes" value="${build}/classes" />
    <pathconvert targetos="unix" property="classes.unix">
        <path location="${classes}"/>
    </pathconvert>

    <!-- Call the external config validator script to make sure the config is ok and consistent -->
    <ant antfile="validate-properties.xml" inheritall="true"/>

    <!-- Create the required output directories. -->
    <mkdir dir="${src.generated.java}" />
    <mkdir dir="${src.generated.c}" />
    <mkdir dir="${src.generated.c}/Unix" />
    <mkdir dir="${src.generated.c}/Windows" />
    <mkdir dir="${classes}" />

    <!-- Create the classpath for ANTLR.
         This requires the user-defined "antlr.jar" property. -->
    <path id="antlr.classpath">
      <pathelement location="${antlr.jar}" />
    </path>

    <!-- Create the classpath for using GlueGen. -->
    <path id="gluegen.classpath" >
      <pathelement location="${classes}" />
      <pathelement location="${antlr.jar}" />
    </path>

    <!-- The location of the GlueGen source and the C grammar files. -->
    <property name="c.grammar" value="${src.antlr}/com/jogamp/gluegen/cgram" />
    <property name="j.grammar" value="${src.antlr}/com/jogamp/gluegen/jgram" />

    <!-- The resulting location of the generated Java files from the
      - C grammar via ANTLR. -->
    <property name="c.grammar.out.dir" value="${src.generated.java}/com/jogamp/gluegen/cgram" />
    <property name="j.grammar.out.dir" value="${src.generated.java}/com/jogamp/gluegen/jgram" />

    <property name="archive.name"     value="gluegen-${gluegen.version}-${os.and.arch}" />
    <property name="archive"          value="${build}/${archive.name}" />

    <!-- the launcher is compiled and packaged explicit - if android -->
    <property name="jogamp-android-launcher.classes" value="jogamp/android/launcher/**"/>

    <!-- optional android classes - if android -->
    <property name="java.part.android" value="jogamp/common/os/android/**"/>

    <!-- property name="java.part.awt" value="com/jogamp/common/util/awt/** jogamp/common/awt/**"/-->
    <property name="java.part.awt" value="com/jogamp/common/util/awt/**"/>
    <property name="java.part.nonjava" value="com/jogamp/common/util/bin/*" />
    <property name="gluegen-rt.classes" value="com/jogamp/gluegen/runtime/**"/>
    <property name="jogamp.common.classes" value="com/jogamp/common/** jogamp/common/**"/>
    <property name="java.part.jcpp" value="com/jogamp/gluegen/jcpp/**"/>
    <property name="java.part.java11" value="com/jogamp/gluegen/structgen/**"/>

    <property name="gluegen.excludes.all" value="${gluegen.excludes.nsig} ${jogamp-android-launcher.classes}" />
  </target>

  <target name="init.gg" depends="init">
    <!-- Define the GlueGen task we just built -->
    <taskdef name="gluegen" classname="com.jogamp.gluegen.ant.GlueGenTask"
             classpathref="gluegen.classpath" />
  </target>

  <target name="set.debug">
    <property name="c.compiler.debug" value="true" />
    <property name="javacdebug"       value="true" />
    <property name="javacdebuglevel"  value="source,lines,vars" />
  </target>
  <target name="init.debug" depends="set.debug, init"/>

  <property name="gluegen.root" value="../" />

  <!-- Use GlueGen to generate the source code for the ElfHeader
       implementation. Note that to make the build process simpler (in
       particular, the nightly builds) we do not do this every time we
       run the build, but instead check in the generated sources to
       the source tree. -->
  <target name="generate.os.sources" depends="init.gg" >
    <property name="stub.includes.gluegen.gg"  value="stub_includes/gluegen" />
    <dirset id="stub.includes.fileset.os" dir=".">
      <include name="stub_includes/os/**" />
    </dirset>
    <gluegen src="stub_includes/os/elf_header.h"
             config="elf-header.cfg"
             includeRefId="stub.includes.fileset.os"
             literalInclude="${stub.includes.gluegen.gg}"
             emitter="com.jogamp.gluegen.JavaEmitter"
             debug="false">
      <classpath refid="gluegen.classpath" />
    </gluegen>
    <!-- Only to cherry pick defines -> java files
    <gluegen src="stub_includes/os/elf_eh_const.h"
             config="elf-eh-const.cfg"
             includeRefId="stub.includes.fileset.os"
             literalInclude="${stub.includes.gluegen.gg}"
             emitter="com.jogamp.gluegen.JavaEmitter"
             debug="false">
      <classpath refid="gluegen.classpath" />
    </gluegen>
    <gluegen src="stub_includes/os/elf_sh_const.h"
             config="elf-sh-const.cfg"
             includeRefId="stub.includes.fileset.os"
             literalInclude="${stub.includes.gluegen.gg}"
             emitter="com.jogamp.gluegen.JavaEmitter"
             debug="false">
      <classpath refid="gluegen.classpath" />
    </gluegen> -->
  </target>

    <!-- ================================================================== -->
    <!--
       - Compile the native C code for GlueGen's dynamic linker interface.
      -->

    <target name="declare.win32.vc6" if="isVC6">
      <echo message="Win32.VC6" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.win32.msvc" />
      <property name="linker.cfg.id"                        value="linker.cfg.win32.msvc" />
    </target>

    <target name="declare.win32.vc7" if="isVC7">
      <echo message="Win32.VC7" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.win32.msvc" />
      <property name="linker.cfg.id"                        value="linker.cfg.win32.msvc" />
    </target>

    <target name="declare.win32.vc8" if="isVC8">
      <echo message="Win32.VC8" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.win32.msvc" />
      <property name="linker.cfg.id"                        value="linker.cfg.win32.msvc" />
    </target>

    <target name="declare.win32.vc8_x64" if="isVC8_X64">
      <echo message="Win32.VC8_X64" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.win32.msvc" />
      <property name="linker.cfg.id"                        value="linker.cfg.win32.msvc" />
    </target>

    <target name="declare.win32.vc9" if="isVC9">
      <echo message="Win32.VC9" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.win32.msvc" />
      <property name="linker.cfg.id"                        value="linker.cfg.win32.msvc" />
    </target>

    <target name="declare.win32.mingw" if="isMingW32">
      <echo message="Win32.MingW" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.win32.mingw" />
      <property name="linker.cfg.id"                        value="linker.cfg.win32.mingw" />
    </target>

    <target name="declare.win64.mingw" if="isMingW64">
      <echo message="Win64.MingW" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.win64.mingw" />
      <property name="linker.cfg.id"                        value="linker.cfg.win64.mingw" />
    </target>

    <target name="declare.win32" depends="declare.win32.vc6,declare.win32.vc7,declare.win32.vc8,declare.win32.vc8_x64,declare.win32.vc9,declare.win32.mingw,declare.win64.mingw" if="isWindows" >
      <property name="c.src.dir.os"                         value="windows" />
    </target>

    <target name="declare.linux.x86" if="isLinuxX86">
      <echo message="Linux.x86" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux.x86" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.x86" />
    </target>

    <target name="declare.linux.amd64" if="isLinuxAMD64">
      <echo message="Linux.AMD64" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux.amd64" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.amd64" />
    </target>

    <target name="declare.linux.ia64" if="isLinuxIA64">
      <echo message="Linux.IA64" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux" />
    </target>

    <target name="declare.linux.armv6" if="isLinuxARMv6">
      <echo message="Linux.armv6" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux.armv6" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.armv6" />
    </target>

    <target name="declare.linux.aarch64" if="isLinuxARM64">
      <echo message="Linux.aarch64" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux.aarch64" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.aarch64" />
    </target>

    <target name="declare.linux.alpha" if="isLinuxAlpha">
      <echo message="Linux.alpha" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.alpha" />
    </target>

    <target name="declare.linux.hppa" if="isLinuxHppa">
      <echo message="Linux.hppa" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.hppa" />
    </target>

    <target name="declare.linux.mips" if="isLinuxMips">
      <echo message="Linux.mips" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.mips" />
    </target>

    <target name="declare.linux.mipsel" if="isLinuxMipsel">
      <echo message="Linux.mipsel" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.mipsel" />
    </target>

    <target name="declare.linux.ppc" if="isLinuxPpc">
      <echo message="Linux.ppc" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.ppc" />
    </target>

    <target name="declare.linux.ppc64" if="isLinuxPpc64">
      <echo message="Linux.ppc64" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.ppc64" />
    </target>

    <target name="declare.linux.ppc64le" if="isLinuxPpc64le">
      <echo message="Linux.ppc64le" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.ppc64le" />
    </target>

    <target name="declare.linux.riscv64" if="isLinuxRiscV64">
      <echo message="Linux.riscv64" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.riscv64" />
    </target>

    <target name="declare.linux.s390" if="isLinuxs390">
      <echo message="Linux.s390" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.s390" />
    </target>

    <target name="declare.linux.s390x" if="isLinuxs390x">
      <echo message="Linux.s390x" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.s390x" />
    </target>

    <target name="declare.linux.sparc" if="isLinuxSparc">
      <echo message="Linux.sparc" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.linux" />
      <property name="linker.cfg.id"                        value="linker.cfg.linux.sparc" />
    </target>

    <target name="declare.linux" depends="declare.linux.x86,declare.linux.amd64,declare.linux.ia64,declare.linux.hppa,declare.linux.mips,declare.linux.mipsel,declare.linux.ppc,declare.linux.ppc64,declare.linux.ppc64le,declare.linux.riscv64,declare.linux.s390,declare.linux.s390x,declare.linux.sparc,declare.linux.armv6,declare.linux.aarch64" if="isLinux" >
      <property name="c.src.dir.os"                         value="unix" />
    </target>

    <target name="declare.android" if="isAndroid" >
      <property name="c.src.dir.os"                         value="unix" />
    </target>

    <target name="declare.solaris32" if="isSolaris32Bit">
      <echo message="Solaris" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.solaris" />
      <property name="linker.cfg.id"                        value="linker.cfg.solaris" />
    </target>

    <target name="declare.solarisSparcv9" if="isSolarisSparcv9">
      <echo message="SolarisSparcv9" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.solaris.sparcv9" />
      <property name="linker.cfg.id"                        value="linker.cfg.solaris.sparcv9" />
    </target>

    <target name="declare.solarisAMD64" if="isSolarisAMD64">
      <echo message="SolarisAMD64" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.solaris.amd64" />
      <property name="linker.cfg.id"                        value="linker.cfg.solaris.amd64" />
    </target>

    <target name="declare.solaris" depends="declare.solaris32,declare.solarisSparcv9,declare.solarisAMD64" if="isSolaris" >
      <property name="c.src.dir.os"                         value="unix" />
    </target>

    <target name="declare.macosx" if="isOSX">
      <echo message="MacOSX" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.macosx" />
      <property name="linker.cfg.id"                        value="linker.cfg.macosx" />
      <property name="c.src.dir.os"                         value="unix" />
    </target>

    <target name="declare.ios.amd64" if="isIOSAmd64">
      <echo message="IOSAmd64" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.ios.amd64" />
      <property name="linker.cfg.id"                        value="linker.cfg.ios.amd64" />
      <property name="c.src.dir.os"                         value="unix" />
    </target>

    <target name="declare.ios.arm64" if="isIOSArm64">
      <echo message="IOSArm64" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.ios.arm64" />
      <property name="linker.cfg.id"                        value="linker.cfg.ios.arm64" />
      <property name="c.src.dir.os"                         value="unix" />
    </target>

    <target name="declare.freebsd.amd64" if="isFreeBSDAMD64">
      <echo message="FreeBSDAMD64" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.freebsd" />
      <property name="linker.cfg.id"                        value="linker.cfg.freebsd.amd64" />
      <property name="c.src.dir.os"                         value="unix" />
    </target>

    <target name="declare.freebsd.x86" if="isFreeBSDX86">
      <echo message="FreeBSDX86" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.freebsd" />
      <property name="linker.cfg.id"                        value="linker.cfg.freebsd.x86" />
      <property name="c.src.dir.os"                         value="unix" />
    </target>

    <target name="declare.freebsd" depends="declare.freebsd.x86,declare.freebsd.amd64" if="isFreeBSD" >
      <property name="c.src.dir.os"                         value="unix" />
    </target>

    <target name="declare.hpux" if="isHPUX">
      <echo message="HP-UX" />
      <property name="compiler.cfg.id"                      value="compiler.cfg.hpux" />
      <property name="linker.cfg.id"                        value="linker.cfg.hpux" />
      <property name="c.src.dir.os"                         value="unix" />
    </target>

    <target name="c.configure" depends="gluegen.cpptasks.detect.os,gluegen.cpptasks.setup.compiler,declare.win32,declare.linux,declare.android,declare.solaris,declare.macosx,declare.ios.amd64,declare.ios.arm64,declare.freebsd,declare.hpux,gluegen.cpptasks.configure.compiler" />

    <target name="c.manifest" if="isVC8Family">
      <!-- exec mt, the Microsoft Manifest Tool, to include DLL manifests in order to resolve the location of msvcr80.dll -->
      <msvc.manifest objdir="${build}/obj" dllname="gluegen_rt" />
    </target>

    <target name="gluegen.build.native" depends="init, c.configure" >
      <property name="c.compiler.src.files.common" value="src/native/common/*.c" />
      <property name="c.compiler.src.files.os" value="src/native/${c.src.dir.os}/*.c" />

      <property name="output.lib.name" value="gluegen_rt" /> <!-- dash replaced by underscore to allow static linkage via JEP 178 -->
      <property name="output.lib.name.os" value="${native.library.prefix}${output.lib.name}.${native.library.suffix}" />

      <uptodate property="gluegen.build.skip.native">
        <srcfiles dir= "${project.root}"  includes="${c.compiler.src.files.os}"/>
        <srcfiles dir= "${project.root}"  includes="${c.compiler.src.files.common}"/>
        <mapper type="merge" to="${gluegen.lib.dir}/${output.lib.name.os}"/>
      </uptodate>

      <condition property="gluegen.package.native.done" value="true">
        <isset property="gluegen.build.skip.native"/>
      </condition>
      <antcall target="gluegen.build.c.impl" inheritAll="true" inheritRefs="true" />
    </target>

    <target name="gluegen.build.c.impl" depends="init, c.configure" unless="gluegen.build.skip.native">
      <echo message="clearing gluegen.build.shasum.done (2) - was ${gluegen.build.shasum.done}"/>
      <var name="gluegen.build.shasum.done" unset="true"/>
      <var name="gluegen.package.native.done" unset="true"/>
      <fail message="Requires '${compiler.cfg.id}'"      unless="compiler.cfg.id"/>
      <fail message="Requires '${linker.cfg.id}'"        unless="linker.cfg.id"/>

      <echo message="Output lib name = ${output.lib.name} -> ${output.lib.name.os} [${output.lib.type}]" />

      <mkdir dir="${gluegen.lib.dir}"/>

      <echo message="Compiling ${c.compiler.src.files.os} ${c.compiler.src.files.common}" />
      <echo message="user.dir=${user.dir}" />

      <cc outtype="${output.lib.type}"
          usehighleveltool="true"
          writesoname="true"
          objdir="${gluegen.lib.dir}"
          outfile="${gluegen.lib.dir}/${output.lib.name}"
          optimize="${c.compiler.optimise}"
          debug="${c.compiler.debug}"
          multithreaded="true"
          exceptions="false"
          rtti="false">

        <!-- TODO: versioninfo  companyname="java.net"
                      legalcopyright="Copyright"
                      productname="GlueGen"
                      productversion="x.y.z"
                      description="Description"
                      fileversion="x.y.z"
                      filecomments="File Comment" /-->

        <fileset dir="..">
          <patternset>
            <include name="${c.compiler.src.files.os}" />
            <include name="${c.compiler.src.files.common}" />
          </patternset>
        </fileset>

        <compiler extends="${compiler.cfg.id}" >
          <sysincludepath path="${java.includes.dir}"/>
          <sysincludepath path="${java.includes.dir.platform}"/>
          <sysincludepath path="${stub.includes.dir}/platform"/>

          <includepath path="${src.generated.c}" />
          <includepath path="${src.generated.c}/Unix" if="isUnix"/>
          <includepath path="${src.generated.c}/Unix" if="isOSX"/>
          <includepath path="${src.generated.c}/Unix" if="isIOS"/>
          <includepath path="${src.generated.c}/Windows" if="isWindows"/>
        </compiler>

        <linker extends="${linker.cfg.id}" />

      </cc>

      <gluegen.make.libsymbols builddir="${build}"
         nativelib="${gluegen.lib.dir}/${output.lib.name.os}"
         symbolsfile="${gluegen.lib.dir}/${native.library.prefix}${output.lib.name}.symbols" />

      <antcall target="gluegen.cpptasks.striplibs" inheritRefs="true">
          <param name="libdir" value="${gluegen.lib.dir}"/>
      </antcall>

      <antcall target="c.manifest" inheritRefs="true" />
    </target>

    <target name="gluegen.package.native" depends="init, c.configure" unless="gluegen.package.native.done" >
      <property name="gluegen.package.native.done" value="true" />
      <copy file="Manifest-rt-natives"
            tofile="${build}/Manifest-rt-natives.temp"
            overwrite="true">
          <filterset>
              <filter token="VERSION" value="${jogamp.version}"/>
              <filter token="BUILD_VERSION" value="${gluegen.version}"/>
              <filter token="SCM_BRANCH" value="${gluegen.build.branch}"/>
              <filter token="SCM_COMMIT" value="${gluegen.build.commit}"/>
              <filter token="SHA_SOURCES" value="${gluegen.build.sha.sources}"/>
              <filter token="SHA_CLASSES" value="${gluegen.build.sha.classes}"/>
              <filter token="SHA_CLASSES_THIS" value="0"/>
              <filter token="SHA_NATIVES" value="${gluegen.build.sha.natives}"/>
              <filter token="SHA_NATIVES_THIS" value="${gluegen.build.sha.natives}"/>
              <filter token="BASEVERSION" value="${jogamp.version.base}"/>
              <filter token="JAR_CODEBASE_TAG" value="${jogamp.jar.codebase}"/>
          </filterset>
      </copy>

      <native.tag.jar objdir="${build}/obj"
                      nativejarfile="${build}/gluegen-rt-natives-${os.and.arch}.jar"
                      manifestfile="${build}/Manifest-rt-natives.temp"
                      module="common"
                      includelibs="*${output.lib.name}.${native.library.suffix}" />

      <!-- Produce duplicates for different configurations, since non-native-jar aliasing (Bug 1023/Bug 1024) -->
      <!-- copy file="${build}/gluegen-rt-natives-${os.and.arch}.jar" tofile="${build}/gluegen-rt-android-natives-${os.and.arch}.jar"/ -->
    </target>

  <!-- ================================================================== -->
  <!--
    - Build GlueGen.
    -->
  <target name="generate-hash-maps">

    <!-- Int*Maps -->
    <antcall target="create-map" inheritrefs="true">
        <param name="map.name" value="IntObjectHashMap"/>
        <param name="map.key" value="int"/>
        <param name="map.keyHash" value="\1"/>
        <param name="map.value" value="Object"/>
        <param name="map.null" value="null"/>
    </antcall>

    <antcall target="create-map" inheritrefs="true">
        <param name="map.name" value="IntLongHashMap"/>
        <param name="map.key" value="int"/>
        <param name="map.keyHash" value="\1"/>
        <param name="map.value" value="long"/>
        <param name="map.null" value="-1"/>
    </antcall>

    <!-- Long*Maps -->
    <antcall target="create-map" inheritrefs="true">
        <param name="map.name" value="LongObjectHashMap"/>
        <param name="map.key" value="long"/>
        <param name="map.keyHash" value="HashUtil.getAddrHash32_EqualDist(\1)"/>
        <param name="map.value" value="Object"/>
        <param name="map.null" value="null"/>
    </antcall>

    <antcall target="create-map" inheritrefs="true">
        <param name="map.name" value="LongIntHashMap"/>
        <param name="map.key" value="long"/>
        <param name="map.keyHash" value="HashUtil.getAddrHash32_EqualDist(\1)"/>
        <param name="map.value" value="int"/>
        <param name="map.null" value="-1"/>
    </antcall>

    <antcall target="create-map" inheritrefs="true">
        <param name="map.name" value="LongLongHashMap"/>
        <param name="map.key" value="long"/>
        <param name="map.keyHash" value="HashUtil.getAddrHash32_EqualDist(\1)"/>
        <param name="map.value" value="long"/>
        <param name="map.null" value="-1"/>
    </antcall>

  </target>

  <target name="create-map">
    <!-- substitutes certain token in IntIntHashmap to create new primitive HasmMap-->
    <copy file="${src.java}/com/jogamp/common/util/IntIntHashMap.java"
        tofile="${src.generated.java}/com/jogamp/common/util/${map.name}.java" overwrite="true">
        <filterchain>
            <replaceregex pattern="IntIntHashMap" replace="${map.name}"/>
            <replaceregex pattern="@see ${map.name}" replace="@see IntIntHashMap"/>
            <replaceregex pattern="/\*value\*/int/\*value\*/" replace="${map.value}"/>
            <replaceregex pattern="/\*key\*/int/\*key\*/" replace="${map.key}"/>
            <replaceregex pattern="/\*keyHash\*/(.*)/\*keyHash\*/" replace="${map.keyHash}"/>
            <replaceregex pattern="/\*null\*/-1/\*null\*/" replace="${map.null}"/>
        </filterchain>
        <!-- no clue why we have to do this twice... otherwise it will only replace one token per line -->
        <filterchain>
            <replaceregex pattern="/\*value\*/int/\*value\*/" replace="${map.value}"/>
        </filterchain>
    </copy>
  </target>

  <target name="generate-primitive-stacks">

    <!-- IntegerStack -->
    <antcall target="create-pstack" inheritrefs="true">
        <param name="pstack.name" value="IntegerStack"/>
        <param name="pstack.testname" value="TestIntegerStack01"/>
        <param name="pstack.value" value="int"/>
        <param name="pstack.value2" value="IntBuffer"/>
    </antcall>

  </target>

  <target name="create-pstack">
    <copy file="${src.java}/com/jogamp/common/util/FloatStack.java"
        tofile="${src.generated.java}/com/jogamp/common/util/${pstack.name}.java" overwrite="true">
        <filterchain>
            <replaceregex pattern="FloatStack" replace="${pstack.name}"/>
            <replaceregex pattern="@see ${pstack.name}" replace="@see FloatStack"/>
            <replaceregex pattern="/\*value\*/float/\*value\*/" replace="${pstack.value}"/>
            <replaceregex pattern="/\*value2\*/FloatBuffer/\*value2\*/" replace="${pstack.value2}"/>
        </filterchain>
    </copy>
    <mkdir dir="${gluegen.root}/${rootrel.build}/test/build/gensrc/classes"/>
    <copy file="${gluegen.root}/src/junit/com/jogamp/common/util/TestFloatStack01.java"
        tofile="${gluegen.root}/${rootrel.build}/test/build/gensrc/classes/com/jogamp/common/util/${pstack.testname}.java" overwrite="true">
        <filterchain>
            <replaceregex pattern="FloatStack" replace="${pstack.name}"/>
            <replaceregex pattern="TestFloatStack01" replace="${pstack.testname}"/>
            <replaceregex pattern="@see ${pstack.name}" replace="@see FloatStack"/>
            <replaceregex pattern="/\*value\*/float/\*value\*/" replace="${pstack.value}"/>
            <replaceregex pattern="/\*value2\*/FloatBuffer/\*value2\*/" replace="${pstack.value2}"/>
        </filterchain>
    </copy>
  </target>

  <target name="gluegen.build.check.java" depends="init">
      <uptodate property="gluegen.build.skip.java1">
        <srcfiles dir= "."            includes="*.xml"/>
        <srcfiles dir= "${src.java}"  includes="**"/>
        <srcfiles dir= "${src.jcpp}"  includes="**"/>
        <srcfiles dir= "${c.grammar}" includes="*.g"/>
        <srcfiles dir= "${j.grammar}" includes="*.g"/>
        <mapper type="merge" to="${build}/gluegen.jar"/>
      </uptodate>
      <uptodate property="gluegen.build.skip.java2">
        <srcfiles dir= "."            includes="*.xml"/>
        <srcfiles dir= "${src.java}"  includes="**"/>
        <srcfiles dir= "${src.jcpp}"  includes="**"/>
        <srcfiles dir= "${c.grammar}" includes="*.g"/>
        <srcfiles dir= "${j.grammar}" includes="*.g"/>
        <mapper type="merge" to="${build}/gluegen-rt.jar"/>
      </uptodate>
      <condition property="gluegen.build.skip.java" value="true">
        <or>
          <isset property="gluegen.build.skip.java1"/>
          <isset property="gluegen.build.skip.java2"/>
        </or>
      </condition>
  </target>

    <!--
    - Using ANTLR generate the specified Java files.
    -
    - @param target the grammar file to process
    - @param output.dir the directory to write the generated files to.  If
    -        the directory does not exist, it will be created.
    -->
  <target name="generate.java">
    <!-- Generate the Java files -->
    <antlr target="${output.dir}/${target}" outputdirectory="${output.dir}" debug="no" trace="no">
      <classpath refid="antlr.classpath" />
    </antlr>
  </target>

  <!--
    - Using ANTLR generate the specified Java files with an overridden
    - grammar file.
    -
    - @param target the grammar file to process
    - @param override the overridding grammar file
    - @param output.dir the directory to write the generated files to.  If
    -        the directory does not exist, it will be created.
   -->
  <target name="generate.java.override">
    <!-- Generate the Java files -->
    <antlr target="${output.dir}/${target}" glib="${output.dir}/${override}" outputdirectory="${output.dir}" debug="no" trace="no">
      <classpath refid="antlr.classpath" />
    </antlr>
  </target>

  <target name="gluegen.build.javase">
    <!-- Because ANTLR looks for importVocab files in the current
         working directory, it likes to have all of its files,
         including supergrammars, in one place, so copy all of the
         grammars to the output directory up front so we don't put
         temporary files into the source tree -->
    <mkdir dir="${c.grammar.out.dir}" />
    <copy todir="${c.grammar.out.dir}">
      <fileset dir="${c.grammar}">
        <include name="*.g" />
      </fileset>
    </copy>
    <mkdir dir="${j.grammar.out.dir}" />
    <copy todir="${j.grammar.out.dir}">
      <fileset dir="${j.grammar}">
        <include name="*.g" />
      </fileset>
    </copy>

    <!-- Generate the Java files from the C grammar using ANTLR. -->
    <antcall target="generate.java"  inheritRefs="true">
      <param name="output.dir" value="${c.grammar.out.dir}" />
      <param name="target"     value="StdCParser.g" />
    </antcall>
    <antcall target="generate.java.override"  inheritRefs="true">
      <param name="output.dir" value="${c.grammar.out.dir}" />
      <param name="target"     value="GnuCParser.g" />
      <param name="override"   value="StdCParser.g" />
    </antcall>
    <antcall target="generate.java"  inheritRefs="true">
      <param name="output.dir" value="${c.grammar.out.dir}" />
      <param name="target"     value="GnuCTreeParser.g" />
    </antcall>
    <antcall target="generate.java.override"  inheritRefs="true">
      <param name="output.dir" value="${c.grammar.out.dir}" />
      <param name="target"     value="GnuCEmitter.g" />
      <param name="override"   value="GnuCTreeParser.g" />
    </antcall>
    <antcall target="generate.java.override"  inheritRefs="true">
      <param name="output.dir" value="${c.grammar.out.dir}" />
      <param name="target"     value="HeaderParser.g" />
      <param name="override"   value="GnuCTreeParser.g" />
    </antcall>
    <antcall target="generate.java"  inheritRefs="true">
      <param name="output.dir" value="${j.grammar.out.dir}" />
      <param name="target"     value="JavaParser.g" />
    </antcall>

    <!-- Build GlueGen using the generated Java files along with the
         original source in multiple stages below. -->

    <!-- Compile gluegen-rt first including generation of native headers -->
    <!-- This has a hard Java8 target spec requirement: release {source, target} -->
    <javac destdir="${classes}"
           includeAntRuntime="false"
           includes="${gluegen-rt.classes} ${jogamp.common.classes}"
           excludes="${gluegen.excludes.all} ${java.part.android} ${java.part.java11}"
           nativeheaderdir="${src.generated.c}"
           memoryMaximumSize="${javac.memorymax}"
           encoding="UTF-8"
           release="${target.releaselevel}"
           debug="${javacdebug}" debuglevel="${javacdebuglevel}">
      <src path="${src.java}" />
      <src path="${src.generated.java}" />
      <classpath refid="cc_gluegen.classpath" />
    </javac>

    <!-- move platform-specific native headers into the right directories -->
    <move file="${src.generated.c}/jogamp_common_os_UnixDynamicLinkerImpl.h" todir="${src.generated.c}/Unix" failonerror="false" quiet="true"/>
    <move file="${src.generated.c}/jogamp_common_os_WindowsDynamicLinkerImpl.h" todir="${src.generated.c}/Windows" failonerror="false" quiet="true"/>

    <!-- make non-java code available in classpath -->
    <copy todir="${classes}">
        <fileset dir="${src.java}"
                 includes="${java.part.nonjava}"
                 excludes="**/*.java"/>
    </copy>

    <!-- Compile gluegen (compile time).  -->
    <!-- This has a hard Java8 target spec requirement: release {source, target} -->
    <javac destdir="${classes}"
           includeAntRuntime="true"
           excludes="${gluegen.excludes.all} ${gluegen-rt.classes} ${java.part.android} ${java.part.java11}"
           memoryMaximumSize="${javac.memorymax}"
           encoding="UTF-8"
           release="${target.releaselevel}"
           debug="${javacdebug}" debuglevel="${javacdebuglevel}">
      <src path="${src.jcpp}" />
      <src path="${src.java}" />
      <src path="${src.generated.java}" />
      <classpath refid="cc_gluegen.classpath" />
    </javac>

    <!-- Compile gluegen (compile time).  -->
    <!-- This has a Java11 bytecote target for java.part.java11 -->
    <javac destdir="${classes}"
           includeAntRuntime="true"
           excludes="${gluegen.excludes.all} ${gluegen-rt.classes} ${java.part.android}"
           memoryMaximumSize="${javac.memorymax}"
           encoding="UTF-8"
           release="${target.buildlevel}"
           debug="${javacdebug}" debuglevel="${javacdebuglevel}">
      <src path="${src.java}" />
      <classpath refid="cc_gluegen.classpath" />
    </javac>
  </target>

  <target name="gluegen.package.javase">
    <java classname="com.jogamp.common.util.SHASum" logError="true" failonerror="true" fork="true" newenvironment="true"
          classpath="${classes}"
          outputproperty="gluegen.build.sha.classes.gluegen">
        <sysproperty key="java.library.path" value="${gluegen.lib.dir}"/>

        <arg value="--include"/>
        <arg value="${classes.unix}/.*\.class"/>

        <arg value="--exclude"/>
        <arg value="${classes.unix}/jogamp/android/launcher"/>

        <arg value="${classes.unix}"/>
    </java>
    <copy file="Manifest"
          tofile="${build}/Manifest.temp"
          overwrite="true">
        <filterset>
            <filter token="VERSION" value="${jogamp.version}"/>
            <filter token="BUILD_VERSION" value="${gluegen.version}"/>
            <filter token="SCM_BRANCH" value="${gluegen.build.branch}"/>
            <filter token="SCM_COMMIT" value="${gluegen.build.commit}"/>
            <filter token="SHA_SOURCES" value="${gluegen.build.sha.sources}"/>
            <filter token="SHA_CLASSES" value="${gluegen.build.sha.classes}"/>
            <filter token="SHA_CLASSES_THIS" value="${gluegen.build.sha.classes.gluegen}"/>
            <filter token="SHA_NATIVES" value="${gluegen.build.sha.natives}"/>
            <filter token="SHA_NATIVES_THIS" value="0"/>
            <filter token="BASEVERSION" value="${jogamp.version.base}"/>
            <filter token="JAR_CODEBASE_TAG" value="${jogamp.jar.codebase}"/>
        </filterset>
    </copy>

    <!-- Build gluegen.jar. -->
    <jar destfile="${build}/gluegen.jar" manifest="${build}/Manifest.temp" filesonly="true">
      <service type="javax.annotation.processing.Processor">
        <provider classname="com.jogamp.gluegen.structgen.CStructAnnotationProcessor"/>
      </service>
      <fileset dir="${classes}">
        <include name="**/*.class" />
        <exclude name="${jogamp-android-launcher.classes}" />
      </fileset>
      <fileset dir="resources/assets">
        <include name="**" />
      </fileset>
    </jar>

    <java classname="com.jogamp.common.util.SHASum" logError="true" failonerror="true" fork="true" newenvironment="true"
          classpath="${classes}"
          outputproperty="gluegen.build.sha.classes.gluegen-rt">
        <sysproperty key="java.library.path" value="${gluegen.lib.dir}"/>

        <arg value="--include"/>
        <arg value="${classes.unix}/com/jogamp/gluegen/runtime/.*\.class" />
        <arg value="--include"/>
        <arg value="${classes.unix}/com/jogamp/common/.*" />
        <arg value="--include"/>
        <arg value="${classes.unix}/jogamp/common/.*" />

        <arg value="--exclude"/>
        <arg value="${classes.unix}/jogamp/android/launcher"/>
        <arg value="--exclude"/>
        <arg value="${classes.unix}/jogamp/common/os/android" />
        <arg value="--exclude"/>
        <arg value="${classes.unix}/com/jogamp/gluegen/jcpp" />

        <arg value="${classes.unix}"/>
    </java>
    <copy file="Manifest-rt"
          tofile="${build}/Manifest-rt.temp"
          overwrite="true">
        <filterset>
            <filter token="VERSION" value="${jogamp.version}"/>
            <filter token="BUILD_VERSION" value="${gluegen.version}"/>
            <filter token="SCM_BRANCH" value="${gluegen.build.branch}"/>
            <filter token="SCM_COMMIT" value="${gluegen.build.commit}"/>
            <filter token="SHA_SOURCES" value="${gluegen.build.sha.sources}"/>
            <filter token="SHA_CLASSES" value="${gluegen.build.sha.classes}"/>
            <filter token="SHA_CLASSES_THIS" value="${gluegen.build.sha.classes.gluegen-rt}"/>
            <filter token="SHA_NATIVES" value="${gluegen.build.sha.natives}"/>
            <filter token="SHA_NATIVES_THIS" value="0"/>
            <filter token="BASEVERSION" value="${jogamp.version.base}"/>
            <filter token="JAR_CODEBASE_TAG" value="${jogamp.jar.codebase}"/>
        </filterset>
    </copy>

    <!-- Build gluegen-rt.jar. -->
    <jar destfile="${build}/gluegen-rt.jar" manifest="${build}/Manifest-rt.temp" filesonly="true">
      <fileset dir="${classes}">
        <include name="com/jogamp/gluegen/runtime/*.class" />
        <include name="com/jogamp/common/**" />
        <include name="jogamp/common/**" />
        <exclude name="${jogamp-android-launcher.classes}" />
        <exclude name="${java.part.android}" />
        <exclude name="${java.part.jcpp}" />
      </fileset>
      <fileset dir="resources/assets">
        <include name="**" />
      </fileset>
    </jar>

    <!-- copy file="Manifest-rt-alt"
          tofile="${build}/Manifest-rt-alt.temp"
          overwrite="true">
        <filterset>
            <filter token="VERSION" value="${jogamp.version}"/>
            <filter token="BUILD_VERSION" value="${gluegen.version}"/>
            <filter token="SCM_BRANCH" value="${gluegen.build.branch}"/>
            <filter token="SCM_COMMIT" value="${gluegen.build.commit}"/>
            <filter token="SHA_SOURCES" value="${gluegen.build.sha.sources}"/>
            <filter token="SHA_CLASSES" value="${gluegen.build.sha.classes}"/>
            <filter token="SHA_CLASSES_THIS" value="${gluegen.build.sha.classes.gluegen-rt-alt}"/>
            <filter token="SHA_NATIVES" value="${gluegen.build.sha.natives}"/>
            <filter token="SHA_NATIVES_THIS" value="0"/>
            <filter token="BASEVERSION" value="${jogamp.version.base}"/>
            <filter token="JAR_CODEBASE_TAG" value="${jogamp.jar.codebase}"/>
        </filterset>
    </copy -->
    <!-- Build gluegen-rt-alt.jar. -->
    <!-- jar destfile="${build}/gluegen-rt-alt.jar" manifest="${build}/Manifest-rt-alt.temp">
      <fileset dir="${classes}">
        <include name="com/jogamp/gluegen/runtime/*.class" />
        <include name="com/jogamp/common/**" />
        <include name="jogamp/common/**" />
        <exclude name="${jogamp-android-launcher.classes}" />
        <exclude name="${java.part.android}" />
        <exclude name="${java.part.jcpp}" />
      </fileset>
      <fileset dir="resources/assets">
        <include name="**" />
      </fileset>
    </jar -->

    <copy file="jogamp-fat.mf"
          tofile="${build}/jogamp-fat.mf"
          overwrite="true">
        <filterset>
            <filter token="VERSION" value="${jogamp.version}"/>
            <filter token="BUILD_VERSION" value="${gluegen.version}"/>
            <filter token="SCM_BRANCH" value="${gluegen.build.branch}"/>
            <filter token="SCM_COMMIT" value="${gluegen.build.commit}"/>
            <filter token="SHA_SOURCES" value="${gluegen.build.sha.sources}"/>
            <filter token="SHA_CLASSES" value="${gluegen.build.sha.classes}"/>
            <filter token="SHA_CLASSES_THIS" value="${gluegen.build.sha.classes}"/>
            <filter token="SHA_NATIVES" value="${gluegen.build.sha.natives}"/>
            <filter token="SHA_NATIVES_THIS" value="${gluegen.build.sha.natives}"/>
            <filter token="BASEVERSION" value="${jogamp.version.base}"/>
            <filter token="JAR_CODEBASE_TAG" value="${jogamp.jar.codebase}"/>
        </filterset>
    </copy>

    <copy file="jogamp-fat-test.mf"
          tofile="${build}/jogamp-fat-test.mf"
          overwrite="true">
        <filterset>
            <filter token="VERSION" value="${jogamp.version}"/>
            <filter token="BUILD_VERSION" value="${gluegen.version}"/>
            <filter token="SCM_BRANCH" value="${gluegen.build.branch}"/>
            <filter token="SCM_COMMIT" value="${gluegen.build.commit}"/>
            <filter token="SHA_SOURCES" value="${gluegen.build.sha.sources}"/>
            <filter token="SHA_CLASSES" value="${gluegen.build.sha.classes}"/>
            <filter token="SHA_CLASSES_THIS" value="${gluegen.build.sha.classes}"/>
            <filter token="SHA_NATIVES" value="${gluegen.build.sha.natives}"/>
            <filter token="SHA_NATIVES_THIS" value="${gluegen.build.sha.natives}"/>
            <filter token="BASEVERSION" value="${jogamp.version.base}"/>
            <filter token="JAR_CODEBASE_TAG" value="${jogamp.jar.codebase}"/>
        </filterset>
    </copy>

    <!-- Copy antlr.jar into build directory for convenience so
         gluegen.jar can be run via "java -jar". antlr.jar is
         referenced via a Class-Path entry in the Manifest of
         gluegen.jar. -->
    <copy file="${antlr.jar}" todir="${build}" />

    <!-- copy a jnlp with empty codebase into build folder for local testing
         overwrite property in gluegen.proerpties if desired             -->
    <property name="gluegen.jnlp.codebase" value=""/>

    <copy file="${gluegen.root}/jnlp-files/gluegen-rt.jnlp" todir="${build}">
        <filterchain>
            <replacestring from="GLUEGEN_CODEBASE_TAG" to="${gluegen.jnlp.codebase}"/>
        </filterchain>
    </copy>
  </target>

  <target name="gluegen.build.android" if="android-jars.available">
    <!--compile gluegen-rt-android last-->
    <!-- This has a hard Java8 target spec requirement: source, target + bootclasspath -->
    <javac destdir="${classes}"
           includeAntRuntime="false"
           includes="${gluegen-rt.classes} ${jogamp.common.classes}"
           excludes="${gluegen.excludes.all}"
           memoryMaximumSize="${javac.memorymax}"
           encoding="UTF-8"
           release="${target.releaselevel}"
           debug="${javacdebug}" debuglevel="${javacdebuglevel}">
      <src path="${src.java}" />
      <src path="${src.generated.java}" />
      <classpath refid="cc_gluegen_android.classpath" />
    </javac>
  </target>

  <target name="gluegen.package.android" if="android-jars.available">
    <java classname="com.jogamp.common.util.SHASum" logError="true" failonerror="true" fork="true" newenvironment="true"
          classpath="${classes}"
          outputproperty="gluegen.build.sha.classes.gluegen-rt-android">
        <sysproperty key="java.library.path" value="${gluegen.lib.dir}"/>

        <arg value="--include"/>
        <arg value="${classes.unix}/com/jogamp/gluegen/runtime/.*\.class" />
        <arg value="--include"/>
        <arg value="${classes.unix}/com/jogamp/common/.*" />
        <arg value="--include"/>
        <arg value="${classes.unix}/jogamp/common/.*" />

        <arg value="--exclude"/>
        <arg value="${classes.unix}/jogamp/android/launcher"/>
        <arg value="--exclude"/>
        <arg value="${classes.unix}/com/jogamp/gluegen/jcpp" />

        <arg value="${classes.unix}"/>
    </java>
    <copy file="Manifest-rt-android"
          tofile="${build}/Manifest-rt-android.temp"
          overwrite="true">
        <filterset>
            <filter token="VERSION" value="${jogamp.version}"/>
            <filter token="BUILD_VERSION" value="${gluegen.version}"/>
            <filter token="SCM_BRANCH" value="${gluegen.build.branch}"/>
            <filter token="SCM_COMMIT" value="${gluegen.build.commit}"/>
            <filter token="SHA_SOURCES" value="${gluegen.build.sha.sources}"/>
            <filter token="SHA_CLASSES" value="${gluegen.build.sha.classes}"/>
            <filter token="SHA_CLASSES_THIS" value="${gluegen.build.sha.classes.gluegen-rt-android}"/>
            <filter token="SHA_NATIVES" value="${gluegen.build.sha.natives}"/>
            <filter token="SHA_NATIVES_THIS" value="0"/>
            <filter token="BASEVERSION" value="${jogamp.version.base}"/>
            <filter token="JAR_CODEBASE_TAG" value="${jogamp.jar.codebase}"/>
        </filterset>
    </copy>

    <!-- Build gluegen-rt-android.jar. -->
    <jar destfile="${build}/gluegen-rt-android.jar" manifest="${build}/Manifest-rt-android.temp" filesonly="true">
      <fileset dir="${classes}">
        <include name="com/jogamp/gluegen/runtime/*.class" />
        <include name="com/jogamp/common/**" />
        <include name="jogamp/common/**" />
        <include name="${java.part.android}" />
        <exclude name="${jogamp-android-launcher.classes}" />
        <exclude name="${java.part.jcpp}" />
      </fileset>
      <fileset dir="resources/assets">
        <include name="**" />
      </fileset>
    </jar>
  </target>

  <target name="gluegen.build.java" depends="gluegen.build.java.impl">
      <condition property="gluegen.package.java.done" value="true">
        <isset property="gluegen.build.skip.java"/>
      </condition>
  </target>
  <target name="gluegen.build.java.impl" depends="gluegen.cpptasks.detect.os,gluegen.build.check.java" unless="gluegen.build.skip.java">
    <echo message="clearing gluegen.build.shasum.done (1) - was ${gluegen.build.shasum.done}"/>
    <var name="gluegen.build.shasum.done" unset="true"/>
    <var name="gluegen.package.java.done" unset="true"/>
    <antcall target="generate-hash-maps"        inheritRefs="true"/>
    <antcall target="generate-primitive-stacks" inheritRefs="true"/>
    <antcall target="gluegen.build.javase"      inheritRefs="true"/>
    <antcall target="gluegen.build.android"     inheritRefs="true"/>
  </target>

  <target name="gluegen.build.shasum" depends="gluegen.cpptasks.detect.os" unless="gluegen.build.shasum.done">
    <property name="gluegen.build.shasum.done" value="true"/>
    <java classname="com.jogamp.common.util.SHASum" logError="true" failonerror="true" fork="true" newenvironment="true"
          classpath="${classes}"
          outputproperty="gluegen.build.sha.sources">
        <sysproperty key="java.library.path" value="${gluegen.lib.dir}"/>
        <!-- jvmarg value="-Djogamp.debug.SHASum"/ -->

        <arg value="--exclude"/>
        <arg value=".*\.log"/>

        <arg value="--exclude"/>
        <arg value="../make/lib/toolchain"/>

        <arg value="../src"/>
        <arg value="../jcpp/src"/>
        <arg value="../make"/>
    </java>
    <java classname="com.jogamp.common.util.SHASum" logError="true" failonerror="true" fork="true" newenvironment="true"
          classpath="${classes}"
          outputproperty="gluegen.build.sha.classes">
        <sysproperty key="java.library.path" value="${gluegen.lib.dir}"/>
        <arg value="${classes.unix}"/>
    </java>
    <java classname="com.jogamp.common.util.SHASum" logError="true" failonerror="true" fork="true" newenvironment="true"
          classpath="${classes}"
          outputproperty="gluegen.build.sha.natives">
        <sysproperty key="java.library.path" value="${gluegen.lib.dir}"/>
        <arg value="${gluegen.lib.dir}/${output.lib.name.os}"/>
    </java>
    <echo message="gluegen.build.sha.sources ${gluegen.build.sha.sources}"/>
    <echo message="gluegen.build.sha.classes ${gluegen.build.sha.classes}"/>
    <echo message="gluegen.build.sha.natives ${gluegen.build.sha.natives}"/>
  </target>

  <target name="gluegen.package.java" depends="gluegen.cpptasks.detect.os" unless="gluegen.package.java.done">
    <property name="gluegen.package.java.done" value="true"/>
    <antcall target="gluegen.package.javase"      inheritRefs="true"/>
    <antcall target="gluegen.package.android"     inheritRefs="true"/>
  </target>

  <target name="gluegen.build.check.android-launcher" depends="init">
      <uptodate property="gluegen.build.skip.android-launcher">
        <srcfiles dir= "."            includes="*.xml"/>
        <srcfiles dir= "resources/android" includes="**/*.xml"/>
        <srcfiles dir= "${src.java}/jogamp/android/launcher"  includes="**"/>
        <mapper type="merge" to="${build}/jogamp-android-launcher.jar"/>
      </uptodate>
  </target>

  <target name="android-launcher.build" depends="gluegen.cpptasks.detect.os,gluegen.build.check.android-launcher" if="android-jars.available" unless="gluegen.build.skip.android-launcher">
    <!-- This has a hard Java8 target spec requirement: source, target + bootclasspath -->
    <javac destdir="${classes}"
           includeAntRuntime="false"
           includes="${jogamp-android-launcher.classes}"
           excludes="${jogamp.common.classes}"
           memoryMaximumSize="${javac.memorymax}"
           encoding="UTF-8"
           release="${target.releaselevel}"
           debug="${javacdebug}" debuglevel="${javacdebuglevel}">
      <src path="${src.java}" />
      <classpath refid="android.classpath" />
    </javac>
  </target>

  <target name="android-launcher.package" depends="android-launcher.build" if="isAndroid" unless="gluegen.build.skip.android-launcher">
    <java classname="com.jogamp.common.util.SHASum" logError="true" failonerror="true" fork="true" newenvironment="true"
          classpath="${classes}"
          outputproperty="gluegen.build.sha.classes.jogamp-android-launcher">
        <sysproperty key="java.library.path" value="${gluegen.lib.dir}"/>

        <arg value="--include"/>
        <arg value="${classes.unix}/jogamp/android/launcher/.*"/>

        <arg value="${classes.unix}/jogamp/android/launcher/"/>
    </java>
    <copy file="Manifest-android-launcher"
          tofile="${build}/Manifest-android-launcher.temp"
          overwrite="true">
        <filterset>
            <filter token="VERSION" value="${jogamp.version}"/>
            <filter token="BUILD_VERSION" value="${gluegen.version}"/>
            <filter token="SCM_BRANCH" value="${gluegen.build.branch}"/>
            <filter token="SCM_COMMIT" value="${gluegen.build.commit}"/>
            <filter token="SHA_SOURCES" value="${gluegen.build.sha.sources}"/>
            <filter token="SHA_CLASSES" value="${gluegen.build.sha.classes}"/>
            <filter token="SHA_CLASSES_THIS" value="${gluegen.build.sha.classes.jogamp-android-launcher}"/>
            <filter token="SHA_NATIVES" value="${gluegen.build.sha.natives}"/>
            <filter token="SHA_NATIVES_THIS" value="0"/>
            <filter token="BASEVERSION" value="${jogamp.version.base}"/>
            <filter token="JAR_CODEBASE_TAG" value="${jogamp.jar.codebase}"/>
        </filterset>
    </copy>

    <jar destfile="${build}/jogamp-android-launcher.jar" manifest="${build}/Manifest-android-launcher.temp" filesonly="true">
      <fileset dir="${classes}">
        <include name="${jogamp-android-launcher.classes}" />
      </fileset>
    </jar>
    <aapt.signed
        assetsdir="resources/assets-launcher"
        jarbuilddir="${build}"
        jarbasename="jogamp-android-launcher"
        nativebuilddir="${build}"
        nativebasename="non-existing"
        androidmanifest.path="resources/android/AndroidManifest-Launcher.xml"
        androidresources.path="resources/android/res"
        jarmanifest.path="${build}/Manifest-android-launcher.temp"
        version.code="${jogamp.version.int}"
        version.name="${jogamp.version}"
      />
  </target>

  <target name="gluegen.build.check.aapt" depends="init">
      <uptodate property="gluegen.build.skip.aapt">
        <srcfiles dir= "."                includes="*.xml"/>
        <srcfiles dir= "${src.java}"      includes="**"/>
        <srcfiles dir= "${src.generated}" includes="**"/>
        <mapper type="merge" to="${build}/gluegen-rt-${os.and.arch}.apk"/>
      </uptodate>
  </target>

  <target name="android.package" depends="gluegen.cpptasks.detect.os,gluegen.build.check.aapt" if="isAndroid" unless="gluegen.build.skip.aapt" >

    <aapt.signed
        assetsdir="resources/assets"
        jarbuilddir="${build}"
        jarbasename="gluegen-rt-android"
        nativebuilddir="${gluegen.lib.dir}"
        nativebasename="${output.lib.name}"
        android.abi="${android.abi}"
        androidmanifest.path="resources/android/AndroidManifest-Runtime.xml"
        androidresources.path="resources/android/res"
        jarmanifest.path="${build}/Manifest-rt-android.temp"
        version.code="${jogamp.version.int}"
        version.name="${jogamp.version}"
      />
  </target>

  <target name="base.compile" description="Base compile ensuring valid build results w/o tampering the artifact.properties"
                              depends="clean-temp, android-launcher.build, gluegen.build.java, gluegen.build.native, gluegen.build.shasum, gluegen.package.java, gluegen.package.native, android-launcher.package" />

  <target name="all.no_junit" description="Release build" depends="base.compile, tag.build, android.package, developer-zip-archive" >
      <antcall target="clean-temp" inheritAll="true" inheritRefs="true" />
  </target>
  <target name="all" description="Release build" depends="base.compile, tag.build, junit.compile, android.package, developer-zip-archive" >
      <antcall target="clean-temp" inheritAll="true" inheritRefs="true" />
  </target>

  <target name="all.debug" description="Debug build" depends="init.debug, base.compile, tag.build, junit.compile, developer-zip-archive" >
      <antcall target="clean-temp" inheritAll="true" inheritRefs="true" />
  </target>

  <target name="all.ide" description="Debug IDE build including all junit tests, but don't tag the build or create archives" depends="init.debug, base.compile, tag.build, junit.compile" >
      <antcall target="clean-temp" inheritAll="true" inheritRefs="true" />
  </target>

  <target name="clean-temp" depends="init">
    <delete includeEmptyDirs="true" failonerror="false">
      <fileset dir="${project.root}/build-temp" />
      <fileset dir="${project.root}" includes="make/GnuCTreeParserTokenTypes.txt make/STDCTokenTypes.txt" />
    </delete>
  </target>

  <target name="clean" depends="clean-temp">
    <delete includeEmptyDirs="true" failonerror="false">
      <fileset dir="${build}" />
    </delete>
  </target>

  <target name="tag.build" depends="init">
    <echo message='gluegen.build.version=${jogamp.version}${line.separator}'      file="${build}/artifact.properties"/>
    <echo message='gluegen.build.number=${gluegen.build.number}${line.separator}' file="${build}/artifact.properties" append="true"/>
    <echo message='gluegen.build.id=${gluegen.build.id}${line.separator}'         file="${build}/artifact.properties" append="true"/>
    <echo message='gluegen.build.branch=${gluegen.build.branch}${line.separator}' file="${build}/artifact.properties" append="true"/>
    <echo message='gluegen.build.commit=${gluegen.build.commit}${line.separator}' file="${build}/artifact.properties" append="true"/>
    <echo message='gluegen.build.sha.sources=${gluegen.build.sha.sources}${line.separator}' file="${build}/artifact.properties" append="true"/>
    <echo message='gluegen.build.sha.classes=${gluegen.build.sha.classes}${line.separator}' file="${build}/artifact.properties" append="true"/>
    <echo message='gluegen.build.sha.natives=${gluegen.build.sha.natives}${line.separator}' file="${build}/artifact.properties" append="true"/>
  </target>

  <target name="junit.compile" depends="init">
    <ant antfile="build-test.xml" target="junit.compile"/>
  </target>

  <target name="junit.run" depends="init,junit.compile">
    <ant antfile="build-test.xml" target="junit.run"/>
  </target>

  <target name="doxygen.all.zip" depends="doxygen.public, doxygen.all, doxygen.zip"/>
  <target name="doxygen.public.zip" depends="doxygen.public, doxygen.zip"/>

  <target name="doxygen.public" depends="init">
    <!-- Build the general public Javadoc in the target folder hierarchy doxygen/gluegen/doxygen -->
    <delete dir="${doxygen.gluegen.public.path}" includeEmptyDirs="true" quiet="true" failonerror="false" />
    <mkdir dir="${doxygen.gluegen.public.path}" />
    <copy file="${project.root}/doxygen/doxygen-awesome.css" todir="${build}" overwrite="true"/>
    <copy file="${project.root}/doxygen/Doxyfile.javapublic.in"
        tofile="${build}/Doxyfile.javapublic"
        overwrite="true">
        <filterset>
            <filter token="BUILD_DIR" value="${build.abs-path}"/>
            <filter token="CURRENT_SOURCE_DIR" value="${project.root.abs-path}"/>
            <filter token="GLUEGEN_VERSION_LONG" value="${jogamp.version}"/>
            <filter token="GLUEGEN_DOCS_DIR" value="${doxygen.gluegen.public.path}"/>
        </filterset>
    </copy>
    <exec dir="${build}" executable="doxygen"
         vmlauncher="false"
         failonerror="false">
        <arg line="Doxyfile.javapublic"/>
    </exec>
  </target>

  <target name="doxygen.all" depends="init">
    <!-- Build the general developer Javadoc in the target folder hierarchy doxygen/gluegen/doxygen_dev -->
    <delete dir="${doxygen.gluegen.dev.path}" includeEmptyDirs="true" quiet="true" failonerror="false" />
    <mkdir dir="${doxygen.gluegen.dev.path}" />
    <copy file="${project.root}/doxygen/doxygen-awesome.css" todir="${build}" overwrite="true"/>
    <copy file="${project.root}/doxygen/Doxyfile.javaall.in"
        tofile="${build}/Doxyfile.javaall"
        overwrite="true">
        <filterset>
            <filter token="BUILD_DIR" value="${build.abs-path}"/>
            <filter token="CURRENT_SOURCE_DIR" value="${project.root.abs-path}"/>
            <filter token="GLUEGEN_VERSION_LONG" value="${jogamp.version}"/>
            <filter token="GLUEGEN_DOCS_DIR" value="${doxygen.gluegen.dev.path}"/>
        </filterset>
    </copy>
    <exec dir="${build}" executable="doxygen"
         vmlauncher="false"
         failonerror="false">
        <arg line="Doxyfile.javaall"/>
    </exec>
  </target>

  <target name="doxygen.zip" depends="init">
    <archive.7z destfile="${build}/javadoc.7z"
         basedir="${doxygen.root.path}"
         includes="gluegen/**" />
  </target>


  <target name="javadoc" depends="init">
    <!-- Build the general public Javadoc in the target folder hierarchy javadoc/gluegen/javadoc -->
    <delete dir="${javadoc.gluegen.path}" includeEmptyDirs="true" quiet="true" failonerror="false" />
    <mkdir dir="${javadoc.gluegen.path}" />
    <javadoc packagenames="com.jogamp.*"
             sourcepath="${src.java};${src.jcpp};${src.generated.java}"
             destdir="${javadoc.gluegen.path}" windowtitle="GlueGen Runtime Documentation"
             overview="../src/java/com/jogamp/gluegen/package.html"
             encoding="UTF-8"
             source="${target.sourcelevel}"
             maxmemory="${javac.memorymax}"
             stylesheetfile="doc/javadoc/stylesheet.css">
        <classpath refid="javadoc_gluegen.classpath" />
        <link offline="true" href="${javadoc.link}" packagelistLoc="142-packages" />
        <arg value="--frames"/>
        <arg value="${javadoc.xarg1}"/>
        <arg value="-html5"/>
        <arg value="--show-packages=all"/>
    </javadoc>
    <copy todir="${javadoc.gluegen.path}/resources" overwrite="true">
        <fileset dir="doc/javadoc/resources" includes="*" />
    </copy>
    <archive.7z destfile="${build}/javadoc.7z"
                basedir="${javadoc.root.path}"
                includes="gluegen/**" />
  </target>

    <!-- ================================================================== -->
    <!--
       - Build the per-platform binary zip archive for developers.
       - This must be called after all of the build targets complete.
      -->

    <target name="developer-src-zip" depends="init">
        <!--delete includeEmptyDirs="true" quiet="true" failonerror="false">
            <fileset dir="${build}" includes="gluegen-java-src.zip" />
        </delete-->
        <zip destfile="${build}/gluegen-java-src.zip" level="0">
            <fileset dir="${src.java}"/>
            <fileset dir="${build}/gensrc/java"/>
            <fileset dir="${src.jcpp}"/>
        </zip>
    </target>

    <target name="developer-zip-archive" depends="init,developer-src-zip" if="build.archiveon">
        <delete includeEmptyDirs="true" quiet="true" dir="${archive}" failonerror="false" />
        <mkdir dir="${archive}" />
        <copy todir="${archive}">
            <fileset dir=".."       includes="LICENSE.txt"/>
            <fileset dir="${build}" includes="artifact.properties"/>
        </copy>
        <mkdir dir="${archive}/jar" />
        <copy todir="${archive}/jar">
            <fileset dir="${build}" includes="gluegen*.jar"/>
            <fileset dir="${build}" includes="*.apk"/>
            <fileset dir="${build}" includes="gluegen-java-src.zip"/>
        </copy>
        <mkdir dir="${archive}/lib" />
        <copy todir="${archive}/lib">
            <fileset dir="${build}/obj" includes="*${native.library.suffix}"/>
        </copy>
        <mkdir dir="${archive}/jnlp-files" />
        <copy todir="${archive}/jnlp-files">
            <fileset dir="${project.root}/jnlp-files" includes="*" />
        </copy>
        <mkdir dir="${archive}/dist" />
        <copy todir="${archive}/dist">
            <fileset dir="${build}" includes="jogamp-fat.mf"/>
            <fileset dir="${build}" includes="jogamp-fat-test.mf"/>
            <fileset dir="lib" includes="junit.jar"/>
        </copy>

        <archive.7z destfile="${build}/${archive.name}.7z"
             basedir="${build}"
             includes="${archive.name}/**" />
        <!-- Clean up after ourselves -->
        <delete includeEmptyDirs="true" quiet="true" dir="${archive}" failonerror="false" />
    </target>

        <!-- Put  the files created by target gluegen.build from
         build directory to maven repository, local or remote
         (targets maven.install and maven.deploy.snapshot respectively)-->

    <import file="maven-common.xml" />

    <target name="maven.prepare.pom">
        <copy file="pom-template.xml" tofile="${build}/pom-${artifactId}.xml" overwrite="true">
            <filterset>
                <filter token="ARTIFACTID" value="${artifactId}"/>
                <filter token="VERSION" value="${maven.artifacts.version}"/>
                <filter token="DESCRIPTION" value="${description}"/>
                <filter token="DEPENDENCIES" value=""/>
            </filterset>
        </copy>
    </target>

    <target name="maven.prepare.native.pom">
        <loadfile srcfile="pom-rt-dependency.xml" property="maven.dependencies.section"/>
        <copy file="pom-template.xml" tofile="${build}/pom-${artifactId}-${os.and.arch}.xml" overwrite="true">
            <filterchain description="Put in the dependencies section, then replace tokens">
                <replacetokens>
                    <token key="DEPENDENCIES" value="${maven.dependencies.section}"/>
                </replacetokens>
                <replacetokens>
                    <token key="ARTIFACTID" value="${artifactId}"/>
                    <token key="VERSION" value="${maven.artifacts.version}"/>
                    <token key="DESCRIPTION" value="${description}"/>
                </replacetokens>
            </filterchain>
        </copy>
    </target>

    <target name="maven.install.artifact">
        <antcall target="maven.prepare.pom" inheritall="true"/>
        <exec executable="mvn" dir="${build}">
            <arg value="install:install-file"/>
            <arg value="-Dfile=${artifactId}.jar"/>
            <arg value="-DpomFile=pom-${artifactId}.xml"/>
            <arg value="-DcreateChecksum=true"/>
        </exec>
    </target>


    <target name="maven.install.native.artifact">
        <antcall target="maven.prepare.native.pom" inheritall="true"/>
        <exec executable="mvn" dir="${build}">
            <arg value="install:install-file"/>
            <arg value="-Dfile=${artifactId}-${os.and.arch}.jar"/>
            <arg value="-DpomFile=pom-${artifactId}-${os.and.arch}.xml"/>
            <arg value="-DcreateChecksum=true"/>
            <arg value="-Dclassifier=${os.and.arch}"/>
        </exec>
    </target>

    <target name="maven.deploy.artifact">
        <antcall target="maven.prepare.pom" inheritall="true"/>
        <exec executable="mvn" dir="${build}">
            <arg value="deploy:deploy-file"/>
            <arg value="-DrepositoryId=sonatype-nexus-snapshots"/>
            <arg value="-Durl=https://oss.sonatype.org/content/repositories/snapshots/"/>

            <arg value="-Dfile=${artifactId}.jar"/>
            <arg value="-DpomFile=pom-${artifactId}.xml"/>
            <arg value="-DcreateChecksum=true"/>
        </exec>
    </target>

    <target name="maven.deploy.native.artifact">
        <antcall target="maven.prepare.native.pom" inheritall="true"/>
        <exec executable="mvn" dir="${build}">
            <arg value="deploy:deploy-file"/>
            <arg value="-DrepositoryId=sonatype-nexus-snapshots"/>
            <arg value="-Durl=https://oss.sonatype.org/content/repositories/snapshots/"/>

            <arg value="-Dfile=${artifactId}-${os.and.arch}.jar"/>
            <arg value="-DpomFile=pom-${artifactId}-${os.and.arch}.xml"/>
            <arg value="-DcreateChecksum=true"/>
            <arg value="-Dclassifier=${os.and.arch}"/>
        </exec>
    </target>

    <target name="maven.antcalls">
        <antcall target="maven.${mvn.task}.artifact" inheritall="true">
            <param name="artifactId" value="gluegen"/>
            <param name="description" value="GlueGen - JNI Glue Code Generator"/>
        </antcall>
        <antcall target="maven.${mvn.task}.artifact" inheritall="true">
            <param name="artifactId" value="gluegen-rt"/>
            <param name="description" value="GlueGen runtime"/>
        </antcall>
        <antcall target="maven.${mvn.task}.native.artifact" inheritall="true">
            <param name="artifactId" value="gluegen-rt-natives"/>
            <param name="description" value="GlueGen runtime native libraries for ${os.and.arch}"/>
        </antcall>
    </target>

    <target name="maven.install" depends="init, base.compile, tag.build">
        <property name="maven.artifacts.version" value="${jogamp.version.base}"/>
        <antcall target="maven.antcalls" inheritall="true">
            <param name="mvn.task" value="install"/>
        </antcall>
    </target>

    <target name="maven.deploy.snapshot" depends="init, base.compile, tag.build">
        <property name="maven.artifacts.version" value="${jogamp.version.base}-SNAPSHOT"/>
        <antcall target="maven.antcalls" inheritall="true">
            <param name="mvn.task" value="deploy"/>
        </antcall>
    </target>

</project>
