Skip to content

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

@droyo

Description

@droyo

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    c-bindingsWhen dune is trying to interop with C

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions