(library
 (name uring)
 (public_name uring)
 (foreign_archives uring)
 (libraries cstruct fmt optint unix)
 (foreign_stubs
  (language c)
  (names uring_stubs)
  (include_dirs include)
  (extra_deps include/liburing/compat.h primitives.h)))

; "opam install lintcstubs-arity" to update primitives.h
(rule
 (enabled_if %{bin-available:lintcstubs_arity_cmt})
 (action
  (with-stdout-to
   primitives.h.new
   (run %{bin:lintcstubs_arity_cmt} %{dep:.uring.objs/byte/uring.cmt}))))

(rule
 (enabled_if %{bin-available:lintcstubs_arity_cmt})
 (alias runtest)
 (action
  (diff primitives.h primitives.h.new)))

(rule
 (targets config.ml)
 (deps
  include/liburing.h
  include/liburing/io_uring.h
  include/liburing/io_uring/bpf_filter.h
  include/liburing/io_uring_version.h
  include/liburing/io_uring/query.h
  include/liburing/barrier.h
  include/liburing/compat.h)
 (action
  (run ./include/discover.exe)))

; The way the liburing header files get copied around here is pretty confusing!
; The headers are (partly) generated by running the configure script.
; Building the OCaml library requires these (generated) headers,
; so they need to be the output of a dune rule.
; The generated files are spread over a tree, but dune rules must put all
; outputs in the same directory.
; So, we first use a no-infer action to run configure, then copy everything
; we need from the resulting tree (under "vendor") to this directory, flattening the structure.
; Then, more dune rules copy those files back into the correct tree structure,
; under "include".

(rule
 (deps
  (source_tree %{project_root}/vendor/liburing))
 (targets
  liburing.a
  dlluring.so
  barrier.h
  compat.h
  io_uring.h
  liburing.h
  query.h
  bpf_filter.h
  io_uring_version.h)
 (action
  (no-infer
   (progn
    (chdir
     %{project_root}/vendor/liburing
     (progn
      (run ./configure)
      (setenv
       CFLAGS
       "%{ocaml-config:ocamlc_cflags}"
       (run make -j -C src))))
    (copy %{project_root}/vendor/liburing/src/liburing.a liburing.a)
    (copy %{project_root}/vendor/liburing/src/liburing.so.2.15 dlluring.so)
    (copy %{project_root}/vendor/liburing/src/include/liburing.h liburing.h)
    (copy %{project_root}/vendor/liburing/src/include/liburing/io_uring.h io_uring.h)
    (copy %{project_root}/vendor/liburing/src/include/liburing/barrier.h barrier.h)
    (copy %{project_root}/vendor/liburing/src/include/liburing/compat.h compat.h)
    (copy %{project_root}/vendor/liburing/src/include/liburing/io_uring_version.h io_uring_version.h)
    (copy %{project_root}/vendor/liburing/src/include/liburing/io_uring/query.h query.h)
    (copy %{project_root}/vendor/liburing/src/include/liburing/io_uring/bpf_filter.h bpf_filter.h)))))

(subdir include (copy_files ../liburing.h))
(subdir include/liburing (copy_files ../../{io_uring,io_uring_version,barrier,compat}.h))
(subdir include/liburing/io_uring (copy_files ../../../{query,bpf_filter}.h))
