let create
  ?(channel=stdout)
  ?(mode:[`Classic|`Sophisticated] = `Sophisticated)
  ?columns:(_columns=75)
  ?(description = default_tagline_description)
  ?log_file
  ?(log_level=1)
  ()
  =
  let log_channel =
    match log_file with
    | None -> None
    | Some fn ->
        let oc = open_out_gen [Open_textOpen_wronlyOpen_creatOpen_trunc] 0o644 fn in
        let f = Format.formatter_of_out_channel oc in
        Format.fprintf f "### Starting build.\n";
        Some (f, oc)
  in

  let display_line =
    match mode with
    | `Classic -> Classic
    | `Sophisticated ->
      (* We assume Unix is not degraded. *)
      let n = ANSI.get_columns () in
      let tag_chars = List.length description in
      Sophisticated
        { ds_channel         = stdout;
          ds_start_time      = gettimeofday ();
          ds_last_update     = 0.0;
          ds_last_target     = start_target;
          ds_last_tags       = Tags.empty;
          ds_last_cached     = false;
          ds_changed         = false;
          ds_update_interval = default_update_interval;
          ds_columns         = n;
          ds_jobs            = 0;
          ds_jobs_cached     = 0;
          ds_tagline         = create_tagline description;
          ds_seen_tags       = Tags.empty;
          ds_pathname_length = n -
                                 (countdown_chars + 1 + jobs_chars + 1 + jobs_cached_chars + 1 +
                                  cache_chars + 1 + tag_chars + 1 + ticker_chars + 2);
          ds_tld             = description }
  in
  { di_log_level    = log_level;
    di_log_channel  = log_channel;
    di_channel      = channel;
    di_formatter    = Format.formatter_of_out_channel channel;
    di_display_line = display_line;
    di_finished     = false }