From 2b49123ae17dee0ad0fee1013ea01d02900e25e1 Mon Sep 17 00:00:00 2001 From: Jeremie Dimino Date: Thu, 21 Dec 2017 19:59:09 +0800 Subject: [PATCH] Update documentation to reflect cross compilation Describes how to setup targets and toolchains and the changes to the workspace syntax. --- doc/advanced-topics.rst | 93 +++++++++++++++++++++++++++++++++++++++++ doc/usage.rst | 27 ++++++++---- 2 files changed, 113 insertions(+), 7 deletions(-) diff --git a/doc/advanced-topics.rst b/doc/advanced-topics.rst index 73aa90fd..640cb7a9 100644 --- a/doc/advanced-topics.rst +++ b/doc/advanced-topics.rst @@ -102,6 +102,99 @@ set of predicates: it is linked as part of a driver or meant to add a ``-ppx`` argument to the compiler, choose the former behavior +Cross Compilation +================= + +Jbuilder allows for cross compilation by defining build contexts with +multiple targets. Targets are specified by adding a ``targets`` field +to the definition of a build context. + +``targets`` takes a list of target name. It can be either: + +- ``native`` which means using the native tools that can build + binaries that run on the machine doing the build + +- the name of an alternative toolchain + +Note that at the moment, there is no official support for +cross-compilation in OCaml. Jbuilder supports the two following +opam-cross-x repositories: + +- `opam-cross-windows `_ +- `opam-cross-android `_ + +To build Windows binaries using opam-cross-windows, write ``windows`` +in the list of targets. To build Android binaries using +opam-cross-android, write ``android`` in the list of targets. + +For example, the following workspace file defines three different +targets for the ``default`` build context: + +.. code:: scheme + + (context (default (targets (native windows android)))) + +This configuration defines three build contexts: + +- ``default`` +- ``default.windows`` +- ``default.android`` + +Note that the ``native`` target is always implicitly added when not +present. However, when implicitly added ``jbuilder build @install`` +will skip this context, i.e. ``default`` will only be used for +building executables needed by the other contexts. + +With such a setup, calling ``jbuilder build @install`` will build all +the packages three times. + +Note that instead of writing a ``jbuild-workspace`` file, you can also +use the ``-x`` command line option. Passing ``-x foo`` to ``jbuilder`` +without having a ``jbuild-workspace`` file is the same as writing the +following ``jbuild-workspace`` file: + +.. code:: scheme + + (context (default (targets (foo)))) + +If you have a ``jbuild-workspace`` and pass a ``-x foo`` option, +``foo`` will be added as target of all context stanzas. + +How does it work? +----------------- + +In such a setup, binaries that need to be built and executed in the +``default.windows`` or ``default.android`` contexts as part of the +build, will no longer be executed. Instead, all the binaries that will +be executed will come from the ``default`` context. One consequence of +this is that all preprocessing (ppx or otherwise) will be done using +binaries built in the ``default`` context. + +To clarify this with an example, let's assume that you have the +following ``src/jbuild`` file: + +.. code:: scheme + + (executable ((name foo))) + (rule (with-stdout-to blah (run ./foo.exe))) + +When building ``_build/default/src/blah``, jbuilder will resolve ``./foo.exe`` to +``_build/default/src/foo.exe`` as expected. However, for +``_build/default.windows/src/blah`` jbuilder will resolve ``./foo.exe`` to +``_build/default/src/foo.exe`` + +Assuming that the right packages are installed or that your workspace +has no external dependencies, jbuilder will be able to cross-compile a +given package without doing anything special. + +Some packages might still have to be updated to support cross-compilation. For +instance if the ``foo.exe`` program in the previous example was using +``Sys.os_type``, it should instead take it as a command line argument: + +.. code:: scheme + + (rule (with-stdout-to blah (run ./foo.exe -os-type ${os_type}))) + Classical ppx ============= diff --git a/doc/usage.rst b/doc/usage.rst index 4c81b382..0aa183b9 100644 --- a/doc/usage.rst +++ b/doc/usage.rst @@ -334,9 +334,9 @@ a typical ``jbuild-workspace`` file looks like: .. code:: scheme - (context ((switch 4.02.3))) - (context ((switch 4.03.0))) - (context ((switch 4.04.0))) + (context (opam (switch 4.02.3))) + (context (opam (switch 4.03.0))) + (context (opam (switch 4.04.0))) The rest of this section describe the stanzas available. @@ -354,13 +354,13 @@ context ~~~~~~~ The ``(context ...)`` stanza declares a build context. The argument -can be either ``default`` for the default build context or can be the -description of an opam switch, as follows: +can be either ``default`` or ``(default)`` for the default build +context or can be the description of an opam switch, as follows: .. code:: scheme - (context ((switch ) - )) + (context (opam (switch ) + )) ```` are: @@ -374,6 +374,10 @@ description of an opam switch, as follows: - ``(merlin)`` instructs Jbuilder to use this build context for merlin +Both ``(default ...)`` and ``(opam ...)`` accept a ``targets`` field +in order to setup cross compilation. See `Cross Compilation`_ for more +information. + Merlin reads compilation artifacts and it can only read the compilation artifacts of a single context. Usually, you should use the artifacts from the ``default`` context, and if you have the @@ -384,6 +388,15 @@ For rare cases where this is not what you want, you can force Jbuilder to use a different build contexts for merlin by adding the field ``(merlin)`` to this context. +Note that the following syntax is still accepted but is deprecated: + +.. code:: scheme + + (context ((switch ) + )) + +it is interpreted the same as ``(context (opam (switch ...) ...))``. + Building JavaScript with js_of_ocaml ====================================