diff --git a/.gitignore b/.gitignore
index c0898adb983c5bcb543b1ad78faccb6438ba1887..2d7627c834c7cd274681f3bc2d7632f43356b117 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 /_build/
 /clangml-transforms.install
 .merlin
-*~
\ No newline at end of file
+*~
+/clangml-transforms.opam
diff --git a/Makefile b/Makefile
index bd4948f01ff7aee460c96460dcc1c94052c9443e..7b6e2f6a3c8ae2e492262f15b3c4c3e384e3f458 100644
--- a/Makefile
+++ b/Makefile
@@ -1,15 +1,12 @@
 DUNE_INSTALL_PREFIX = _build/install/default
 
 .PHONY : all
-all :
+all : clangml-transforms.opam
 	dune build
 
 .PHONY : install
 install : all
 	dune build @install
-# obuild does not support line break in 'requires' field
-	sed -i '/requires = "[^"]*$$/{:x N;s/\n */ /;/[^"]$$/bx}' \
-		$(DUNE_INSTALL_PREFIX)/lib/clangml-transforms/META
 	dune install
 
 .PHONY : uninstall
@@ -18,9 +15,11 @@ uninstall :
 
 .PHONY : tests
 tests :
-	dune build tests/tests.exe
-	_build/default/tests/tests.exe
+	dune runtest
 
 .PHONY : clean
 clean :
 	dune clean
+
+clangml-transforms.opam : dune-project
+	dune build clangml-transforms.opam
diff --git a/clangml-transforms.opam b/clangml-transforms.opam
deleted file mode 100644
index 0f0c5a694a32692756e3245a07edff202cc960e4..0000000000000000000000000000000000000000
--- a/clangml-transforms.opam
+++ /dev/null
@@ -1,17 +0,0 @@
-opam-version: "2.0"
-synopsis: "Code transformers for clangml"
-maintainer: "Thierry Martinez <Thierry.Martinez@inria.fr>"
-authors: "Thierry Martinez <Thierry.Martinez@inria.fr>"
-homepage: "https://gitlab.inria.fr/tmartine/clangml-transforms"
-bug-reports: "https://gitlab.inria.fr/tmartine/clangml-transforms/issues"
-license: "BSD"
-dev-repo: "git+https://gitlab.inria.fr/tmartine/clangml-transforms.git"
-build:  ["dune" "build" "-p" name "-j" jobs]
-# use Makefile for install since there is some manual patches applied
-install: [make "install"]
-remove: [make "uninstall"]
-depends: [
-  "clangml"
-  "visitors"
-  "dolog"
-  "ocaml" {>= "4.02.0" & < "4.08.0"}]
diff --git a/clangml-transforms/for_memcad.ml b/clangml-transforms/for_memcad.ml
index e76181b20dc93d932ab37c6de79b6a282be670ef..628c554d7d8ea5f525f8b18dcccf16d3e2d4235a 100644
--- a/clangml-transforms/for_memcad.ml
+++ b/clangml-transforms/for_memcad.ml
@@ -1,3 +1,5 @@
+module Log = Dolog.Log
+
 let bin_op qual_type lhs kind rhs =
   Clang.Ast.node ~qual_type (Clang.Ast.BinaryOperator { lhs; kind; rhs })
 
diff --git a/dune-project b/dune-project
index a26d6e273960e2ad7964d33d61b10331724184e8..f793440a12eb1135341317f0c46d41716d298bef 100644
--- a/dune-project
+++ b/dune-project
@@ -1 +1,18 @@
-(lang dune 1.6)
+(lang dune 1.10)
+
+(generate_opam_files true)
+
+(license BSD)
+(maintainers "Thierry Martinez <thierry.martinez@inria.fr>")
+(authors "Thierry Martinez <thierry.martinez@inria.fr>")
+(source (uri "git+https://gitlab.inria.fr/memcad/clangml-transforms"))
+(homepage "https://gitlab.inria.fr/memcad/clangml-transforms")
+(bug_reports "https://gitlab.inria.fr/memcad/clangml-transforms/issues")
+(documentation "https://gitlab.inria.fr/memcad/clangml-transforms")
+
+(package
+ (name clangml-transforms)
+ (synopsis "Code transformers for clangml")
+ (depends
+  (clangml (>= 4.0.1))
+  (visitors (>= 20190711))))
diff --git a/tests/dune b/tests/dune
index 987eef5b88a7e416e8b8fdd5b31c7d52071cd7bf..747e152f549a27a1910abea2074f905a38e8c893 100644
--- a/tests/dune
+++ b/tests/dune
@@ -1,3 +1,3 @@
 (executable
   (name tests)
-  (libraries clangml-transforms))
\ No newline at end of file
+  (libraries clangml-transforms clangml.compare clangml.show))
\ No newline at end of file
diff --git a/tests/tests.ml b/tests/tests.ml
index edcd8ff9e2c03c98a289a1727d56a206b6c1f5cc..a212daf9b3e04c8c653f0f2cc071b1145084fae2 100644
--- a/tests/tests.ml
+++ b/tests/tests.ml
@@ -4,12 +4,12 @@ let has_errors = ref false
 
 let check_translation_decl source target =
   let transformed = For_memcad.transform_decl source in
-  if not (Clang.Ast.equal_decl transformed target) then
+  if Clangml_compare.Decl.compare transformed target <> 0 then
     begin
       Format.eprintf "@[From:@ %a@]@.@[Got:@ %a@]@.@[Expected:@ %a@]@."
-        Clang.Ast.pp_decl source
-        Clang.Ast.pp_decl transformed
-        Clang.Ast.pp_decl target;
+        Clangml_show.pp_decl source
+        Clangml_show.pp_decl transformed
+        Clangml_show.pp_decl target;
       has_errors := true
     end
 
@@ -23,15 +23,16 @@ let () =
   | { desc = { items = [ _; decl ]}} ->
       begin
         match For_memcad.transform_decl decl with
-        | { desc = Function { name = "f"; body = Some { desc = Compound [
+        | { desc = Function { name = IdentifierName "f";
+            body = Some { desc = Compound [
             { desc = Decl [{ desc = Var _ }]};
             { desc = Expr { desc = BinaryOperator { kind = Assign; rhs =
               { desc = Call {
-                callee = { desc = DeclRef "g"};
+                callee = { desc = DeclRef { name = IdentifierName "g" }};
                 args = []}}}}}]}}} -> ()
         | decl ->
             Format.fprintf Format.err_formatter "%a\n"
-              Clang.Ast.pp_decl decl;
+              Clangml_show.pp_decl decl;
             assert false
       end
   | _ -> assert false
@@ -52,7 +53,8 @@ let () =
   | { desc = { items = [ decl ]}} ->
       begin
         match For_memcad.transform_decl decl with
-        | { desc = Function { name = "f"; body = Some { desc = Compound [
+        | { desc = Function { name = IdentifierName "f";
+            body = Some { desc = Compound [
             { desc = If {
               cond = {
                 desc = BinaryOperator { kind = EQ;
@@ -64,28 +66,33 @@ let () =
                   desc = BinaryOperator { kind = EQ;
                   lhs = { desc = IntegerLiteral (Int 2)};
                   rhs = { desc = IntegerLiteral (Int 3)}}};
-                then_branch = { desc = Expr { desc = StringLiteral "true" }};
+                then_branch = { desc = Expr {
+                  desc = StringLiteral { bytes = "true" } }};
                 else_branch = Some {
                   desc = If {
                   cond = {
                     desc = BinaryOperator { kind = EQ;
                     lhs = { desc = IntegerLiteral (Int 4)};
                     rhs = { desc = IntegerLiteral (Int 5)}}};
-                  then_branch = { desc = Expr { desc = StringLiteral "true" }};
+                  then_branch = { desc = Expr {
+                    desc = StringLiteral { bytes = "true" }}};
                   else_branch = Some {
-                    desc = Expr { desc = StringLiteral "false"}}}}}};
+                    desc = Expr {
+                      desc = StringLiteral { bytes = "false" }}}}}}};
               else_branch = Some {
                 desc = If {
                 cond =
                   { desc = BinaryOperator { kind = EQ;
                     lhs = { desc = IntegerLiteral (Int 4)};
                     rhs = { desc = IntegerLiteral (Int 5)}}};
-                then_branch = { desc = Expr { desc = StringLiteral "true" }};
+                then_branch = { desc = Expr {
+                  desc = StringLiteral { bytes = "true" }}};
                 else_branch = Some
-                  { desc = Expr { desc = StringLiteral "false"}}}}}}]}}} -> ()
+                  { desc = Expr {
+                    desc = StringLiteral { bytes = "false"}}}}}}}]}}} -> ()
         | decl ->
             Format.fprintf Format.err_formatter "%a\n"
-              Clang.Ast.pp_decl decl;
+              Clangml_show.pp_decl decl;
             assert false
       end
   | _ -> assert false
@@ -101,17 +108,18 @@ let () =
   | { desc = { items = [ decl ]}} ->
       begin
         match For_memcad.transform_decl decl with
-        | { desc = Function { name = "f"; body = Some { desc = Compound [
-            { desc = Decl [{ desc = Var { name = "res" }}]};
+        | { desc = Function { name = IdentifierName "f";
+            body = Some { desc = Compound [
+            { desc = Decl [{ desc = Var { var_name = "res" }}]};
             { desc = Expr { desc = BinaryOperator {
               kind = Assign;
-              lhs = { desc = DeclRef "res" };
+              lhs = { desc = DeclRef { name = IdentifierName "res" }};
               rhs = { desc = Call {
-                callee = { desc = DeclRef "malloc" };
+                callee = { desc = DeclRef { name = IdentifierName "malloc" }};
                 args = [{ desc = IntegerLiteral (Int 4)}]}}}}}]}}} -> ()
         | decl ->
             Format.fprintf Format.err_formatter "%a\n"
-              Clang.Ast.pp_decl decl;
+              Clangml_show.pp_decl decl;
             assert false
       end
   | _ -> assert false
diff --git a/visitors/clangml_visitors.ml b/visitors/clangml_visitors.ml
index 6bc84e55414f86c0cf27f54548c6288ffcbd6fb1..4101c714a138e4ac39de4647dfb949a71320892c 100644
--- a/visitors/clangml_visitors.ml
+++ b/visitors/clangml_visitors.ml
@@ -64,7 +64,7 @@
     end
   end
 
-  module%import Clang = struct  
+  module%import Clang = struct
     [%%recursive
      module%import Ast = struct
        type concrete_location = _
@@ -79,7 +79,7 @@
           variety = "reduce"; name = "base_reduce"; polymorphic = true },
         visitors {
           variety = "mapreduce"; name = "base_mapreduce"; polymorphic = true }]
-  
+
     [%%recursive
      module%import Types = struct
        type language = _ [@@rewrite]