<?xml version="1.0" encoding="UTF-8"?>

<!-- JOCL's main build file-->
<project name="JOCL" default="default" basedir=".">

    <description>Builds, tests, and runs the project JOCL.</description>

    <import file="nbproject/build-impl.xml"/>

    <property name="gluegen.root" value="${basedir}/../gluegen" />
    <property name="jogl.root" value="${basedir}/../jogl" />

    <property name="etc.build.dir" value="${basedir}/etc/build" />
    <property name="headers.dest" value="${basedir}/resources/includes/CL" />

    <!-- Pull in GlueGen cpptasks build file -->
    <import file="${gluegen.root}/make/gluegen-cpptasks.xml" />

    <target name="-pre-compile" depends="prepare-build,preprocess-headers">

        <path id="gluegen.classpath">
            <pathelement location="${file.reference.gluegen.jar}" />
            <pathelement location="${antlr.jar}" />
        </path>

        <taskdef name="gluegen" classname="com.sun.gluegen.ant.GlueGenTask" classpathref="gluegen.classpath" />

        <!--OpenCL Impl including OpenGL interoperability-->
        <dirset id="jocl.include.path" dir="${basedir}">
            <include name="resources/includes"/>
            <include name="resources/stubs_includes/jvm"/>
            <include name="resources/stubs_includes/gl"/>
            <include name="resources/stubs_includes/common"/>
        </dirset>

        <echo message=" - - - generate JOCL binding files - - - "/>

        <echo message="generate CL interface..."/>
        <gluegen src="resources/opencl.h"
                 config="resources/cl-if.cfg"
                 includeRefid="jocl.include.path"
                 emitter="com.sun.gluegen.JavaEmitter">
            <classpath refid="gluegen.classpath" />
        </gluegen>

        <echo message="generate CLGLI interface..."/>
        <gluegen src="resources/opencl.h"
                 config="resources/clgl-if.cfg"
                 includeRefid="jocl.include.path"
                 emitter="com.sun.gluegen.JavaEmitter">
            <classpath refid="gluegen.classpath" />
        </gluegen>

        <echo message="generate GLImpl..."/>
        <gluegen src="resources/opencl.h"
                 config="resources/cl-impl.cfg"
                 includeRefid="jocl.include.path"
                 emitter="com.sun.gluegen.JavaEmitter">
            <classpath refid="gluegen.classpath" />
        </gluegen>
        <echo message=" - - - JOCL binding files generated - - - "/>

    </target>

    <target name="prepare-build" depends="gluegen.properties.load.user">

        <property name="headers.orig" value="${basedir}/resources/includes/CL_orig" />

        <!--compile build utilities-->
        <mkdir dir="${etc.build.dir}"/>

        <javac destdir="${etc.build.dir}" classpath="${ant.core.lib}" source="1.5" debug="true" debuglevel="lines,vars,source">
            <src path="${basedir}/etc/src"/>
        </javac>

        <taskdef name="update-headers"            classname="com.mbien.ant.HeaderFileDownloader"     classpath="${etc.build.dir}"/>
        <taskdef name="uncomment-function-params" classname="com.mbien.ant.FunctionParamUncommenter" classpath="${etc.build.dir}"/>

    </target>

    <target name="-post-compile" depends="c.compile.default" />

    <target name="c.compile.default" depends="gluegen.cpptasks.detect.os, gluegen.cpptasks.detect.compiler, jocl.c.compile, c.rename.lib.mingw" />

    <target name="jocl.c.compile" depends="c.setup.build">

        <echo message=" - - - compiling JOCL natives - - - "/>
        <echo message="${compiler.cfg.id}"/>
        <echo message="${linker.cfg.id}"/>

        <mkdir dir="${obj.jocl.dir}/${namespace}" />
        <mkdir dir="${natives.jocl.dir}/${namespace}" />

        <cc outtype="shared"
            objdir="${obj.jocl.dir}/${namespace}"
            outfile="${natives.jocl.dir}/${namespace}/${output.lib.name}"
            optimize="${c.compiler.optimise}"
            debug="${c.compiler.debug}"
            multithreaded="true"
            exceptions="false"
            rtti="false">

            <fileset dir="gensrc/native" includes="*.c"/>

            <compiler extends="${compiler.cfg.id}" >

                <includepath path="${java.includes.dir}"/>
                <includepath path="${java.includes.dir.platform}"/>

                <!-- TODO should we use our own or jogl's GL headers?  -->
                <includepath path="${basedir}/resources/includes"/>
            <!--
                <includepath path="${jogl.root}/make/stub_includes/opengl/GL3"/>
                <includepath path="${jogl.root}/make/stub_includes/opengl"/>
            -->

            </compiler>

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

        </cc>

        <echo message=" - - - JOCL natives compiled - - - "/>

    </target>

    <target name="c.setup.build" depends="gluegen.cpptasks.configure.compiler, gluegen.cpptasks.declare.compiler, c.configure.default, jocl.configure.linker">

        <property name="obj.dir" value="${build.dir}/obj"/>
        <property name="natives.dir" value="${build.dir}/natives"/>

        <property name="output.lib.name" value="jocl"/>
        <property name="obj.jocl.dir" value="${obj.dir}/${output.lib.name}"/>
        <property name="natives.jocl.dir" value="${build.dir}/natives/${output.lib.name}"/>

        <property name="c.compiler.optimise" value="none"/>
        <property name="c.compiler.debug" value="false"/>
        <property name="namespace" value=""/>

    </target>

    <!-- linker configuration -->
    <target name="jocl.configure.linker">
        
        <linker id="linker.cfg.linux.jocl" extends="linker.cfg.linux">
            <syslibset dir="/usr/lib" libs="OpenCL"/>
        </linker>

        <linker id="linker.cfg.linux.amd64.jocl" extends="linker.cfg.linux.amd64" >
            <syslibset dir="/usr/lib" libs="OpenCL"/>
        </linker>

        <linker id="linker.cfg.win32.mingw.jocl" extends="linker.cfg.win32.mingw">
            <linkerarg value="-Wl,--kill-at" /> <!-- remove @ from function names -->
            <syslibset dir="C:/NVIDIAComputingSDK/OpenCL/common/lib/Win32" libs="OpenCL"/>
        </linker>

        <linker id="linker.cfg.macosx.jocl" extends="linker.cfg.macosx">
            <linkerarg value="-framework" />
            <linkerarg value="OpenCL" />
        </linker>

    </target>

    <!-- configure for current platform -->
    <target name="c.configure.default" depends="c.configure.os" />
    <target name="c.configure.os"      depends="c.configure.win, c.configure.linux, c.configure.macosx" />
    <target name="c.configure.win"     depends="c.configure.win.mingw"                          if="isWindows" />
    <target name="c.configure.linux"   depends="c.configure.linux.x86, c.configure.linux.amd64" if="isLinux" />

    <target name="c.configure.win.mingw" if="isMingW">
        <echo message="Win.MingW" />
        <property name="compiler.cfg.id"  value="${compiler.cfg.id.base}" />
        <property name="linker.cfg.id"    value="linker.cfg.win32.mingw.jocl" />
    </target>
    <target name="c.configure.linux.x86" if="isLinuxX86">
        <echo message="Linux.x86" />
        <property name="compiler.cfg.id"  value="${compiler.cfg.id.base}" />
        <property name="linker.cfg.id"    value="linker.cfg.linux.jocl" />
    </target>
    <target name="c.configure.linux.amd64" if="isLinuxAMD64">
        <echo message="Linux.AMD64" />
        <property name="compiler.cfg.id"  value="${compiler.cfg.id.base}" />
        <property name="linker.cfg.id"    value="linker.cfg.linux.amd64.jocl" />
    </target>
    <target name="c.configure.macosx"      if="isOSX">
        <echo message="MacOS" />
        <property name="compiler.cfg.id"  value="${compiler.cfg.id.base}" />
        <property name="linker.cfg.id"    value="linker.cfg.macosx.jocl" />
    </target>

    <target name="-post-clean">
        <delete dir="gensrc"/>
        <delete dir="${etc.build.dir}"/>
        <delete dir="${headers.dest}"/>
    </target>

    <target name="update-headers" depends="prepare-build">

        <property name="registry.url" value="http://www.khronos.org/registry/cl/api/1.0/"/>

        <!-- download new headers from OpenCL registry if necessary -->
        <update-headers header="${headers.orig}/cl.h" url="${registry.url}cl.h"/>
        <update-headers header="${headers.orig}/cl_gl.h" url="${registry.url}cl_gl.h"/>
        <update-headers header="${headers.orig}/cl_platform.h" url="${registry.url}cl_platform.h"/>

    </target>

    <target name="preprocess-headers" depends="prepare-build">

        <mkdir dir="${headers.dest}"/>

        <!--uncomment function names in c headers and copy modified files into include path-->
        <uncomment-function-params src="${headers.orig}/cl.h" dest="${headers.dest}/cl.h"/>
        <uncomment-function-params src="${headers.orig}/cl_gl.h" dest="${headers.dest}/cl_gl.h"/>

        <!--nothing to uncomment in this headers-->
        <copy file="${headers.orig}/cl_platform.h" toDir="${headers.dest}" overwrite="true"/>
        <copy file="${headers.orig}/cl_ext.h" toDir="${headers.dest}" overwrite="true"/>

    </target>

    <!--cut and paste from gluegen -->
    <target name="c.rename.lib.mingw" if="isMingW">
      <!-- FIXME: this is a hack; the cpptask should have an option to change the
           suffix or at least understand the override from .so to .dll -->
      <move file="${natives.jocl.dir}/${namespace}/libjocl.so" tofile="${natives.jocl.dir}/${namespace}/jocl.dll" />
    </target>

    <target name="-javadoc-build" depends="init">

        <mkdir dir="${dist.javadoc.dir}"/>

        <javadoc author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}"
            docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true"
            noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}"
            private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}"
            use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}"
            windowtitle="${javadoc.windowtitle}">

            <arg line="${javadoc.additionalparam} -J-Dnativetaglet.mapping=${basedir}/resources/native-taglet.properties"/>
            <taglet name="net.highteq.nativetaglet.NativeTaglet" path="${gluegen.root}/build/gluegen.jar:/home/mbien/NetBeansProjects/JOGL/jocl/"/>

            <classpath>
                <pathelement path="${javac.classpath}"/>
            </classpath>
            
            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
                <filename name="**/*.java"/>
            </fileset>
            <fileset dir="${src.java.dir}" excludes="${excludes}" includes="${includes}">
                <filename name="**/*.java"/>
            </fileset>
            <fileset dir="${src.native.dir}" excludes="${excludes}" includes="${includes}">
                <filename name="**/*.java"/>
            </fileset>
            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
                <include name="**/*.java"/>
            </fileset>
        </javadoc>
    </target>

</project>