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

[ocaml-5.1.0]: Bytecode -custom exes fail to link with cc a C++ compiler #12790

Closed
shayne-fletcher opened this issue Nov 27, 2023 · 2 comments · Fixed by #12791
Closed

[ocaml-5.1.0]: Bytecode -custom exes fail to link with cc a C++ compiler #12790

shayne-fletcher opened this issue Nov 27, 2023 · 2 comments · Fixed by #12791

Comments

@shayne-fletcher
Copy link
Contributor

shayne-fletcher commented Nov 27, 2023

Since ocaml-5.1.0, bytecode -custom executables fail to link if given -cc a C++ compiler (e.g -cc "clang++" will fail but -cc "clang" works).

$ cat > hello_world.ml
let () = print_string "Hello world!\n"
^D
$ ocamlc.opt -o hello-world ./hello_world.ml -custom -cc "clang++"
clang-16: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
ld: Undefined symbols:
  _caml_builtin_cprim, referenced from:
      _caml_build_primitive_table in libcamlrun.a[14](dynlink.b.o)
      _caml_build_primitive_table_builtin in libcamlrun.a[14](dynlink.b.o)
  _caml_names_of_builtin_cprim, referenced from:
      _caml_build_primitive_table in libcamlrun.a[14](dynlink.b.o)
      _caml_main in libcamlrun.a[56](startup_byt.b.o)
clang-16: error: linker command failed with exit code 1 (use -v to see invocation)
File "./hello_world.ml", line 1:
Error: Error while building custom runtime system

This regression was introduce in this commit and the reason is as follows: -custom bytecode executables link with compiler generated C like

#if defined __cplusplus
extern "C" {
#endif
typedef long value;

typedef value (*caml_primitive)();

...
extern value caml_abs_float(void);
...

const caml_primitive caml_builtin_cprim[] = {caml_abs_float, ...};
const char* const caml_names_of_builtin_cprim = {"caml_abs_float", ...};

...

#if defined __cplusplus
}
#endif

Since caml_builtin_cprim and caml_names_of_builtin_cprim are const qualified, when compiled with a C++ compiler (>= C++11), they are given internal linkage 1 (unlike C).

The fix is to arrange for the generated code to mark caml_builtin_cprim and caml_names_of_builtin_cprim as extern:

extern const caml_primitive caml_builtin_cprim[] = {caml_abs_float, ...};
extern const char* const caml_names_of_builtin_cprim = {"caml_abs_float", ...};

Footnotes

  1. C++11: C.1.2 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf

@xavierleroy
Copy link
Contributor

Hello Shayne, nice to hear from you, and thanks for the report. The older I get, the less C and C++ make sense to me, but each in its own different way...

Do you really need to use a C++ compiler with ocamlc -custom ? Couldn't you just omit the -cc option, or give it a C compiler?

@shayne-fletcher
Copy link
Contributor Author

hello xavier!

the context here is the buck2 hack, flow & pyre builds (among others) at meta.

Do you really need to use a C++ compiler with ocamlc -custom

it's a very complicated multi-language setup that we work with. swapping out cc is non-trivial to say the least. i've tried a lot of things to work-around with some success but no one fix that will work for all targets.

Couldn't you just omit the -cc option

this could be a possibility but would require some effort in flow to adapt to i think.

all things considered if we can get something like #12791 through that would be the ideal. an alternative is to revert 99a05d2

xavierleroy pushed a commit that referenced this issue Dec 3, 2023
Fixes: #12790

Co-authored-by: Shayne Fletcher <shaynefletcher@meta.com>
Octachron pushed a commit that referenced this issue Dec 5, 2023
Fixes: #12790

Co-authored-by: Shayne Fletcher <shaynefletcher@meta.com>
(cherry picked from commit 16969c2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants