Can someone here help me with my OCaml project setup?
I want to create a build environment using dune, since I am working on a gui application I want to build the lablgtk example from here : GTK Hello World! I am able to build it using the instructions from the link, but I would like to use dune to build it, that is currently not working. I get an error that a cmi file is missing.
Output in Command-Line Interface:
File "main.ml", line 10, characters 2-44:
10 | window#connect#destroy ~callback:Main.quit;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This expression has type GtkSignal.id
but an expression was expected of type unit
because it is in the left-hand side of a sequence
Infro from Merlin in VScode
This expression has type GtkSignal.id but an expression was expected of type
unit
because it is in the left-hand side of a sequence
GtkSignal.id is abstract because no corresponding cmi file was found in path.merlin
Output with dune build main.exe --verbose
Workspace root: /home/patrick/git/hello
Running[0]: /usr/bin/nproc > /tmp/duneaf7943.output 2> /dev/null
Auto-detected concurrency: 4
disable binary cache
Running[1]: /usr/bin/ocamlc.opt -config > /tmp/dune2611b5.output
Dune context:
{ name = "default"
; kind = "default"
; profile = Dyn
; merlin = true
; for_host = None
; fdo_target_exe = None
; build_dir = "default"
; toplevel_path = Some External "/home/patrick/.opam/default/lib/toplevel"
; ocaml_bin = External "/usr/bin"
; ocaml = Ok External "/home/patrick/.opam/default/bin/ocaml"
; ocamlc = External "/usr/bin/ocamlc.opt"
; ocamlopt = Ok External "/usr/bin/ocamlopt.opt"
; ocamldep = Ok External "/usr/bin/ocamldep.opt"
; ocamlmklib = Ok External "/usr/bin/ocamlmklib.opt"
; env =
map
{ "INSIDE_DUNE" : "/home/patrick/git/hello/_build/default"
; "OCAMLFIND_IGNORE_DUPS_IN" :
"/home/patrick/git/hello/_build/install/default/lib"
; "OCAMLPATH" :
"/home/patrick/git/hello/_build/install/default/lib"
; "OCAMLTOP_INCLUDE_PATH" :
"/home/patrick/git/hello/_build/install/default/lib/toplevel"
; "OCAML_COLOR" : "always"
; "OPAMCOLOR" : "always"
}
; findlib_path = [ External "/home/patrick/.opam/default/lib" ]
; arch_sixtyfour = true
; natdynlink_supported = true
; supports_shared_libraries = true
; ocaml_config =
{ version = "4.10.0"
; standard_library_default = "/usr/lib/ocaml"
; standard_library = "/usr/lib/ocaml"
; standard_runtime = "the_standard_runtime_variable_was_deleted"
; ccomp_type = "cc"
; c_compiler = "gcc"
; ocamlc_cflags = [ "-O2"; "-fno-strict-aliasing"; "-fwrapv"; "-fPIC" ]
; ocamlopt_cflags = [ "-O2"; "-fno-strict-aliasing"; "-fwrapv" ]
; bytecomp_c_compiler =
[ "gcc"
; "-O2"
; "-fno-strict-aliasing"
; "-fwrapv"
; "-fPIC"
; "-D_FILE_OFFSET_BITS=64"
; "-D_REENTRANT"
]
; bytecomp_c_libraries = [ "-lm"; "-ldl"; "-lpthread" ]
; native_c_compiler =
[ "gcc"
; "-O2"
; "-fno-strict-aliasing"
; "-fwrapv"
; "-D_FILE_OFFSET_BITS=64"
; "-D_REENTRANT"
]
; native_c_libraries = [ "-lm"; "-ldl" ]
; cc_profile = []
; architecture = "amd64"
; model = "default"
; int_size = 63
; word_size = 64
; system = "linux"
; asm = [ "as" ]
; asm_cfi_supported = true
; with_frame_pointers = false
; ext_exe = ""
; ext_obj = ".o"
; ext_asm = ".s"
; ext_lib = ".a"
; ext_dll = ".so"
; os_type = "Unix"
; default_executable_name = "a.out"
; systhread_supported = true
; host = "x86_64-pc-linux-gnu"
; target = "x86_64-pc-linux-gnu"
; profiling = false
; flambda = false
; spacetime = false
; safe_string = false
; exec_magic_number = "Caml1999X027"
; cmi_magic_number = "Caml1999I027"
; cmo_magic_number = "Caml1999O027"
; cma_magic_number = "Caml1999A027"
; cmx_magic_number = "Caml1999Y027"
; cmxa_magic_number = "Caml1999Z027"
; ast_impl_magic_number = "Caml1999M027"
; ast_intf_magic_number = "Caml1999N027"
; cmxs_magic_number = "Caml1999D027"
; cmt_magic_number = "Caml1999T027"
; natdynlink_supported = true
; supports_shared_libraries = true
; windows_unicode = false
}
}
Actual targets:
- _build/default/main.exe
Running[2]: (cd _build/default && /usr/bin/ocamlc.opt -w @[email protected]@30..39@[email protected]@[email protected] -strict-sequence -strict-formats -short-paths -keep-locs -g -bin-annot -I .main.eobjs/byte -I /home/patrick/.opam/default/lib/lablgtk2 -I /usr/lib/ocaml/threads -no-alias-deps -opaque -o .main.eobjs/byte/dune__exe__Main.cmo -c -impl main.ml)
Command [2] exited with code 2:
$ (cd _build/default && /usr/bin/ocamlc.opt -w @[email protected]@30..39@[email protected]@[email protected] -strict-sequence -strict-formats -short-paths -keep-locs -g -bin-annot -I .main.eobjs/byte -I /home/patrick/.opam/default/lib/lablgtk2 -I /usr/lib/ocaml/threads -no-alias-deps -opaque -o .main.eobjs/byte/dune__exe__Main.cmo -c -impl main.ml)
File "main.ml", line 10, characters 2-44:
10 | window#connect#destroy ~callback:Main.quit;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This expression has type GtkSignal.id
but an expression was expected of type unit
because it is in the left-hand side of a sequence
The warning is correct (the example code is bad style). The difference is that dune by default considers it to be a fatal error (when doing a dev build), whereas other build systems may consider it to be only a warning, or not show it at all (see
ocamlc -strict-sequence
).To fix it, you can define a helper operator like this:
Then replace e.g.
with
You'll have to fix
factory#add_item
too. e.g. with: