109 lines
2.5 KiB
Perl
109 lines
2.5 KiB
Perl
|
|
$ 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
|