<?xml version="1.0"?>
<rss version="2.0">
  <channel>
    <title>Knowledge Base on camlcity.org</title>
    <link>http://knowledge.camlcity.org</link>
    <language>en</language>
    <description>Technical details about O'Caml</description>

    
        <item>
          <title>KB 003: Disable setuid-root on Linux</title>
          <guid>http://www.camlcity.org/knowledge/kb_003_disable_setuid.html</guid>
          <link>http://www.camlcity.org/knowledge/kb_003_disable_setuid.html</link>
          <description>

&#60;div&#62;
  &#60;b&#62;What I learned when programming the GODI autobuilder&#60;/b&#62;&#60;br/&#62;&#38;#160;
&#60;/div&#62;

&#60;div&#62;
  
In Linux books and the usual documentation you can read about two ways
of securing chroot environments: by clearing the setuid-root bits file by
file, or by disabling the setuid mechanism in the mount flags. Actually,
there is a third way since kernel 2.6.26.

&#60;/div&#62;

&#60;div&#62;
  
Recently I secured the sandbox environment running the GODI autobuilder.
It compiles and possibly runs untrusted code coming from the GODI
repository. One open security hole was that this chroot environment
did not systematically disable setuid. As you might know, it is possible
on all Unix OS to set a flag for an executable so that this program runs
as a different user (setuid bit). If this other user is root, the
executable gains system privileges, and this can be potentially abused
to run user code with such privileges. Well, not every setuid program
is a problem, but it might be (generally or in special circumstances),
and it is good practice to turn off all setuid execution in secured
chroot environments.

&#60;p&#62;
My chroot directories are partially bind-mounted, and thus I could not
easily disable setuid in the mount flags. But there is another way:
Just clear the capability bounding set (bset), and you are done.

&#60;/p&#62;&#60;h2&#62;Capabilities&#60;/h2&#62;
&#60;p&#62;
What&#38;#39;s that? Well, the root user gets under Linux its special
privileges because it has &#60;i&#62;capabilities&#60;/i&#62;. Every capability
corresponds to a special right, e.g. root can run &#38;#34;chown&#38;#34; with
arbitrary arguments because it has the CAP_CHOWN bit set. A non-root
user has no capabilities. So our goal is to prevent that root (or any
other user) can get capablities in the secured environment. When an
executable is run setuid-root the kernel just adds the capabilities of
root to the process (besides changing the uid to 0).

&#60;/p&#62;&#60;p&#62;
The trick is now that one can restrict the capabilities a process (and
all its subprocesses) can ever get. There is a mask for capabilities
called the bounding set. This mask controls which capabilities an
executable can additionally get from the setuid bit (or from a
file capability), and by emptying this set, this feature is effectively
turned off. This mask does neither have an effect on the capabilities a
process already has nor on the capabilities the process inherits to
children. It just controls what can be gained by setting file attributes.

&#60;/p&#62;&#60;p&#62;
Unfortunately, there is no command to do this. We need to write a
little C program &#60;code&#62;dropbset.c&#60;/code&#62;:

&#60;/p&#62;&#60;pre&#62;
#include &#38;#60;unistd.h&#38;#62;
#include &#38;#60;stdio.h&#38;#62;
#include &#38;#60;stdlib.h&#38;#62;
#include &#38;#60;sys/prctl.h&#38;#62;
#include &#38;#60;linux/prctl.h&#38;#62;
#include &#38;#60;linux/capability.h&#38;#62;
#include &#38;#60;errno.h&#38;#62;

int main (int argc, char *argv[]) {
        int code;
        unsigned long cap;

        for (cap=0; cap &#38;#60;= 63; cap++) {
                code = prctl(PR_CAPBSET_DROP, cap, 0, 0, 0);
                if (code == -1 &#38;#38;&#38;#38; errno != EINVAL) {
                        perror(&#38;#34;prctl error&#38;#34;);
                        exit(1);
                }
        }

        code = execv(&#38;#34;/bin/bash&#38;#34;, argv);
        if (code == -1) {
                perror(&#38;#34;exec error&#38;#34;);
                exit(1);
        }
        exit(0);   // hmmmm...
}
&#60;/pre&#62;

The program can be simply compiled with

&#60;pre&#62;
gcc -o dropbset dropbset.c
&#60;/pre&#62;

Before running it, we need to ensure it gets the required privileges
to do the PR_CAPBSET_DROP operation. As root, do

&#60;pre&#62;
setcap CAP_SETPCAP=pe dropbset
&#60;/pre&#62;

This command sets a &#60;i&#62;file capability&#60;/i&#62; - a mechanism very much like
the setuid bit, but restricted to a single capability only. Here, we need
CAP_SETPCAP in order to run the operation. If you did not set this
file capability, you could run dropbset only as root. (NB: The file
capability is stored together with the file in the extended attributes.)

&#60;p&#62;
Now let&#38;#39;s try it (remember dropbset just execs bash, and hence is called
in exactly the same way): As non-root do:

&#60;/p&#62;&#60;pre&#62;
./dropbset -c &#38;#34;ping 127.0.0.1&#38;#34;
&#60;/pre&#62;

You get an error &#38;#34;Operation not permitted&#38;#34;. ping is normally
setuid-installed so that unprivileged users get raw access to the
network for pinging.

&#60;p&#62;
Once the bset is empty, there is no way a child process can add any
capability to its effective set because of file attributes. &#60;b&#62;Not even
root can do this:&#60;/b&#62;

&#60;/p&#62;&#60;pre&#62;
# id
uid=0(root) gid=0(root) groups=0(root)
# dropbset -c &#38;#39;ping 127.0.0.1&#38;#39;
ping: icmp open socket: Operation not permitted
&#60;/pre&#62;


&#60;/div&#62;

&#60;div&#62;
  Gerd Stolpmann works as O&#38;#39;Caml consultant

&#60;/div&#62;

&#60;div&#62;
  
&#60;/div&#62;


          </description>
        </item>
      
        <item>
          <title>KB 002: OCaml Programs As Shared Libraries</title>
          <guid>http://www.camlcity.org/knowledge/kb_002_shared_library.html</guid>
          <link>http://www.camlcity.org/knowledge/kb_002_shared_library.html</link>
          <description>

&#60;div&#62;
  &#60;b&#62;Compile programs into .so files&#60;/b&#62;&#60;br/&#62;&#38;#160;
&#60;/div&#62;

&#60;div&#62;
  
Since quite some time the OCaml code generator supports the creation of
position-independent code (PIC). This is e.g. required to load OCaml modules
dynamically. Another use is to output OCaml programs as shared libraries.

&#60;/div&#62;

&#60;div&#62;
  
&#60;p&#62;
Let&#38;#39;s assume we have this little program:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
prog.ml:
    print_endline &#38;#34;Hello World, OCaml&#38;#34;;;
&#60;/pre&#62;

The main program in C:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
main.c:
    #include &#60;stddef.h&#62;
    #include &#60;stdio.h&#62;
    #include &#60;caml&#62;
    int main(int argc, char *argv[]) {
        printf(&#38;#34;Hello World, C\n&#38;#34;);
        caml_startup(argv);
        return 0;
    }
&#60;/caml&#62;&#60;/stdio.h&#62;&#60;/stddef.h&#62;&#60;/pre&#62;

The idea here is that the main program is written in C, and initializes
from there the OCaml program.

&#60;p&#62;The following applies to OCaml-3.11 and higher.

&#60;/p&#62;&#60;h2&#62;Statically-linked version as documented in the manual&#60;/h2&#62;

Let&#38;#39;s first look at what you can also find in the manual:

&#60;p&#62;Here, we create a single prog_impl.o file from prog.ml, and this object
contains the whole code of the OCaml program, but omits the OCaml runtime:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
$ ocamlopt -c prog.ml
$ ocamlopt -output-obj -o prog_impl.o prog.cmx
&#60;/pre&#62;

For compiling the C program we use &#60;code&#62;ocamlc&#60;/code&#62; as driver
because it adds all required options when invoking the C compiler
(alternatively you can grab the options from &#38;#34;ocamlc -config&#38;#34;,
variable &#60;code&#62;native_c_compiler&#60;/code&#62;):

&#60;pre style=&#34;font-size:smaller&#34;&#62;
$ ocamlc -c main.c
&#60;/pre&#62;

Linking everything together:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
$ cc -o main main.o prog_impl.o -L`ocamlc -where` -lasmrun -lm -ldl
&#60;/pre&#62;

&#60;code&#62;libasmrun.a&#60;/code&#62; is available in the OCaml standard library
directory, and we have to add this directory to the search path with
&#60;code&#62;-L`ocamlc -where`&#60;/code&#62;.

&#60;p&#62;&#60;b&#62;Creating libprog.a:&#60;/b&#62; A possible simplification
for the user is to put the whole OCaml code, including the runtime,
into a static archive:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
$ rm -rf libprog.a
$ ar rc libprog.a prog_impl.o
$ asmrun_members=$(ar t `ocamlc -where`/libasmrun.a | grep -v &#38;#39;__.*&#38;#39;)
$ mkdir -p tmp_asmrun
$ ( cd tmp_asmrun &#38;#38;&#38;#38; ar x `ocamlc -where`/libasmrun.a )
$ for mem in $asmrun_members; do ar rc libprog.a tmp_asmrun/$mem; done
$ ranlib libprog.a
$ rm -rf tmp_asmrun
&#60;/pre&#62;

The link command is then:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
$ cc -o main main.o -L. -lprog -lm -ldl
&#60;/pre&#62;

Note that we need to add the contents of libasmrun.a to libprog.a. If we
do not do this, and try to add -lasmrun instead, we run into a problem
with circular references between static libraries (which is not supported
by the linker).

&#60;p&#62;From where did we get &#38;#34;-lm -ldl&#38;#34;? If you want to be 100% correct, take
this list from the variable &#60;code&#62;native_c_libraries&#60;/code&#62; printed
by &#38;#34;ocamlc -config&#38;#34;.


&#60;/p&#62;&#60;h2&#62;Dynamically-linked version&#60;/h2&#62;

Unfortunately, this depends on your platform/CPU:

&#60;ul&#62;
  &#60;li&#62;x86-32: A standard OCaml installation works. There is a downside,
though: OCaml cannot create PIC for x86-32. This is not a blocker on
x86-32, because the dynamic loader of the OS can relocate on the fly.
Nevertheless, there is a price to pay, namely that the text segment cannot
be put into sharable memory, i.e. the RAM consumption is higher.
  &#60;/li&#62;&#60;li&#62;x86-64: You need to build OCaml so that libasmrun.a is compiled
as PIC - see below how to do it. Code produced by ocamlopt is normally
PIC anyway unless you give -fno-PIC on the command-line. Just don&#38;#39;t do
this, and the generated code will be right.
  &#60;/li&#62;&#60;li&#62;ARM (since OCaml-4.00): Basically it can be made working, but
there is a difficulty: The code generator for ARM disables PIC by
default. Especially the standard library is not PIC, and any other
3rd-party code isn&#38;#39;t, too. The simplest way to fix this is to change
the file &#60;code&#62;asmcomp/arm/arch.ml&#60;/code&#62; in the OCaml sources so that
the variable &#60;code&#62;pic_code&#60;/code&#62; is initialized with &#60;code&#62;true&#60;/code&#62;.
In addition to this, you need to compile libasmrun.a with PIC as for
x86-64.
  &#60;/li&#62;&#60;li&#62;Other CPU&#38;#39;s are not supported.&#60;/li&#62;
&#60;/ul&#62;

&#60;p&#62;
&#60;b&#62;How to enable PIC for libasmrun.a:&#60;/b&#62; When building OCaml, you need
to configure it so that PIC is enabled:

&#60;/p&#62;&#60;ul&#62;
  &#60;li&#62;Linux (and probably other platforms using the GNU toolchain):
&#60;pre style=&#34;font-size:smaller&#34;&#62;
 ./configure -cc &#38;#34;gcc -fPIC&#38;#34; -aspp &#38;#34;gcc -c -fPIC&#38;#34;
&#60;/pre&#62;
  &#60;/li&#62;&#60;li&#62;MacOS X: same
  &#60;/li&#62;&#60;li&#62;Other platforms: Unknown
&#60;/li&#62;&#60;/ul&#62;

If you are using GODI, you can add configure options in godi.conf:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCAML_CONF_ARGS=-cc &#38;#34;gcc -fPIC&#38;#34; -aspp &#38;#34;gcc -c -fPIC&#38;#34;
&#60;/pre&#62;

Note that you need to rebuild both godi-ocaml-src and godi-ocaml.

&#60;p&#62;
&#60;b&#62;How to create libasmrun.so:&#60;/b&#62; Now do

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
$ ocamlopt -output-obj -o libprog.so prog.cmx
$ cc -o main main.o -Wl,-rpath,. -L. -lprog
&#60;/pre&#62;

Test it (Linux - on OS X use &#38;#34;otool -L&#38;#34;):

&#60;pre style=&#34;font-size:smaller&#34;&#62;
$ ldd ./main
&#60;/pre&#62;

This should print libprog.so as dependent library.

&#60;p&#62;Note that it is not necessary in this case to add &#38;#34;-lm -ldl&#38;#34; to the
link command, as this has already been recorded in libprog.so.
&#60;/p&#62;
&#60;/div&#62;

&#60;div&#62;
  Gerd Stolpmann works as O&#38;#39;Caml consultant

&#60;/div&#62;

&#60;div&#62;
  
&#60;/div&#62;


          </description>
        </item>
      
        <item>
          <title>KB 001: OMake Recipes</title>
          <guid>http://www.camlcity.org/knowledge/kb_001_omake_recipes.html</guid>
          <link>http://www.camlcity.org/knowledge/kb_001_omake_recipes.html</link>
          <description>

&#60;div&#62;
  &#60;b&#62;How to use the OMake build utility best&#60;/b&#62;&#60;br/&#62;&#38;#160;
&#60;/div&#62;

&#60;div&#62;
  
The &#60;a href=&#34;http://omake.metaprl.org&#34;&#62;OMake utility&#60;/a&#62; is easy to use
for simple projects: After &#38;#34;omake --install&#38;#34; it drops a template OMakefile
into the current directory, and you simply need to fill it out to get
started. But what if you need more than what is provided in the template?
Here, I&#38;#39;ve collected a number of recipes for advanced configurations.

&#60;/div&#62;

&#60;div&#62;
  
&#60;p&#62;
&#60;b&#62;Available recipes:&#60;/b&#62;
&#60;/p&#62;&#60;ul&#62;
  &#60;li&#62;&#60;a href=&#34;#multi-programs&#34;&#62;Building multiple programs or libraries&#60;/a&#62;
  &#60;/li&#62;&#60;li&#62;&#60;a href=&#34;#multi-dirs&#34;&#62;Building in multiple directories&#60;/a&#62;
  &#60;/li&#62;&#60;li&#62;&#60;a href=&#34;#camlp4&#34;&#62;How to enable camlp4&#60;/a&#62;
  &#60;/li&#62;&#60;li&#62;&#60;a href=&#34;#deviating-flags&#34;&#62;Sections with deviating compiler flags&#60;/a&#62;
  &#60;/li&#62;&#60;li&#62;&#60;a href=&#34;#deps&#34;&#62;Handling dependencies between project libraries&#60;/a&#62;
  &#60;/li&#62;&#60;li&#62;&#60;a href=&#34;#many-deps&#34;&#62;Many dependencies between project libraries&#60;/a&#62;
  &#60;/li&#62;&#60;li&#62;&#60;a href=&#34;#ocamldoc&#34;&#62;How to create ocamldoc documentation&#60;/a&#62;
  &#60;/li&#62;&#60;li&#62;&#60;a href=&#34;#cmdline&#34;&#62;How to interpret command-line parameters&#60;/a&#62;
  &#60;/li&#62;&#60;li&#62;&#60;a href=&#34;#objs-in-subdirs&#34;&#62;Putting the build objects into subdirectories&#60;/a&#62;
  &#60;/li&#62;&#60;li&#62;&#60;a href=&#34;#profile&#34;&#62;Profile builds&#60;/a&#62;
  &#60;/li&#62;&#60;li&#62;&#60;a href=&#34;#generate&#34;&#62;Generating files&#60;/a&#62;
  &#60;/li&#62;&#60;li&#62;&#60;a href=&#34;#stublibs&#34;&#62;Compiling stub libraries&#60;/a&#62;
  &#60;/li&#62;&#60;li&#62;&#60;a href=&#34;#dot-prob&#34;&#62;The &#38;#34;:&#38;#34; problem&#60;/a&#62;
  &#60;/li&#62;&#60;li&#62;&#60;a href=&#34;#clean&#34;&#62;Cleaning completely&#60;/a&#62;
  &#60;/li&#62;&#60;li&#62;&#60;a href=&#34;#expr-or-stmt&#34;&#62;Expressions or statements?&#60;/a&#62;
&#60;/li&#62;&#60;/ul&#62;


&#60;p&#62;
&#60;b&#62;Starting point:&#60;/b&#62;
A simple OMakefile for a program could look like:
&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
USE_OCAMLFIND = true
OCAMLPACKS = lwt

FILES[] =
    foo
    bar

.DEFAULT: $(OCamlProgram myprog, $(FILES))
&#60;/pre&#62;

For a library, just use
&#60;pre style=&#34;font-size:smaller&#34;&#62;
.DEFAULT: $(OCamlLibrary mylib, $(FILES))
&#60;/pre&#62;

instead of the &#60;code&#62;OCamlProgram&#60;/code&#62; line. The following recipes
are, in some sense, variations of these simple patterns.

&#60;p&#62;
Normally, you just only set variables to control the build. Some of
the variables only affect the linker, some only the compiler, and
a number both (here the important ones):

&#60;/p&#62;&#60;style type=&#34;text/css&#34;&#62;
.omakevars { font-size: smaller }
.omakevars TH { text-align: left }
.var { font-family: monospace }
&#60;/style&#62;

&#60;p&#62;
&#60;/p&#62;&#60;table class=&#34;omakevars&#34;&#62;
  &#60;tr&#62;&#60;th&#62;Variable&#60;/th&#62; &#60;th&#62;Compiler?&#60;/th&#62; &#60;th&#62;Linker?&#60;/th&#62; &#60;th&#62;Comment&#60;/th&#62;
    &#60;/tr&#62;

  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;USE_OCAMLFIND&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;true/false - whether to use findlib&#60;/td&#62;&#60;/tr&#62;

  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;OCAMLINCLUDES&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;search path for compiled modules and archives, also used by the
dependency scanner&#60;/td&#62;&#60;/tr&#62;
  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;OCAMLFINDFLAGS&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;additional flags to pass to ocamlfind&#60;/td&#62;&#60;/tr&#62;
  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;OCAMLPACKS&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;findlib packages to include in build&#60;/td&#62;&#60;/tr&#62;
  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;BYTE_ENABLED&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;true/false - whether bytecode compiler is enabled&#60;/td&#62;&#60;/tr&#62;
  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;NATIVE_ENABLED&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;true/false - whether nativecode compiler is enabled&#60;/td&#62;&#60;/tr&#62;
  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;OCAMLCFLAGS&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;flags to pass to &#38;#34;ocamlc&#38;#34;&#60;/td&#62;&#60;/tr&#62;
  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;OCAMLOPTFLAGS&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;flags to pass to &#38;#34;ocamlopt&#38;#34;&#60;/td&#62;&#60;/tr&#62;
  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;OCAMLFLAGS&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;flags to pass to &#38;#34;ocamlc&#38;#34; and &#38;#34;ocamlopt&#38;#34;&#60;/td&#62;&#60;/tr&#62;
  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;OCAML_BYTE_LINK_FLAGS&#60;/td&#62;
      &#60;td&#62;&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;flags to pass to &#38;#34;ocamlc&#38;#34; when linking an executable&#60;/td&#62;&#60;/tr&#62;
  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;OCAML_NATIVE_LINK_FLAGS&#60;/td&#62;
      &#60;td&#62;&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;flags to pass to &#38;#34;ocamlopt&#38;#34; when linking an executable&#60;/td&#62;&#60;/tr&#62;
  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;OCAML_LINK_FLAGS&#60;/td&#62;
      &#60;td&#62;&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;flags to pass to both &#38;#34;ocamlc&#38;#34; and &#38;#34;ocamlopt&#38;#34; when linking 
executables&#60;/td&#62;&#60;/tr&#62;
  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;OCAML_LIBS&#60;/td&#62;
      &#60;td&#62;&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;library archives of the project to link into executables&#60;/td&#62;&#60;/tr&#62;
  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;OCAML_OTHER_LIBS&#60;/td&#62;
      &#60;td&#62;&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;library archives outside the project to link into executables&#60;/td&#62;&#60;/tr&#62;
  &#60;tr&#62;&#60;td class=&#34;var&#34;&#62;OCAML_LIB_FLAGS&#60;/td&#62;
      &#60;td&#62;&#60;/td&#62;
      &#60;td&#62;X&#60;/td&#62;
      &#60;td&#62;extra flags when linking libraries&#60;/td&#62;&#60;/tr&#62;
&#60;/table&#62;

&#60;hr/&#62;

&#60;a name=&#34;multi-programs&#34;&#62;&#60;/a&#62;
&#60;h2&#62;Building multiple programs or libraries&#60;/h2&#62;

OMake allows it to split an OMakefile into sections. Each section can
define its own set of variables, and its own build rules.  A section
defines a scope for variables: a section sees the variables of the
surrounding section, but modifications to variables are local to the
section, and not automatically propagated to the surrounding section
(unless you &#38;#34;export&#38;#34; definitions - not covered here).

&#60;p&#62;For example, this OMakefile builds two programs from a
different set of files, and links different libraries into the
programs:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
USE_OCAMLFIND = true
OCAMLPACKS = lwt

section
    FILES[] =
        foo
        bar

    .DEFAULT: $(OCamlProgram myprog1, $(FILES))

section
    FILES[] =
        bar
        baz

    .DEFAULT: $(OCamlProgram myprog2, $(FILES))
&#60;/pre&#62;

Basically, it makes sense to set linking-related variables that
are interpreted by &#60;code&#62;OCamlProgram&#60;/code&#62; and &#60;code&#62;OCamlLibrary&#60;/code&#62;,
like &#60;code&#62;OCAML_LIBS&#60;/code&#62; (see &#38;#34;Starting point&#38;#34; for a list of variables
interpreted at link time).

&#60;p&#62;
What does not work here is to set variables that (only or also) affect
the compiler (i.e. &#38;#34;ocamlc -c&#38;#34; and &#38;#34;ocamlopt -c&#38;#34;). If you e.g. set
&#60;code&#62;OCAMLINCLUDES&#60;/code&#62; or &#60;code&#62;OCAMLPACKS&#60;/code&#62; within a
section, there will be no effect on compilation (only on
linking). Below you find another recipe that shows how to do that, but
this simple recipe here does not allow it.

&#60;/p&#62;&#60;hr/&#62;

&#60;a name=&#34;multi-dirs&#34;&#62;&#60;/a&#62;
&#60;h2&#62;Building in multiple directories&#60;/h2&#62;

Given you have a directory hierarchy

&#60;pre&#62;
  root
   +--- dir1
   +--- dir2
&#60;/pre&#62;

and you want to build in all three directories. How can we describe
this?

&#60;p&#62;&#60;b&#62;Solution 1: Multiple OMakefiles&#60;/b&#62;

&#60;/p&#62;&#60;p&#62;Here, only root contains OMakeroot, and all three directories have
their own OMakefile. Also, you need to &#38;#34;chain&#38;#34; the files: In
root/OMakefile, there needs to be a &#60;code&#62;.SUBDIRS&#60;/code&#62; directive,
like:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
# Before .SUBDIRS: Put here definitions that are visible in the whole project:
USE_OCAMLFIND = true
OCAMLPACKS = lwt

.SUBDIRS: dir1 dir2

# After .SUBDIRS: Add here definitions that are only applied in the root dir:
FILES[] =
    mainprog

OCAMLINCLUDES = dir1 dir2
OCAML_LIBS = dir1/lib1 dir2/lib2

.DEFAULT: $(OCamlProgram myprog, $(FILES))
&#60;/pre&#62;

Now, put into dir1/OMakefile and dir2/OMakefile the definitions that
are local to these directories, e.g.

&#60;pre style=&#34;font-size:smaller&#34;&#62;
FILES[] =
    file1
    files
OCAMLFLAGS = -g
OCAMLPACKS += netstring

.DEFAULT: $(OCamlLibrary lib1, $(FILES))
&#60;/pre&#62;

Basically, the definitions in the sub-OMakefiles have their own
scoping environment, as if they were encapsulated in
a &#60;code&#62;section&#60;/code&#62;.  The scoping rules for directories and for
sections are not identical, though. In particular, you can also define
in a sub-OMakefile variables that affect the compilation,
like &#60;code&#62;OCAMLFLAGS&#60;/code&#62;, &#60;code&#62;OCAMLPACKS&#60;/code&#62;,
or &#60;code&#62;OCAMLINCLUDES&#60;/code&#62;.

&#60;p&#62;&#60;b&#62;Solution 2: .SUBDIRS with body&#60;/b&#62;

&#60;/p&#62;&#60;p&#62;Sometimes, you don&#38;#39;t want to put OMakefiles into subdirectories, or
the OMakefiles in several directories would be identical. To handle
this case, it is allowed to put the definitions for the subdirectory
into the body of .SUBDIRS (i.e. indented):

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
# Before .SUBDIRS: Put here definitions that are visible in the whole project:
USE_OCAMLFIND = true
OCAMLPACKS = lwt

.SUBDIRS: dir1 dir2
    .DEFAULT: $(OCamlProgram myprog, main)
&#60;/pre&#62;

This works exactly as if you had written the definitions in the body into
separate OMakefiles in the subdirs.


&#60;hr/&#62;

&#60;a name=&#34;camlp4&#34;&#62;&#60;/a&#62;
&#60;h2&#62;How to enable camlp4&#60;/h2&#62;

If you use ocamlfind, this is very simple, just set

&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCAMLFINDFLAGS += -syntax camlp4o
OCAMLPACKS += camlp4
&#60;/pre&#62;

(or use &#38;#34;-syntax camlp4r&#38;#34; if you prefer the revised syntax). In order
to activate a custom preprocessor written for camlp4, like xstrp4,
just add this findlib package to &#60;code&#62;OCAMLPACKS&#60;/code&#62;

&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCAMLPACKS += xstrp4
&#60;/pre&#62;

Note that the variable &#60;code&#62;OCAMLFINDFLAGS&#60;/code&#62; not only affects
ocamlc and ocamlopt, but also ocamldep, i.e. the dependency scanning
is also done with camlp4 and the activated syntax extensions.

&#60;p&#62;Some custom preprocessors accept command-line arguments. For
example, you can define macros on the command-line with the macro
preprocessor:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCAMLPACKS += camlp4.macro               # the macro preprocessor
OCAMLFINDFLAGS += $(mapprefix -ppopt, -D NAME=value)
&#60;/pre&#62;

The strange &#38;#34;mapprefix&#38;#34; expression just prepends &#60;code&#62;-ppopt&#60;/code&#62;
to every space-separated part of the second argument - well, in the
end, camlp4 is called with &#60;code&#62;-D NAME=value&#60;/code&#62; appended to
the command-line.

&#60;p&#62;
If you don&#38;#39;t trust in ocamlfind, you can also directly set the
preprocessor command, e.g.

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCAMLFLAGS += -pp camlp4of
&#60;/pre&#62;

but custom extensions like &#60;code&#62;xstrp4&#60;/code&#62; can then not be enabled
by simply adding the package to &#60;code&#62;OCAMLPACKS&#60;/code&#62;. Instead, you
would have to find out the right options for camlp4of, and add them
to the command passed with -pp.

&#60;p&#62;
As camlp4 reduces the compilation speed tremendously, you often want
to enable it only for a few files, but not for the whole project.
See the following recipe how to do this.

&#60;/p&#62;&#60;hr/&#62;

&#60;a name=&#34;deviating-flags&#34;&#62;&#60;/a&#62;
&#60;h2&#62;Sections with deviating compiler flags&#60;/h2&#62;

As already explained above, the &#60;code&#62;section&#60;/code&#62; construct
normally does not allow to modify compiler flags, but only linker
flags. You may for example want to do this to invoke a preprocessor
only for certain source files.

&#60;p&#62;
Note that you do not need this technique if you just set the compiler
flags in a sub-OMakefile to different values than in the main
OMakefile, because OMake already handles this case automatically.

&#60;/p&#62;&#60;p&#62;
The compiler flags have an effect on the standard build rules, which
are defined by pattern rules like

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
%.cmo: %.ml
    $(OCamlC) -c $&#38;#60;
&#60;/pre&#62;

(the actual standard definitions are a lot more complicated),
where &#60;code&#62;OCamlC&#60;/code&#62; is a variable that also expands the compiler
flags like &#60;code&#62;OCAMLINCLUDES&#60;/code&#62;. Normally, the build rules just
take the values these flags have at the end of the OMakefile. If you
now want to force OMake to take the values set in a
certain &#60;code&#62;section&#60;/code&#62;, the trick is to recall the build rule
within the section. Here is an example:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
section
    OCAMLINCLUDES = additional_include_dir

    foo.cmi:
    foo.cmo:
    foo.cmx:
    foo.o:
&#60;/pre&#62;

This means that the module &#60;code&#62;foo&#60;/code&#62; is compiled with the
changed compiler flags. Note that we omit the bodies of the
build rules - which OMake interprets to leave the body unchanged (i.e.
take it from the pattern), and only to apply the current set of
variables to the old body.

&#60;p&#62;
One application is to instruct OMake to compile certain modules with
a preprocessor. The following defines a function doing this:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
Camlp4o(module) =
    section
        OCAMLPACKS += camlp4
        OCAMLFINDFLAGS += -syntax camlp4o
        $(module).cmi:
        $(module).cmo:
        $(module).o:
        $(module).cmx:
&#60;/pre&#62;

You can call this function for every module as in

&#60;pre style=&#34;font-size:smaller&#34;&#62;
Camlp4o(mod1)
Camlp4o(mod2)
&#60;/pre&#62;

to enable camlp4 just for these modules.

&#60;p&#62;Note that you need to name the modules explicitly that get a deviating
set of compiler flags. You can, however, use an iteration to apply
the deviating set to all modules you deal with in a section:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
section
    FILES[] =
        foo
        bar
        baz
    CAMLP4_FILES[] =
        bar
        baz
    OCAML_LIBS[] =
        mylib1
        mylib2

    foreach(f, $(CAMLP4_FILES))
        Camlp4o($(f))

    .DEFAULT: $(OCamlProgram myprog1, $(FILES))
&#60;/pre&#62;

&#60;p&#62;&#60;b&#62;Not limited to camlp4:&#60;/b&#62; This is, of course, not limited to
requiring camlp4. Another example it to increase the inlining value
just for a certain file:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
Inline(module,limit) =
    section
        OCAMLOPTFLAGS += -inline $(limit)
        $(module).cmi:
        $(module).cmo:
        $(module).o:
        $(module).cmx:

Inline(mod1, 10)
Inline(mod2, 15)
&#60;/pre&#62;

&#60;hr/&#62;

&#60;a name=&#34;deps&#34;&#62;&#60;/a&#62;
&#60;h2&#62;Handling dependencies between project libraries&#60;/h2&#62;

Imagine you build a number of libraries, either in separate OMakefiles
or in separate sections. For example, let&#38;#39;s assume this directory
hierarchy:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
root
 +--- directory1    # containing lib1
 +--- directory2    # containing lib2
&#60;/pre&#62;

It is very simple to just use a library while building another (or
building a program). E.g. if you need lib1 to build lib2, just set
in &#60;code&#62;directory2/OMakefile&#60;/code&#62;

&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCAMLINCLUDES[] =
    ../directory1
&#60;/pre&#62;

to make the library available. &#60;code&#62;OCAMLINCLUDES&#60;/code&#62; is a far-reaching
variable: the directories enumerated in it are not only added as
&#60;code&#62;-I&#60;/code&#62; flags in the compiler commands to run, but also considered
for dependency scanning. That means when a source file in directory1 is
changed, the modules that depend on it in directory2 are automatically
found out, and added to the list of things to recompile.

&#60;p&#62;If you build a program using the libraries, you have to do a tiny
additional step: In the OMakefile building the program also set
&#60;code&#62;OCAML_LIBS&#60;/code&#62; in addition to &#60;code&#62;OCAMLINCLUDES&#60;/code&#62;.
&#60;code&#62;OCAML_LIBS&#60;/code&#62; needs to be set to the paths to the library
archives (i.e. to the cma/cmxa files, but omit the suffix). For example,
if there are programs to build in &#60;code&#62;root/OMakefile&#60;/code&#62;, set

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCAMLINCLUDES[] =
    directory1
    directory2
OCAML_LIBS[] =
    directory1/archive1
    directory2/archive2
&#60;/pre&#62;

to link these archives while building the programs. 


&#60;hr/&#62;
&#60;a name=&#34;many-deps&#34;&#62;&#60;/a&#62;
&#60;h2&#62;Many dependencies between project libraries&#60;/h2&#62;

&#60;p&#62;
OMake will automatically take care of the dependencies between the
libraries, and even between individual files. However, there is
a disadvantage of doing only this: OMake does not provide a means
of defining indirect dependencies well. For example, if you have
&#60;code&#62;lib1&#60;/code&#62; using &#60;code&#62;lib2&#60;/code&#62;, and the latter uses
&#60;code&#62;lib3&#60;/code&#62;, you need to list &#60;code&#62;lib3&#60;/code&#62; as a prerequisite
for &#60;code&#62;lib1&#60;/code&#62;, even if there is no direct relationship.
For large projects with dozens of libraries this turns out to be a
big problem, because such &#38;#34;expanded&#38;#34; dependencies are unmaintainable.

&#60;/p&#62;&#60;p&#62;&#60;b&#62;Solution 1:&#60;/b&#62; Define the dependencies only in the main OMakefile.

&#60;/p&#62;&#60;p&#62;The idea is that there is a paragraph at the beginning of the main
OMakefile describing the dependencies, e.g. if we have a directory hierarchy

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
root
 +--- directory1       # contains lib1
 +--- directory2       # contains lib2
 +--- directory3       # contains lib3
 +--- directory4       # build something else
&#60;/pre&#62;

we can define a number of variables in &#60;code&#62;root/OMakefile&#60;/code&#62; as

&#60;pre style=&#34;font-size:smaller&#34;&#62;
LIB3_INCLUDES[] =
    $(dir directory3)
LIB2_INCLUDES[] =
    $(dir directory2)
    $(LIB3_INCLUDES)
LIB1_INCLUDES[] =
    $(dir directory1)
    $(LIB2_INCLUDES)
&#60;/pre&#62;

and in the sub-OMakefile for a certain library we set only
&#60;code&#62;OCAMLINCLUDES&#60;/code&#62; to one of the prepared variables, e.g.
if lib4 needs lib1, we set in &#60;code&#62;directory4/OMakefile&#60;/code&#62; for lib4:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCAMLINCLUDES = $(LIB1_INCLUDES)
&#60;/pre&#62;

&#60;p&#62;Why did we call the function &#60;code&#62;dir&#60;/code&#62; while setting
the &#60;code&#62;LIB*_INCLUDES&#60;/code&#62; variables? Remember that we use the
variable &#60;code&#62;LIB1_INCLUDES&#60;/code&#62; in a subdirectory, so
e.g. &#60;code&#62;directory2&#60;/code&#62; is here
actually &#60;code&#62;../directory2&#60;/code&#62;. If we invoke &#60;code&#62;dir&#60;/code&#62;,
the variable magically rembers where it was defined, and if it is
recalled from a different directory, OMake automatically adjusts
the path.

&#60;/p&#62;&#60;p&#62;&#60;small&#62;(Detail: You might have noticed
that &#60;code&#62;LIB1_INCLUDES&#60;/code&#62; is actually an array of an array. This does not
harm us here, because when OMake expands such structured variables to
command-line arguments, it just flattens them to a list of arguments.)&#60;/small&#62;

&#60;/p&#62;&#60;p&#62;For building programs, we also need the library archives. We can
use the same pattern as for the include path:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
LIB3_ARCHIVES[] =
    $(file directory3/archive3)
LIB2_ARCHIVES[] =
    $(file directory2/archive2)
    $(LIB3_ARCHIVES)
LIB1_ARCHIVES[] =
    $(file directory1/archive1)
    $(LIB2_ARCHIVES)
&#60;/pre&#62;

(Note that we need here to call &#60;code&#62;file&#60;/code&#62; instead of &#60;code&#62;dir&#60;/code&#62;).

&#60;p&#62;For creating an executable linking in lib1 and all predecessors, just
use

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCAMLINCLUDES = $(LIB1_INCLUDES)
OCAML_LIBS = $(LIB1_ARCHIVES)
&#60;/pre&#62;

If the library archives have all the same name, you can also do:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCAMLINCLUDES = $(LIB1_INCLUDES)
OCAML_LIBS = $(addsuffix /archivename, $(LIB1_INCLUDES))
&#60;/pre&#62;

If the archives have the same name as the directories:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
mapname(name) =
    value $(name)/$(basename $(name))

OCAMLINCLUDES = $(LIB1_INCLUDES)
OCAML_LIBS = $(foreach $(mapname), $(LIB1_INCLUDES))
&#60;/pre&#62;



&#60;p&#62;&#60;b&#62;Solution 2 (advanced):&#60;/b&#62; Extract the dependency data from META files.

&#60;/p&#62;&#60;p&#62;Here we assume that we have already META files in the subdirectories.
We want to use ocamlfind to look up paths and archive names:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
root
 +--- directory1       # contains lib1
 |     +---- META
 +--- directory2       # contains lib2
 |     +---- META
 +--- directory3       # contains lib3
 |     +---- META
 +--- directory4       # contains lib4
       +---- META
&#60;/pre&#62;

The first thing to do is to set &#60;code&#62;OCAMLPATH&#60;/code&#62; so it contains
the &#60;code&#62;root&#60;/code&#62; directory: Into &#60;code&#62;root/OMakefile&#60;/code&#62; put:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
setenv(OCAMLPATH, $(absname .):$(getenv OCAMLPATH,$(string)))
&#60;/pre&#62;

&#60;p&#62;&#60;small&#62;(Details: &#60;code&#62;absname&#60;/code&#62; returns the absolute path name
of the argument. &#60;code&#62;$(string)&#60;/code&#62; is just the empty string. In OMake
there is no good way of writing the empty string as a quoted literal.)&#60;/small&#62;

&#60;/p&#62;&#60;p&#62;Now we can refer to the libraries as packages. The package names are
just the directory names, e.g. &#38;#34;directory3&#38;#34; would mean lib3. It is,
however, not sufficient to just add these names to &#60;code&#62;OCAMLPACKS&#60;/code&#62;,
because OMake would then not consider these libraries as part of the
project, but as packages outside the project.

&#60;/p&#62;&#60;p&#62;The solution is to still set &#60;code&#62;OCAMLINCLUDES&#60;/code&#62; in the
sub-OMakefiles like in solution 1.  This time, however, we call
ocamlfind for getting the values.  To do so, define
in &#60;code&#62;root/OMakefile&#60;/code&#62; before the
&#60;code&#62;.SUBDIRS&#60;/code&#62; line

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
all_dirs = $(subdirs .)

get_project_findlib_dirs(pkg) =
    dirs = $(shella ocamlfind query -r $(pkg))
    fdirs =
    foreach (d, $(dirs))
        if $(mem $(dir $(d)), $(all_dirs))
            fdirs += $(d)
            export
        export
    value $(fdirs)

get_project_findlib_archives(pkg,pred) =
    dirs = $(shella ocamlfind query -format %d/%a -predicates $(pred) -r $(pkg))
    fdirs =
    foreach (d, $(dirs))
        if $(mem $(dir $(d)), $(all_dirs))
            fdirs += $(d)
            export
        export
    value $(fdirs)
&#60;/pre&#62;

Note that these functions only output directories and archives inside the
project.

&#60;p&#62;&#60;small&#62;(Detail: Note that the &#60;code&#62;mem&#60;/code&#62; function is used to
check whether a directory &#60;code&#62;d&#60;/code&#62; occurs in a list of
directories &#60;code&#62;all_dirs&#60;/code&#62;. This works independently of the
path by which the directories are referenced. Actually, &#60;code&#62;d&#60;/code&#62;
is normally a relative path, and &#60;code&#62;all_dirs&#60;/code&#62; contains
absolute paths. Cool, isn&#38;#39;t it.)&#60;/small&#62;

&#60;/p&#62;&#60;p&#62;How to use this: In the sub-OMakefiles that create libraries:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCAMLPACKS += directory1 directory2
OCAMLINCLUDES = $(get_project_findlib_dirs $(OCAMLPACKS))
&#60;/pre&#62;

&#60;p&#62;With the &#60;code&#62;OCAMLPACKS&#60;/code&#62; line the project-local findlib
packages are added to the build. The &#60;code&#62;OCAMLINCLUDES&#60;/code&#62; setting
is only necessary to instruct the scanner that the dependencies
to these packages are also needed.

&#60;/p&#62;&#60;p&#62;In the sub-OMakefiles that create programs (here
just &#60;code&#62;program&#60;/code&#62;):

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCAMLPACKS += directory1 directory2

program.run: $(get_project_findlib_archives $(OCAMLPACKS), byte)
program.opt: $(get_project_findlib_archives $(OCAMLPACKS), native)
&#60;/pre&#62;

You need the two &#38;#34;program.run&#38;#34;/&#38;#34;program.opt&#38;#34; lines for every program
you create. The effect is that the library archives of the project-local
packages are added as dependency to the build.

&#60;hr/&#62;
&#60;a name=&#34;ocamldoc&#34;&#62;&#60;/a&#62;
&#60;h2&#62;How to create ocamldoc documentation&#60;/h2&#62;

The following function works well - all interfaces with mli suffix
are assumed to contain docs:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
public.InterfaceDoc(name, files) =
    protected.mlifiles = $(filter-exists $(addsuffix .mli, $(files)))
    protected.cmifiles = $(addsuffix .cmi, $(removesuffix $(mlifiles)))

    $(name).idoc: $(mlifiles) $(cmifiles) /.PHONY/OCamlGeneratedFilesTarget
        ocamlfind ocamldoc -dump $(name).idoc -stars \
            $(PREFIXED_OCAMLINCLUDES) -package &#38;#34;$(OCAMLPACKS)&#38;#34; \
            $(mlifiles)
    return $(name).idoc
&#60;/pre&#62;

You call this function like this in every OMakefile
compiling &#60;code&#62;$(FILES)&#60;/code&#62;:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
InterfaceDoc(filename, $(FILES))
&#60;/pre&#62;

This creates a file &#60;code&#62;filename.idoc&#60;/code&#62; (idoc for interface
documentation) in the current directory. This file is a binary description
of the documentation, and it can be used in a final ocamldoc step
(modify this as needed):

&#60;pre style=&#34;font-size:smaller&#34;&#62;
IDOCS[] =
    subdirectory1/filename1.idoc
    subdirectory2/filename2.idoc

.PHONY: html-doc
html-doc: $(IDOCS)
    mkdir -p html
    rm -rf html/*
    ocamlfind ocamldoc -d html -stars -t &#38;#34;My title&#38;#34; -html \
        $(mapprefix -load, $(IDOCS))
&#60;/pre&#62;

&#60;hr/&#62;
&#60;a name=&#34;cmdline&#34;&#62;&#60;/a&#62;
&#60;h2&#62;How to interpret command-line parameters&#60;/h2&#62;

If you try to modify a variable by setting it on the command-line, this
often does not work. For example, if you try to override 
&#60;code&#62;BYTE_ENABLED&#60;/code&#62; with

&#60;pre style=&#34;font-size:smaller&#34;&#62;
$ omake BYTE_ENABLED=true
&#60;/pre&#62;

this setting is often ignored. The reason for this is that omake
interprets command-line assignments just as initial assignments, but
not as overriding assignments like traditional &#38;#34;make&#38;#34;.  If your OMakefile
contains already something like

&#60;pre style=&#34;font-size:smaller&#34;&#62;
BYTE_ENABLED = $(not $(OCAMLOPT_EXISTS))
&#60;/pre&#62;

this will simply overwrite the initial setting given on the command-line.

&#60;p&#62;Note that the standard build definitions, as in
e.g. &#60;code&#62;OCaml.om&#60;/code&#62; (part of the OMake deployment) also
set many control variables. These settings are, however, overridable.
Look at OMakeroot to see why:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
open build/C
open build/OCaml
open build/LaTeX
DefineCommandVars()
.SUBDIRS: .
&#60;/pre&#62;

In English, this just means that the three standard build definition
files are loaded, and first after that the command-line assignments
are evaluated. Finally, the &#60;code&#62;.SUBDIRS: .&#60;/code&#62; directive
includes the OMakefile in the same directory.

&#60;p&#62;So, what to do? If you have a block at the beginning of your OMakefile
where you customize variables, like

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
BYTE_ENABLED = true
NATIVE_ENABLED = $(OCAMLOPT_EXISTS)
OCAMLPACKS = p1 p2 p3
&#60;/pre&#62;

you just call &#60;code&#62;DefineCommandVars&#60;/code&#62; again after this block:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
DefineCommandVars()
&#60;/pre&#62;

This evaluates the assignments given on the command-line again, and the
caller can override your customizations.

&#60;p&#62;There is also the possibility to set variables only if they aren&#38;#39;t
already set. Unfortunately, OMake does not know the popular &#38;#34;make&#38;#34; syntax
&#38;#34;variable ?= value&#38;#34;, and we have to do it on our own:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
if $(not $(defined X))
    X = default_value
    export
&#60;/pre&#62;

There are other formulations:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
var_default(name, value) =
    if $(not $(defined $(name)))
        setvar($(name), $(value))
        export
    export

var_default(X, default_value)
&#60;/pre&#62;

Another option, closer to a normal assignment:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
var_default(value, name) =         # different order!
    if $(not $(defined $(name)))
        setvar($(name), $(value))
        export
    export

var_default(X)
    default_value
&#60;/pre&#62;


&#60;hr/&#62;
&#60;a name=&#34;objs-in-subdirs&#34;&#62;&#60;/a&#62;
&#60;h2&#62;Putting the build objects into subdirectories&#60;/h2&#62;

Normally, OMake puts the output files of a build into the same
directories as the source files. It is possible to change this.
Assume the directory hierarchy is

&#60;pre style=&#34;font-size:smaller&#34;&#62;
root
 +---- directory1_src
 +---- directory1_out
 +---- directory2_src
 +---- directory2_out
&#60;/pre&#62;

and we want that the output files of the sources in &#60;code&#62;*_src&#60;/code&#62;
appear in &#60;code&#62;*_out&#60;/code&#62;. This is achieved by changing the 
&#60;code&#62;.SUBDIRS&#60;/code&#62; line in &#60;code&#62;root/OMakefile&#60;/code&#62; into

&#60;pre style=&#34;font-size:smaller&#34;&#62;
vmount(-l, directory1_src, directory1_out)     # &#38;#34;minus ell&#38;#34; as first arg
vmount(-l, directory2_src, directory2_out)
.SUBDIRS: directory1_out directory2_out
&#60;/pre&#62;

The effect of &#60;code&#62;vmount&#60;/code&#62; is that the files in the source
directories are automatically linked into the output directories.
After that, you do not refer to the source directories anymore, but
just to the output directories.

&#60;p&#62;&#60;b&#62;Building several versions of the same:&#60;/b&#62; You can use the vmount
feature to build several output directories from the same source directory,
and have different configurations for each output. Example:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
section
    vmount(-l, directory1_src, directory1_normal)
    ENABLE_DEBUG = false
    .SUBDIRS: directory1_normal

section
    vmount(-l, directory1_src, directory1_debug)
    ENABLE_DEBUG = true
    .SUBDIRS: directory1_debug
&#60;/pre&#62;

Of course, both versions share the same OMakefile (residing
in &#60;code&#62;directory1_src&#60;/code&#62;). Because of this, we set one
variable &#60;code&#62;ENABLE_DEBUG&#60;/code&#62; differently in both versions.
You can now use conditionals like

&#60;pre style=&#34;font-size:smaller&#34;&#62;
if $(ENABLE_DEBUG)
    OCAMLFINDFLAGS += $(mapprefix -ppopt, -D DEBUG)
    # set a camlp4 macro for IFDEF
&#60;/pre&#62;

in &#60;code&#62;directory1_src/OMakefile&#60;/code&#62; to enable the debug code
if the OMakefile is interpreted in the &#38;#34;right&#38;#34; output directory.

&#60;p&#62;&#60;b&#62;Note that the OMake developers consider vmount still as
experimental.&#60;/b&#62;

&#60;/p&#62;&#60;hr/&#62;
&#60;a name=&#34;profile&#34;&#62;&#60;/a&#62;
&#60;h2&#62;Profile builds&#60;/h2&#62;

A gprof profile build is enabled by passing -p to ocamlopt. In an
application project, we can do this like

&#60;pre style=&#34;font-size:smaller&#34;&#62;
if $(defined ENABLE_PROF)
    OCAMLOPTFLAGS += -p
    export
&#60;/pre&#62;

If the user calls omake on the command-line as

&#60;pre style=&#34;font-size:smaller&#34;&#62;
omake ENABLE_PROF=anyvalue
&#60;/pre&#62;

the feature is enabled.

&#60;p&#62;&#60;b&#62;Simultaneous profile and non-profile builds:&#60;/b&#62; If you develop
a library for the general public, you may want to provide both a
non-profile and a profile build. Given the following directory layout

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
root
 +---- directory1_src
 +---- directory1_normal
 +---- directory1_gprof
&#60;/pre&#62;

you can use the vmount feature to enable the profile build only in
directory1_gprof. (We assume here that you do not build anything in
&#60;code&#62;root&#60;/code&#62;.) In &#60;code&#62;root/OMakefile&#60;/code&#62; replace the normal
&#60;code&#62;.SUBDIRS&#60;/code&#62; line with

&#60;pre style=&#34;font-size:smaller&#34;&#62;
section
    vmount(-l, directory1_src, directory1_normal)
    ENABLE_PROF = false
    .SUBDIRS: directory1_normal

section
    vmount(-l, directory1_src, directory1_gprof)
    ENABLE_PROF = true
    .SUBDIRS: directory1_gprof
&#60;/pre&#62;

Put all your sources into &#60;code&#62;directory1_src&#60;/code&#62;, and leave the other
two directories empty. The &#60;code&#62;directory1_src/OMakefile&#60;/code&#62; should
contain

&#60;pre style=&#34;font-size:smaller&#34;&#62;
if $(defined ENABLE_PROF)
    OCAMLOPTFLAGS += -p
    BYTE_ENABLED = false
    export
&#60;/pre&#62;

at the beginning. If you now build your projects, you get everything twice:
In &#60;code&#62;directory1_normal&#60;/code&#62; profiling is disabled, whereas in
&#60;code&#62;directory1_gprof&#60;/code&#62; it is enabled.

&#60;p&#62;When installing your project as findlib library, there is the
possibility to put all archive and cmi files into the same findlib
directory. The cmi files should be the same in both versions, so you
can take them from either version. The native archives, however, are
different (both the .cmxa and the .a files). An install target
(in &#60;code&#62;root/OMakefile&#60;/code&#62;) could e.g. do

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
.PHONY: install
install:
    ln-or-cp directory1_gprof/myarchive.cmxa directory1_gprof/myarchive.p.cmxa 
    ln-or-cp directory1_gprof/myarchive.a directory1_gprof/myarchive.p.a 
    ocamlfind install mylib META \
        directory1_src/*.mli \
        directory1_normal/*.cmi \
        directory1_normal/myarchive.cma \
        directory1_normal/myarchive.cmxa \
        directory1_normal/myarchive.a \
        directory1_gprof/myarchive.p.cmxa \
        directory1_gprof/myarchive.p.a
&#60;/pre&#62;

and the META file would refer to the archives like

&#60;pre style=&#34;font-size:smaller&#34;&#62;
archive(byte) = &#38;#34;myarchive.cma&#38;#34;
archive(native) = &#38;#34;myarchive.cmxa&#38;#34;
archive(native,gprof) = &#38;#34;myarchive.p.cmxa&#38;#34;
&#60;/pre&#62;

This way, the profile-enabled version of your library is automatically
taken when &#60;code&#62;ocamlfind ocamlopt -p&#60;/code&#62; runs.

&#60;p&#62;&#60;b&#62;Note that the OMake developers consider vmount still as
experimental.&#60;/b&#62;

&#60;/p&#62;&#60;hr/&#62;
&#60;a name=&#34;generate&#34;&#62;&#60;/a&#62;
&#60;h2&#62;Generating files&#60;/h2&#62;

Three standard cases are already handled by OMake:

&#60;ul&#62;
&#60;li&#62;ocamllex: OMake automatically finds files ending in .mll, and runs ocamllex
  to generate to corresponding .ml files
&#60;/li&#62;&#60;li&#62;ocamlyacc: Similarly, files ending in .mly are processed by ocamlyacc
&#60;/li&#62;&#60;li&#62;menhir: If you set &#60;code&#62;MENHIR_ENABLED=true&#60;/code&#62;, files ending in
  .mly are instead processed by menhir
&#60;/li&#62;&#60;/ul&#62;

If you use a different generator, you need to add rules for handling
these. 

&#60;p&#62;Example: The &#60;code&#62;atdgen&#60;/code&#62; utility can generate I/O serializers
for given type definitions. If called like

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
atdgen -t foo.atd
&#60;/pre&#62;

it generates from the description &#60;code&#62;foo.atd&#60;/code&#62; two files, namely
&#60;code&#62;foo_t.ml&#60;/code&#62; and &#60;code&#62;foo_t.mli&#60;/code&#62;. We create this rule
for it:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
%_t.ml %_t.mli: %.atd
    atdgen -t $&#38;#60;
&#60;/pre&#62;

Note that you should describe all output files on the left side of the
colon, and all input files on the right side. In the
command, &#60;code&#62;$&#38;#60;&#60;/code&#62; is replaced by the leftmost input file.

&#60;p&#62;It most cases, adding such a rule is already fully sufficient to
drive the generation, and to include the generated files into the
dependency graph. OMake calls ocamldep with the &#60;code&#62;-modules&#60;/code&#62;
flag meaning that it emits the dependencies by module names and not by
files. Because of that, ocamldep also prints dependencies on modules
that do not yet exist as files, but first need to be generated. OMake
then postprocesses these dependencies, and compares them with the
left sides of the rules to check whether the files can be generated.


&#60;/p&#62;&#60;hr/&#62;
&#60;a name=&#34;stublibs&#34;&#62;&#60;/a&#62;
&#60;h2&#62;Compiling stub libraries&#60;/h2&#62;

OMake contains full support for C projects. Nevertheless, for stub
libraries wrapping C functions for use in OCaml some special definitions
should be made.

&#60;p&#62;The problem here is that OMake has its own idea what the C compiler
to call is, and with which flags. With a few configurations, though,
one can tell OMake to call the right C compiler with the right flags:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
CC_CONFIG = $(shell $(OCAMLC) -config | grep bytecode_c_compiler:)
CC = $(nth 1, $(CC_CONFIG))
CFLAGS = $(nth-tl 2, $(CC_CONFIG))
CFLAGS += -I$(shell $(OCAMLC) -where)
&#60;/pre&#62;

These are essentially the same flags that are added when you compile
a C file and use ocamlc as driver (e.g. &#60;code&#62;ocamlc -c file.c&#60;/code&#62;).

&#60;p&#62;In a native-only project you can replace &#38;#34;bytecode_c_compiler&#38;#34; with
&#38;#34;native_c_compiler&#38;#34; (this avoids the -fPIC flag giving a minimal boost).

&#60;/p&#62;&#60;p&#62;The built-in link function &#60;code&#62;OCamlLibrary&#60;/code&#62; does not support
stub libraries. Because of this we need to define our own rules. Given
the following source files

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
foo.ml
foo.mli
foo_stubs.c
&#60;/pre&#62;

we would like to generate these outputs:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
libfoo.a           # containing foo_stubs.o
libfoo.so
foo.cma            # the compiled foo.ml
foo.cmxa
&#60;/pre&#62;

The rules doing this:

&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCAML_MKLIB_FLAGS = ...       # set e.g. to: -lbar

if $(BYTE_ENABLED)
    foo.cma libfoo$(EXT_LIB): foo.cmo foo_stubs$(EXT_OBJ)
        ocamlmklib -o foo foo.cmo foo_stubs$(EXT_OBJ) \
             $(OCAML_BYTE_LINK_FLAGS) $(OCAML_LINK_FLAGS) $(OCAML_MKLIB_FLAGS)

if $(NATIVE_ENABLED)
    foo.cmxa libfoo$(EXT_LIB): foo.cmx foo_stubs$(EXT_OBJ)
        ocamlmklib -custom -o foo foo.cmx foo_stubs$(EXT_OBJ) \
             $(OCAML_NATIVE_LINK_FLAGS) $(OCAML_LINK_FLAGS) $(OCAML_MKLIB_FLAGS)
&#60;/pre&#62;

Note that we do not specify that libfoo.so (or libfoo.dll on Windows) is
also created, at least on many platforms.

&#60;hr/&#62;
&#60;a name=&#34;dot-prob&#34;&#62;&#60;/a&#62;
&#60;h2&#62;The &#38;#34;:&#38;#34; problem&#60;/h2&#62;

Beware that the OMake grammar has some ambiguities. For example

&#60;pre style=&#34;font-size:smaller&#34;&#62;
echo A : B
&#60;/pre&#62;

does not output &#38;#34;A : B&#38;#34;, but rather defines a dependency that &#38;#34;echo&#38;#34; and
&#38;#34;A&#38;#34; depend on &#38;#34;B&#38;#34;.

&#60;b&#62;How to circumvent:&#60;/b&#62;
&#60;ul&#62;
  &#60;li&#62;Put : into quotes (&#38;#34;:&#38;#34;) if meaningful (note that such quotes are
passed down to invoked commands)
  &#60;/li&#62;&#60;li&#62;Put : into OMake quotes ($&#38;#34;:&#38;#34;). This should always work
  &#60;/li&#62;&#60;li&#62;Quote : with a backslash (\:)
  &#60;/li&#62;&#60;li&#62;It is also no problem if the colon occurs inside &#60;code&#62;$(...)&#60;/code&#62;
&#60;/li&#62;&#60;/ul&#62;

Note that the problem does not occur when you define a variable
(e.g. &#60;code&#62;X = A : B&#60;/code&#62;).

&#60;hr/&#62;

&#60;a name=&#34;clean&#34;&#62;&#60;/a&#62;
&#60;h2&#62;Cleaning completely&#60;/h2&#62;

I often switch between different ocaml versions (e.g. currently between
ocaml-3.12 and ocaml-4.00), and I have of a separate omake instance for
each version. So far everything works great.

&#60;p&#62;Sometimes, however, I compile a project with a different ocaml version
than the last time. Now I get errors, even for &#38;#34;omake clean&#38;#34;, e.g.:

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
*** omake: reading OMakefiles
*** omake error:
   File /opt/godi-4.00/lib/omake/build/C.om: line 4, characters 2-32
   unbound variable: public.OMakeVersion
&#60;/pre&#62;

The problem is that OMake caches some values between invocations, namely
in the files ending in &#60;code&#62;.omc&#60;/code&#62;.

&#60;p&#62;The solutions:
&#60;/p&#62;&#60;ul&#62;
  &#60;li&#62;Remove all &#60;code&#62;.omc&#60;/code&#62; files, and &#60;code&#62;.omakedb&#60;/code&#62; in
      the topmost directory
  &#60;/li&#62;&#60;li&#62;Call omake with flag &#60;code&#62;--flush-includes&#60;/code&#62;
&#60;/li&#62;&#60;/ul&#62;

&#60;hr/&#62;
&#60;a name=&#34;expr-or-stmt&#34;&#62;&#60;/a&#62;
&#60;h2&#62;Expressions or statements?&#60;/h2&#62;

You may already have wondered by we write

&#60;pre style=&#34;font-size:smaller&#34;&#62;
.DEFAULT: $(OCamlProgram ...)
&#60;/pre&#62;

if the program is to built by default, but only

&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCamlProgram(...)
&#60;/pre&#62;

if not. Essentially, OMake distinguishes between contexts where you
invoke functions as expressions returning values, and contexts where
functions are only seen as statements, returning nothing.

&#60;p&#62;On the outermost level, everything is a statement, e.g.

&#60;/p&#62;&#60;ul&#62;
  &#60;li&#62;A statement defining a variable: &#60;pre&#62;VAR = expr&#60;/pre&#62;
  &#60;/li&#62;&#60;li&#62;A statement defining a build rule:
&#60;pre&#62;
file.html: file.txt
    transform-txt-to-html file.txt
&#60;/pre&#62;
  &#60;/li&#62;&#60;li&#62;A conditional statement:
&#60;pre&#62;
if $(condition)
    statement1
else
    statement2
&#60;/pre&#62;
&#60;/li&#62;&#60;/ul&#62;

Within statements, you can substitute arguments by using expressions.
In an expression, the executable code is within &#60;code&#62;$(...)&#60;/code&#62; parentheses:

&#60;ul&#62;
  &#60;li&#62;Substitute the value of a variable: &#60;pre&#62;$(VAR)&#60;/pre&#62;
  &#60;/li&#62;&#60;li&#62;Call a function: &#60;pre&#62;$(getenv PATH)&#60;/pre&#62;
  &#60;/li&#62;&#60;li&#62;Conditional: &#60;pre&#62;$(if $(condition),$(getenv V1),$(getenv V2))&#60;/pre&#62;
&#60;/li&#62;&#60;/ul&#62;

Actually, the distinction between expressions and statements is only
syntactical, because statement blocks are allowed to return values:

&#60;pre&#62;
value $(expression...)
&#60;/pre&#62;

(in function definitions you can also use &#60;code&#62;return&#60;/code&#62; if you
want to leave the function immediately). And, of course, expressions
may have side effects, e.g.

&#60;pre&#62;
$(setvar VAR, $(...))
&#60;/pre&#62;

sets &#60;code&#62;VAR&#60;/code&#62; in the same way as the
statement &#60;code&#62;VAR=$(...)&#60;/code&#62;  would have. In some sense, the
duality between &#38;#34;statement syntax&#38;#34; and &#38;#34;expression syntax&#38;#34; exists
to keep some compatibility with traditional &#38;#34;make&#38;#34;.

&#60;p&#62;Now back to our initial question. &#60;code&#62;OCamlProgram&#60;/code&#62; is a
function that defines a number of build rules, and finally returns the
main targets as an array of strings. If you
execute &#60;code&#62;OCamlProgram&#60;/code&#62; as a statement, the returned array
is silently dropped. If you invoke it as an expression, as in

&#60;/p&#62;&#60;pre style=&#34;font-size:smaller&#34;&#62;
.DEFAULT: $(OCamlProgram prog, $(FILES))
&#60;/pre&#62;

the function returns the array [| &#38;#34;prog&#38;#34;; &#38;#34;prog.opt&#38;#34;; &#38;#34;prog.run&#38;#34; |]
after definining the build rules as side effect, and this is the
same as if you had written

&#60;pre style=&#34;font-size:smaller&#34;&#62;
OCamlProgram(prog, $(FILES))
.DEFAULT: prog prog.opt prog.run
&#60;/pre&#62;

effectively declaring these targets as default targets.

&#60;br/&#62;
&#60;br/&#62;

&#60;/div&#62;

&#60;div&#62;
  Gerd Stolpmann works as O&#38;#39;Caml consultant

&#60;/div&#62;

&#60;div&#62;
  
&#60;/div&#62;


          </description>
        </item>
      
  </channel>
</rss>
