<section id='ocaml'>
  <title>OCaml Packages</title>
  <abstract>
    <para>
      This section describes how to prepare packages which contain
      applications written in OCaml, OCaml modules and OCaml language
      itself.
    </para>
  </abstract>
  <section id='ocaml.name'>
    <title>Naming conventions</title>
    <para>
      OCaml libraries should have names prefixed with 
      <literal>ocaml-</literal> (examples: <literal>ocaml-camlp4</literal>,
      <literal>ocaml-odbc</literal>).  Similarly tools that are only usable
      during OCaml development (like <literal>ocaml-otags</literal> or
      <literal>ocaml-mlglade</literal>) also should be prefixed with
      <literal>ocaml-</literal>.
    </para>
    <para>
      However programs, that have same general use outside OCaml 
      development shouldn't. For example there is <literal>hevea</literal>
      package, not <literal>ocaml-hevea</literal>.
    </para>
    <para>
      Rationale: it should be easy to identify tools usable during
      ocaml development just by looking at their name. Also we don't want
      to clutter global package namespace (think about 
      <literal>postgres</literal> package).  However information
      that hevea is written in ocaml is of little importance to the
      end user.
    </para>
    <para>
      Package name should be all in lowercase. There is no 
      <literal>HeVeA</literal> or any other <literal>WEirD-StUFF</literal>.
      Same goes for directory it is installed in. For example for
      <literal>ocaml-lablgl</literal> it is 
      <literal>%{_libdir}/lablgl</literal>, not 
      <literal>%{_libdir}/lablGL</literal>. Also findlib package names
      should be all in lowercase.
    </para>
    <para>
      Rationale: it is hard to remember capitalization of name, when it
      needs to be used in compiler flags.
    </para>
  </section>
  <section id='ocaml.dist'>
    <title>What is distributed?</title>
    <para>
      When you create package with OCaml module, following files should
      be included in package:
      <itemizedlist> 
        <listitem>
          <para>
            All <filename>*.cmi</filename> files.
          </para>
        </listitem>
        <listitem>
          <para>
            All <filename>*.cmx</filename> files. They contain small
            inline functions and therefore are needed during compilation.
          </para>
        </listitem>
        <listitem>
          <para>
            <filename>*.cma</filename> and <filename>*.cmxa</filename>
            archives. They are often called <filename>foo.cma</filename>
            and <filename>foo.cmxa</filename>
          </para>
        </listitem>
        <listitem>
          <para>
            <filename>*.a</filename> archives for corresponding 
            <filename>*.cmxa</filename> (<filename>foo.a</filename> for
            <filename>foo.cmxa</filename>).
          </para>
        </listitem>
        <listitem>
          <para>
            <filename>*.a</filename> archives with compiled C parts
            of library (this is often <filename>libfoo.a</filename>).
          </para>
        </listitem>
        <listitem>
          <para>
            <filename>dll*.so</filename> dynamic link library for
            runtime system (<filename>dllfoo.so</filename>). If package
            contains parts written in C and doesn't produce
            <filename>dll*.so</filename>, you should fix it. See
            <filename>ocaml-odbc.spec</filename> for an example.
          </para>
        </listitem>
        <listitem>
          <para>
            Any examples. They are often very helpful. If there is just one,
            or two files, you can gzip them and put as 
            <literal>%doc</literal>. Otherwise copy them to 
            <literal>%{_examplesdir}</literal>.
          </para>
        </listitem>
      </itemizedlist>
    </para>
    <para>
      Following files should NOT be distributed:
      <itemizedlist> 
        <listitem>
          <para>
            <filename>*.cmo</filename> object files. There is however
            one exception -- if file is needed for link (like 
            <filename>gtkInit.cmo</filename> in lablgtk or 
            <filename>std_exit.cmo</filename> in OCaml itself),
            then it should be of course included.
          </para>
        </listitem>
        <listitem>
          <para>
            <filename>*.o</filename> for corresponding 
            <filename>*.cmx</filename>. They are included in 
            <filename>*.a</filename> anyway. Exception -- as above.
          </para>
        </listitem>
        <listitem>
          <para>
            <filename>*.ml</filename> sources.
          </para>
        </listitem>
        <listitem>
          <para>
            <filename>*.mli</filename> interface sources. However, if
            package lacks any documentation (which is unfortunately often
            the case), you can include <filename>*.mli</filename>, but
            it should be gziped and placed in package as 
            <literal>%doc</literal>.
          </para>
        </listitem>
      </itemizedlist> 
    </para>
  </section>
  <section id='ocaml.lang'>
    <title>OCaml Language</title>
    <para>
      Package with OCaml itself is split into several subpackages:
      <variablelist>
        <varlistentry>
          <term>ocaml-runtime</term>
          <listitem>
            <para>
              <filename>ocamlrun</filename> and base 
              <filename>dll*.so</filename>.
            </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>ocaml</term>
          <listitem>
            <para>
              Bytecode and native compilers, standard library,
              debugger and other tools.
            </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>ocaml-camlp4</term>
          <listitem>
            <para>
              Pre Processor Pretty Printer. Provides: 
              <literal>camlp4</literal>.
            </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>ocaml-x11graphics</term>
          <listitem>
            <para>
              Just <filename>dllgraphics.so</filename>. Not in
              <literal>ocaml-runtime</literal> since it requires
              <literal>XFree86-libs</literal> to run.
            </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>ocaml-x11graphics-devel</term>
          <listitem>
            <para>
              Development parts of <literal>Graphics</literal>
              module. Similar split holds for 
             <literal>ocaml-labltk</literal> and 
             <literal>ocaml-labltk-devel</literal> subpackages.
            </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>ocaml-devel</term>
          <listitem>
            <para>
              <filename>*.cm[iox]</filename> files resulting
              from compilation of OCaml compiler itself. It is needed
              by some programs.
            </para>
          </listitem>
        </varlistentry>
      </variablelist>
    </para>
    <para>
      Standard OCaml library path is <filename>%{_libdir}/ocaml</filename>.
      <filename>%{_libdir}/ocaml/ld.conf</filename> contains just this
      directory (see below for details). 
    </para>
    <para>
      OCaml C includes are placed in <filename>%{_includedir}/caml</filename>,
      but compatibility symlink <filename>%{_libdir}/ocaml/caml</filename>
      is provided.
    </para>
    <para>
      <command>ocamlc</command> and <command>ocamlcopt</command> are symlinked
      to <command>ocamlc.opt</command> and <command>ocamlcopt.opt</command>
      respectively. However <command>ocamlc.byte</command> and 
      <command>ocamlcopt.byte</command> are also provided in case there
      are some problems with .opt compilers.
    </para>
  </section>
  <section id='ocaml.modules'>
    <title>OCaml Modules</title>
    <para>
      If package has <filename>dll*.so</filename> stuff, it should be split
      into two parts -- base package with just <filename>dll*.so</filename>
      and <literal>-devel</literal> subpackage with rest. If there is
      no <filename>dll*.so</filename> we produce just 
      <literal>-devel</literal> subpackage. For example is library
      <literal>foo</literal> is written all in OCaml, so there is no
      <filename>dll*.so</filename>, you should make 
      <filename>ocaml-foo.spec</filename> with no <literal>%files</literal>
      section for main package, just for <literal>ocaml-foo-devel</literal>.
    </para>
    <para>
      While having just <literal>-devel</literal> might seem odd, but:
      <itemizedlist>
        <listitem>
          <para>
            It is consistent.
          </para>
        </listitem>
        <listitem>
          <para>
            If OCaml will ever support dynamic loading (of either bytecode
            libraries or native code libraries (this can be done even
            now, but needs to be further investigated)), we won't have to
            change package names.
          </para>
        </listitem>
      </itemizedlist>
    </para>
    <para>
      Package named <literal>foo</literal> should be installed in
      <filename>%{_libdir}/ocaml/foo</filename>. Also 
      <filename>dll*.so</filename> should go there, but there should be
      symlinks to them in <filename>%{_libdir}/ocaml</filename>.
      Therefore there is no need to modify 
      <filename>%{_libdir}/ocaml/ld.conf</filename>.
    </para>
    <para>
      <filename>%{_libdir}/ocaml/foo</filename> should be owned by
      <literal>ocaml-foo</literal>, not by <literal>ocaml-foo-devel</literal>.
    </para>
    <para>
      Base package should use rpm macro 
      <literal>%require_eq ocaml-runtime</literal>, while -devel package
      <literal>%require_eq ocaml</literal>, so they won't be installed with
      possibly incompatible OCaml version.
    </para>
  </section>
  <section id='ocaml.findlib'>
    <title>findlib</title>
    <para>
      findlib is package management tool for OCaml libraries. Information
      about packages is stored in <filename>META</filename> files.
      <!-- need more... -->
    </para>
    <para>
      Even if package use findlib to install itself, it should be placed
      in <filename>%{_libdir}/ocaml/foo</filename>, not in
      <filename>%{_libdir}/ocaml/site-lib/foo</filename> (this is to be
      consistent with packages not using findlib). However 
      <filename>META</filename> file should be installed in 
      <filename>%{_libdir}/ocaml/site-lib/foo/META</filename>.
    </para>
    <para>
      If there is no <filename>META</filename> file for package, you
      should consider creating one.
    </para>
  </section>
  <section id='ocaml.flags'>
    <title>Flags for compilation</title>
    <para>
      <filename>.c</filename> files should be compiled with 
      <filename>%{__cc}</filename> (not <command>gcc</command>, 
      <command>cc</command> nor <command>ocamlc</command>).
      During compilation standard <literal>%{rpmcflags}</literal>
      should be used (this is the same as with other packages in PLD).
    </para>
    <para>
      <filename>.ml</filename> should not be compiled with 
      <option>-g</option> <command>ocamlc</command> option. If bundled
      <filename>Makefile</filename> does so, you should fix it.
    </para>
  </section>
  <section id='ocaml.toplevel'>
    <title>Toplevel systems</title>
    <para>
      As OCaml can now handle dynamic loading interactive systems are
      not of much use (one can always do <literal>#load 
      "foobar.cma"</literal>). However if you feel interactive system
      linked with some library might be needed, separate it into
      <literal>-toplevel</literal> subpackage.
    </para>
  </section>
</section>
