******************** jbuild specification ******************** ``jbuild`` files are the main part of Jbuilder, and are the origin of its name. They are used to describe libraries, executables, tests, and everything Jbuilder needs to know about. The syntax of ``jbuild`` files is described in :ref:``metadata-format`` section. Stanzas ======= ``jbuild`` files are composed of stanzas. For instance a typical ``jbuild`` looks like: .. code:: scheme (library ((name mylib) (libraries (base lwt)))) (rule ((targets (foo.ml)) (deps (generator/gen.exe)) (action (run ${<} -o ${@})))) The following sections describe the available stanzas and their meaning. jbuild_version -------------- ``(jbuild_version 1)`` specifies that we are using the version 1 of the Jbuilder metadata format in this ``jbuild`` file. library ------- The ``library`` stanza must be used to describe OCaml libraries. The format of library stanzas is as follows: .. code:: scheme (library ((name ) )) ```` is the real name of the library. It determines the names of the archive files generated for the library as well as the module name under which the library will be available, unless ``(wrapped false)`` is used (see below). It must be a valid OCaml module name but doesn't need to start with a uppercase letter. For instance, the modules of a library named ``foo`` will be available as ``Foo.XXX`` outside of ``foo`` itself. It is however allowed to write an explicit ``Foo`` module, in which case this will be the interface of the library and you are free to expose only the modules you want. ```` are: - ``(public_name )`` this is the name under which the library can be referred to as a dependency when it is not part of the current workspace, i.e. when it is installed. Without a ``(public_name ...)`` field, the library will not be installed by Jbuilder. The public name must start by the package name it is part of and optionally followed by a dot and anything else you want. The package name must be one of the packages that Jbuilder knows about, as determined by the :ref:`opam-files` - ``(synopsis )`` should give a one-line description of the library. This is used by tools that list installed libraries - ``(modules )`` specifies what modules are part of the library. By default Jbuilder will use all the .ml/.re files in the same directory as the ``jbuild`` file. This include ones that are present in the file system as well as ones generated by user rules. You can restrict this list by using a ``(modules )`` field. ```` uses the `Ordered set language`_ where elements are module names and don't need to start with a uppercase letter. For instance to exclude module ``Foo``: ``(modules (:standard \ foo))`` - ``(libraries ())`` is used to specify the dependencies of the library. See the section about `Library dependencies`_ for more details - ``(wrapped )`` specifies whether the modules of the library should be available only through the top-level library module, or should all be exposed at the top level. The default is ``true`` and it is highly recommended to keep it this way. Because OCaml top-level modules must all be unique when linking an executables, polluting the top-level namespace will make your library unusable with other libraries if there is a module name clash. This option is only intended for libraries that manually prefix all their modules by the library name and to ease porting of existing projects to Jbuilder - ``(preprocess )`` specifies how to preprocess files if needed. The default is ``no_processing``. Other options are described in the `Preprocessing specification`_ section - ``(preprocessor_deps ())`` specifies extra dependencies of the preprocessor, for instance if the preprocessor reads a generated file. The specification of dependencies is described in the `Dependency specification`_ section - ``(optional)``, if present it indicates that the library should only be built and installed if all the dependencies are available, either in the workspace or in the installed world. You can use this to provide extra features without adding hard dependencies to your project - ``(c_names ())``, if your library has stubs, you must list the C files in this field, without the ``.c`` extension - ``(cxx_names ())`` is the same as ``c_names`` but for C++ stubs - ``(install_c_headers ())``, if your library has public C header files that must be installed, you must list them in this field, with the ``.h`` extension - ``(modes ())`` modes (``byte`` and ``native``) which should be built by default. This is only useful when writing libraries for the OCaml toplevel - ``(no_dynlink)`` is to disable dynamic linking of the library. This is for advanced use only, by default you shouldn't set this option - ``(kind )`` is the kind of the library. The default is ``normal``, other available choices are ``ppx_rewriter`` and ``ppx_deriver`` and must be set when the library is intended to be used as a ppx rewriter or a ``[@@deriving ...]`` plugin. The reason why ``ppx_rewriter`` and ``ppx_deriver`` are split is historical and hopefully we won't need two options soon - ``(ppx_runtime_libraries ())`` is for when the library is a ppx rewriter or a ``[@@deriving ...]`` plugin and has runtime dependencies. You need to specify these runtime dependencies here - ``(virtual_deps ()``. Sometimes opam packages enable a specific feature only if another package is installed. This is for instance the case of ``ctypes`` which will only install ``ctypes.foreign`` if the dummy ``ctypes-foreign`` package is installed. You can specify such virtual dependencies here. You don't need to do so unless you use Jbuilder to synthesize the ``depends`` and ``depopts`` sections of your opam file - ``js_of_ocaml``. See the section about :ref:`jbuild-jsoo` - ``flags``, ``ocamlc_flags`` and ``ocamlopt_flags``. See the section about `OCaml flags`_ - ``(library_flags ())`` is a list of flags that are passed as it to ``ocamlc`` and ``ocamlopt`` when building the library archive files. You can use this to specify ``-linkall`` for instance. ```` is a list of strings supporting `Variables expansion`_ - ``(c_flags )`` specifies the compilation flags for C stubs, using the `Ordered set language`_. This field supports ``(:include ...)`` forms - ``(cxx_flags )`` is the same as ``c_flags`` but for C++ stubs - ``(c_library_flags )`` specifies the flags to pass to the C compiler when constructing the library archive file for the C stubs. ```` uses the `Ordered set language`_ and supports ``(:include ...)`` forms. When you are writing bindings for a C library named ``bar``, you should typically write ``-lbar`` here, or whatever flags are necessary to to link against this library - ``(self_build_stubs_archive )`` indicates to Jbuilder that the library has stubs, but that the stubs are built manually. The aim of the field is to embed a library written in foreign language and/or building with another build system. It is not for casual uses, see the `re2 library `__ for an example of use Note that when binding C libraries, Jbuilder doesn't provide special support for tools such as ``pkg-config``, however it integrates easily with `configurator `__ by using ``(c_flags (:include ...))`` and ``(c_library_flags (:include ...))``. executable ---------- The ``executable`` stanza must be used to describe an executable. The format of executable stanzas is as follows: .. code:: scheme (executable ((name ) )) ```` is a module name that contains the main entry point of the executable. There can be additional modules in the current directory, you only need to specify the entry point. Given an ``executable`` stanza with ``(name )``, Jbuilder will know how to build ``.exe``, ``.bc`` and ``.bc.js``. ``.exe`` is a native code executable, ``.bc`` is a bytecode executable which requires ``ocamlrun`` to run and ``.bc.js`` is a JavaScript generated using js_of_ocaml. Note that in case native compilation is not available, ``.exe`` will in fact be a custom byte-code executable. Custom in the sense of ``ocamlc -custom``, meaning that it is a native executable that embeds the ``ocamlrun`` virtual machine as well as the byte code. As such you can always rely on ``.exe`` being available. Moreover, it is usually preferable to use ``.exe`` in custom rules or when calling the executable by hand. This is because running a byte-code executable often requires loading shared libraries that are locally built, and so requires additional setup such as setting specific environment variables and jbuilder doesn't do at the moment. Native compilation is considered not available when there is no ``ocamlopt`` binary at the same place as where ``ocamlc`` was found, or when there is a ``(modes (...))`` field not listing ``native``. ```` are: - ``(public_name )`` specifies that the executable should be installed under that name. It is the same as adding the following stanza to your ``jbuild`` file: .. code:: scheme (install ((section bin) (files ((.exe as ))))) - ``(package )`` if there is a ``(public_name ...)`` field, this specifies the package the executables are part of - ``(libraries ())`` specifies the library dependencies. See the section about `Library dependencies`_ for more details - ``(link_flags )`` specifies additional flags to pass to the linker. This field supports ``(:include ...)`` forms - ``(modules )`` specifies which modules in the current directory Jbuilder should consider when building this executable. Modules not listed here will be ignored and cannot be used inside the executable described by the current stanza. It is interpreted in the same way as the ``(modules ...)`` field of `library`_ - ``(modes ())`` modes (``byte`` and ``native``) which should be built by default. If the stanza has a ``(public_name ...)`` field and ``native`` is not listed here, the byte-code version will be installed instead. - ``(preprocess )`` is the same as the ``(preprocess ...)`` field of `library`_ - ``(preprocessor_deps ())`` is the same as the ``(preprocessor_deps ...)`` field of `library`_ - ``js_of_ocaml``. See the section about `js_of_ocaml`_ - ``flags``, ``ocamlc_flags`` and ``ocamlopt_flags``. See the section about specifying `OCaml flags`_ executables ----------- The ``executables`` stanza is the same as the ``executable`` stanza, except that it is used to describe several executables sharing the same configuration. It shares the same fields as the ``executable`` stanza, except that instead of ``(name ...)`` and ``(public_name ...)`` you must use: - ``(names ())`` where ```` is a list of entry point names. As for ``executable`` you only need to specify the modules containing the entry point of each executable - ``(public_names ())`` describes under what name each executable should be installed. The list of names must be of the same length as the list in the ``(names ...)`` field. Moreover you can use ``-`` for executables that shouldn't be installed rule ---- The ``rule`` stanza is used to create custom user rules. It tells Jbuilder how to generate a specific set of files from a specific set of dependencies. The syntax is as follows: .. code:: scheme (rule ((targets ()) (action ) )) ```` is a list of file names. Note that currently Jbuilder only support user rules with targets in the current directory. ```` is the action to run to produce the targets from the dependencies. See the `User actions`_ section for more details. ```` are: - ``(deps ())`` to specify the dependencies of the rule. See the `Dependency specification`_ section for more details. - ``(fallback)`` to specify that this is a fallback rule. A fallback rule means that if the targets are already present in the source tree, jbuilder will ignore the rule. It is an error if only a subset of the targets are present in the tree. The common use of fallback rules is to generate default configuration files that may be generated by a configure script. - ``(locks ())`` specify that the action must be run while holding the following locks. See the `Locks`_ section for more details. Note that contrary to makefiles or other build systems, user rules currently don't support patterns, such as a rule to produce ``%.y`` from ``%.x`` for any given ``%``. This might be supported in the future. inferred rules ~~~~~~~~~~~~~~ When using the action DSL (see `User actions`_), it is most of the time obvious what are the dependencies and targets. For instance: .. code:: scheme (rule ((targets (b) (deps (a) (action (copy ${<} ${@})))))) In this example it is obvious by inspecting the action what the dependencies and targets are. When this is the case you can use the following shorter syntax, where Jbuilder infers dependencies and targets for you: .. code:: scheme (rule ) For instance: .. code:: scheme (rule (copy a b)) Note that in Jbuilder, targets must always be known statically. Especially, this mean that Jbuilder must be able to statically determine all targets. For instance, this ``(rule ...)`` stanza is rejected by Jbuilder: .. code:: scheme (rule (copy a b.${read:file})) ocamllex -------- ``(ocamllex ())`` is essentially a shorthand for: .. code:: scheme (rule ((targets (.ml)) (deps (.mll)) (action (chdir ${ROOT} (run ${bin:ocamllex} -q -o ${<}))))) ocamlyacc --------- ``(ocamlyacc ())`` is essentially a shorthand for: .. code:: scheme (rule ((targets (.ml .mli)) (deps (.mly)) (action (chdir ${ROOT} (run ${bin:ocamlyacc} ${<}))))) menhir ------ The basic form for defining menhir parsers (analogous to ocamlyacc) is: .. code:: scheme (menhir ((modules ( ...)))) Modular parsers can be defined by adding a ``merge_into`` field. This correspond to the ``--base`` command line option of ``menhir``. With this option, a single parser named ``base_name`` is generated. .. code:: scheme (menhir ((merge_into ) (modules ( ...)))) Extra flags can be passed to menhir using the ``flags`` flag: .. code:: scheme (menhir ((flags ( ...)) (modules ( ...)))) alias ----- The ``alias`` stanza lets you add dependencies to an alias, or specify an action to run to construct the alias. The syntax is as follows: .. code:: scheme (alias ((name ) (deps ()) )) ```` is an alias name such as ``runtest``. ```` specifies the dependencies of the alias. See the `Dependency specification`_ section for more details. ```` are: - ````, an action to run when constructing the alias. See the `User actions`_ section for more details. - ``(package )`` indicates that this alias stanza is part of package ```` and should be filtered out if ```` is filtered out from the command line, either with ``--only-packages `` or ``-p `` - ``(locks ())`` specify that the action must be run while holding the following locks. See the `Locks`_ section for more details. The typical use of the ``alias`` stanza is to define tests: .. code:: scheme (alias ((name runtest) (action (run ${exe:my-test-program.exe} blah)))) See the section about :ref:`running-tests` for details. Note that if your project contains several packages and you run test the tests from the opam file using a ``build-test`` field, then all your ``runtest`` alias stanzas should have a ``(package ...)`` field in order to partition the set of tests. install ------- The ``install`` stanza is what lets you describe what Jbuilder should install, either when running ``jbuilder install`` or through opam. Libraries and executables don't need an ``install`` stanza to be installed, just a ``public_name`` field. Everything else needs an ``install`` stanza. The syntax is as follows: .. code:: scheme (install ((section
) (files ()) )) ``
`` is the installation section, as described in the opam manual. The following sections are available: - ``lib`` - ``libexec`` - ``bin`` - ``sbin`` - ``toplevel`` - ``share`` - ``share_root`` - ``etc`` - ``doc`` - ``stublibs`` - ``man`` - ``misc`` ```` is the list of files to install. Each element in the list must be either a literal filename or a S-expression of the form: .. code:: scheme ( as ) where ```` describe how the file will be installed. For instance, to install a file ``mylib.el`` as ``emacs/site-lisp/mylib.el`` in the ``share_root`` section: (install ((section share_root) (files ((mylib.el as emacs/site-lisp/mylib.el))))) ```` are: - ``(package )``. If there are no ambiguities, you can omit this field. Otherwise you need it to specify which package these files are part of. The package is not ambiguous when the first parent directory to contain a ``.opam`` file contains exactly one ``.opam`` file Handling of the .exe extension on Windows ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Under Microsoft Windows, executables must be suffixed with ``.exe``. Jbuilder tries to make sure that executables are always installed with this extension on Windows. More precisely, when installing a file via an ``(install ...)`` stanza, if the source file has extension ``.exe`` or ``.bc``, then Jbuilder implicitly adds the ``.exe`` extension to the destination, if not already present. copy_files ---------- The ``copy_files`` and ``copy_files#`` stanzas allow to specify that files from another directory could be copied if needed to the current directory. The syntax is as follows: .. code:: scheme (copy_files ) ```` represents the set of files to copy, see the :ref:`glob ` for details. The difference between ``copy_files`` and ``copy_files#`` is the same as the difference between the ``copy`` and ``copy#`` action. See the `User actions`_ section for more details. include ------- The ``include`` stanza allows to include the contents of another file into the current jbuild file. Currently, the included file cannot be generated and must be present in the source tree. This feature is intended to be used in conjunction with promotion, when parts of a jbuild file are to be generated. For instance: .. code:: scheme (include jbuild.inc) (rule (with-stdout-to jbuild.inc.gen (run ./gen-jbuild.exe))) (alias ((name runtest) (action (diff jbuild.inc jbuild.inc.gen)))) With this jbuild file, running jbuilder as follow will replace the ``jbuild.inc`` file in the source tree by the generated one: .. code:: shell $ jbuilder build @runtest --auto-promote Common items ============ Ordered set language -------------------- A few fields takes as argument an ordered set and can be specified using a small DSL. This DSL is interpreted by jbuilder into an ordered set of strings using the following rules: - ``:standard`` denotes the standard value of the field when it is absent - an atom not starting with a ``:`` is a singleton containing only this atom - a list of sets is the concatenation of its inner sets - ``( \ )`` is the set composed of elements of ```` that do not appear in ```` In addition, some fields support the inclusion of an external file using the syntax ``(:include )``. This is useful for instance when you need to run a script to figure out some compilation flags. ```` is expected to contain a single S-expression and cannot contain ``(:include ...)`` forms. Most fields using the ordered set language also support `Variables expansion`_. Variables are expanded after the set language is interpreted. Variables expansion ------------------- Some fields can contains variables of the form ``$(var)`` or ``${var}`` that are expanded by Jbuilder. Jbuilder supports the following variables: - ``ROOT`` is the relative path to the root of the build context. Note that ``ROOT`` depends on the worksace configuration. As such you shouldn't use ``ROOT`` to denote the root of your project. Use ``SCOPE_ROOT`` instead for this purpose - ``SCOPE_ROOT`` is the root of the current scope. It is typically the toplevel directory of your project and as long as you have at least one ``.opam`` file there, ``SCOPE_ROOT`` is independent of the workspace configuration - ``CC`` is the C compiler command line (list made of the compiler name followed by its flags) that was used to compile OCaml in the current build context - ``CXX`` is the C++ compiler command line being used in the current build context - ``ocaml_bin`` is the path where ``ocamlc`` lives - ``OCAML`` is the ``ocaml`` binary - ``OCAMLC`` is the ``ocamlc`` binary - ``OCAMLOPT`` is the ``ocamlopt`` binary - ``ocaml_version`` is the version of the compiler used in the current build context - ``ocaml_where`` is the output of ``ocamlc -where`` - ``ARCH_SIXTYFOUR`` is ``true`` if using a compiler targeting a 64 bit architecture and ``false`` otherwise - ``null`` is ``/dev/null`` on Unix or ``nul`` on Windows In addition, ``(action ...)`` fields support the following special variables: - ``@`` expands to the list of target - ``<`` expands to the first dependency, or the empty string if there are no dependencies - ``^`` expands to the list of dependencies, separated by spaces - ``path:`` expands to ```` - ``path-no-dep:`` is the same as ``path:``, except that ```` is not considered as a dependency of the action. For instance ``(chdir ${ROOT} (run foo --base ${path-no-dep:bar}))`` in ``src/blah/jbuild`` will expand to ``(chdir ../.. (run foo --base src/blah/bar))`` where ``src/blah/bar`` doesn't have to be an existing or buildable file - ``exe:`` is the same as ````, except when cross-compiling, in which case it will expand to ```` from the host build context - ``bin:`` expands to a path to ``program``. If ``program`` is installed by a package in the workspace (see `install`_ stanzas), the locally built binary will be used, otherwise it will be searched in the ``PATH`` of the current build context. Note that ``(run ${bin:program} ...)`` and ``(run program ...)`` behave in the same way. ``${bin:...}`` is only necessary when you are using ``(bash ...)`` or ``(system ...)`` - ``lib::`` expands to a path to file ```` of library ````. If ```` is available in the current workspace, the local file will be used, otherwise the one from the installed world will be used - ``libexec::`` is the same as ``lib:...`` except when cross-compiling, in which case it will expand to the file from the host build context - ``lib-available:`` expands to ``true`` or ``false`` depending on whether the library is available or not. A library is available iff at least one of the following condition holds: - it is part the installed worlds - it is available locally and is not optional - it is available locally and all its library dependencies are available - ``version:`` expands to the version of the given package. Note that this is only supported for packages that are being defined in the current scope - ``read:`` expands to the contents of the given file - ``read-lines:`` expands to the list of lines in the given file - ``read-strings:`` expands to the list of lines in the given file, unescaped using OCaml lexical convention The ``${:...}`` forms are what allows you to write custom rules that work transparently whether things are installed or not. Note that aliases are ignored by both ``${<}`` and ``${^}``. The intent of this last form is to reliably read a list of strings generated by an OCaml program via: .. code:: ocaml List.iter (fun s -> print_string (String.escaped s)) l #. Expansion of lists Forms that expands to list of items, such as ``${CC}``, ``${^}``, ``${@}`` or ``${read-lines:...}``, are suitable to be used in, say, ``(run )``. For instance in: .. code:: scheme (run foo ${^}) if there are two dependencies ``a`` and ``b``, the produced command will be equivalent to the shell command: .. code:: shell $ foo "a" "b" If you want the two dependencies to be passed as a single argument, you have to quote the variable as in: .. code:: scheme (run foo "${^} ") (for now the final space is necessary) which is equivalent to the following shell command: .. code:: shell $ foo "a b " (the items of the list are concatenated with space). Note that, since ``${^}`` is a list of items, the first one may be used as a program name, for instance: .. code:: scheme (rule ((targets (result.txt)) (deps (foo.exe (glob_files *.txt))) (action (run ${^})))) Here is another example: .. code:: scheme (rule ((targets (foo.exe)) (deps (foo.c)) (action (run ${CC} -o ${@} ${<} -lfoolib)))) Library dependencies -------------------- Dependencies on libraries are specified using ``(libraries ...)`` fields in ``library`` and ``executables`` stanzas. For libraries defined in the current scope, you can use either the real name or the public name. For libraries that are part of the installed world, or for libraries that are part of the current workspace but in another scope, you need to use the public name. For instance: ``(libraries (base re))``. When resolving libraries, libraries that are part of the workspace are always preferred to ones that are part of the installed world. .. _alternative-deps: Alternative dependencies ~~~~~~~~~~~~~~~~~~~~~~~~ In addition to direct dependencies you can specify alternative dependencies. This is described in the :ref:`Alternative dependencies ` section It is sometimes the case that one wants to not depend on a specific library, but instead on whatever is already installed. For instance to use a different backend depending on the target. Jbuilder allows this by using a ``(select ... from ...)`` form inside the list of library dependencies. Select forms are specified as follows: .. code:: scheme (select from ( -> ) ( -> ) ...) ```` are lists of literals, where each literal is one of: - ````, which will evaluate to true if ```` is available, either in the workspace or in the installed world - ``!``, which will evaluate to true if ```` is not available in the workspace or in the installed world When evaluating a select form, Jbuilder will create ```` by copying the file given by the first ``( -> )`` case where all the literals evaluate to true. It is an error if none of the clauses are selectable. You can add a fallback by adding a clause of the form ``(-> )`` at the end of the list. Preprocessing specification --------------------------- Jbuilder accepts three kinds of preprocessing: - ``no_preprocessing``, meaning that files are given as it to the compiler, this is the default - ``(action )`` to preprocess files using the given action - ``(pps ())`` to preprocess files using the given list of ppx rewriters Note that in any cases, files are preprocessed only once. Jbuilder doesn't use the ``-pp`` or ``-ppx`` of the various OCaml tools. Preprocessing with actions ~~~~~~~~~~~~~~~~~~~~~~~~~~ ```` uses the same DSL as described in the `User actions`_ section, and for the same reason given in that section, it will be executed from the root of the current build context. It is expected to be an action that reads the file given as only dependency and outputs the preprocessed file on its standard output. More precisely, ``(preprocess (action ))`` acts as if you had setup a rule for every file of the form: .. code:: scheme (rule ((targets (file.pp.ml)) (deps (file.ml)) (action (with-stdout-to ${@} (chdir ${ROOT} ))))) The equivalent of a ``-pp `` option passed to the OCaml compiler is ``(system " ${<}")``. Preprocessing with ppx rewriters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ```` is expected to be a list where each element is either a command line flag if starting with a ``-`` or the name of a library. Additionally, any sub-list will be treated as a list of command line arguments. So for instance from the following ``preprocess`` field: .. code:: scheme (preprocess (pps (ppx1 -foo ppx2 (-bar 42)))) The list of libraries will be ``ppx1`` and ``ppx2`` and the command line arguments will be: ``-foo -bar 42``. Libraries listed here should be libraries implementing an OCaml AST rewriter and registering themselves using the `ocaml-migrate-parsetree.driver API `__. Jbuilder will build a single executable by linking all these libraries and their dependencies. Note that it is important that all these libraries are linked with ``-linkall``. Jbuilder automatically uses ``-linkall`` when the ``(kind ...)`` field is set to ``ppx_rewriter`` or ``ppx_deriver``. It is guaranteed that the last library in the list will be linked last. You can use this feature to use a custom ppx driver. By default Jbuilder will use ``ocaml-migrate-parsetree.driver-main``. See the section about :ref:`custom-driver` for more details. Per module preprocessing specification ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ By default a preprocessing specification will apply to all modules in the library/set of executables. It is possible to select the preprocessing on a module-by-module basis by using the following syntax: .. code:: scheme (preprocess (per_module ( ()) ( ()) ...)) Where ````, ````, ... are preprocessing specifications and ````, ````, ... are list of module names. For instance: .. code:: scheme (preprocess (per_module (((action (run ./pp.sh X=1 ${<})) (foo bar))) (((action (run ./pp.sh X=2 ${<})) (baz))))) Dependency specification ------------------------ Dependencies in ``jbuild`` files can be specified using one of the following syntax: - ``(file )`` or simply ````: depend on this file - ``(alias )``: depend on the construction of this alias, for instance: ``(alias src/runtest)`` - ``(alias_rec )``: depend on the construction of this alias recursively in all children directories wherever it is defined. For instance: ``(alias_rec src/runtest)`` might depend on ``(alias src/runtest)``, ``(alias src/foo/bar/runtest)``, ... - ``(glob_files )``: depend on all files matched by ````, see the :ref:`glob ` for details - ``(files_recursively_in )``: depend on all files in the subtree with root ```` In all these cases, the argument supports `Variables expansion`_. .. _glob: Glob ~~~~ You can use globs to declare dependencies on a set of files. Note that globs will match files that exist in the source tree as well as buildable targets, so for instance you can depend on ``*.cmi``. Currently jbuilder only support globbing files in a single directory. And in particular the glob is interpreted as follows: - anything before the last ``/`` is taken as a literal path - anything after the last ``/``, or everything if the glob contains no ``/``, is interpreted using the glob syntax The glob syntax is interpreted as follows: - ``\`` matches exactly ````, even if it is a special character (``*``, ``?``, ...) - ``*`` matches any sequence of characters, except if it comes first in which case it matches any character that is not ``.`` followed by anything - ``**`` matches any character that is not ``.`` followed by anything, except if it comes first in which case it matches anything - ``?`` matches any single character - ``[]`` matches any character that is part of ```` - ``[!]`` matches any character that is not part of ```` - ``{,,...,}`` matches any string that is matched by one of ````, ````, ... OCaml flags ----------- In ``library`` and ``executables`` stanzas, you can specify OCaml compilation flags using the following fields: - ``(flags )`` to specify flags passed to both ``ocamlc`` and ``ocamlopt`` - ``(ocamlc_flags )`` to specify flags passed to ``ocamlc`` only - ``(ocamlopt_flags )`` to specify flags passed to ``ocamlopt`` only For all these fields, ```` is specified in the `Ordered set language`_. These fields all support ``(:include ...)`` forms. The default value for ``(flags ...)`` includes some ``-w`` options to set warnings. The exact set depends on whether ``--dev`` is passed to Jbuilder. As a result it is recommended to write ``(flags ...)`` fields as follows: :: (flags (:standard )) .. _jbuild-jsoo: js_of_ocaml ----------- In ``library`` and ``executables`` stanzas, you can specify js_of_ocaml options using ``(js_of_ocaml ())``. ```` are all optional: - ``(flags )`` to specify flags passed to ``js_of_ocaml``. This field supports ``(:include ...)`` forms - ``(javascript_files ())`` to specify ``js_of_ocaml`` JavaScript runtime files. == is specified in the `Ordered set language`_. The default value for ``(flags ...)`` depends on whether ``--dev`` is passed to Jbuilder. ``--dev`` will enable sourcemap and the pretty JavaScript output. User actions ------------ ``(action ...)`` fields describe user actions. User actions are always run from the same subdirectory of the current build context as the jbuild they are defined in. So for instance an action defined in ``src/foo/jbuild`` will be run from ``_build//src/foo``. The argument of ``(action ...)`` fields is a small DSL that is interpreted by jbuilder directly and doesn't require an external shell. All atoms in the DSL support `Variables expansion`_. Moreover, you don't need to specify dependencies explicitly for the special ``${:...}`` forms, these are recognized and automatically handled by Jbuilder. The DSL is currently quite limited, so if you want to do something complicated it is recommended to write a small OCaml program and use the DSL to invoke it. You can use `shexp `__ to write portable scripts or `configurator `__ for configuration related tasks. The following constructions are available: - ``(run )`` to execute a program. ```` is resolved locally if it is available in the current workspace, otherwise it is resolved using the ``PATH`` - ``(chdir )`` to change the current directory - ``(setenv )`` to set an environment variable - ``(with--to )`` to redirect the output to a file, where ```` is one of: ``stdout``, ``stderr`` or ``outputs`` (for both ``stdout`` and ``stderr``) - ``(ignore- `` is one of: ``stdout``, ``stderr`` or ``outputs`` - ``(progn ...)`` to execute several commands in sequence - ``(echo )`` to output a string on stdout - ``(write-file )`` writes ```` to ```` - ``(cat )`` to print the contents of a file to stdout - ``(copy )`` to copy a file - ``(copy# )`` to copy a file and add a line directive at the beginning - ``(system )`` to execute a command using the system shell: ``sh`` on Unix and ``cmd`` on Windows - ``(bash )`` to execute a command using ``/bin/bash``. This is obviously not very portable - ``(diff )`` is similar to ``(run diff )`` but is better and allows promotion. See `Diffing and promotion`_ for more details - ``(diff? )`` is the same as ``(diff )`` except that it is ignored when ```` or ```` doesn't exists As mentioned ``copy#`` inserts a line directive at the beginning of the destination file. More precisely, it inserts the following line: .. code:: ocaml # 1 "" Most languages recognize such lines and update their current location, in order to report errors in the original file rather than the copy. This is important as the copy exists only under the ``_build`` directory and in order for editors to jump to errors when parsing the output of the build system, errors must point to files that exist in the source tree. In the beta versions of jbuilder, ``copy#`` was called ``copy-and-add-line-directive``. However, most of time one wants this behavior rather than a bare copy, so it was renamed to something shorter. Note: expansion of the special ``${:...}`` is done relative to the current working directory of the part of the DSL being executed. So for instance if you have this action in a ``src/foo/jbuild``: .. code:: scheme (action (chdir ../../.. (echo ${path:jbuild}))) Then ``${path:jbuild}`` will expand to ``src/foo/jbuild``. When you run various tools, they often use the filename given on the command line in error messages. As a result, if you execute the command from the original directory, it will only see the basename. To understand why this is important, let's consider this jbuild living in ``src/foo``: :: (rule ((targets (blah.ml)) (deps (blah.mll)) (action (run ocamllex -o ${@} ${<})))) Here the command that will be executed is: .. code:: bash ocamllex -o blah.ml blah.mll And it will be executed in ``_build//src/foo``. As a result, if there is an error in the generated ``blah.ml`` file it will be reported as: :: File "blah.ml", line 42, characters 5-10: Error: ... Which can be a problem as you editor might think that ``blah.ml`` is at the root of your project. What you should write instead is: :: (rule ((targets (blah.ml)) (deps (blah.mll)) (action (chdir ${ROOT} (run ocamllex -o ${@} ${<}))))) Locks ----- Given two rules that are independent, Jbuilder will assume that there associated action can be run concurrently. Two rules are considered independent if none of them depend on the other, either directly or through a chain of dependencies. This basic assumption allows to parallelize the build. However, it is sometimes the case that two independent rules cannot be executed concurrently. For instance this can happen for more complicated tests. In order to prevent jbuilder from running the actions at the same time, you can specify that both actions take the same lock: .. code:: scheme (alias ((name runtest) (deps (foo)) (locks (m)) (action (run test.exe ${<})))) (alias ((name runtest) (deps (bar)) (locks (m)) (action (run test.exe ${<})))) Jbuilder will make sure that the executions of ``test.exe foo`` and ``test.exe bar`` are serialized. Although they don't live in the filesystem, lock names are interpreted as file names. So for instance ``(with-lock m ...)`` in ``src/jbuild`` and ``(with-lock ../src/m)`` in ``test/jbuild`` refer to the same lock. Note also that locks are per build context. So if your workspace has two build contexts setup, the same rule might still be executed concurrently between the two build contexts. If you want a lock that is global to all build contexts, simply use an absolute filename: .. code:: scheme (alias ((name runtest) (deps (foo)) (locks (/tcp-port/1042)) (action (run test.exe ${<})))) .. _ocaml-syntax: Diffing and promotion --------------------- ``(diff )`` is very similar to ``(run diff )``. In particular it behaves in the same way: - when ```` and ```` are equal, it doesn't nothing - when they are not, the differences are shown and the action fails However, it is different for the following reason: - the exact command used to diff files can be configured via the ``--diff-command`` command line argument. Note that it is only called when the files are not byte equals - by default, it will use ``patdiff`` if it is installed. ``patdiff`` is a better diffing program. You can install it via opam with: .. code:: sh $ opam install patdiff - since ``(diff a b)`` is a builtin action, Jbuilder knowns that ``a`` and ``b`` are needed and so you don't need to specify them explicitly as dependencies - you can use ``(diff? a b)`` after a command that might or might not produce ``b``. For cases where commands optionally produce a *corrected* file - it allows promotion. See below Promotion ~~~~~~~~~ Whenever an action ``(diff )`` or ``(diff? )`` fails because the two files are different, jbuilder allows you to promote ```` as ```` if ```` is a source file and ```` is a generated file. More precisely, let's consider the following jbuild file: .. code:: scheme (rule (with-stdout-to data.out (run ./test.exe))) (alias ((name runtest) (action (diff data.expected data.out)))) Where ``data.expected`` is a file committed in the source repository. You can use the following workflow to update your test: - update the code of your test - run ``jbuilder runtest``. The diff action will fail and a diff will be printed - check the diff to make sure it is what you expect - run ``jbuilder promote``. This will copy the generated ``data.out`` file to ``data.expected`` directly in the source tree You can also use ``jbuilder runtest --auto-promote`` which will automatically do the promotion. OCaml syntax ============ If a ``jbuild`` file starts with ``(* -*- tuareg -*- *)``, then it is interpreted as an OCaml script that generates the ``jbuild`` file as described in the rest of this section. The code in the script will have access to a `Jbuild_plugin `__ module containing details about the build context it is executed in. The OCaml syntax gives you an escape hatch for when the S-expression syntax is not enough. It is not clear whether the OCaml syntax will be supported in the long term as it doesn't work well with incremental builds. It is possible that it will be replaced by just an ``include`` stanza where one can include a generated file. Consequently **you must not** build complex systems based on it.