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

GCC/LLVM support #4

Open
Rantanen opened this issue Dec 5, 2017 · 8 comments
Open

GCC/LLVM support #4

Rantanen opened this issue Dec 5, 2017 · 8 comments

Comments

@Rantanen
Copy link
Owner

Rantanen commented Dec 5, 2017

In theory the COM libraries created using intercom should be cross-platform compatible. There's no major Windows dependencies involved here.

The big issue is the lack of midl for GCC/LLVM. As such the intercom-utils would need a new cpp-classes or similar command that processes the Rust sources similar to what idl does, but instead of producing an idl file, the command produces C++ sources similar to the various _i.c and _i.h sources that midl produces.

These sources need to implement C++ classes that result in compatible vtable definitions with the COM vtables. Ideally they should use the same "stdcall" calling convention that we already use in the intercom functions for Windows COM. However we do have the option of using "stdcall" on Windows and something else that behaves better on Linux as long as that "something else" is binary compatible between GCC/LLVM/Rustc.


Tasks:

  • Implement the C++ header generation in intercom-utils.
  • Enable the cpp unit tests for Linux builds on Travis. This involves wrapping the CoInitialize/CoUninitialize in some sort of IntercomInit/Uninit method that is able to call the CoInitialize/etc. on Windows and loads the type library using dlopen or similar on Linux. The CoCreateInstance needs to be abstracted so that on Linux we acquire the ClassFactory and construct the instance manually.
  • Enable unit testing on Travis with both GCC and LLVM.
@Rantanen
Copy link
Owner Author

Rantanen commented Dec 5, 2017

The only real Windows dependency is SysAllocString call in intercom/src/bstr.rs. This probably needs to be disabled for linux build to work. We can go without support for Strings to start with until #6 gets implemented.

@Fluxie
Copy link
Contributor

Fluxie commented Dec 16, 2017

I will start working on the CoCreateInstancee implementation. Whatever that will eventually mean:) Somehow we need to ensure that the same C++ code base can be compiled on different platforms.

A minor subset of the tests now compile on gcc: https://github.com/Fluxie/intercom/tree/gcc-proto.

@Rantanen
Copy link
Owner Author

"Whatever that will eventually mean" is probably going to be...

  • Dynamically load the shared library with dlopen or equivalent.
  • Look up the "DllGetClassObject" symbol,
    which is expanded by the com_library attribute.
  • Invoke the DllGetClassObject giving the correct CLSID and use the IID_ClassFactory as the riid.

After this everything is "COM": The provided pointer should implement IClassFactory interface inheriting from IUnknown.

The big question is how should we get the shared library in the first place. CoCreateInstance takes only the CLSID as a parameter to identify the final library and uses registry (or equivalent) mechanism to look up the actual library binary.

I see three options:

  1. Implement some kind of a registration mechanism for non-Windows platforms.
  2. Implement our own CreateInstance signature, which takes the library path as a parameter.
  3. Implement a C++ class with the CreateInstance as a method. The C++ class would have two constructors: One usable in Windows, which constructs it in such a way that it ends up delegating to CoCreateInstance and one that takes the library path and falls back on dlopen.

@Fluxie
Copy link
Contributor

Fluxie commented Dec 17, 2017

I started playing around with dlopen yesterday. Didn't get too far though as I had to do some shopping.

  1. Implement some kind of a registration mechanism for non-Windows platforms.

I would like to avoid any approach that requires registration, at least initially. I'm currently thinking that the wrapper C++ classes that I will eventually implement would just know which library to use when constructing the Rust object and create an instance of the object when the C++ wrapper is constructed. On Windows the constructor could just call CoCreateInstance.

Side-note: We should probably generate a manifest for the Rust libraries automatically to help with the context-free activation. Registration even on Windows can be annoying when you deploy the application.
https://msdn.microsoft.com/en-us/library/ms973913.aspx

@Rantanen
Copy link
Owner Author

I would like to avoid any approach that requires registration, at least initially

I agree. Personally I'm not a fan of the global registration mechanism on Windows. I guess it makes sense for APIs that are meant to update with other products, such as the Office API, but for basic library usage it's just painful.

I'm currently thinking that the wrapper C++ classes that I will eventually implement would just know which library to use

I completely forgot the wrapper classes know the library they are used with. This sounds like the perfect option.

Side-note: We should probably generate a manifest for the Rust libraries automatically to help with the context-free activation.

Already part of #26. Just took a small detour of it to possibly enable the vswhere usage.

@Fluxie
Copy link
Contributor

Fluxie commented Dec 22, 2017

The branch https://github.com/Fluxie/intercom/tree/gcc-proto now has a working CMake configuration and the C++ test cases succeed. It is not fit for merge as-is, however. I will implement basic support for generating the basic C++ header files for the first pull request.

@Fluxie
Copy link
Contributor

Fluxie commented Dec 27, 2017

Basic support generating the C++ headers from Rust code is now implemented in https://github.com/Fluxie/intercom/tree/gcc-proto. I no longer need the headers generated with the MIDL compiler to run the tests.

@Rantanen Rantanen added this to the Public release milestone Feb 8, 2018
@Rantanen
Copy link
Owner Author

Rantanen commented Nov 9, 2018

@Fluxie Is this still pending something? I've been under the impression that GCC/LLVM support is done - the big things missing are mainly nicer interface for the C++ wrappers, but that's not really a GCC/LLVM issue as such but a general "Make C++ better" issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants