From bc8bd22f399eb8fcc9c4333f9e3571d698a18a22 Mon Sep 17 00:00:00 2001 From: Patrick Ferris Date: Sat, 27 May 2023 15:01:49 +0100 Subject: [PATCH 1/5] Allow windows users to run dune build --- .github/workflows/main.yml | 1 + dune-project | 1 + lib_eio_posix/dune | 1 + 3 files changed, 3 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 247525ac4..036dd1487 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -56,6 +56,7 @@ jobs: opam pin -yn eio_windows.dev . opam install ocamlfind.1.9.5 kcas alcotest mdx crowbar -y opam install eio eio_windows --deps-only + - run: opam exec -- dune build - run: opam exec -- dune runtest - run: opam exec -- dune exec -- ./examples/net/main.exe docker: diff --git a/dune-project b/dune-project index ecb88cb3a..b1f786b7c 100644 --- a/dune-project +++ b/dune-project @@ -46,6 +46,7 @@ (uring (>= 0.5)))) (package (name eio_posix) + (allow_empty) (synopsis "Eio implementation for POSIX systems") (description "An Eio implementation for most Unix-like platforms") (depends diff --git a/lib_eio_posix/dune b/lib_eio_posix/dune index 0131354a3..080dd8150 100644 --- a/lib_eio_posix/dune +++ b/lib_eio_posix/dune @@ -11,4 +11,5 @@ (rule (targets config.ml) + (enabled_if (= %{os_type} "Unix")) (action (run ./include/discover.exe))) From 92c16d940505f2c9480ffaa5f86a7b2721071c15 Mon Sep 17 00:00:00 2001 From: Patrick Ferris Date: Sat, 27 May 2023 15:45:56 +0100 Subject: [PATCH 2/5] Add dscheck to windows test CI deps --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 036dd1487..d39d3312b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -54,7 +54,7 @@ jobs: - run: | opam pin -yn eio.dev . opam pin -yn eio_windows.dev . - opam install ocamlfind.1.9.5 kcas alcotest mdx crowbar -y + opam install ocamlfind.1.9.5 kcas alcotest mdx crowbar dscheck -y opam install eio eio_windows --deps-only - run: opam exec -- dune build - run: opam exec -- dune runtest From bce6a871b8601193af8b17fc17556e0dd31f3839 Mon Sep 17 00:00:00 2001 From: Patrick Ferris Date: Sat, 27 May 2023 22:11:25 +0100 Subject: [PATCH 3/5] Pin ocamlbuild --- .github/workflows/main.yml | 2 -- eio_windows.opam | 2 ++ eio_windows.opam.template | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d39d3312b..b8ce31375 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -47,9 +47,7 @@ jobs: ocaml-compiler: ocaml.5.0.0,ocaml-option-mingw opam-repositories: | dra27: https://github.com/dra27/opam-repository.git#windows-5.0 - duniverse: git+https://github.com/dune-universe/opam-overlays normal: https://github.com/ocaml/opam-repository.git - default: https://github.com/ocaml-opam/opam-repository-mingw.git#opam2 # --with-version=dev is not available, and --with-test also tries running tests for packages (like MDX) which fail... - run: | opam pin -yn eio.dev . diff --git a/eio_windows.opam b/eio_windows.opam index b007be8d2..fd7c878e7 100755 --- a/eio_windows.opam +++ b/eio_windows.opam @@ -32,6 +32,8 @@ build: [ ] dev-repo: "git+https://github.com/ocaml-multicore/eio.git" pin-depends: [ + # With Fdopen's patch, the only thing we need from opam-repo-mingw + [ "ocamlbuild.dev" "git+https://github.com/patricoferris/ocamlbuild#b72c0dfdd6f1066d50da4b924b8196237696f66b" ] # Removes base bytes for crowbar [ "ocplib-endian.dev" "git+https://github.com/Leonidas-from-XIV/ocplib-endian#fda4d5525063c8444020be369c63de23d39c246e" ] # Needed for the cstruct read and writes without copying diff --git a/eio_windows.opam.template b/eio_windows.opam.template index 7f38c1a6a..78b5f6b3b 100755 --- a/eio_windows.opam.template +++ b/eio_windows.opam.template @@ -1,4 +1,6 @@ pin-depends: [ + # With Fdopen's patch, the only thing we need from opam-repo-mingw + [ "ocamlbuild.dev" "git+https://github.com/patricoferris/ocamlbuild#b72c0dfdd6f1066d50da4b924b8196237696f66b" ] # Removes base bytes for crowbar [ "ocplib-endian.dev" "git+https://github.com/Leonidas-from-XIV/ocplib-endian#fda4d5525063c8444020be369c63de23d39c246e" ] # Needed for the cstruct read and writes without copying From 9793ae03f752e9dda247c8e3e6817a2a1c4d8c1e Mon Sep 17 00:00:00 2001 From: Patrick Ferris Date: Sat, 27 May 2023 23:22:35 +0100 Subject: [PATCH 4/5] Vendor cstruct stubs and remove pins --- dune-project | 3 +- eio_windows.opam | 6 - eio_windows.opam.template | 5 - lib_eio_windows/dune | 4 +- lib_eio_windows/eio_windows_cstruct_stubs.c | 149 ++++++++++++++++++++ lib_eio_windows/unix_cstruct.ml | 42 ++++++ 6 files changed, 194 insertions(+), 15 deletions(-) create mode 100755 lib_eio_windows/eio_windows_cstruct_stubs.c create mode 100755 lib_eio_windows/unix_cstruct.ml diff --git a/dune-project b/dune-project index b1f786b7c..4bd7483c5 100644 --- a/dune-project +++ b/dune-project @@ -46,7 +46,7 @@ (uring (>= 0.5)))) (package (name eio_posix) - (allow_empty) + (allow_empty) ; Work-around for dune bug #6938 (synopsis "Eio implementation for POSIX systems") (description "An Eio implementation for most Unix-like platforms") (depends @@ -61,7 +61,6 @@ (allow_empty) ; Work-around for dune bug #6938 (depends (eio (= :version)) - (cstruct-unix (= dev)) (kcas (and (>= 0.3.0) :with-test)) (alcotest (and (>= 1.4.0) :with-test)))) (package diff --git a/eio_windows.opam b/eio_windows.opam index fd7c878e7..0a55bb97e 100755 --- a/eio_windows.opam +++ b/eio_windows.opam @@ -11,7 +11,6 @@ bug-reports: "https://github.com/ocaml-multicore/eio/issues" depends: [ "dune" {>= "3.7"} "eio" {= version} - "cstruct-unix" {= "dev"} "kcas" {>= "0.3.0" & with-test} "alcotest" {>= "1.4.0" & with-test} "odoc" {with-doc} @@ -34,9 +33,4 @@ dev-repo: "git+https://github.com/ocaml-multicore/eio.git" pin-depends: [ # With Fdopen's patch, the only thing we need from opam-repo-mingw [ "ocamlbuild.dev" "git+https://github.com/patricoferris/ocamlbuild#b72c0dfdd6f1066d50da4b924b8196237696f66b" ] - # Removes base bytes for crowbar - [ "ocplib-endian.dev" "git+https://github.com/Leonidas-from-XIV/ocplib-endian#fda4d5525063c8444020be369c63de23d39c246e" ] - # Needed for the cstruct read and writes without copying - [ "cstruct.dev" "git+https://github.com/djs55/ocaml-cstruct#471ca03b49b3a372945fcf13c89e0447a8bd3932" ] - [ "cstruct-unix.dev" "git+https://github.com/djs55/ocaml-cstruct#471ca03b49b3a372945fcf13c89e0447a8bd3932" ] ] \ No newline at end of file diff --git a/eio_windows.opam.template b/eio_windows.opam.template index 78b5f6b3b..ff2aa6f2a 100755 --- a/eio_windows.opam.template +++ b/eio_windows.opam.template @@ -1,9 +1,4 @@ pin-depends: [ # With Fdopen's patch, the only thing we need from opam-repo-mingw [ "ocamlbuild.dev" "git+https://github.com/patricoferris/ocamlbuild#b72c0dfdd6f1066d50da4b924b8196237696f66b" ] - # Removes base bytes for crowbar - [ "ocplib-endian.dev" "git+https://github.com/Leonidas-from-XIV/ocplib-endian#fda4d5525063c8444020be369c63de23d39c246e" ] - # Needed for the cstruct read and writes without copying - [ "cstruct.dev" "git+https://github.com/djs55/ocaml-cstruct#471ca03b49b3a372945fcf13c89e0447a8bd3932" ] - [ "cstruct-unix.dev" "git+https://github.com/djs55/ocaml-cstruct#471ca03b49b3a372945fcf13c89e0447a8bd3932" ] ] \ No newline at end of file diff --git a/lib_eio_windows/dune b/lib_eio_windows/dune index 5e08cf31d..3a0fc6ea0 100644 --- a/lib_eio_windows/dune +++ b/lib_eio_windows/dune @@ -6,8 +6,8 @@ (foreign_stubs (language c) (include_dirs ../lib_eio/unix/include) - (names eio_windows_stubs)) - (libraries eio eio.unix eio.utils fmt cstruct-unix)) + (names eio_windows_stubs eio_windows_cstruct_stubs)) + (libraries eio eio.unix eio.utils fmt)) (rule (targets config.ml) diff --git a/lib_eio_windows/eio_windows_cstruct_stubs.c b/lib_eio_windows/eio_windows_cstruct_stubs.c new file mode 100755 index 000000000..863f41d7a --- /dev/null +++ b/lib_eio_windows/eio_windows_cstruct_stubs.c @@ -0,0 +1,149 @@ +/* From mirage/ocaml-cstruct +Copyright (c) 2012 Anil Madhavapeddy +Copyright (c) 2012 Pierre Chambart +Copyright (c) Christiano F. Haesbaert +Copyright (c) Citrix Inc +Copyright (c) David Sheets +Copyright (c) Drup +Copyright (c) Hannes Mehnert +Copyright (c) Jeremy Yallop +Copyright (c) Mindy Preston +Copyright (c) Nicolas Ojeda Bar +Copyright (c) Richard Mortier +Copyright (c) Rudi Grinberg +Copyright (c) Thomas Gazagnaire +Copyright (c) Thomas Leonard +Copyright (c) Vincent Bernardoff +Copyright (c) pqwy + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +CAMLprim value eio_windows_cstruct_read(value val_fd, value val_c) +{ + CAMLparam2(val_fd, val_c); + CAMLlocal3(val_buf, val_ofs, val_len); + uint8_t *buf; + size_t len; + ssize_t n = 0; + int win32err = 0; + SOCKET s; + HANDLE h; + DWORD numread; + int ok; + + val_buf = Field(val_c, 0); + val_ofs = Field(val_c, 1); + val_len = Field(val_c, 2); + + buf = (uint8_t *)Caml_ba_data_val(val_buf) + Long_val(val_ofs); + len = (size_t)Long_val(val_len); + + switch (Descr_kind_val(val_fd)) + { + case KIND_SOCKET: + s = Socket_val(val_fd); + + caml_release_runtime_system(); + n = recv(s, buf, len, 0); + win32err = WSAGetLastError(); + caml_acquire_runtime_system(); + + if (n == SOCKET_ERROR) + { + win32_maperr(win32err); + uerror("stub_cstruct_read", Nothing); + } + break; + case KIND_HANDLE: + h = Handle_val(val_fd); + caml_release_runtime_system(); + ok = ReadFile(h, buf, len, &numread, NULL); + win32err = GetLastError(); + n = numread; + caml_acquire_runtime_system(); + + if (!ok) + { + win32_maperr(win32err); + uerror("stub_cstruct_read", Nothing); + } + break; + default: + caml_failwith("unknown Descr_kind_val"); + } + + CAMLreturn(Val_int(n)); +} + +CAMLprim value eio_windows_cstruct_write(value val_fd, value val_c) +{ + CAMLparam2(val_fd, val_c); + CAMLlocal3(val_buf, val_ofs, val_len); + val_buf = Field(val_c, 0); + val_ofs = Field(val_c, 1); + val_len = Field(val_c, 2); + void *buf = (char *)Caml_ba_data_val(val_buf) + Long_val(val_ofs); + size_t len = Long_val(val_len); + ssize_t n = 0; + + int win32err = 0; + switch (Descr_kind_val(val_fd)) + { + case KIND_SOCKET: + SOCKET s = Socket_val(val_fd); + + caml_release_runtime_system(); + n = send(s, buf, len, 0); + win32err = WSAGetLastError(); + caml_acquire_runtime_system(); + + if (n == SOCKET_ERROR) + { + win32_maperr(win32err); + unix_error(errno, "stub_cstruct_write", Nothing); + } + break; + case KIND_HANDLE: + HANDLE h = Handle_val(val_fd); + DWORD numwritten; + caml_release_runtime_system(); + int ok = WriteFile(h, buf, len, &numwritten, NULL); + win32err = GetLastError(); + + n = numwritten; + caml_acquire_runtime_system(); + + if (!ok) + { + win32_maperr(win32err); + uerror("stub_cstruct_write", Nothing); + } + break; + default: + caml_failwith("unknown Descr_kind_val"); + } + + CAMLreturn(Val_int(n)); +} \ No newline at end of file diff --git a/lib_eio_windows/unix_cstruct.ml b/lib_eio_windows/unix_cstruct.ml new file mode 100755 index 000000000..86138a091 --- /dev/null +++ b/lib_eio_windows/unix_cstruct.ml @@ -0,0 +1,42 @@ +(* See the end of the file for the license *) +external stub_write : Unix.file_descr -> Cstruct.t -> int = "eio_windows_cstruct_write" + +let rec write fd buf = + if Cstruct.length buf > 0 then begin + let n = stub_write fd buf in + write fd @@ Cstruct.shift buf n + end + +let writev fd bufs = List.iter (write fd) bufs + +external read : Unix.file_descr -> Cstruct.t -> int = "eio_windows_cstruct_read" + +(* From mirage/ocaml-cstruct +Copyright (c) 2012 Anil Madhavapeddy +Copyright (c) 2012 Pierre Chambart +Copyright (c) Christiano F. Haesbaert +Copyright (c) Citrix Inc +Copyright (c) David Sheets +Copyright (c) Drup +Copyright (c) Hannes Mehnert +Copyright (c) Jeremy Yallop +Copyright (c) Mindy Preston +Copyright (c) Nicolas Ojeda Bar +Copyright (c) Richard Mortier +Copyright (c) Rudi Grinberg +Copyright (c) Thomas Gazagnaire +Copyright (c) Thomas Leonard +Copyright (c) Vincent Bernardoff +Copyright (c) pqwy + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) \ No newline at end of file From 81325ebae749152cc92b9f742c8d3bb50d50c15c Mon Sep 17 00:00:00 2001 From: Patrick Ferris Date: Sat, 27 May 2023 23:40:26 +0100 Subject: [PATCH 5/5] Tidy GHA for windows --- .github/workflows/main.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b8ce31375..85f2ef300 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -52,8 +52,7 @@ jobs: - run: | opam pin -yn eio.dev . opam pin -yn eio_windows.dev . - opam install ocamlfind.1.9.5 kcas alcotest mdx crowbar dscheck -y - opam install eio eio_windows --deps-only + opam install eio eio_windows --deps-only --with-test - run: opam exec -- dune build - run: opam exec -- dune runtest - run: opam exec -- dune exec -- ./examples/net/main.exe