2026-06-10

Dynamic Options with OCaml’s Arg Library

The compiler I’m working on accepts several options - like most other command line programs. However, I wanted to allow only some combinations. E.g. in

-i               interpret
-msp430 [mcu]    compile for some MSP430 MCU
-S               emit assembly code

the -S should only be valid with -msp430. Turns out you can implement this restrictions with OCaml’s Arg library:

let opt_i = ref false in
let opt_S = ref false in

let rest = ref [] in
let skip arg : unit = rest := arg :: !rest in

let opts = ref [] in
opts := Arg.align [
  ("--", Arg.Rest skip, "");

    ("-i", Arg.Set opt_i, "");

  ("-msp430", Arg.String (fun _mcu ->
       opts := Arg.align [
           ("--", Arg.Rest skip, "");
           ("-S", Arg.Set opt_S, "");
         ];
     ), "");
];

match Arg.parse_dynamic opts skip usage with
| exception Arg.Bad msg -> prerr_endline msg
| exception Arg.Help msg -> print_endline msg
| () -> !rest |> List.iter print_endline