Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ctypes external_library_name doesn't support a value which doesn't translate to a valid ocaml module name #5511

Closed
Khady opened this issue Mar 10, 2022 · 13 comments · Fixed by ocaml/opam-repository#21380

Comments

@Khady
Copy link
Contributor

Khady commented Mar 10, 2022

Expected Behavior

When using external_library_name icu-io dune shouldn't throw an error. It should translate the name into something valid in ocaml instead.

Actual Behavior

Description:
  ("Invalid Module_name.t", { s = "icu-io__c_generated_types" })
Raised at Stdune__code_error.raise in file "otherlibs/stdune/code_error.ml",
  line 11, characters 30-62
Called from Dune_rules__ctypes_rules.Stanza_util.generated_modules in file
  "src/dune_rules/ctypes_rules.ml", line 129, characters 8-39
Called from Dune_rules__ctypes_rules.Stanza_util.generated_ml_and_c_files in
  file "src/dune_rules/ctypes_rules.ml", line 142, characters 6-30
Called from Dune_rules__dir_contents.Load.load_text_files.(fun) in file
  "src/dune_rules/dir_contents.ml", line 175, characters 31-75
Called from Fiber.Scheduler.exec in file "src/fiber/fiber.ml", line 854,
  characters 10-13
-> required by ("dir-contents-get0", ("default", "default/icu"))
-> required by ("gen-rules", "default/icu")
-> required by ("load-dir", In_build_dir "default/icu")
-> required by
   ("build-alias", { dir = "default/icu"; name = "default" })
-> required by ("toplevel", ())

The file icu_io__c_library_flags.sexp also contains ("-licu_io") which is incorrect

$ pkg-config --libs icu-io
-licuio -licui18n -licuuc -licudata

Reproduction

(library
 (name icu)
 (public_name icu)
 (libraries )
 (ctypes
  (external_library_name icu-io)
  (build_flags_resolver pkg_config)
  (headers (include "unicode/ubrk.h" "unicode/utext.h"))
  (type_description
   (instance Type)
   (functor Type_description))
  (function_description
   (concurrency unlocked)
   (instance Function)
   (functor Function_description))
  (generated_types Types_generated)
  (generated_entry_point C)
  ))

Specifications

  • Version of dune (output of dune --version): 3.0.3
  • Version of ocaml (output of ocamlc --version): 4.12.1
  • Operating system (distribution and version): debian 10
@bobot
Copy link
Collaborator

bobot commented Mar 10, 2022

cc @mbacarella

@mbacarella
Copy link
Collaborator

Hmm, right. It takes a string though it writes out intermediate module names derived from that string.

Should be a pretty simple fix. What's the space of valid module names? Is it [A-Z][a-z0-9_]*?

@Khady
Copy link
Contributor Author

Khady commented Mar 11, 2022

at least [A-Z][a-zA-Z0-9_]*

@rr0gi
Copy link

rr0gi commented Mar 14, 2022

@Khady
Copy link
Contributor Author

Khady commented Mar 14, 2022

is there more to do than fixing Module_name.of_string (or writing an alternative version that correctly mangles the name)?

@bobot
Copy link
Collaborator

bobot commented Mar 14, 2022

I would prefer an alternative version which mangles the name. The fix should also check that the name given in the external_library_name field of the stanza can be mangled, otherwise give a nice message, the code is here:

(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+ function_description =
multi_field "function_description" Function_description.decode
and+ headers = field_o "headers" Headers.decode
and+ generated_types = field_o "generated_types" Module_name.decode

You could use the StringLike module to easily create a decoder:

module Make (S : Stringlike_intf.S_base) : Stringlike_intf.S with type t = S.t

like the one Module_name.decode:

Stringlike.Make (struct

@Khady
Copy link
Contributor Author

Khady commented Mar 14, 2022

The fix should also check that the name given in the external_library_name field of the stanza can be mangled, otherwise give a nice message

What would be a name that can't be mangled?

@bobot
Copy link
Collaborator

bobot commented Mar 14, 2022

It is perhaps not the mangling that would fail, but perhaps something else. If the whole toolchain can support (external_library_name "foo!#what?/oups~ in space") we can keep the string decoder otherwise it is better to not get another backtrace somewhere, no?

@Khady
Copy link
Contributor Author

Khady commented May 6, 2022

@bobot is it what you were thinking about? https://github.com/ocaml/dune/pull/5667/files

The next step would be to do (external_lib_name |> External_lib_name.to_module_name |> Module_name.to_string) in the right places I believe.

Khady added a commit to Khady/dune that referenced this issue May 9, 2022
@Khady
Copy link
Contributor Author

Khady commented May 9, 2022

Potentially fixed by #5667

@Khady
Copy link
Contributor Author

Khady commented May 9, 2022

The file icu_io__c_library_flags.sexp also contains ("-licu_io") which is incorrect

I don't know how to test for that

@Khady
Copy link
Contributor Author

Khady commented May 9, 2022

$ make test
./dune.exe runtest
File "test/blackbox-tests/test-cases/ctypes/lib-external-name-need-mangling.t/run.t", line 1, characters 0-0:
------ test/blackbox-tests/test-cases/ctypes/lib-external-name-need-mangling.t/run.t
++++++ test/blackbox-tests/test-cases/ctypes/lib-external-name-need-mangling.t/run.t.corrected
File "test/blackbox-tests/test-cases/ctypes/lib-external-name-need-mangling.t/run.t", line 13, characters 0-1:
 |Bind to a C library which has a name invalid in ocaml
 |
 |  $ LIBEX=$(realpath "$PWD/../libneed-mangling")
 |
 |This silly looking hack is to make sure the .pc file points to the sandbox. We
 |cannot set ${prefix} to be interpreted relative to the .pc itself ufortunately
 |  $ awk "BEGIN{print \"prefix=$LIBEX\"} {print}" $LIBEX/need-mangling.pc > need-mangling.pc
 |
 |  $ DYLD_LIBRARY_PATH="$LIBEX" LD_LIBRARY_PATH="$LIBEX" PKG_CONFIG_PATH="$PWD:$PKG_CONFIG_PATH" dune exec ./example.exe
 |  4
 |
 |  $ cat _build/default/stubgen/need-mangling__c_library_flags.sexp
+|  ("-L/workspace_root/test/blackbox-tests/test-cases/ctypes/libneed-mangling" "-lneed-mangling")

looks ok

Khady added a commit to Khady/dune that referenced this issue May 12, 2022
Khady added a commit to Khady/dune that referenced this issue May 12, 2022
rgrinberg pushed a commit to Khady/dune that referenced this issue May 16, 2022
add test for external library name that isn't valid in ocaml

issue ocaml#5511

Signed-off-by: Louis Roché (Ahrefs) <[email protected]>
Khady added a commit to Khady/dune that referenced this issue May 17, 2022
rgrinberg pushed a commit that referenced this issue May 17, 2022
add test for external library name that isn't valid in ocaml

issue #5511

Signed-off-by: Louis Roché (Ahrefs) <[email protected]>

ps-id: 0B6EC9CA-8480-4955-9DF1-9A066A118968
rgrinberg added a commit to rgrinberg/opam-repository that referenced this issue May 17, 2022
…ne-site, dune-rpc, dune-rpc-lwt, dune-private-libs, dune-glob, dune-configurator, dune-build-info, dune-action-plugin and chrome-trace (3.2.0)

CHANGES:

- Fixed ``dune describe workspace --with-deps`` so that it correctly
  handles Reason files, as well as files any other dialect. (ocaml/dune#5701, @esope)

- Disable alerts when compiling code in vendored directories (ocaml/dune#5683,
  @NathanReb)

- Fixed ``dune describe --with-deps``, that crashed when some
  preprocessing was required in a dune file using ``per_module``.
  (ocaml/dune#5682, fixes ocaml/dune#5680, @esope)

- Add `$ dune describe pp` to print the preprocssed ast of sources. (ocaml/dune#5615,
  fixes ocaml/dune#4470, @cannorin)

- Report dune file evaluation errors concurrently. In the same way we report
  build errors. (ocaml/dune#5655, @rgrinberg)

- Watch mode now default to clearing the terminal on rebuild (ocaml/dune#5636, fixes,
  ocaml/dune#5216, @rgrinberg)

- The output of jobs that finished but were cancelled is now omitted. (ocaml/dune#5631,
  fixes ocaml/dune#5482, @rgrinberg)

- Allows to configure all the default destination directories with `./configure`
  (adds `bin`, `sbin`, `data`, `libexec`). Use `OPAM_SWITCH_PREFIX` instead of
  calling the `opam` binaries in `dune install`. Fix handling of multiple
  `libdir` in `./configure` for handling `/usr/lib/ocaml/` and
  `/usr/local/lib/ocaml`. In `dune install` forbid relative directories in
  `libdir`, `docdir` and others specific directory setting because their handling
  was inconsistent (ocaml/dune#5516, fixes ocaml/dune#3978 and ocaml/dune#5455, @bobot)

- `--terminal-persistence=clear-on-rebuild` will no longer destroy scrollback
  on some terminals (ocaml/dune#5646, @rgrinberg)

- Add a fmt command as a shortcut of `dune build @fmt --auto-promote` (ocaml/dune#5574,
  @tmattio)

- Watch mode now tracks copied external files, external directories for
  dependencies, dune files in OCaml syntax, files used by `include` stanzas,
  dune-project, opam files, libraries builtin with compiler, and foreign
  sources (ocaml/dune#5627, ocaml/dune#5645, ocaml/dune#5652, ocaml/dune#5656, ocaml/dune#5672, ocaml/dune#5691, ocaml/dune#5722, fixes ocaml/dune#5331,
  @rgrinberg)

- Improve metrics for cram tests. Include test names in the event and add a
  category for cram tests (ocaml/dune#5626, @rgrinberg)

- Allow specifying multiple licenses in project file (ocaml/dune#5579, fixes ocaml/dune#5574,
  @liyishuai)

- Match `glob_files` only against files in external directories (ocaml/dune#5614, fixes
  ocaml/dune#5540, @rgrinberg)

- Add pid's to chrome trace output (ocaml/dune#5617, @rgrinberg)

- Fix race when creating local cache directory (ocaml/dune#5613, fixes ocaml/dune#5461, @rgrinberg)

- Add `not` to boolean expressions (ocaml/dune#5610, fix ocaml/dune#5503, @rgrinberg)

- Fix relative dependencies outside the workspace (ocaml/dune#4035, fixes ocaml/dune#5572, @bobot)

- Allow to specify `--prefix` via the environment variable
  `DUNE_INSTALL_PREFIX` (ocaml/dune#5589, @vapourismo)

- Dune-site.plugin: add support for `archive(native|byte, plugin)` used in the
  wild before findlib documented `plugin(native|byte)` in 2015 (ocaml/dune#5518, @bobot)

- Fix a bug where Dune would not correctly interpret `META` files in alternative
  layout (ie when the META file is named `META.$pkg`). The `Llvm` bindings were
  affected by this issue. (ocaml/dune#5619, fixes ocaml/dune#5616, @nojb)

- Support `(binaries)` in `(env)` in dune-workspace files (ocaml/dune#5560, fix ocaml/dune#5555,
  @emillon)

- (mdx) stanza: add support for (locks). (ocaml/dune#5628, fixes ocaml/dune#5489, @emillon)

- (mdx) stanza: support including files in different directories using relative
  paths, and provide better error messages when paths are invalid (ocaml/dune#5703, ocaml/dune#5704,
  fixes ocaml/dune#5596, @emillon)

- Fix ctypes rules for external lib names which aren't valid ocaml names
  (ocaml/dune#5667, fixes ocaml/dune#5511, @Khady)
@Khady
Copy link
Contributor Author

Khady commented May 17, 2022

Fixed by 3075bd4

@Khady Khady closed this as completed May 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment