diff --git a/src/dune_rules/ctypes/ctypes_field.ml b/src/dune_rules/ctypes/ctypes_field.ml index 0bfbdcae1cd..2c4960f9b83 100644 --- a/src/dune_rules/ctypes/ctypes_field.ml +++ b/src/dune_rules/ctypes/ctypes_field.ml @@ -158,44 +158,48 @@ include Stanza.Make (struct let decode = let open Dune_lang.Decoder in fields - (let+ external_library_name = field "external_library_name" string - and+ build_flags_resolver = - field_o "build_flags_resolver" Build_flags_resolver.decode - and+ type_description = field "type_description" Type_description.decode - and+ loc_fd, function_description = - located (multi_field "function_description" Function_description.decode) - and+ headers = field_o "headers" Headers.decode - and+ generated_types = field_o "generated_types" Module_name.decode - and+ generated_entry_point = field "generated_entry_point" Module_name.decode - and+ deps = field_o "deps" (repeat Dep_conf.decode) - and+ version = Syntax.get_exn syntax in - let external_library_name = External_lib_name.of_string external_library_name in - (match - String.Map.of_list_map function_description ~f:(fun fd -> - let key = c_generated_functions_cout_c_of_lib ~external_library_name fd in - key, ()) - with - | Ok _ -> () - | Error (_, a, _) -> - User_error.raise - ~loc:loc_fd - [ Pp.textf - "Only a single (function_description) can instantiate %s as %s." - (Module_name.to_string a.functor_) - (Module_name.to_string a.instance) - ]); - { external_library_name - ; build_flags_resolver = - Option.value build_flags_resolver ~default:Build_flags_resolver.default - ; headers = Option.value headers ~default:Headers.default - ; type_description - ; function_description - ; generated_types = - Option.value generated_types ~default:(Module_name.of_string "Types_generated") - ; generated_entry_point - ; deps = Option.value ~default:[] deps - ; version - }) + (let* deps = field "deps" (Bindings.decode Dep_conf.decode) ~default:Bindings.empty in + String_with_vars.add_user_vars_to_decoding_env + (Bindings.var_names deps) + (let+ external_library_name = field "external_library_name" string + and+ build_flags_resolver = + field_o "build_flags_resolver" Build_flags_resolver.decode + and+ type_description = field "type_description" Type_description.decode + and+ loc_fd, function_description = + located (multi_field "function_description" Function_description.decode) + and+ headers = field_o "headers" Headers.decode + and+ generated_types = field_o "generated_types" Module_name.decode + and+ generated_entry_point = field "generated_entry_point" Module_name.decode + and+ version = Syntax.get_exn syntax in + let external_library_name = External_lib_name.of_string external_library_name in + (match + String.Map.of_list_map function_description ~f:(fun fd -> + let key = c_generated_functions_cout_c_of_lib ~external_library_name fd in + key, ()) + with + | Ok _ -> () + | Error (_, a, _) -> + User_error.raise + ~loc:loc_fd + [ Pp.textf + "Only a single (function_description) can instantiate %s as %s." + (Module_name.to_string a.functor_) + (Module_name.to_string a.instance) + ]); + { external_library_name + ; build_flags_resolver = + Option.value build_flags_resolver ~default:Build_flags_resolver.default + ; headers = Option.value headers ~default:Headers.default + ; type_description + ; function_description + ; generated_types = + Option.value + generated_types + ~default:(Module_name.of_string "Types_generated") + ; generated_entry_point + ; deps = Bindings.to_list deps + ; version + })) ;; let () = diff --git a/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/bar.h b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/bar.h new file mode 100644 index 00000000000..8508c9d9481 --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/bar.h @@ -0,0 +1 @@ +#define BAR_VERSION 1 diff --git a/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/baz.h b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/baz.h new file mode 100644 index 00000000000..04d503787d5 --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/baz.h @@ -0,0 +1 @@ +#define BAZ_VERSION 1 diff --git a/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/dune b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/dune new file mode 100644 index 00000000000..5c7407000f0 --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/dune @@ -0,0 +1,21 @@ +(executable + (name example) + (flags + (:standard -w -9-27)) + (ctypes + (external_library_name libexample) + (build_flags_resolver pkg_config) + (deps + (:foo_h "foo.h") + (:bar_h bar.h) + baz.h) + (headers + (preamble + "#include \n#include \"%{foo_h}\"\n#include \"%{bar_h}\"\n#include \"baz.h\"\n#include \"%{dep:qux.h}\"")) + (type_description + (instance Types) + (functor Type_description)) + (function_description + (instance Functions) + (functor Function_description)) + (generated_entry_point C))) diff --git a/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/dune-project b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/dune-project new file mode 100644 index 00000000000..1e9b8cc3eeb --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/dune-project @@ -0,0 +1,5 @@ +(lang dune 3.8) + +(using ctypes 0.3) + +(use_standard_c_and_cxx_flags false) diff --git a/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/example.ml b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/example.ml new file mode 100644 index 00000000000..75fa327f298 --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/example.ml @@ -0,0 +1,6 @@ +let () = + Printf.printf "%d\n" (C.Functions.add2 C.Types.foo_version); + Printf.printf "%d\n" (C.Functions.add2 C.Types.bar_version); + Printf.printf "%d\n" (C.Functions.add2 C.Types.baz_version); + Printf.printf "%d\n" (C.Functions.add2 C.Types.qux_version); + () diff --git a/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/foo.h b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/foo.h new file mode 100644 index 00000000000..b6083666e87 --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/foo.h @@ -0,0 +1 @@ +#define FOO_VERSION 1 diff --git a/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/function_description.ml b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/function_description.ml new file mode 100644 index 00000000000..05c43d79e2f --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/function_description.ml @@ -0,0 +1,8 @@ +open Ctypes + +module Types = Types_generated + +module Functions (F : Ctypes.FOREIGN) = struct + open F + let add2 = foreign "example_add2" (int @-> returning int) +end diff --git a/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/qux.h b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/qux.h new file mode 100644 index 00000000000..74cdee31332 --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/qux.h @@ -0,0 +1 @@ +#define QUX_VERSION 1 diff --git a/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/run.t b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/run.t new file mode 100644 index 00000000000..7679883a3cf --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/run.t @@ -0,0 +1,18 @@ +Build an example library as a DLL and set up the environment so that it looks +like a system/distro library that can be probed with pkg-config and dynamically +loaded. + +Then generate cstubs for it, build an executable that uses those cstubs, and +run the executable that tests the library through the cstubs. + + $ LIBEX=$(realpath "$PWD/../libexample") + $ DYLD_LIBRARY_PATH="$LIBEX" LD_LIBRARY_PATH="$LIBEX" PKG_CONFIG_PATH="$LIBEX/pkgconfig" PKG_CONFIG_ARGN="--define-prefix" dune exec ./example.exe + File "dune", line 14, characters 38-46: + 14 | "#include \n#include \"%{foo_h}\"\n#include \"%{bar_h}\"\n#include \"baz.h\"\n#include \"%{dep:qux.h}\"")) + ^^^^^^^^ + Error: %{foo_h} isn't allowed in this position. + File "dune", line 14, characters 61-69: + 14 | "#include \n#include \"%{foo_h}\"\n#include \"%{bar_h}\"\n#include \"baz.h\"\n#include \"%{dep:qux.h}\"")) + ^^^^^^^^ + Error: %{bar_h} isn't allowed in this position. + [1] diff --git a/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/type_description.ml b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/type_description.ml new file mode 100644 index 00000000000..96e2916ea0a --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/deps-full-spec.t/type_description.ml @@ -0,0 +1,9 @@ +module Types (F : Ctypes.TYPE) = struct + open F + + let foo_version = constant "FOO_VERSION" int + let bar_version = constant "BAR_VERSION" int + let baz_version = constant "BAZ_VERSION" int + let qux_version = constant "QUX_VERSION" int + +end