Git Product home page Git Product logo

dune's Introduction

⚠️ CAUTION

The developer team released OCaml 5.0.0 in December 2022. This release sports a full rewrite of its runtime system for shared-memory parallel programming using domains and native support for concurrent programming using effect handlers.

Owing to the large number of changes, the initial 5.0 release is more experimental than usual. It is recommended that all users wanting a stable release use the 4.14 release which will continue to be supported and updated while 5.x reaches feature and stability parity. Similarly, if you need one of the ports not yet supported in the 5.0 release you must use the 4.14 release.

The initial release of OCaml 5.0 only supports the native compiler under ARM64 and x86-64 architectures under Linux, macOS and the BSDs. On Windows, only the MinGW-w64 port is supported in OCaml 5.0 and the Cygwin port is restored in 5.1. On Linux, native code support for RISC-V and s390x/IBM Z is available in OCaml 5.1 and in 5.2 for Power.

❗ From OCaml 5.0 onwards, native compilation is available only on 64-bit systems. Native compilation on 32-bit systems is no longer available, nor are there plans to bring it back. The bytecode compiler will continue to work on all architectures.

Branch trunk Branch 5.2 Branch 5.1 Branch 5.0 Branch 4.14

Github CI Build Status (trunk branch) Github CI Hygiene Status (trunk branch) AppVeyor Build Status (trunk branch)

Github CI Build Status (5.2 branch) AppVeyor Build Status (5.2 branch)

Github CI Build Status (5.1 branch) AppVeyor Build Status (5.1 branch)

Github CI Build Status (5.0 branch) AppVeyor Build Status (5.0 branch)

Github CI Build Status (4.14 branch) AppVeyor Build Status (4.14 branch)

README

Overview

OCaml is a functional, statically-typed programming language from the ML family, offering a powerful module system extending that of Standard ML and a feature-rich, class-based object system.

OCaml comprises two compilers. One generates bytecode which is then interpreted by a C program. This compiler runs quickly, generates compact code with moderate memory requirements, and is portable to many 32 or 64 bit platforms. Performance of generated programs is quite good for a bytecoded implementation. This compiler can be used either as a standalone, batch-oriented compiler that produces standalone programs, or as an interactive REPL system.

The other compiler generates high-performance native code for a number of processors. Compilation takes longer and generates bigger code, but the generated programs deliver excellent performance, while retaining the moderate memory requirements of the bytecode compiler. The native-code compiler currently runs on the following platforms:

Tier 1 (actively maintained) Tier 2 (maintained when possible)

x86 64 bits

Linux, macOS, Windows, FreeBSD

NetBSD, OpenBSD, OmniOS (Solaris)

ARM 64 bits

Linux, macOS

FreeBSD, OpenBSD, NetBSD

Power 64 bits

Linux (little-endian, ABIv2)

Linux (big-endian, ABIv2)

RISC-V 64 bits

Linux

IBM Z (s390x)

Linux

Other operating systems for the processors above have not been tested, but the compiler may work under other operating systems with little work.

All files marked "Copyright INRIA" in this distribution are Copyright © 1996-2023 Institut National de Recherche en Informatique et en Automatique (INRIA) and distributed under the conditions stated in file LICENSE.

Installation

See the file INSTALL.adoc for installation instructions on machines running Unix, Linux, macOS, WSL and Cygwin. For native Microsoft Windows, see README.win32.adoc.

Documentation

The OCaml manual is distributed in HTML, PDF, and Emacs Info files. It is available at

Availability

The complete OCaml distribution can be accessed at

Releases

More information about when and how new releases of OCaml are published is available at release-info/introduction.md, see also release-info/calendar.md for a prospective calendar for future OCaml versions. For past versions, release-info/News contains a short description of major changes in previous versions.

Keeping in Touch with the Caml Community

There is an active and friendly discussion forum at

The OCaml mailing list is the longest-running forum for OCaml users. You can email it at

You can subscribe and access list archives via the Web interface at

There also exist other mailing lists, chat channels, and various other forums around the internet for getting in touch with the OCaml and ML family language community. These can be accessed at

In particular, the IRC channel #ocaml on Libera has a long history and welcomes questions.

Bug Reports and User Feedback

Please report bugs using the issue tracker at https://github.com/ocaml/ocaml/issues

To be effective, bug reports should include a complete program (preferably small) that exhibits the unexpected behavior, and the configuration you are using (machine type, etc).

Contributing

For information on contributing to OCaml, see HACKING.adoc and CONTRIBUTING.md.

Separately maintained components

Some libraries and tools which used to be part of the OCaml distribution are now maintained separately and distributed as OPAM packages. Please use the issue trackers at their respective new homes:

Library Removed since OPAM package

The Stream and Genlex standard library modules

OCaml 5.0

camlp-streams

The Graphics library

OCaml 4.09

graphics

The Num library

OCaml 4.06

num

The OCamlbuild tool

OCaml 4.03

ocamlbuild

The camlp4 tool

OCaml 4.02

camlp4

The LablTk library

OCaml 4.02

labltk

The CamlDBM library

OCaml 4.00

dbm

The OCamlWinTop Windows toplevel

OCaml 4.00

none

dune's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dune's Issues

How to add support for capnp code generation?

I wanted to tell jbuilder how to build OCaml files from capnp schema files. I tried:

 ((targets (%.ml %.mli))
  (deps (%.capnp))
  (action (run capnpc -o ocaml ${<}))))

But it seems that doesn't work. It would be good to say something about this in the manual (even if it's that it isn't possible).

Incorrect hint

# Error: Findlib package "irmin-mem" not found.
# -> required by "test/irmin-mem/jbuild (context default)"
# Hint: try: jbuilder external-lib-deps --missing -p irmin-mirage -j 4

But then:

$ jbuilder external-lib-deps --missing -p irmin-mirage
jbuilder: required argument TARGET is missing
Usage: jbuilder external-lib-deps [OPTION]... TARGET...
Try `jbuilder external-lib-deps --help' or `jbuilder --help' for more information.

Run tests command

I understand this isn't implemented yet, but it's a pre-requisite for me to actually use jbuilder in a couple of open source projects. What's the ETA on having this?

If this isn't a priority, then perhaps I can help on this?

Error: no packages are defined here

I was trying to come up with some very little project that shows, hopefully, how to use jbuilder, because at least for me it's a bit mystical; that project is here: https://github.com/alinpopa/jbuilder_example01

Trying to build it using the bellow command, and I'm getting the following error, which doesn't really make too much sense to me:

jbuilder build --debug-actions --debug-dependency-path --debug-rules --debug-findlib @install

Workspace root: /Users/alin/work/ocaml/jbuilder_example01
File "bin/jbuild", line 1, characters 0-0:
Error: no packages are defined here

I believe that I'm trying to find out what's the magical incantation to build a proper project, with some minimalistic structure, only very few modules, etc. I'd think that having an example project, more than a very simple one liner hello world, would help a bit with starting working with jbuilder (at least this would help me, but I wasn't able to find a proper simple project, without using a mix of opam/make/merlin files, which confuses me a lot).
Sorry, I'd have raise this as a question on some mailinglist/slack channel/something, but turns out that there is no such communication channel? For example, a JaneStreet OCaml mailing list, or anything... is this mailing list something I could use for such a topic? https://groups.google.com/forum/#!forum/ocaml-core

Thanks.

clean subcommand

A command to delete _build and all targets by jbuilder would be nice to have

Can't build jbuilder

First off, I'd like to apologize in advance if this is not the proper location for this. I can not find any information on how to install jbuilder, nor can I find any information on a mailing list or some means to contact the project community regarding my problems trying to install this software.

I see there is a Makefile, so I type make:
ocaml bootstrap.ml
File "bootstrap.ml", line 11, characters 5-8:
Error: Syntax error
make: *** [boot.exe] Error 2

I can only assume that my version of ocaml is old. I'm trying to install jbuilder on CentOS 7 (as is necessary for some other software).

rpm -qa | grep ocaml
ocaml-4.01.0-22.7.el7_2.x86_64
ocaml-runtime-4.01.0-22.7.el7_2.x86_64
ocaml-findlib-1.3.3-6.el7.x86_64
ocaml-compiler-libs-4.01.0-22.7.el7_2.x86_64

How to use normal ppx rewriters?

I see the following passage in the manual:

You are however free to use ppx rewriters that are not based on ppx_driver in
this list, since ppx_driver is able to import rewriters that where not
designed for ppx_driver.

But I'm not sure how to enable things like js_of_ocaml.ppx for example. As the only preprocessors that seem to work are jane street's.

Would be nice to update the quickstart manual with an example for this as well by the way. Some non jane street preprocessors are quite common.

bugfix

diff --git a/src/future.ml b/src/future.ml
index 58174ca..9153c35 100644
--- a/src/future.ml
+++ b/src/future.ml
@@ -387,7 +387,7 @@ module Scheduler = struct
        | [s] -> Format.fprintf ppf "%s" s
        | (x :: _) as group ->
           Format.fprintf ppf "%s.{%a}"
-            (Filename.chop_extension x)
+            (Filename.remove_extension x)
             (Format.pp_print_list ~pp_sep:pp_comma pp_ext)
             group in
      let pp_contexts ppf = function

no rule found for .merlin-exists

When I follow the instructions for building hello world in the quick start guide, I get

$ jbuilder build hello_world.exe
Workspace root: /home/nathan/pill/src/hello-world
Running[0]: /home/nathan/.opam/4.04.0/bin/ocamlc.opt -config > /tmp/jbuildcad7cf.output
Running[1]: /home/nathan/.opam/4.04.0/bin/ocamlfind printconf path > /tmp/jbuild71440f.output
Running[2]: /usr/local/bin/opam config var lib > /tmp/jbuildc7d285.output
Actual targets:
- _build/default/hello_world.exe
No rule found for _build/default/.merlin-exists

.mli only modules

When porting cohttp to jbuilder, I discovered that .mli only modules don't seem to work. Since ocamlbuild supports them, it would be great if jbuilder would as well.

Project broken with jbuilder HEAD

[vb@haramis ~/code/bitsouk/bs_devkit]% make
jbuilder build @install
Workspace root: /home/vb/code/bitsouk/bs_devkit
Running[0]: /home/vb/.opam/4.04.0/bin/ocamlfind printconf path > /tmp/jbuild592f1a.output
Running[1]: /home/vb/.opam/4.04.0/bin/ocamlc.opt -config > /tmp/jbuild78d33e.output
Actual targets:
- alias install
Running[2]: (cd _build/default && ../.ppx/default/ppx_bin_prot+ppx_sexp_conv/ppx.exe -dirname src --dump-ast -o src/bs_devkit.pp.ml --impl src/bs_devkit.ml)

Command [2] exited with code 2:
$ (cd _build/default && ../.ppx/default/ppx_bin_prot+ppx_sexp_conv/ppx.exe -dirname src --dump-ast -o src/bs_devkit.pp.ml --impl src/bs_devkit.ml)
../.ppx/default/ppx_bin_prot+ppx_sexp_conv/ppx.exe: unknown option '-dirname'.
ppx.exe [options] [<files>]
  --as-ppx                    Act as a -ppx rewriter
  --dump-ast                  Output a binary AST instead of source code
  -o FILE                     Output to this file instead of the standard output
  --intf FILE                 Treat FILE as a .mli file
  --impl FILE                 Treat FILE as a .ml file
  --cookie NAME=EXPR          Set the cookie NAME to EXPR
  -loc-filename <string>      File name to use in locations
  -reserve-namespace <string> Mark the given namespace as reserved
  -no-check                   Disable checks (unsafe)
  -apply <names>              Apply these transformations in order (comma-separated list)
  -dont-apply <names>         Exclude these transformations
  -no-merge                   Do not merge context free transformations (better for debugging rewriters)
  -help                       Display this list of options
  --help                      Display this list of options
make: *** [Makefile:2: all] Error 1

I'm getting this. It seems the compiled ppx executable is called with an option it does not support. Maybe you will understand something from this log…

Include subdirectories

I'm trying to convert to jbuilder an existing project that contains its sources spread in different sub-directories (~140 ml files). It seems that jbuilder looks only to sub-directories in order to find sub-libraries or just file to copy. Is it the case?

I'm trying to add a stanza (includes (sub_dirs (dirs)) that would tell to also look at these directories for .h, .ml, .mli, as if they where in the jbuild directory. It is not in the roadmap, but is it ok?

It seems to require to change quite a lot of types, such as in Module the ml_fname and mli_fname fields from string to Path.t.

Latest version of ppx_deriving not working with jbuilder

Hi,
I have pinned the latest version of https://github.com/whitequark/ppx_deriving which implements migrate_parsetree based ppx. However, using (preprocess (pps (ppx_deriving.std))) doesn't seem to apply any ppx_deriving based transformations. Is my usage not correct? If so could you please provide guidance of how we can use ppx_deriving with jbuilder.

I opened an issue is ppx_deriving but I got directed here instead.
ocaml-ppx/ppx_deriving#134 (comment)

per_file support for flags

I would like to change the flags on a specific file (e.g. a generated file where I want to disable some warnings). Is this currently possible? If not, I think using something like this could be useful:

(flags (per_file (<flag> (module-list)))

"key "CAML_LD_LIBRARY_PATH" present multiple times"

Not sure if it's an opam 2 bug or a jbuilder one. cc @AltGr

When I use the workspace feature (after doing eval `opam config env --switch 4.03.0` ) I get:

Running[1]: /usr/bin/opam config env --root /home/gabriel/.opam --switch 4.04.0 --sexp > /tmp/jbuild5f4db6.output
File "", line 1, characters 0-796:
Error: key "CAML_LD_LIBRARY_PATH" present multiple times

And indeed, the relevant piece of the opam output is:

  ("CAML_LD_LIBRARY_PATH" "/home/gabriel/.opam/4.04.0/lib/stublibs")
  ("CAML_LD_LIBRARY_PATH" "/home/gabriel/.opam/4.04.0/lib/ocaml/stublibs:/home/gabriel/.opam/4.04.0/lib/ocaml")
  ("CAML_LD_LIBRARY_PATH" "/home/gabriel/.opam/4.04.0/lib/stublibs:/home/gabriel/.opam/4.04.0/lib/ocaml/stublibs:/home/gabriel/.opam/4.04.0/lib/ocaml")

I'm not sure which of opam or jbuilder should be made more resilient here. I would guess both. :p

ppx_jane+ppx_driver.runner error: unknown option '-embed-errors'

I'm using jbuilder 1.0+beta3.
I'm trying to use ppx_jane, because I'm using [@@deriving sexp] for one of my type, but I can't really make jbuilder work with it.
jbuild file:

(jbuild_version 1)

(executables
 ((names (myparsing))
  (libraries (core))
  (preprocess (pps (ppx_jane ppx_driver.runner)))
))

jbuilder log:

# jbuilder build myparsing.exe
$ /home/stryker/.opam/system/bin/ocamlfind printconf path > /tmp/jbuild743bf3.output
$ /usr/bin/ocamlc.opt -config > /tmp/jbuild78e625.output
> Warning: discarding value of variable "color" in OCAMLPARAM
$ /usr/bin/opam config var lib > /tmp/jbuildbed18f.output
# Jbuilder context:
#  ((name default)
#   (kind default)
#   (merlin true)
#   (for_host ())
#   (build_dir _build/default)
#   (toplevel_path (/home/stryker/.opam/system/lib/toplevel))
#   (ocaml_bin /usr/bin)
#   (ocaml /usr/bin/ocaml)
#   (ocamlc /usr/bin/ocamlc.opt)
#   (ocamlopt (/usr/bin/ocamlopt.opt))
#   (ocamldep /usr/bin/ocamldep.opt)
#   (ocamllex /usr/bin/ocamllex.opt)
#   (ocamlyacc /usr/bin/ocamlyacc)
#   (ocamlmklib /usr/bin/ocamlmklib)
#   (env ())
#   (findlib_path (/home/stryker/.opam/system/lib))
#   (arch_sixtyfour true)
#   (natdynlink_supported true)
#   (opam_vars ((lib /home/stryker/.opam/system/lib)))
#   (ocamlc_config
#    ((architecture amd64)
#     (asm as)
#     (asm_cfi_supported true)
#     (ast_impl_magic_number Caml1999M016)
#     (ast_intf_magic_number Caml1999N015)
#     (bytecomp_c_compiler
#      "gcc -O  -D_FILE_OFFSET_BITS=64 -D_REENTRANT -O -fPIC")
#     (bytecomp_c_libraries "-lm  -ldl -lcurses -lpthread")
#     (cc_profile -pg)
#     (ccomp_type cc)
#     (cma_magic_number Caml1999A011)
#     (cmi_magic_number Caml1999I017)
#     (cmo_magic_number Caml1999O010)
#     (cmt_magic_number Caml2012T004)
#     (cmx_magic_number Caml1999Y014)
#     (cmxa_magic_number Caml1999Z013)
#     (cmxs_magic_number Caml2007D002)
#     (default_executable_name a.out)
#     (exec_magic_number Caml1999X011)
#     (ext_asm .s)
#     (ext_dll .so)
#     (ext_lib .a)
#     (ext_obj .o)
#     (host x86_64-pc-linux-gnu)
#     (model default)
#     (native_c_compiler "gcc -O  -D_FILE_OFFSET_BITS=64 -D_REENTRANT")
#     (native_c_libraries "-lm  -ldl")
#     (native_pack_linker "ld -r --hash-style=both --as-needed --build-id -o ")
#     (os_type Unix)
#     (ranlib ranlib)
#     (standard_library /usr/lib/ocaml)
#     (standard_library_default /usr/lib/ocaml)
#     (standard_runtime /usr/bin/ocamlrun)
#     (system linux)
#     (systhread_supported true)
#     (target x86_64-pc-linux-gnu)
#     (version 4.02.3)
#     (with_frame_pointers false)))
#   (which
#    ((ocamlc (/usr/bin/ocamlc.opt))
#     (ocamlfind (/home/stryker/.opam/system/bin/ocamlfind)))))
$ (cd _build/default && ../.ppx/default/ppx_jane+ppx_driver.runner/ppx.exe -dirname . -inline-test-drop-with-deadcode -bench-drop-with-deadcode -embed-errors false --dump-ast -o myparsing.pp.ml --impl myparsing.ml)
> ../.ppx/default/ppx_jane+ppx_driver.runner/ppx.exe: unknown option '-embed-errors'.
> ppx.exe [extra_args] [<files>]
>   -dirname <dir>                   Name of the current directory relative to the root of the project
>   -inline-test-lib                 A base name to use for generated identifiers (has to be globally unique in a program).ppx_inline_test (and ppx_bench) are disabled unless this flag is passed.
>   -inline-test-drop                Drop unit tests
>   -inline-test-drop-with-deadcode  Drop unit tests by wrapping them inside deadcode to prevent unused variable warnings.
>   -bench-drop                      Drop inline benchmarks
>   -bench-drop-with-deadcode        Drop inline benchmarks by wrapping them inside deadcode to prevent unused variable warnings.
>   -as-ppx                          Run as a -ppx rewriter (must be the first argument)
>   -o <filename>                    Output file (use '-' for stdout)
>   -reserve-namespace <string>      Mark the given namespace as reserved
>   -loc-filename <string>           File name to use in locations
>   -no-optcomp                      Do not use optcomp
>   -dump-ast                        Dump the marshaled ast to the output file instead of pretty-printing it
>   -dparsetree                      Print the parsetree (same as ocamlc -dparsetree)
>   -impl <file>                     Treat the input as a .ml file
>   -intf <file>                     Treat the input as a .mli file
>   -no-check                        Disable checks (unsafe)
>   -debug-attribute-drop            Debug attribute dropping
>   -print-transformations           Print linked-in code transformations, in the order they are applied
>   -apply <names>                   Apply these transformations in order (comma-separated list)
>   -help                            Display this list of options
>   --help                           Display this list of options
[2]

Customize --dev options

I would like to be able to customize the options added by --dev (I personally dislike 6 and 9 in some code bases).

I think it would also be nice to have -keep-locs and -short-paths there too.

Invalid META files cause jbuilder to crash

If a sub-package of an installed META file jbuilder looks at contain a dependency to a library that is not installed, jbuilder crashes immediately. It should crash only if we try to use this sub-package

Build fails with "Path.Local.parent called on the root"

After I got the most basic hello world program running from the quick start guide, I then tried to build a program that depends on Core. It failed with the error message mentioned in the issue title.

More concretely, this bash snippet

set -x
cat hello_world.ml
cat jbuild
cat jbuild-workspace
jbuilder build hello_world.exe || echo FAILED
cat _build/log

yields

+ cat hello_world.ml
open Core.Std

let command =
  let open Command.Let_syntax in
  Command.basic' ~summary:"say hello to the world"
    [%map_open
     let () = return ()
     in
     fun () ->
       print_endline "Hello, world!"
    ]
+ cat jbuild
;; -*- mode: lisp -*-

(jbuild_version 1)

(executables
 ((names (hello_world))
  (libraries (core))))
+ cat jbuild-workspace
;; -*- mode: lisp -*-
(context (
 (switch system)
 (merlin false)
))
+ jbuilder build hello_world.exe
Workspace root: /home/nathan/pill/src/hello-world
Running[0]: /usr/local/bin/opam config var root > /tmp/jbuild1cabf7.output
Running[1]: /usr/local/bin/opam config env --root /home/nathan/.opam --switch system --sexp > /tmp/jbuildb8308b.output
Running[2]: /usr/bin/ocamlc -config > /tmp/jbuild733b0a.output
Running[3]: /usr/bin/ocamlfind printconf path > /tmp/jbuildaf51b3.output
Running[4]: /usr/local/bin/opam config var lib > /tmp/jbuild796e42.output
Actual targets:
- _build/system/hello_world.exe
Internal error, please report upstream including the contents of _build/log.
Description: Path.Local.parent called on the root
Backtrace:
Raised at file "src/import.ml", line 20, characters 43-65
Called from file "src/lib_db.ml", line 19, characters 43-60
Called from file "src/lib_db.ml", line 19, characters 16-60
Called from file "src/lib_db.ml", line 19, characters 16-60
Called from file "src/lib_db.ml" (inlined), line 24, characters 14-45
Called from file "src/lib_db.ml", line 28, characters 8-42
Called from file "src/lib_db.ml", line 123, characters 43-68
Called from file "src/build_system.ml", line 201, characters 8-16
Called from file "src/build_system.ml", line 214, characters 16-24
Called from file "src/build_system.ml", line 201, characters 8-16
Called from file "src/build_system.ml", line 201, characters 8-16
Called from file "src/build_system.ml", line 231, characters 17-38
Called from file "src/build_system.ml", line 314, characters 27-53
Called from file "src/future.ml", line 93, characters 8-12
+ echo FAILED
FAILED
+ cat _build/log
# jbuilder build hello_world.exe
$ /usr/local/bin/opam config var root > /tmp/jbuild1cabf7.output
$ /usr/local/bin/opam config env --root /home/nathan/.opam --switch system --sexp > /tmp/jbuildb8308b.output
$ /usr/bin/ocamlfind printconf path > /tmp/jbuildaf51b3.output
$ /usr/local/bin/opam config var lib > /tmp/jbuild796e42.output
$ /usr/bin/ocamlc -config > /tmp/jbuild733b0a.output
# Jbuilder context:
#  ((name system)
#   (kind ((root /home/nathan/.opam) (switch system)))
#   (merlin false)
#   (for_host ())
#   (build_dir _build/system)
#   (toplevel_path (/home/nathan/.opam/system/lib/toplevel))
#   (ocaml_bin /usr/bin)
#   (ocaml /usr/bin/ocaml)
#   (ocamlc /usr/bin/ocamlc)
#   (ocamlopt (/usr/bin/ocamlopt))
#   (ocamldep /usr/bin/ocamldep)
#   (ocamllex /usr/bin/ocamllex)
#   (ocamlyacc /usr/bin/ocamlyacc)
#   (ocamlmklib /usr/bin/ocamlmklib)
#   (env
#    ((CAML_LD_LIBRARY_PATH
#      /home/nathan/.opam/system/lib/stublibs:/usr/lib/ocaml/stublibs)
#     (MANPATH :/home/nathan/.opam/system/man)
#     (OCAML_TOPLEVEL_PATH /home/nathan/.opam/system/lib/toplevel)
#     (OPAMSWITCH system)
#     (PATH
#      /home/nathan/.opam/system/bin:/home/nathan/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin)
#     (PERL5LIB /home/nathan/.opam/system/lib/perl5)))
#   (findlib_path
#    (/usr/lib/ocaml/METAS
#     /usr/lib/ocaml
#     /usr/local/lib/ocaml/4.02.3
#     /home/nathan/.opam/system/lib))
#   (arch_sixtyfour true)
#   (natdynlink_supported true)
#   (opam_vars ((lib /home/nathan/.opam/system/lib) (root /home/nathan/.opam)))
#   (ocamlc_config
#    ((architecture amd64)
#     (asm as)
#     (asm_cfi_supported true)
#     (ast_impl_magic_number Caml1999M016)
#     (ast_intf_magic_number Caml1999N015)
#     (bytecomp_c_compiler
#      "gcc -O  -D_FILE_OFFSET_BITS=64 -D_REENTRANT -O -fPIC")
#     (bytecomp_c_libraries "-lm  -ldl -lcurses -lpthread")
#     (cc_profile -pg)
#     (ccomp_type cc)
#     (cma_magic_number Caml1999A011)
#     (cmi_magic_number Caml1999I017)
#     (cmo_magic_number Caml1999O010)
#     (cmt_magic_number Caml2012T004)
#     (cmx_magic_number Caml1999Y014)
#     (cmxa_magic_number Caml1999Z013)
#     (cmxs_magic_number Caml2007D002)
#     (default_executable_name a.out)
#     (exec_magic_number Caml1999X011)
#     (ext_asm .s)
#     (ext_dll .so)
#     (ext_lib .a)
#     (ext_obj .o)
#     (host x86_64-pc-linux-gnu)
#     (model default)
#     (native_c_compiler "gcc -O  -D_FILE_OFFSET_BITS=64 -D_REENTRANT")
#     (native_c_libraries "-lm  -ldl")
#     (native_pack_linker "ld -r --hash-style=both --as-needed --build-id -o ")
#     (os_type Unix)
#     (ranlib ranlib)
#     (standard_library /usr/lib/ocaml)
#     (standard_library_default /usr/lib/ocaml)
#     (standard_runtime /usr/bin/ocamlrun)
#     (system linux)
#     (systhread_supported true)
#     (target x86_64-pc-linux-gnu)
#     (version 4.02.3)
#     (with_frame_pointers false)))
#   (which ((ocamlc (/usr/bin/ocamlc)) (ocamlfind (/usr/bin/ocamlfind)))))

jbuilder adding findlib path of local library

See my attempt at porting cohttp to jbuilder: mirage/ocaml-cohttp#533

The relevant jbuild files:

lwt/jbuild

(jbuild_version 1)

(library
 ((name cohttp_lwt_unix)
  (public_name cohttp-lwt-unix)
  (wrapped false)
  (libraries (conduit.lwt-unix magic-mime lwt.unix cohttp cohttp-lwt))))

lwt-core/jbuild

(jbuild_version 1)

(library
 ((name cohttp_lwt)
  (public_name cohttp-lwt)
  (preprocess (pps (ppx_sexp_conv)))
  (wrapped false)
  (libraries (lwt uri cohttp))))

And yet jbuilder is adding <switch>/lib/cohttp to the include path

Running[2]: (cd _build/default && /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/bin/ocamlopt.opt -w -40 -g -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/base -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/base/caml -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/base/shadow_stdlib -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/base64 -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/bytes -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/cohttp -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/fieldslib -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/lwt -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/ocaml -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/re -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/result -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/sexplib -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/sexplib/0 -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/stringext -I /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/lib/uri -no-alias-deps -I lwt-core -o lwt-core/cohttp_lwt.cmx -c -impl lwt-core/cohttp_lwt.pp.ml)
Running[3]: (cd _build/default && /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/bin/ocamlc.opt -w -40 -g -a -o lwt-core/cohttp_lwt.cma lwt-core/cohttp_lwt_body.cmo lwt-core/cohttp_lwt_s.cmo lwt-core/cohttp_lwt.cmo lwt-core/string_io_lwt.cmo)

Command [3] exited with code 2:
$ (cd _build/default && /home/rgrinberg/.opam/ocaml-base-compiler.4.04.0/bin/ocamlc.opt -w -40 -g -a -o lwt-core/cohttp_lwt.cma lwt-core/cohttp_lwt_body.cmo lwt-core/cohttp_lwt_s.cmo lwt-core/cohttp_lwt.cmo lwt-core/string_io_lwt.cmo)
File "_none_", line 1:
Error: Files lwt-core/cohttp_lwt.cmo and lwt-core/cohttp_lwt_s.cmo
       make inconsistent assumptions over interface Cohttp_lwt_s

compiling exe fails with "No rule found for _build/default/.merlin-exists"

[ben@euler .../toys/hello-jbuild/qs1]$ ls
hello_world.ml  jbuild

[ben@euler .../toys/hello-jbuild/qs1]$ cat hello_world.ml
print_endline "Hello, world!"

[ben@euler .../toys/hello-jbuild/qs1]$ cat jbuild
(executables (
  (names (hello_world))
  (libraries ())
))

[ben@euler .../toys/hello-jbuild/qs1]$ jbuilder build hello_world.exe
Workspace root: /home/ben/code/ocaml/toys/hello-jbuild/qs1
Running[0]: /usr/bin/ocamlc.opt -config > /tmp/jbuild1c997e.output
Running[1]: /usr/local/bin/opam config var lib > /tmp/jbuilde571d9.output
Actual targets:
- _build/default/hello_world.exe
No rule found for _build/default/.merlin-exists

[ben@euler .../toys/hello-jbuild/qs1]$ cat _build/log 
# jbuilder build hello_world.exe
$ /usr/bin/ocamlc.opt -config > /tmp/jbuild1c997e.output
$ /usr/local/bin/opam config var lib > /tmp/jbuilde571d9.output
# Jbuilder context:
#  ((name default)
#   (kind default)
#   (merlin true)
#   (for_host ())
#   (build_dir _build/default)
#   (toplevel_path (/home/ben/.opam/system/lib/toplevel))
#   (ocaml_bin /usr/bin)
#   (ocaml /usr/bin/ocaml)
#   (ocamlc /usr/bin/ocamlc.opt)
#   (ocamlopt (/usr/bin/ocamlopt.opt))
#   (ocamldep /usr/bin/ocamldep.opt)
#   (ocamllex /usr/bin/ocamllex.opt)
#   (ocamlyacc /usr/bin/ocamlyacc)
#   (ocamlmklib /usr/bin/ocamlmklib.opt)
#   (env ())
#   (findlib_path (/home/ben/.opam/system/lib))
#   (arch_sixtyfour false)
#   (natdynlink_supported true)
#   (opam_vars ((lib /home/ben/.opam/system/lib)))
#   (ocamlc_config
#    ((architecture i386)
#     (asm as)
#     (asm_cfi_supported true)
#     (ast_impl_magic_number Caml1999M020)
#     (ast_intf_magic_number Caml1999N018)
#     (bytecomp_c_compiler
#      "gcc -std=gnu99 -O2 -fno-strict-aliasing -fwrapv -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT -fPIC")
#     (bytecomp_c_libraries "-lm  -ldl -lcurses -lpthread                  ")
#     (cc_profile -pg)
#     (ccomp_type cc)
#     (cma_magic_number Caml1999A012)
#     (cmi_magic_number Caml1999I021)
#     (cmo_magic_number Caml1999O011)
#     (cmt_magic_number Caml2012T008)
#     (cmx_magic_number Caml1999Y015)
#     (cmxa_magic_number Caml1999Z014)
#     (cmxs_magic_number Caml2007D002)
#     (default_executable_name a.out)
#     (exec_magic_number Caml1999X011)
#     (ext_asm .s)
#     (ext_dll .so)
#     (ext_lib .a)
#     (ext_obj .o)
#     (flambda false)
#     (host i686-pc-linux-gnu)
#     (model default)
#     (native_c_compiler
#      "gcc -std=gnu99 -O2 -fno-strict-aliasing -fwrapv -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT")
#     (native_c_libraries "-lm  -ldl")
#     (native_pack_linker "ld -r  -o ")
#     (os_type Unix)
#     (ranlib ranlib)
#     (safe_string false)
#     (spacetime false)
#     (standard_library /usr/lib/ocaml)
#     (standard_library_default /usr/lib/ocaml)
#     (standard_runtime /usr/bin/ocamlrun)
#     (system linux_elf)
#     (systhread_supported true)
#     (target i686-pc-linux-gnu)
#     (version 4.04.0)
#     (with_frame_pointers false)))
#   (which ((ocamlc (/usr/bin/ocamlc.opt)) (ocamlfind ()))))

Using jbuilder installed from an opam pin at revision 3e9b52a

Feature request: `public_name` for executables

I'm really liking jbuilder - it's reduced the number of moving parts in a build quite significantly. One of the few things that still irks me is that there's a bit too much boilerplate to define an executable.

I'd like to be able to write (by analogy with the library stanza):

(executables
 ((name foo)
  (public_name bar)))

and have it work the same as what I currently write:

(executables
 ((names (foo))))
(install
 ((section bin)
  (files ((foo.exe as bar)))))

(It's also unclear to me why jbuilder uses single for library but plural for executables, and why a library has one name but an executable has several names. Is this a historical accident or a use-case I haven't run into yet?)

Suggetion: Move vendored libs to own dir

Having a structure such as:

vendor/re
vendor/cmdliner

Would make this repo a little easier to work with. For example, it will grep a lot more useful.

I realize that this might complicate the bootstrapping but perhaps it's worth it.

How to use sedlex?

Hi,
I am trying to build a project that uses sedlex for lexing tokens. I have (preprocess (pps (sedlex))) in my jbuild file. However, I keep getting uninterpreted extension %sedlex.regexp?. Am I specifying the sedlex ppx incorrectly?

support for watermarking source files

Topkg has the great feature to be able to watermark source files depending on the context: see http://erratique.ch/software/topkg/doc/Topkg.Pkg.html#VALwatermarks

VERSION has a special treatment: for releases, it is exactly the package version. When compiled in --dev mode (or the equivalent) it uses git describe. So if you get a binary built in dev mode, it's easy to set the output of <binary> --version to the right thing, just use let version = "%%VERSION%%" in your program.

Support for inline tests/benchmarks

Some thoughts on how to add automatic support for inline tests/benchmarks in jbuilder.

Currently Jane Street jenga rules support linking inline test and/or benchmark runners as soon as ones uses ppx_inline_test and/or ppx_bench. Additionally they automatically run the tests in parallel as part of the runtest alias.

This is a really useful feature for development and it would be great to add this to jbuilder. The rules are not very complicated to setup, however I'd like to support this without hardcoding the knowledge of the various libraries and their layout (ppx_bench, ppx_inline_tests, ppx_expect, ...) inside jbuilder. This is for two reason:

  • to avoid having to update jbuilder whenever the details of these subsystems change. They don't change very often but do change from now and then
  • to allow other people to reuse the same mechanism for their own test/benchmark systems

Proposal

The runners

For any given library Jbuilder systematically setups rules for building <lib>-test-runner.exe and <lib>-bench-runner.exe executables. These executables link all of library <lib> and are used for running tests and benchmarks respectively.

Additional runner libraries

The various runners require additional libraries, essentially to report the results at the end. We need two things: a way to specify these additional libraries and a way to specify the code to run at the end of the runner. Currently the jenga rules hardcode this information and know what .cmx/.cmo to link last fo each runner.

Specifying additional libraries

We can simply add them in the jbuild of the ppx:

(library
 ((name ppx_inline_test)
  ...
  (ppx_runner_library (test ppx_inline_test.runner))))

and Jbuilder will know to link ppx_inline_test.runner in the test runner of any libraries using this ppx.

Specifying the reporter

To make things simple, we provide a small libmain library allowing one to set the entry point:

(** Set the main entry point of the program *)
val set_main : (unit -> unit) -> unit

(** Execute the registered entry point. Never returns *)
val run_main : unit -> _

(** Are we linked as part of a library test/benchmark runner or a normal executable? *)
val is_library_runner : unit -> bool

and jbuilder will add a module that calls run_main as the last .cmx/.cmo on the command line to link the runner.

running tests in parallel

We formalise the convention of ppx_inline_test for running tests in parallel: foo-runner.exe --list-partitions returns a list of partitions and ... --partition blah selects tests from partition blah.

Runtime test dependencies

Sometime inline tests require extra dependencies when running. For instance when they read a file. The jenga rules support this by looking for an (inline_tests ...) field in (library ...) stanzas:

(library
 ((name foo)
  ...
  (inline_tests ((deps (blah))))))

We can do the same in jbuilder.

helper scripts

The jenga rules generate helper shell scripts allowing one to run the tests/benchmarks manually. Instead, ppx_inline_test can provide an executable to call the generated runner appropriately. Alternatively we could extend jbuilder exec so that one can do:

$ jbuilder exec ./foo-test-runner.exe ...

docs syntax

This section of the docs gives as an example:

(action "./${<} blah")

I think this is old syntax? I get an error using it, but either (bash ...) or (run ...) works fine.

Error while trying to compile an executable.

[vb@parvati ~/code/bitsouk/bitmex]% make
jbuilder build src/poloniex_data.exe
Workspace root: /home/vb/code/bitsouk/bitmex
Running[0]: /home/vb/.opam/valet/bin/ocamlc.opt -config > /tmp/jbuildd1ddd3.output
Running[1]: /home/vb/.opam/valet/bin/ocamlfind printconf path > /tmp/jbuild71d06b.output
Running[2]: /usr/bin/opam config var lib > /tmp/jbuild3482ab.output
Actual targets:
- _build/default/src/poloniex_data.exe
Internal error, please report upstream.
Description: Path.Local.parent called on the root
Backtrace:
make: *** [Makefile:2: all] Error 1

Additional info:

[vb@parvati ~/code/bitsouk/bitmex]% cat src/jbuild
(executables
 ((names (bfx_data bfx bitmex_data bitmex poloniex_data poloniex))
  (preprocess (pps (ppx_sexp_conv)))
  (libraries (uuidm bs-api))
  ))
[vb@parvati ~/code/bitsouk/bitmex]% ls -l src
total 220
-rw-rw-r-- 1 vb users 15115  6 mars  16:06 bfx_data.ml
-rw-rw-r-- 1 vb users 42455  9 mars  18:01 bfx.ml
-rw-rw-r-- 1 vb users 15299  6 mars  16:06 bitmex_data.ml
-rw-rw-r-- 1 vb users 72521  9 mars  18:01 bitmex.ml
-rw-rw-r-- 1 vb users   151  9 mars  18:02 jbuild
-rw-rw-r-- 1 vb users  6212  6 mars  16:06 leak.ml
-rw-rw-r-- 1 vb users 14585  9 mars  11:03 poloniex_data.ml
-rw-rw-r-- 1 vb users 44775  9 mars  18:01 poloniex.ml

Use with opam-cross-windows

Is it possible to use jbuilder with https://github.com/whitequark/opam-cross-windows? I tried a hackish approach of putting the $SWITCH/windows-sysroot/bin at the front of my $PATH but that gives me an error stating that ocamlyacc isn't available at the same path.

I see that jbuilder is expecting all ocaml* executables to live in the same directort. I don't see a simple way to work around this. Any suggestions?

Thank you!

jbuild plugins

It is currently impossible for users to extend the jbuild syntax. The ml syntax offers an escape hatch but you have to switch the whole file. One possible way to allow this would be:

(plugin:foo <arg>)

where foo would be a command that would take the S-expression <arg> on stdin and output some jbuild syntax on stdout, which would be more or less inlined in the file. Possibly it could use a different version of the spec.

For that to work well with the jenga integration, the command would have to output what files it reads and globs it evaluates.

doc generation

It would be great if we could generate docs using jbuilder + odoc. @diml and @trefis said that there are some Jenga rules somewhere for this, it would be really nice if these would be imported in jbuilder.

Jbuilder doesn't support 2 executables sharing a module

E.g. something like:

(executables
 ((modules (x1 helper))
  (names (x1))))

(executables
 ((modules (x2 helper))
  (names (x2))))

It will complain that helper has multiple rules defined for it. This isn't a big deal because you can always just make helper a library but it would be good to either document if this is intended or lift this small limitation.

other file extensions with preprocessor

I'm trying to build a project written in Reason with jbuilder.
Basically all my project files have a .re or .rei extension. .re/.rei are the equivalent of .ml/.mli. Compilation happens with a refmt as preprocessor, e.g. ocamlopt -pp "refmt --print binary" -impl hello_world.re -o hello_world.exe". I tried to build some rules for this, but didn't manage to get them working. I'm not entirely sure, after reading the manual, if this is possible. Is it possible?

Example: a project with hello.ml which depends on a function exposed by someReasonFile.re.

(executable
  ((name hello)))
 (rule
     ((targets (someReasonFile.re))
      (action  (system "refmt --print binary ${<}"))))   

I'm getting Unbounded Module SomeReasonFile. What's wrong with this rule?
Can I generalize this rule to all files with .re extensions?

If hello.ml would be written in Reason (needing a preprocessor step), how would the executable look like?

Two executables stanza

I tried to duplicate the hello_world example twice with the following jbuild file:

(executables
 ((names (hello_world))
))

(executables
 ((names (hello_world2))
))

But I obtained an error because of multiple rules generated:

{$HOME/.opam/4.02.3/bin/ocamlopt.opt, _build/default/.merlin-exists, _build/default/hello_world2.cmi, _build/default/hello_world2.depends.sexp, _build/default/hello_world2.ml, _build/default/hello_world2.requires.sexp} -> {_build/default/hello_world2.cmx, _build/default/hello_world2.o}
{$HOME/.opam/4.02.3/bin/ocamlopt.opt, _build/default/.merlin-exists, _build/default/hello_world.depends.sexp, _build/default/hello_world.requires.sexp, _build/default/hello_world2.cmi, _build/default/hello_world2.ml} -> {_build/default/hello_world2.cmx, _build/default/hello_world2.o}
Multiple rules generated for _build/default/hello_world2.o

Is it supported to have multiple executables rules?

double quote in .merlin is not right

this line in .merlin:
FLG -ppx "_build/.ppx/4.04.0/ppx_type_conv+ppx_fields_conv/ppx.exe --as-ppx"

cause error when open .ml file.

"main.ml" 48L, 1028Csh: 1: Syntax error: Unterminated quoted string

(merlin) backtrace:
(merlin) project flags: unknown flag: --as-ppx"
Error detected while processing function merlin#Register..merlin#LoadProject:
line    2:
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/hwu/.opam/4.04.0/share/merlin/vim/autoload/merlin.py", line 740, in setup_merlin
    failures = command("project","get")
  File "/home/hwu/.opam/4.04.0/share/merlin/vim/autoload/merlin.py", line 201, in command
    return merlin_process().command(context(cmd))
  File "/home/hwu/.opam/4.04.0/share/merlin/vim/autoload/merlin.py", line 168, in command
    raise Error(value)
merlin.Error: {u'message': u'Error while running external preprocessor\nCommand line: "_build/.ppx/4.04.0/ppx_type_conv+ppx_fields_conv/ppx.exe \
'/tmp/camlppx8a78b1\' \'/tmp/camlppx16180d\' 1>/dev/null 2>/dev/null', u'valid': True, u'type': u'type', u'sub': []}

change double quote to single quote, the problem disappear.

FLG -ppx '_build/.ppx/4.04.0/ppx_type_conv+ppx_fields_conv/ppx.exe --as-ppx'

Support for -output-obj

Jbuilder seems not yet able to create standalone shared library -output-obj. However it is not very different from linking executables (you just need a +PIC switch). What would be the right way to add it to jbuilder?

  • a new stanza?
  • an option to executables?

Backtrace when dependencies are duplicated

If you write something like:

(library
  ...
  (libraries (foo foo)))

Then you get:

Error: exception Invalid_argument("Map.of_alist_exn")
Backtrace:
Raised at file "pervasives.ml", line 33, characters 20-45
Called from file "src/build.ml", line 61, characters 5-351
Called from file "src/gen_rules.ml", line 210, characters 9-59
Called from file "src/gen_rules.ml", line 827, characters 9-50
Called from file "src/gen_rules.ml", line 839, characters 6-77
Called from file "src/gen_rules.ml", line 1314, characters 6-171
Called from file "src/gen_rules.ml", line 1663, characters 13-117
Called from file "src/import.ml", line 43, characters 12-15
Called from file "src/gen_rules.ml", line 1659, characters 4-380
Called from file "list.ml", line 77, characters 12-15
Called from file "src/gen_rules.ml", line 1670, characters 11-39
Called from file "src/gen_rules.ml", line 1989, characters 6-110
Called from file "src/future.ml", line 88, characters 40-45
Called from file "list.ml", line 59, characters 20-23
Called from file "src/gen_rules.ml", line 1973, characters 2-732
Called from file "src/main.ml", line 48, characters 2-100
Called from file "src/future.ml", line 83, characters 65-70
Called from file "src/future.ml", line 37, characters 9-12
Re-raised at file "src/future.ml", line 17, characters 36-47
Called from file "src/future.ml", line 40, characters 9-23
Called from file "src/import.ml", line 385, characters 8-11
Re-raised at file "src/import.ml", line 387, characters 30-37
Called from file "src/future.ml", line 37, characters 9-12
Re-raised at file "src/future.ml", line 17, characters 36-47
Called from file "src/future.ml", line 40, characters 9-23
Called from file "src/import.ml", line 385, characters 8-11
Re-raised at file "src/import.ml", line 387, characters 30-37
Called from file "src/future.ml", line 37, characters 9-12
Re-raised at file "src/future.ml", line 17, characters 36-47
Called from file "src/future.ml", line 40, characters 9-23
Called from file "src/import.ml", line 385, characters 8-11
Re-raised at file "src/import.ml", line 387, characters 30-37
Called from file "src/future.ml", line 37, characters 9-12
Re-raised at file "src/future.ml", line 17, characters 36-47
Called from file "src/future.ml", line 40, characters 9-23
Called from file "src/import.ml", line 385, characters 8-11
Re-raised at file "src/import.ml", line 387, characters 30-37
Called from file "src/future.ml", line 37, characters 9-12
Re-raised at file "src/future.ml", line 17, characters 36-47
Called from file "src/future.ml", line 40, characters 9-23
Called from file "src/import.ml", line 385, characters 8-11
Re-raised at file "src/import.ml", line 387, characters 30-37
Called from file "src/future.ml", line 618, characters 8-31
Called from file "vendor/cmdliner/src/cmdliner_term.ml", line 27, characters 19-24
Called from file "vendor/cmdliner/src/cmdliner.ml", line 113, characters 32-39
Called from file "vendor/cmdliner/src/cmdliner.ml", line 143, characters 18-36
Called from file "vendor/cmdliner/src/cmdliner.ml", line 258, characters 22-48
Called from file "bin/main.ml", line 648, characters 10-51

Which is probably not the best user-facing error ever.

Testing a ppx define in jbuilder

I would like to test a ppx that I build with jbuilder. I tried several approaches

  • The oldschool method :
    ocaml -noinit -noprompt -ppx my_ppx < test.ml 2>&1 | tail -n +19 > test.result
    diff test.expected test.result
    
    Problem: I can't figure out how to talk about my_ppx.
  • The compiler/jsoo method: inline expect_test in my project and use it on my test file
    Problem: Still can't figure out how to talk about the my_ppx executable, and not sure how to actually run expect_test with it.
  • The "new" method, with toplevel_expect_test
    Problem: Regardless of the fact that the packaging is so badly done that I can't even actually run it. I have no idea how to actually write the build rules for the toplevel that interact with my ppx.

So, what's the solution ? I would really like to be at least able to write the rules for the first (old school) method.

Rename _build to something else

_build is the same name that ocamlbuild uses for running builds. Since a lot of the potential users of jbuilder might be migrating from ocamlbuild, avoiding this possible conflict might be helpful.

Also, it's not unthinkable that some people might want to use jbuilder and ocamlbuild in the same project. Might as well make it as easy as possible for them.

optional compilation

[vb@haramis ~/code/ocaml-websocket]% jbuilder external-lib-deps --missing @install
Error: The following required libraries are missing in the default context:
- cryptokit (optional)

I am using the following stanza:

(library
 ((name rng_cryptokit)
  (public_name websocket.rng_cryptokit)
  (modules (rng_cryptokit))
  (optional)
  (libraries (rng cryptokit))))

Why jbuilder insists on building this if it is flagged optional and that cryptokit is not installed?

How to support bisect_ppx?

bisect_ppx is an odd ppx rewriter because you only want it active when you're measuring coverage. Usually when you're running your test suite. Dually, the tests only require the bisect ppx runtime when measuring the coverage. Ideally, this is something jbuilder would support on a global basis with minimum hassle. @diml any advice on might jbuilder accommodate bisect_ppx?

jbuilder ppx preprocessing not working on simple exampe

I tried using jbuilder to build a simple hello-world app which makes use of ppx_sexp_conv, but couldn't get the ppx preprocessing to work.

hello_world.ml

    open Core.Std
    type t = Hey of int [@@deriving sexp_of]
    let () = printf "Hello, %s world!\n" (Sexp.to_string (sexp_of_t (Hey 99)))

jbuilder:

    (executables
     ((names (hello_world))
      (preprocess (pps (ppx_sexp_conv)))
      (libraries (core))))

command:

$ jbuilder build hello_world.exe --verbose

-> (full log below)

File "hello_world.ml", line 3, characters 54-63:
Error: Unbound value sexp_of_t
Hint: Did you mean sexp_of_int or sexp_of_mat?

Running the generated ppx.exe by hand

(cd _build/default && ../.ppx/default/ppx_sexp_conv/ppx.exe --impl hello_world.ml)

I can see that the [@@deriving sexp_of] is not expanded,

I tried various changes to the preprocess line, i.e adding ppx_driver.main, but this just results in:

$ (cd _build/default && ../.ppx/default/ppx_sexp_conv+ppx_driver.runner/ppx.exe --dump-ast -o hello_world.pp.ml --impl hello_world.ml)
../.ppx/default/ppx_sexp_conv+ppx_driver.runner/ppx.exe: unknown option '--dump-ast'.

Am I doing something wrong, or is this a bug?

Cheers,
Nick

# Workspace root: /home/nic/try-jbuild/hw
Running[0]: /home/nic/.opam/4.02.3/bin/ocamlfind printconf path > /tmp/jbuild2dbb9e.output
Running[1]: /home/nic/.opam/4.02.3/bin/ocamlc.opt -config > /tmp/jbuild2ddd2a.output
# Jbuilder context:
#  ((name default)
#   (kind default)
#   (merlin true)
#   (for_host ())
#   (build_dir _build/default)
#   (toplevel_path (/home/nic/.opam/4.02.3/lib/toplevel))
#   (ocaml_bin /home/nic/.opam/4.02.3/bin)
#   (ocaml /home/nic/.opam/4.02.3/bin/ocaml)
#   (ocamlc /home/nic/.opam/4.02.3/bin/ocamlc.opt)
#   (ocamlopt (/home/nic/.opam/4.02.3/bin/ocamlopt.opt))
#   (ocamldep /home/nic/.opam/4.02.3/bin/ocamldep.opt)
#   (ocamllex /home/nic/.opam/4.02.3/bin/ocamllex.opt)
#   (ocamlyacc /home/nic/.opam/4.02.3/bin/ocamlyacc)
#   (ocamlmklib /home/nic/.opam/4.02.3/bin/ocamlmklib)
#   (env ())
#   (findlib_path (/home/nic/.opam/4.02.3/lib))
#   (arch_sixtyfour true)
#   (natdynlink_supported true)
#   (opam_vars ())
#   (ocamlc_config
#    ((architecture amd64)
#     (asm as)
#     (asm_cfi_supported true)
#     (ast_impl_magic_number Caml1999M016)
#     (ast_intf_magic_number Caml1999N015)
#     (bytecomp_c_compiler
#      "gcc -O -fno-defer-pop -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT -O -fPIC")
#     (bytecomp_c_libraries "-lm  -ldl -lcurses -lpthread")
#     (cc_profile -pg)
#     (ccomp_type cc)
#     (cma_magic_number Caml1999A011)
#     (cmi_magic_number Caml1999I017)
#     (cmo_magic_number Caml1999O010)
#     (cmt_magic_number Caml2012T004)
#     (cmx_magic_number Caml1999Y014)
#     (cmxa_magic_number Caml1999Z013)
#     (cmxs_magic_number Caml2007D002)
#     (default_executable_name a.out)
#     (exec_magic_number Caml1999X011)
#     (ext_asm .s)
#     (ext_dll .so)
#     (ext_lib .a)
#     (ext_obj .o)
#     (host x86_64-unknown-linux-gnu)
#     (model default)
#     (native_c_compiler "gcc -O -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT")
#     (native_c_libraries "-lm  -ldl")
#     (native_pack_linker "ld -r  -o ")
#     (os_type Unix)
#     (ranlib ranlib)
#     (standard_library /home/nic/.opam/4.02.3/lib/ocaml)
#     (standard_library_default /home/nic/.opam/4.02.3/lib/ocaml)
#     (standard_runtime /home/nic/.opam/4.02.3/bin/ocamlrun)
#     (system linux)
#     (systhread_supported true)
#     (target x86_64-unknown-linux-gnu)
#     (version 4.02.3)
#     (with_frame_pointers false)))
#   (which
#    ((ocamlc (/home/nic/.opam/4.02.3/bin/ocamlc.opt))
#     (ocamlfind (/home/nic/.opam/4.02.3/bin/ocamlfind)))))
# Actual targets:
# - _build/default/hello_world.exe
Running[2]: (cd _build/default && /home/nic/.opam/4.02.3/bin/ocamlopt.opt -o ../.ppx/default/ppx_sexp_conv/ppx.exe -I /home/nic/.opam/4.02.3/lib/ocaml-migrate-parsetree -I /home/nic/.opam/4.02.3/lib/ocaml-migrate-parsetree/driver-main -I /home/nic/.opam/4.02.3/lib/ocaml/compiler-libs -I /home/nic/.opam/4.02.3/lib/ppx_core -I /home/nic/.opam/4.02.3/lib/ppx_driver -I /home/nic/.opam/4.02.3/lib/ppx_optcomp -I /home/nic/.opam/4.02.3/lib/ppx_sexp_conv -I /home/nic/.opam/4.02.3/lib/ppx_type_conv -I /home/nic/.opam/4.02.3/lib/result ocamlcommon.cmxa ppx_core.cmxa ppx_optcomp.cmxa ppx_driver.cmxa ppx_sexp_conv_expander.cmxa ppx_type_conv.cmxa result.cmxa migrate_parsetree.cmxa ppx_sexp_conv.cmxa migrate_parsetree_driver_main.cmxa)
Running[3]: (cd _build/default && ../.ppx/default/ppx_sexp_conv/ppx.exe --dump-ast -o hello_world.pp.ml --impl hello_world.ml)
Running[4]: (cd _build/default && /home/nic/.opam/4.02.3/bin/ocamldep.opt -modules hello_world.pp.ml) > _build/default/hello_world.depends.ocamldep-output
Running[5]: (cd _build/default && /home/nic/.opam/4.02.3/bin/ocamlc.opt -w -40 -g -bin-annot -I /home/nic/.opam/4.02.3/lib/bin_prot -I /home/nic/.opam/4.02.3/lib/core -I /home/nic/.opam/4.02.3/lib/core_kernel -I /home/nic/.opam/4.02.3/lib/fieldslib -I /home/nic/.opam/4.02.3/lib/num -I /home/nic/.opam/4.02.3/lib/ocaml -I /home/nic/.opam/4.02.3/lib/ocaml/threads -I /home/nic/.opam/4.02.3/lib/ppx_assert -I /home/nic/.opam/4.02.3/lib/ppx_bench -I /home/nic/.opam/4.02.3/lib/ppx_expect -I /home/nic/.opam/4.02.3/lib/ppx_inline_test -I /home/nic/.opam/4.02.3/lib/result -I /home/nic/.opam/4.02.3/lib/sexplib -I /home/nic/.opam/4.02.3/lib/typerep -I /home/nic/.opam/4.02.3/lib/variantslib -no-alias-deps -I . -o hello_world.cmo -c -impl hello_world.pp.ml)

Command [5] exited with code 2:
$ (cd _build/default && /home/nic/.opam/4.02.3/bin/ocamlc.opt -w -40 -g -bin-annot -I /home/nic/.opam/4.02.3/lib/bin_prot -I /home/nic/.opam/4.02.3/lib/core -I /home/nic/.opam/4.02.3/lib/core_kernel -I /home/nic/.opam/4.02.3/lib/fieldslib -I /home/nic/.opam/4.02.3/lib/num -I /home/nic/.opam/4.02.3/lib/ocaml -I /home/nic/.opam/4.02.3/lib/ocaml/threads -I /home/nic/.opam/4.02.3/lib/ppx_assert -I /home/nic/.opam/4.02.3/lib/ppx_bench -I /home/nic/.opam/4.02.3/lib/ppx_expect -I /home/nic/.opam/4.02.3/lib/ppx_inline_test -I /home/nic/.opam/4.02.3/lib/result -I /home/nic/.opam/4.02.3/lib/sexplib -I /home/nic/.opam/4.02.3/lib/typerep -I /home/nic/.opam/4.02.3/lib/variantslib -no-alias-deps -I . -o hello_world.cmo -c -impl hello_world.pp.ml)
File "hello_world.ml", line 3, characters 54-63:
Error: Unbound value sexp_of_t
Hint: Did you mean sexp_of_int or sexp_of_mat?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.