ocaml / ocaml/dune

ctypes stanza does not compile cstubs .o files with -fPIC

Open
#5,809 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

c-bindings
Dominant language
OCaml
Stars
1.9k
Forks
500
Avg merge
15h 21m
Merged PRs (30d)
277

Description

Please see my minimal example here: https://github.com/droyo/dune32-ctypes-fpic

Expected Behavior

When building a library with the ctypes stub generation in dune 3.2.0, dune should generate position-independent object files. This ensures that they can be put into the shared library $lib/dll$lib_stubs.so later in the build.

Actual Behavior

Dune runs a command like the following:

(cd _build/default && /usr/bin/gcc -g \
  -I /usr/lib/ocaml -I /home/droyo/.opam/default/lib/bigarray-compat \
  -I /home/droyo/.opam/default/lib/ctypes \
  -I /home/droyo/.opam/default/lib/integers \
  -I /home/droyo/.opam/default/lib/stdlib-shims \
  -o libmnl__c_cout_generated_functions__c_stub__libmnl.o \
  -c libmnl__c_cout_generated_functions__c_stub__libmnl.c )

note the lack of -fPIC. In my example, this does not cause a problem on its own, because the relocations that gcc generates are not deemed incompatible with dynamic linking by gcc:

$ objdump -r _build/default/libmnl__c_cout_generated_functions__c_stub__libmnl.o
_build/default/libmnl__c_cout_generated_functions__c_stub__libmnl.o:     file format elf64-x86-64
RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE
000000000000001c R_X86_64_PLT32    mnl_socket_open-0x0000000000000004
000000000000002c R_X86_64_PLT32    caml_copy_nativeint-0x0000000000000004

However, if I patch dune to enable use of the return_errno policy, and use it, the generated c code now requires a R_X86_64_PC32 relocation for Caml_state:

$ objdump -r _build/default/mnl/libmnl__c_cout_generated_functions__c_stub__libmnl.o
RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE
0000000000000015 R_X86_64_PC32     Caml_state-0x0000000000000004

And then compilation fails with the error:

gcc -shared  -g -o dllmnl_stubs.so libmnl__c_cout_generated_functions__c_stub__libmnl.o
ld: libmnl__c_cout_generated_functions__c_stub__libmnl.o: relocation R_X86_64_PC32 against undefined symbol `Caml_state' can not be used when making a shared object; recompile with -fPIC

I can work around this issue with a vendored build_flags_resolver:

(build_flags_resolver
  (vendored
    (c_flags (:standard -fPIC))
    (c_library_flags (:standard -lmnl))))

Reproduction

  1. Checkout https://github.com/droyo/dune32-ctypes-fpic
  2. Install ctypes (dune might pull this in already)
  3. Run dune build
  4. Observe in _build/log that the -fPIC option is absent from the gcc command (or any other flags in :standard, really).

Specifications

  • Version of dune (output of dune --version): 3.2.0
  • Version of ocaml (output of ocamlc --version): reproduced on 4.13.1, 4.14.0
  • Operating system (distribution and version): Arch Linux, kernel 5.17.9, gcc 12.1.0

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the minimal example at https://github.com/droyo/dune32-ctypes-fpic and run dune build. Inspect _build/log and the ctypes-generated object compilation command, comparing it with the reported build_flags_resolver workaround. Done means the generated cstubs object is compiled with position-independent flags and the shared library builds successfully.

Written by the indexing model from the issue text.

Assessment

Domain
build-system
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.