diff --git a/src/dune_rules/ctypes/ctypes_rules.ml b/src/dune_rules/ctypes/ctypes_rules.ml index d27cc6d1396e..2388ea285d6a 100644 --- a/src/dune_rules/ctypes/ctypes_rules.ml +++ b/src/dune_rules/ctypes/ctypes_rules.ml @@ -483,8 +483,7 @@ let gen_rules ~cctx ~(buildable : Buildable.t) ~loc ~scope ~dir ~sctx = ~c_types_includer_module)) ;; -let ctypes_cclib_flags sctx ~expander ~(buildable : Buildable.t) = - let standard = Action_builder.return [] in +let ctypes_cclib_flags ?(standard = Action_builder.return []) sctx ~expander ~(buildable : Buildable.t) = match buildable.ctypes with | None -> standard | Some ctypes -> diff --git a/src/dune_rules/ctypes/ctypes_rules.mli b/src/dune_rules/ctypes/ctypes_rules.mli index 27c1241e1179..689d8673c50d 100644 --- a/src/dune_rules/ctypes/ctypes_rules.mli +++ b/src/dune_rules/ctypes/ctypes_rules.mli @@ -10,7 +10,8 @@ val gen_rules -> unit Memo.t val ctypes_cclib_flags - : Super_context.t + : ?standard:(string list Action_builder.t) + -> Super_context.t -> expander:Expander.t -> buildable:Dune_file.Buildable.t -> string list Action_builder.t diff --git a/src/dune_rules/lib_rules.ml b/src/dune_rules/lib_rules.ml index b362c67b72a1..96c98b2ff15b 100644 --- a/src/dune_rules/lib_rules.ml +++ b/src/dune_rules/lib_rules.ml @@ -331,9 +331,7 @@ let build_stubs lib ~cctx ~dir ~expander ~requires ~dir_contents ~vlib_stubs_o_f Cxx_flags.get_flags ~for_:Link (Context.build_context ctx) | _ -> Action_builder.return [] in - let c_library_flags = - Expander.expand_and_eval_set expander lib.c_library_flags ~standard - in + let c_library_flags = Ctypes_rules.ctypes_cclib_flags sctx ~expander ~buildable:lib.buildable ~standard in let lib_o_files_for_all_modes = Mode.Map.Multi.for_all_modes o_files in let for_all_modes = List.rev_append vlib_stubs_o_files lib_o_files_for_all_modes in if Mode.Dict.Set.to_list modes.ocaml diff --git a/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/dune b/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/dune new file mode 100644 index 000000000000..2ca1e427745b --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/dune @@ -0,0 +1,4 @@ +(executable + (name example) + (modes byte) + (libraries examplelib)) diff --git a/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/dune-project b/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/dune-project new file mode 100644 index 000000000000..d993321861b0 --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/dune-project @@ -0,0 +1,3 @@ +(lang dune 3.10) + +(using ctypes 0.3) diff --git a/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/example.ml b/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/example.ml new file mode 100644 index 000000000000..eebafeb3114f --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/example.ml @@ -0,0 +1,2 @@ +let () = + Printf.printf "%d\n" (Examplelib.C.Functions.add2 2) diff --git a/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/run.t b/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/run.t new file mode 100644 index 000000000000..4b948ec62e0a --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/run.t @@ -0,0 +1,82 @@ + +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. + + + +Run the program in bytecode + $ LIBEX=$(realpath "$PWD/../libexample") + $ tree $LIBEX + /workspace_root/test/blackbox-tests/test-cases/ctypes/libexample + |-- example.h -> ../../../../../../../../default/test/blackbox-tests/test-cases/ctypes/libexample/example.h + |-- libexample.a -> ../../../../../../../../default/test/blackbox-tests/test-cases/ctypes/libexample/libexample.a + |-- libexample.so -> ../../../../../../../../default/test/blackbox-tests/test-cases/ctypes/libexample/libexample.so + `-- pkgconfig + `-- libexample.pc -> ../../../../../../../../../default/test/blackbox-tests/test-cases/ctypes/libexample/pkgconfig/libexample.pc + + 1 directory, 4 files + +Build the stubs.so + + + $ PKG_CONFIG_PATH="$LIBEX/pkgconfig" PKG_CONFIG_ARGN="--define-prefix" dune build stubgen/dllexamplelib_stubs.so + + $ PKG_CONFIG_PATH="$LIBEX/pkgconfig" PKG_CONFIG_ARGN="--define-prefix" dune build ./example.bc + +ocamlrun + bytcode with ocaml requires CAML_LD_LIBRARY_PATH. +Explictly set LIBRARY_PATH at runtime,otherwise dlopen cannot find libexample. +Eventually setting proper build flags for libexample + + $ dune clean + $ PKG_CONFIG_PATH="$LIBEX/pkgconfig" PKG_CONFIG_ARGN="--define-prefix" DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:$LIBEX" CAML_LD_LIBRARY_PATH="$CAML_LD_LIBRARY_PATH:$PWD/_build/default/stubgen" dune exec ./example.bc --display=short + ocamlc stubgen/.examplelib.objs/byte/examplelib.{cmi,cmo,cmt} + ocamldep stubgen/.examplelib.objs/examplelib__C.impl.d + ocamldep stubgen/.examplelib.objs/examplelib__Function_description.impl.d + ocamldep stubgen/.examplelib.objs/examplelib__Libexample__function_gen__Function_description__Functions.impl.d + ocamldep stubgen/.examplelib.objs/examplelib__Libexample__type_gen.impl.d + cc .dune/ccomp/ccomp + pkg-config stubgen/.pkg-config/libexample.cflags + ocamldep stubgen/.examplelib.objs/examplelib__Type_description.impl.d + ocamldep stubgen/.examplelib.objs/examplelib__Types_generated.impl.d + pkg-config stubgen/.pkg-config/libexample.libs + ocamlc stubgen/.examplelib.objs/byte/examplelib__Type_description.{cmi,cmo,cmt} + ocamlopt stubgen/.examplelib.objs/native/examplelib.{cmx,o} + ocamlopt stubgen/.examplelib.objs/native/examplelib__Type_description.{cmx,o} + ocamlc stubgen/.examplelib.objs/byte/examplelib__Libexample__type_gen.{cmi,cmo,cmt} + ocamlopt stubgen/.examplelib.objs/native/examplelib__Libexample__type_gen.{cmx,o} + ocamlopt stubgen/libexample__type_gen.exe + libexample__type_gen stubgen/libexample__c_cout_generated_types.c + cc stubgen/libexample__c_cout_generated_types.exe + libexample__c_cout_generated_types stubgen/libexample__c_generated_types.ml + ocamldep stubgen/.examplelib.objs/examplelib__Libexample__c_generated_types.impl.d + ocamlc stubgen/.examplelib.objs/byte/examplelib__Libexample__c_generated_types.{cmi,cmo,cmt} + ocamlc stubgen/.examplelib.objs/byte/examplelib__Types_generated.{cmi,cmo,cmt} + ocamlopt stubgen/.examplelib.objs/native/examplelib__Libexample__c_generated_types.{cmx,o} + ocamlc stubgen/.examplelib.objs/byte/examplelib__Function_description.{cmi,cmo,cmt} + ocamlopt stubgen/.examplelib.objs/native/examplelib__Types_generated.{cmx,o} + ocamlopt stubgen/.examplelib.objs/native/examplelib__Function_description.{cmx,o} + ocamlc stubgen/.examplelib.objs/byte/examplelib__Libexample__function_gen__Function_description__Functions.{cmi,cmo,cmt} + ocamlopt stubgen/.examplelib.objs/native/examplelib__Libexample__function_gen__Function_description__Functions.{cmx,o} + ocamlopt stubgen/libexample__function_gen__Function_description__Functions.exe + libexample__function_gen__Function_description__Functions stubgen/libexample__c_generated_functions__Function_description__Functions.ml + libexample__function_gen__Function_description__Functions stubgen/libexample__c_cout_generated_functions__Function_description__Functions.c + ocamldep stubgen/.examplelib.objs/examplelib__Libexample__c_generated_functions__Function_description__Functions.impl.d + cc stubgen/libexample__c_cout_generated_functions__Function_description__Functions.o + ocamlc stubgen/.examplelib.objs/byte/examplelib__Libexample__c_generated_functions__Function_description__Functions.{cmi,cmo,cmt} + ocamlmklib stubgen/dllexamplelib_stubs.so,stubgen/libexamplelib_stubs.a + ocamlc stubgen/.examplelib.objs/byte/examplelib__C.{cmi,cmo,cmt} + ocamlc .example.eobjs/byte/dune__exe__Example.{cmi,cmti} + ocamlc stubgen/examplelib.cma + ocamlc .example.eobjs/byte/dune__exe__Example.{cmo,cmt} + ocamlc example.bc + 4 + +Utop works with ctypes pkg-config external library. + + $ DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:$LIBEX" PKG_CONFIG_PATH="$LIBEX/pkgconfig" PKG_CONFIG_ARGN="--define-prefix" dune utop --display=short ./ -- example.ml + pkg-config stubgen/.pkg-config/libexample.cflags + pkg-config stubgen/.pkg-config/libexample.libs + ocamlc .utop/.utop.eobjs/byte/dune__exe__Utop.{cmi,cmo,cmt} + ocamlc .utop/utop.bc + 4 diff --git a/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/stubgen/dune b/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/stubgen/dune new file mode 100644 index 000000000000..a426491271df --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/stubgen/dune @@ -0,0 +1,14 @@ +(library + (name examplelib) + (flags (:standard -w -9-27)) + (ctypes + (external_library_name libexample) + (build_flags_resolver pkg_config) + (headers (include "example.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/bytecode-stubs-external-lib.t/stubgen/function_description.ml b/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/stubgen/function_description.ml new file mode 100644 index 000000000000..05c43d79e2fa --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/stubgen/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/bytecode-stubs-external-lib.t/stubgen/type_description.ml b/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/stubgen/type_description.ml new file mode 100644 index 000000000000..41693fda9b31 --- /dev/null +++ b/test/blackbox-tests/test-cases/ctypes/bytecode-stubs-external-lib.t/stubgen/type_description.ml @@ -0,0 +1,3 @@ +module Types (F : Ctypes.TYPE) = struct + +end diff --git a/test/blackbox-tests/test-cases/ctypes/dune b/test/blackbox-tests/test-cases/ctypes/dune index 3d9ec9e03096..a3d6c3586aac 100644 --- a/test/blackbox-tests/test-cases/ctypes/dune +++ b/test/blackbox-tests/test-cases/ctypes/dune @@ -27,6 +27,7 @@ (cram (applies_to + bytecode-stubs-external-lib lib-pkg_config lib-pkg_config-multiple-fd lib-external-name-need-mangling