【问题标题】:Module case name confusion模块案例名称混淆
【发布时间】:2014-01-06 05:00:23
【问题描述】:

我犯了更新软件的错误,现在我无法运行任何 OUnit 测试。

我想我已经设法将问题归结为一个简单的 REPL 会话。

$ ocaml -I /opt/local/lib/ocaml/site-lib/oUnit
        OCaml version 4.01.0

# Ounit.assert_equal;;
Error: Wrong file naming: /opt/local/lib/ocaml/site-lib/oUnit/ounit.cmi
contains the compiled interface for
Ounit when OUnit was expected
# OUnit.assert_equal;;
Error: Reference to undefined global `OUnit'

任何想法我做错了什么?

我在具有默认 case-insensitive/case-preserving 文件系统的 Mac 笔记本电脑上运行此程序,但使用包含路径的大小写没有帮助。


我更大的问题是这样表现的:

ocamlbuild \
  -libs \
  nums,str,unix,oUnit,graph \
  -cflags \
  -g,-w,+a-4,-warn-error,+a-4,-I,/opt/local/lib/ocaml/site-lib/oUnit,-I,/opt/local/lib/ocaml/site-lib/ocamlgraph \
  -lflags \
  -g,-I,/opt/local/lib/ocaml/site-lib/oUnit,-I,/opt/local/lib/ocaml/site-lib/ocamlgraph \
  ./AllTests.native

Error: No implementations provided for the following modules:
     OUnitCore referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2),
       /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
     OUnitLoggerStd referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
     OUnitUtils referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2),
       /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
     OUnitConf referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2),
       /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
     OUnitAssert referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2),
       /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
     OUnitBracket referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2),
       /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
     OUnitTest referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2),
       /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
     OUnitRunner referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
     OUnitChooser referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
     OUnitLogger referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2),
       /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit)
     OUnitTestData referenced from /opt/local/lib/ocaml/site-lib/oUnit/oUnit.cmxa(OUnit2)
Command exited with code 2.
Compilation unsuccessful after building 646 targets (645 cached) in 00:00:02.

【问题讨论】:

    标签: ocaml ocamlbuild ounit


    【解决方案1】:

    您的第一个错误可能是因为您的操作系统不区分文件名中的大小写,但 OCaml 可以:

    $ ocamlobjinfo `ocamlfind query oUnit`/oUnit.cmi
    File /mnt/home/jun/.opam/system/lib/oUnit/oUnit.cmi
    Unit name: OUnit
    Interfaces imported:
        cb146e345f0b34fc8ad4b5afe69d1f20    OUnit
        ...
    

    您可以看到该模块被称为“OUnit”而不是“Ounit”。

    第二个错误显然是因为该库尚未加载到 REPL 中。 REPL 知道该函数的存在,但没有加载任何代码。如果您加载库及其所依赖的库,则可以访问它:

    ocaml -I `ocamlfind query oUnit` unix.cma oUnitAdvanced.cma oUnit.cma
            OCaml version 4.01.0
    
    # OUnit.assert_equal;;
    - : ?cmp:('a -> 'a -> bool) ->
        ?printer:('a -> string) ->
        ?pp_diff:(Format.formatter -> 'a * 'a -> unit) ->
        ?msg:string -> 'a -> 'a -> unit
    = <fun>
    

    【讨论】:

    • 谢谢。看起来我的 REPL 并没有完全重现问题。关于我应该怎么做才能让ocamlbuild 链接的任何想法?我需要-libs 列表中的ounitadvanced 吗?
    【解决方案2】:

    我通过将ocamlbuild 调用更改为使用-use-ocamlfind 解决了这个问题,这似乎可以解决所有路径混乱。

    我还卸载了所有 OCaml 模块,而是安装了 OPAM,然后通过 OPAM 安装了 OUnit 和其他模块,然后重新登录,以便我的环境是原始的。

    现在适合我的构建命令是

    ocamlbuild \
        -use-ocamlfind \
        -libs   graph \
        -pkgs   str,unix,ounit \
        -cflags -g,-w,+a-4,-warn-error,+a-4,-I,/opt/local/lib/ocaml/site-lib/ocamlgraph \
        -lflags -g,-I,/opt/local/lib/ocaml/site-lib/ocamlgraph \
        ./AllTests.native
    

    由我更新的构建脚本生成

    (* Usage: ocaml make.ml [<ModuleToBuild>.{byte,native}] *)
    
    #load "unix.cma";;
    
    let args = match Array.to_list Sys.argv with
      | []      -> failwith "no program on argv"
      | _::[]   -> ["AllTests.byte"]
      | _::argv -> argv
    
    let library_paths = [
      (* TODO: Figure out why `opam install ocamlgraph` fails *)
      "-I"; "/opt/local/lib/ocaml/site-lib/ocamlgraph";
    ]
    
    (* If the -p flag is first in the argument list, then replace it
       with a host of flags that enable profiling via ocamlprof. *)
    let args, c_opt_flags, l_opt_flags =
      match args with
        | "-p"::rest ->
          (* Treat the targets as debug and profile targets. *)
          "-tags"::"debug,profile"
          (* Use profiling versions of the compilers which instrument
             various flow control constructs with entry counters. *)
          ::"-ocamlc"::"ocamlcp"
          ::"-ocamlopt"::"ocamloptp"
          ::rest,
          (* Instrument all available points. *)
          ["-P"; "a"],
          (* Link with a wrapper that dumps profiling data if program
             exits noramlly. *)
          ["-p"]
        | _ -> args, [], []
    
    let standard_flags = [
      "-use-ocamlfind";
      (* TODO: Figure out why `opam install ocamlgraph` fails *)
      "-libs"; "graph";
      "-pkgs"; "str,unix,ounit";  (* TODO: graph *)
      "-cflags"; (String.concat "," (
        [
          "-g";
          "-w"; "+a-4";
          "-warn-error"; "+a-4";
        ]
        @ c_opt_flags
        @ library_paths));
      "-lflags"; (String.concat "," (
        [
          "-g";
        ]
        @ l_opt_flags
        @ library_paths));
    ]
    
    let build_command = "ocamlbuild"
    
    let argv = build_command::(standard_flags @ args)
    
    let _ = begin
      Printf.printf "%s\n" (String.concat " \\\n\t" argv);
      flush stdout;
      Unix.execvp build_command (Array.of_list argv);
    end;;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-16
      • 2012-12-09
      • 1970-01-01
      • 2011-10-17
      • 1970-01-01
      • 1970-01-01
      • 2022-11-27
      相关资源
      最近更新 更多