简体   繁体   中英

What is the proper setup to build the lablgtk hello world using dune?

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 @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -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 @1..3@5..28@30..39@43@46..47@49..57@61..62-40 -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:

(* Connect a signal handler, ignoring the resulting signal ID.
   This avoids having to use [|> ignore] everywhere. *)
let (==>) (signal:(callback:_ -> GtkSignal.id)) callback =
  ignore (signal ~callback)

Then replace eg

window#connect#destroy ~callback:Main.quit;

with

window#connect#destroy ==> Main.quit;

You'll have to fix factory#add_item too. eg with:

let _ : GMenu.menu_item = factory#add_item "Quit" ~key:_Q ~callback:Main.quit in

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM