$ cat > dune-project << EOF > (lang dune 1.1) > > (package > (name e)) > EOF $ cat > dune << EOF > (executable > (public_name e)) > EOF The executable just displays "Hello" and its arguments. $ cat > e.ml << EOF > let () = > print_endline "Hello"; > Array.iteri (fun i s -> > Printf.printf "argv[%d] = %s\n" i s > ) Sys.argv > EOF By default, e is executed with the program name and arguments in argv. $ dune exec ./e.exe a b c Hello argv[0] = ./_build/default/e.exe argv[1] = a argv[2] = b argv[3] = c The special form %{bin:public_name} is supported. $ dune exec %{bin:e} a b c Hello argv[0] = ./_build/install/default/bin/e argv[1] = a argv[2] = b argv[3] = c This wrapper parses its own arguments and executes the rest. $ cat > wrap.sh << 'EOF' > #!/bin/sh > while getopts "xy" o; do > echo "Got option: $o" > done > shift $((OPTIND-1)) > echo Before > "$@" > echo After > EOF $ chmod +x wrap.sh It is possible to put the %{bin:...} pform in arguments rather than first. $ dune exec -- ./wrap.sh -x -y %{bin:e} a b c Got option: x Got option: y Before Hello argv[0] = _build/install/default/bin/e argv[1] = a argv[2] = b argv[3] = c After The first item is still looked up in PATH. $ dune exec ls %{bin:e} _build/install/default/bin/e Pforms can appear several times. $ dune exec ls %{bin:e} %{bin:e} _build/install/default/bin/e _build/install/default/bin/e It should also be possible to call another program that is also supposed to be built if referenced, for this we create a new binary that calls its first argument: $ cat > call_arg.ml << EOF > let () = > let first = Sys.argv.(1) in > Printf.printf "Calling my first arg, %S:\n" first; > let inch, outch = Unix.open_process_args first [|first|] in > print_endline (input_line inch); > let status = Unix.close_process (inch, outch) in > match status with > | Unix.WEXITED 0 -> print_endline "All good" > | _ -> print_endline "Something is Rotten in the State of Dune" > EOF $ cat > called.ml << EOF > let () = print_endline "I was called" > EOF $ cat > dune << EOF > (executables > (public_names e call_arg called) > (libraries unix)) > EOF If we then ask it to execute, both `call_arg` and `called` should be compiled and run, successfully. $ dune exec %{bin:call_arg} %{bin:called} Calling my first arg, "_build/install/default/bin/called": I was called All good