Skip to content

Conversation

@kit-ty-kate
Copy link
Member

C++ projects have been broken quite often due to the C headers not being checked with a C++ compiler.
This PR fixes all problems in the headers as well as add a test checking all headers to be sure they are compatible with C++ in the future.

As you can see in the last commit, this also fixed an issue that made C++ compiler break when using CAML_INTERNALS. This case can be seen in the wild here: ocaml/opam-repository#22140 (comment)

Side note: I've been trying to make this branch work a year and a half ago and never could make it succeed for some reason, but somehow i tried it today again and it works fine with trunk now. I've been trying to be careful when rebasing so hopefully I haven't ported back some old behaviour to the driver somehow.

@kit-ty-kate
Copy link
Member Author

kit-ty-kate commented Sep 22, 2022

I would also suggest to backport it to 5.0 as it is also broken there.
If it is to be backported no changelog entry should be necessary I believe. EDIT: Actually scratch that part, the driver now accept .cpp files so that should be there.

@dra27
Copy link
Member

dra27 commented Sep 22, 2022

precheck#768

@kit-ty-kate kit-ty-kate force-pushed the cpp-tests branch 2 times, most recently from 558c109 to 77a8cf8 Compare September 22, 2022 16:34
@Octachron
Copy link
Member

To resume an offline discussion, backporting the header fixes to 5.0 is fine with me.
However, I think it is better to keep the tests and the cpp file support on trunk (since 5.0 will still benefit for further fixes if the test on trunk detect a problem).

ProcessInterface name
else if Filename.check_suffix name ".c" then
ProcessCFile name
else if Filename.check_suffix name ".cpp" then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are other common extensions for C++: .cxx, .cc, etc, do we want to support them here?

Suggested change
else if Filename.check_suffix name ".cpp" then
else if Filename.check_suffix name ".cpp" then

let c_object_of_filename name =
Filename.chop_suffix (Filename.basename name) ".c" ^ Config.ext_obj
let c_object_of_filename ~ext name =
Filename.chop_suffix (Filename.basename name) ext ^ Config.ext_obj
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use Filename.remove_extension to avoid having to pass ~ext.

@xavierleroy
Copy link
Contributor

Globally: I like the idea of the test but I'm a bit nervous with adding C++ compilation support to ocamlc and ocamlopt. It's always possible to do gcc -I$(ocamlc -where) -c foo.cpp to compile a C++ file that refers to OCaml's headers.

@shindere
Copy link
Contributor

shindere commented Sep 27, 2022 via email

@xavierleroy
Copy link
Contributor

But, doing so, you loose the ability to call the C compiler with the right options. Isn't that a problem / risk?

We're not calling a C compiler in this situation, we're calling a C++ compiler that may be the same command as the C compiler. But the right options for a C compilation may not be the right option for a C++ compilation. Just passing the same options as for a C compilation is a hail Mary. Eh, even choosing between gcc and g++ (or clang and clang++) to compile C++ sources is not obvious. I don't want the OCaml core system to get into this C++ business.

@shindere
Copy link
Contributor

shindere commented Sep 27, 2022 via email

3 tests are defined:
- raw include
- include inside an extern "C"
- raw include after #define CAML_INTERNALS
Copy link
Contributor

@xavierleroy xavierleroy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for resurrecting this PR, it's a useful test to have.

@@ -0,0 +1,17 @@
#define CAML_INTERNALS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CAML_INTERNALS sections of the OCaml 5 header files contain too much C code (as inline functions) to be compilable by a C++ compiler. So, this 3rd test will never work, I'm afraid. Let's just test without CAML_INTERNALS.

(* TEST
modules = "cpp_stubs1.c cpp_stubs2.c cpp_stubs3.c";
readonly_files = "all-includes.h";
flags = "-ccopt -x -ccopt c++ -ccopt -std=c++11";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These flags work with GCC and Clang, but probably not with MSVC. Can the test be turned off for MSVC?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - leftover from #13476, we have a not-msvc action!

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 this pull request may close these issues.

6 participants