Note:

You are viewing a development version of the library. Goto the latest version.

let readme_template_mkd = 
  [
    "% OASIS User Manual";
    "% author Sylvain Le Gall and others";
    "";
    "Introduction";
    "============";
    "";
    "OASIS is a tool to help OCaml developers to integrate configure, build and";
    "install systems in their projects. It should help to create standard entry";
    "points in the source code build system, allowing external tools to analyse";
    "projects easily.";
    "";
    "This tool is freely inspired by [Cabal][] which is the same kind of tool for";
    "[Haskell][].";
    "";
    "  [Cabal]: http://www.haskell.org/cabal";
    "  [Haskell]: http://www.haskell.org";
    "";
    "Everything starts with a single text file, named `_oasis`, at the root of the";
    "project source directory. It contains semi-colon separated fields and sections";
    "that describe what is contained in the project and what to do with it.";
    "";
    "This file is used to generate a skeleton for build, configure and install";
    "systems. Generation can be customized through extra fields or directly inside";
    "generated files.";
    "";
    "The main entry point is an OCaml script `setup.ml`. It is self contained. Once";
    "generated there is no additional dependencies (just like an autoconf";
    "`configure` script).";
    "";
    "OASIS has been created with [OCamlbuild][] in mind. So there is probably some";
    "features/bugs that are oriented toward this build system.";
    "";
    "  [OCamlbuild]: http://brion.inria.fr/gallium/index.php/Ocamlbuild";
    "";
    "Features:";
    "";
    " * OCamlbuild support ([see here](#plugin-ocamlbuild))";
    " * Standard files auto-generation (see here [1](#plugin-devfiles),";
    "   [2](#plugin-meta), [3](#plugin-stdfiles))";
    " * Generic support for all step ([see here](#plugin-custom))";
    " * Internal configure/install ([see here](#plugin-internal))";
    "";
    "Planned features:";
    "";
    " * [OCaml autoconf](http://ocaml-autoconf.forge.ocamlcore.org)";
    " * [OCamlMakefile](http://www.ocaml.info/software.html#build_tools)";
    " * [OMake](http://omake.metaprl.org/index.html)";
    "";
    "Writing `_oasis` file";
    "=====================";
    "";
    "Syntax";
    "------";
    "";
    "The `_oasis` must be a valid UTF-8 text file. This file identify the toplevel";
    "directory of the project.";
    "";
    "Identifiers are just like variable names in OCaml, it cannot contains \"-\" or";
    "numbers at the beginning. Strings follow OCaml convention. For extra";
    "information on the parser/lexer see [Genlex][].";
    "";
    " [Genlex]: http://caml.inria.fr/pub/docs/manual-ocaml/libref/Genlex.html";
    "";
    "A line beginning by `#` is a comment and is ignored. Blank line are ignored.";
    "";
    "The file contains semi-colon fields and sections.";
    "";
    "### Fields";
    "";
    "Fields are defined as `field_name: field_value`:";
    "";
    " * Field name is an identifier, it contains only alphanumeric chars.";
    " * Field name is case insensitive.";
    " * Field value follow OCaml string convention, expect you don't need '\"'";
    "   around it.";
    " * Leading and trailing blanks of field value are removed.";
    " * A field value can continue on several lines, in this case the content of";
    "   the value must be indented one level more then the field name. In the body of";
    "   the value a blank line is represented by `.`.";
    " * If two fields have the same `field_name`, only the latter sets the value.";
    "";
    "The separator ':' can be replaced by '+:' which appends the `field_value` to";
    "the previous value of the value (rather than erasing it). Beware that appending";
    "is value dependent, some fields can concatenate, some cannot.";
    "";
    "The ':' can also be replaced by '\\$:', see";
    "[Conditional value](#conditional-value).";
    "";
    "### Sections";
    "";
    "Sections can be an identifier or a string:";
    "";
    "    Library foo";
    "";
    "or";
    "";
    "    Library \"foo\".";
    "";
    "Section name can be : `Library`, `Executable`, `Document`, `Test` and";
    "`SourceRepository`. Content of a section is indented relative to the section";
    "begin.";
    "";
    "Example:";
    "    # Toplevel fields";
    "    OASISFormat:  1.0";
    "    ";
    "    Library \"foo\"";
    "      # Library fields";
    "      Path: src/";
    "    ";
    "    # Back to toplevel fields";
    "    Synopsis: bar";
    "";
    "### Conditional value";
    "";
    "It is possible to define some fields conditionally. Not all fields can be";
    "specified this way, only fields that have no good default values and that must";
    "be evaluated at runtime is defined.";
    "";
    "For example:";
    "";
    " * Toplevel fields `Name` and `Version` cannot be conditional.";
    " * Library fields `Build` and `Install` can be conditional.";
    "";
    "A condition is defined using a `if ... else ...` construct.";
    "";
    "Example:";
    "";
    "    Library bar";
    "      if os_type(Win32)";
    "        Build: true";
    "      else";
    "        Build: false";
    "";
    "Available tests are :";
    "";
    "$ListOASISTests";
    "";
    "The values from these tests are extracted from theoutput of `ocamlc -config`.";
    "";
    "";
    "An additional `flag` test is available which check that the a Flag is defined. See";
    "the chapter on the [Flag section](#flag).";
    "";
    "Tests and flags can be combined using standard boolean operation:";
    "";
    "* `(expr)`";
    "* `! expr`: negation of `expr`.";
    "* `expr1 && expr2`: boolean and.";
    "* `expr1 || expr2`: boolean or.";
    "* `true` and `false`.";
    "";
    "";
    "For boolean fields, you can replace the `if ... else ...` construct by `\\$:`.";
    "";
    "For example:";
    "";
    "    Library bar";
    "      if os_type(Win32)";
    "        Build: true";
    "      else";
    "        Build: false";
    "";
    "is equivalent to:";
    "";
    "";
    "        Build\\$: os_type(Win32)";
    "";
    "### Features";
    "";
    "OASIS allows to experiment with non-official, experimental features. These";
    "features are included in the code but are not activated by default. In order to";
    "activate them. You need to list them in `AlphaFeatures` or `BetaFeatures` of";
    "your `_oasis`.";
    "";
    "Alpha features are under development and may only be used for testing. They are";
    "not yet well defined, they are evolving quickly and may be removed in future";
    "release of OASIS.";
    "";
    "Beta features are features almost ready to be shipped, they mostly need to be";
    "polished before release. You may use them as they will probably be ready for";
    "the next version of OASIS.";
    "";
    "Once you have activated a features, you get access to more fields and some";
    "parts of the code maybe be activated as well.";
    "";
    "Features allow the OASIS development team to release experiment early and";
    "should avoid long delay between release.";
    "";
    "Available features:";
    "";
    "$ListAllFeatures";
    "";
    "Package";
    "-------";
    "";
    "Package fields are defined outside sections. They apply to the whole project.";
    "";
    "Fields:";
    "";
    "$ListOASISPackageFields";
    "";
    "`BuildDepends` and `BuildTools` are appended to all sections and not used";
    "directly in the package.";
    "";
    "Sections";
    "--------";
    "";
    "There are 6 possible sections:";
    "";
    " * `Flag`: a command line flag.";
    " * `Library`: an OCaml library.";
    " * `Object`: a .cmo/.cmx object (__require BetaFeatures: section\\_object__).";
    " * `Executable`: an OCaml executable.";
    " * `Document`: a document.";
    " * `Test`: a test.";
    " * `SourceRepository`: version control system information.";
    "";
    "None of these sections are mandatory. `Library`, `Executable`, `Document` and";
    "`Test` can be dependent on each other. This not a problem as long as there is no";
    "cycle inside the dependency graph. Dependencies can be expressed through";
    "`BuildDepends` and `BuildTools` fields.";
    "";
    "### Flag";
    "";
    "A flag section defines a configure command line option. It will be translated to";
    "to `--enable-XXX` and `--disable-XXX` for the command line. It can be used";
    "inside conditional fields.";
    "";
    "Fields:";
    "";
    "$ListOASISFlagFields";
    "";
    "### Common fields";
    "";
    "These fields are used inside `Library` and `Executable`.";
    "";
    "Fields:";
    "";
    "$ListOASISBuildFields";
    "";
    "All files defined in the section are relative to `Path`.";
    "";
    "### Library";
    "";
    "Define an OCaml library. OCaml API is generated using `ocamldoc` applied to";
    "`Modules` with `BuildDepends` required flags.";
    "";
    "Fields:";
    "";
    "$ListOASISLibraryFields";
    " * Include all common fields.";
    "";
    "### Object";
    "";
    "__require BetaFeatures: section\\_object__";
    "";
    "Define an OCaml object file. It is very close to a library except that an";
    "object when linked will evaluate all its toplevel statement. This may be ideal";
    "if you want to call for example an initialisation function.";
    "";
    "Fields:";
    "";
    "$ListOASISObjectFields";
    " * Include all common fields.";
    "";
    "### Executable";
    "";
    "Define an OCaml executable. If the executable is a bytecode that use internal";
    "library, an helper script can be generated to set library path.";
    "";
    "Fields:";
    "";
    "$ListOASISExecutableFields";
    " * Include all common fields.";
    "";
    "### Document";
    "";
    "Define a generated document.";
    "";
    "Fields:";
    "";
    "$ListOASISDocumentFields";
    "";
    "### Test";
    "";
    "Define a test to run.";
    "";
    "Fields:";
    "";
    "$ListOASISTestFields";
    "";
    "### SourceRepository";
    "";
    "Define VCS information. There are two special identified repositories:";
    "";
    " * head: identify the main development repository.";
    " * this: identify the repository at the state of the current version.";
    "";
    "Fields:";
    "";
    "$ListOASISSourceRepositoryFields";
    "";
    "Supported VCS types are: darcs, git, svn, cvs, hg, bzr, arch, monotone.";
    "";
    "License";
    "-------";
    "";
    "We have adopted a [DEP-5][] license style description.";
    "";
    " [DEP-5]: http://dep.debian.net/deps/dep5/#license-specification";
    "";
    "The reason of this format is to have machine-readable license description.";
    "Using this former work, we hope to be compatible with future standards of";
    "Debian.";
    "";
    "We have limited the number of license to:";
    "";
    "$ListShortLicenses";
    " * or an URL describing the license";
    "";
    "And license exception to:";
    "";
    "$ListLicenseExceptions";
    " * or an URL describing the license exception";
    "";
    "You can specify a license version using a dash and only digits or dashes at the";
    "end of the license short name.";
    "";
    "Examples :";
    "";
    " * `LGPL-2.1 with OCaml linking exception`: LGPL v2.1 with OCaml linking exception";
    " * `GPL-2+`: GPL v2 or later";
    "";
    "Data files";
    "----------";
    "";
    "`DataFiles` fields help to install extra data inside `\\$datadir/\\$pkg_name`. This";
    "field is a comma separated list of file, with optional value inside parenthesis.";
    "You can override target directory using `fn (\\$datadir/other_location)`.";
    "";
    "You can use wildcard `*` but only for a filename and followed by a single dot";
    "extension: `dir/*.html` is valid but `dir/*` and `dir/*.tar.gz` are not valid.";
    "";
    "Substitution inside text";
    "------------------------";
    "";
    "Substitution is performed using [Buffer.add\\_substitute][].";
    "";
    " [Buffer.add\\_substitute]: http://caml.inria.fr/pub/docs/manual-ocaml/libref/Buffer.html#VALadd_substitute";
    "";
    "Variable are evaluated using environment. This is a mix of various data coming";
    "from `_oasis` file, `ocamlc -config` output and configure tests. So environment";
    "variables depends of each project. You can have a precise idea of what variables";
    "is available looking at the file `setup.data`.";
    "";
    "Here is a list of standard variables:";
    "";
    "$ListStandardVariables";
    "";
    "Other variables are defined depending on your `_oasis` file:";
    "";
    " * Variables from BuildDepends:  `pkg_`  and the name of the findlib package.";
    "   It points to the directory containing the package.";
    "   If there is a version constraint, it is also translated to a variable. It";
    "   contains a boolean value to know if the version is ok or not.";
    "   Internal findlib packages don't create variables.";
    "   Example: `BuildDepends: oUnit (>= 1.0.3)` becomes two variables";
    "   `pkg_oUnit = /usr/lib/ocaml/ounit` and `pkg_oUnit_ge_1_0_3 = true`.";
    " * Variables from external BuildTools: the variable is the name given";
    "   in the field and its value the filename of the executable.";
    "   Example: `BuildTools: make` becomes `make = /usr/bin/make`.";
    " * Dynamic variables from internal BuildTools: the variable is the name";
    "   of the Executable section and its value the filename of the executable.";
    "   Example: `Executable ocamlmod` becomes `ocamlmod =";
    "   _build/src/tools/ocamlmod`. These variables are set through `setup.log`";
    "   rather than `setup.data`. They are set only when the corresponding files";
    "   is built.";
    "";
    "";
    "It is also possible to apply transformation through functions. This is useful";
    "when you need to use properties that need to be determined at runtime:";
    "";
    " * `utoh`: convert an Unix filename into a host filename (e.g. UNIX -> Win32";
    "    conversion).";
    " * `ocaml_escaped`: call to `String.escaped`.";
    "";
    "For example `\\$(utoh src/test.ml)` will be replaced by `src\\test.ml` on Windows.";
    "";
    "Customization of generated files";
    "--------------------------------";
    "";
    "When OASIS generates file, it always replace only lines between";
    "`OASIS_START` and `OASIS_STOP`. These keywords are commented and";
    "followed by data to check that content is unchanged.";
    "";
    "If the file doesn't exist, OASIS will create the whole file using default";
    "header and footer.";
    "";
    "If OASIS detects a change inside the section being replaced, it will create a";
    "backup of the file and issue a warning.";
    "";
    "Customization of setup.ml";
    "-------------------------";
    "";
    "`setup.ml` as any generated files can be customized in its header and footer.";
    "Moreover it can be customized through hook in the code directly.";
    "";
    "TODO: explains hook.";
    "";
    "Using OASIS during software development";
    "---------------------------------------";
    "";
    "Since `_oasis` becomes a central place of information about the building";
    "process, it can be quite cumbersome to run again and again `oasis`. You can";
    "avoid it using the `-dev` flags when calling `oasis` for the first time. This";
    "way it will rebuilt very dependents build files each time you call `ocaml";
    "setup.ml`. A `setup.ml` built this way, should not be distributed. This intended";
    "for development purpose only.";
    "";
    "Plugins";
    "-------";
    "";
    "OASIS is basically built around plugins. They are used to define";
    "specific behavior for generating files and including their own code in `setup.ml`.";
    "";
    "There are 6 categories of plugin:";
    "";
    " * __Conf__: apply to configure step, used in the field `ConfType`";
    " * __Build__: apply to build stepi, used in the field `BuildType`";
    " * __Test__: apply to test sections, used in the field `Type` of a test";
    " * __Doc__: apply to documentation sections, used in the field `Type` of a document";
    " * __Install__: apply to install and uninstall steps, used in the field `DocType`";
    " * __Extra__: everything else, used in the field `Plugins`";
    "";
    "$ListOASISPlugins";
    "";
    "Building and installing";
    "=======================";
    "";
    "The file `setup.ml` is the base system to run every targets. It contains a";
    "self contained OCaml script, that only depends on OCaml standard installation";
    "that doesn't require using stublibs (no Str or Unix). This constraint is";
    "required to be fully portable even on system that doesn't support dynamic";
    "loading.";
    "";
    "The file `setup.data` is the result of the configure step and contains data that";
    "can be used for other step. It is removed only in `distclean` target. The format";
    "of this file is on variable and values per line: `var=\"value\"`. The value is an";
    "OCaml string. The file in this form can be read by `make` and `sh`. Once";
    "generated this file should not be modified.";
    "";
    "The file `setup.log` contains a list of action done and is used and updated by";
    "action done and cancel (e.g. action `install` log files installed which action";
    "`uninstall` remove).";
    "";
    "ocaml setup.ml -configure";
    "-------------------------";
    "";
    "This is the first step to perform. It is mandatory. It runs various test of the";
    "build environment to check that everything required is installed.";
    "";
    "";
    "ocaml setup.ml -build";
    "---------------------";
    "";
    "This step is mandatory. Build libraries and executables.";
    "";
    "ocaml setup.ml -test";
    "--------------------";
    "";
    "This step is optional. Run defined test. Need the build step before.";
    "";
    "ocaml setup.ml -doc";
    "-------------------";
    "";
    "This step is optional. It builds API documentation for library and extra";
    "documentation as defined in `Document`.";
    "";
    "ocaml setup.ml -install";
    "-----------------------";
    "";
    "This step is mandatory. Install what has been built in build and doc step. Also";
    "install data files as defined in `DataFiles` fields.";
    "";
    "ocaml setup.ml -uninstall";
    "-------------------------";
    "";
    "This step is optional. Remove files and libraries installed.";
    "";
    "ocaml setup.ml -reinstall";
    "-------------------------";
    "";
    "This step is optional. Perform an uninstall and then an install step.";
    "";
    "ocaml setup.ml -clean";
    "---------------------";
    "";
    "This step is optional. Clean generated files during build and doc steps.";
    "";
    "ocaml setup.ml -distclean";
    "-------------------------";
    "";
    "This step is optional. Try to go back to pristine source state.";
    "";
    "ocaml setup.ml -all";
    "-------------------";
    "";
    "This step is optional. Run configure, build, test and doc step in one run.";
    "";
    "OASIS usage";
    "===================";
    "";
    "Command line";
    "------------";
    "";
    "$OASISCommandLineHelp";
    "";
  ]