Skip to content

[RFC] Mode-specific foreign stubs #4639

@voodoos

Description

@voodoos

Some projects like the OCaml compiler need to use different C-stubs implementations depending on wheter the target is byte or native. This can be done by passing different C-flags (like preprocessor flags) depending on the mode or by using different source files.

Dune already allows multiple foreign_stubs definitions in the same executable or library stanza:

(executable
 (name stubs_exe)
  (foreign_stubs
    (language c)
    (names c_stubs))      ; c_stubs.c
  (foreign_stubs
    (language c)
    (names c_stubs_2)))   ; c_stubs_2.c

which is equivalent to using (names c_stubs c_stubs_2) if no other field (such as the flags field) differ.

However, as expected, using twice the same source file is forbidden:

(executable
 (name stubs_exe)
  (foreign_stubs
    (language c)
    (names c_stubs))
  (foreign_stubs
    (language c)
    (names c_stubs)))
dune exec ./stubs_exe.exe
File "dune", line 5, characters 11-19:
5 |     (names c_stubs))
               ^^^^^^^^
Error: Multiple sources map to the same object name "c_stubs":
- c_stubs.c
- c_stubs.c

We propose to add a field mode to the foreign_stubs field that would act as a filter defaulting to all modes.

  • This optional field would accept a single value: byte or native
  • A foreign_stubs field with a mode specified will be ignored ("filtered-out") if the current build mode does not match the one specified in its mode field. Thus two different foreign_stubs fields for the same source can coexist if they specify different modes.
  • Absence of the field means both byte and native. That makes this proposal backward compatible. That also means that a foreign_stubs field without a mode field will never be silently filtered-out in favor of another foreign_stubs with an explicit mode field.

For example, one could feed different flags to the compiler depending on the mode:

(executable
 (name stubs_exe)
  (foreign_stubs
    (language c)
    (mode byte)
    (names c_stubs))
  (foreign_stubs
    (language c)
    (mode native)
    (flags :standard -DNATIVE_CODE)
    (names c_stubs)))

Or use different sources depending on the mode:

(executable
 (name stubs_exe)
  (foreign_stubs
    (language c)
    (mode byte)
    (names c_stubs_byte))
  (foreign_stubs
    (language c)
    (mode native)
    (names c_stubs_native)))

Part of this proposal has already been implemented in a fork of Dune used to compile the flambda backend. Our plan is too carefully upstream and complete these changes.

Metadata

Metadata

Assignees

Labels

proposalRFC's that are awaiting discussion to be accepted or rejected

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions