libc++ in Windows

I have been building clang on Windows and I was wanting to use that version of clang to build other things with.

When I had tried to compile against the Microsoft standard library it would not compile successfully. I noticed in the cfe-commits list that it looks like a commit is in the works that should fix most of this.

I would love to build against libc++ on Windows, since the current Microsoft standard library isn’t entirely complete (variadic templates anybody?).

When I was looking at libc++ it didn’t appear to support Windows except maybe under MinGW. What would be a good place to start to get libc++ to work on Windows?

I've been working on this on and off. Here's a braindump of what's needed:

1. Port OS-specific things.

    This is rather small and I've done most of this already.

2. C Standard Library.

    Microsoft's CRT is a royal PITA. It doesn't support a lot of things
    required or expected, and other things have subtle differences.
    Which is why I wrote a new standard library to make point 1 easier.
    At first it was only a set of standard-compliant headers and
    implementation stubs to get it to compile, but I've since
    implemented certain parts. The hardest part for this route is, for
    me at least, libm, and I don't know any modern BSD-licensed libm
    that could be used.
    The other way would be to further try and shoehorn MSVCRT and give
    up C99- and full C++11-compatibility.

3. Implement full dllimport/dllexport semantics so that libc++ can be
    used as a DLL.

    Clang only support rudimentary dllimport/dllexport for functions.
    Making it work with classes is a rather large non-trivial change.
    I've been working on this and apart from vtable-handling and
    cleanups it's mostly finished. Depending on that last point I may
    put up some patches for review soon.

    This also requires changes to how libc++ applies those attributes.
    Using them like ELF visibility doesn't work correctly for templates.

4. Weak externals for PE to enable replacing operator new/delete.

    This was impossible with how dllimport was represented in LLVM
    before. If my patches are excepted, it should be doable, but I
    haven't looked into it again.

5. Port an ABI library like libc++abi.

    I've ported some parts of libc++abi, but it's incomplete and
    untested. It also needs an unwind library, which quickly leads
    to the next point:

6. Exception handling

    This is probably the biggest hurdle. There is some low-level support
    for 64-bit SEH directives in LLVM already. 32-bit has the additional
    Borland patent issue for SEH exception handling. The data structures
    used by MSVC are also undocumented.
    Implementing this for 64-bit by using the DWARF exception tables and
    providing an appropriate personality routine is the easiest case,
    and would also allow catching SEH exceptions from the OS.
    Maybe it's also possible to implement such DWARF-based table-based
    exception handling for 32-bit, without any way to catch SEH
    exceptions.

7. Some minor bugfixes I encountered along the way, like proper COMDAT
    linkage for EH sections, proper varargs handling. I'll try to get
    those committed soon.

-Nico

When I was looking at libc++ it didn’t appear to support Windows except
maybe under MinGW. What would be a good place to start to get libc++ to
work on Windows?

I've been working on this on and off. Here's a braindump of what's needed:

1. Port OS-specific things.

   This is rather small and I've done most of this already.

2. C Standard Library.

   Microsoft's CRT is a royal PITA. It doesn't support a lot of things
   required or expected, and other things have subtle differences.
   Which is why I wrote a new standard library to make point 1 easier.
   At first it was only a set of standard-compliant headers and
   implementation stubs to get it to compile, but I've since
   implemented certain parts. The hardest part for this route is, for
   me at least, libm, and I don't know any modern BSD-licensed libm
   that could be used.
   The other way would be to further try and shoehorn MSVCRT and give
   up C99- and full C++11-compatibility.

Can you give some examples of why using MSVCRT is hard? I would expect
most subtle behavior changes could be overcome, but I'm curious what the
blockers are.

3. Implement full dllimport/dllexport semantics so that libc++ can be
   used as a DLL.

   Clang only support rudimentary dllimport/dllexport for functions.
   Making it work with classes is a rather large non-trivial change.
   I've been working on this and apart from vtable-handling and
   cleanups it's mostly finished. Depending on that last point I may
   put up some patches for review soon.

   This also requires changes to how libc++ applies those attributes.
   Using them like ELF visibility doesn't work correctly for templates.

4. Weak externals for PE to enable replacing operator new/delete.

   This was impossible with how dllimport was represented in LLVM
   before. If my patches are excepted, it should be doable, but I
   haven't looked into it again.

5. Port an ABI library like libc++abi.

   I've ported some parts of libc++abi, but it's incomplete and
   untested. It also needs an unwind library, which quickly leads
   to the next point:

Yep, hard.

I would be more than happy to lend a hand here, if you could point me at something and tell me exactly what needs doing so we could coordinate our efforts.

image001.png

I'm curious. How are you going to set this up so that you can use libc++ on Windows for standard Win32 apps without clashing with Microsoft's c++ standard library at link time? I once made an effort to use libc++ on OSX 10.6 which is based on libstdc++. I could get a program to work, but once I tried to link with system APIs to actually build a real mac application, it would clash with libstdc++.

-James

But Win32 doesn't use the standard library and it's no different than
using STLPort or other STL implementation, and people have been doing
that for ages. Provided that all third party libraries are also built
with the same standard library implementation. I'm very curious where
exactly you ran into problems?

I believe libc++ uses inline namespaces, which should effectively prevent you from having linking conflicts.

Nico Rieck <nico.rieck@gmail.com> writes:

3. Implement full dllimport/dllexport semantics so that libc++ can be
   used as a DLL.

   Clang only support rudimentary dllimport/dllexport for functions.
   Making it work with classes is a rather large non-trivial change.
   I've been working on this and apart from vtable-handling and
   cleanups it's mostly finished. Depending on that last point I may
   put up some patches for review soon.

   This also requires changes to how libc++ applies those attributes.
   Using them like ELF visibility doesn't work correctly for templates.

Seeing all the VC++ ABI related churn on the commits lists I was puzzled
about the lack of dllexport capabilities of Clang, which is a pretty
basic feature. Now your message explains it.

6. Exception handling

   This is probably the biggest hurdle. There is some low-level support
   for 64-bit SEH directives in LLVM already. 32-bit has the additional
   Borland patent issue for SEH exception handling. The data structures
   used by MSVC are also undocumented.
   Implementing this for 64-bit by using the DWARF exception tables and
   providing an appropriate personality routine is the easiest case,
   and would also allow catching SEH exceptions from the OS.
   Maybe it's also possible to implement such DWARF-based table-based
   exception handling for 32-bit, without any way to catch SEH
   exceptions.

This is big issue indeed. Currently, 32bit MinGW is severely handicapped
for some C++ performance-critical applications, not because GCC produces
worse code than VS (it doesn't, in my experience) but because the
exception models available to MinGW are inadequate: you can choose to
slowdown the application (sjlj) or make it crash (dw2). Obviously, Clang
would suffer from the the same problem and implementing SEH seems like
the only remedy. Considering that the Borland patent expires in exactly
a year from now, there is time enough for completing the job and it will
be usable on a not so distant future :slight_smile:

As for the undocumented data structures, I'm allmost certain that you
know this article, but just in case:

http://www.microsoft.com/msj/0197/exception/exception.aspx

Thanks for all your work. I'll be very happy to have an option to VS.
I'll be glad to help testing it.

Regards.

IIRC GCC has Win64 SEH unwind info generation support since 4.7.2.

In regards to the C99 issue, MS just announced that the next version of Visual Studio will implement a lot more of the missing C99 libraries so maybe there will be no need to re-implement that in the libc++ port.

João Matos <ripzonetriton@gmail.com>
writes:

Considering that the Borland patent expires in exactly
a year from now, there is time enough for completing the job and it will
be usable on a not so distant future :slight_smile:

IIRC GCC has Win64 SEH unwind info generation support since 4.7.2.

Yes, but Win64 SEH is different enough to not be covered by the Borland
patent.

Some Apple APIs have c++ code in them (webkit, webcore, javascriptcore). On 10.6, they would be linked against libstdc++ and you'd symbol clashes if you tried to use libc++ in a exe that linked against such libs. I would expect at least some MS core libraries to have c++ code in them and be linked against their std lib also.

Due to how shared libraries work on Windows, this isn't a problem (as long as you're careful with resources). And Microsoft's APIs use only C (or more specifically a subset) and COM.

-Nico

How about libs like MSHMTL and JSCRIPT?

[fixed top-posting]

James Gregurich <bayoubengal@mac.com> writes:

Due to how shared libraries work on Windows, this isn't a problem
(as long as you're careful with resources). And Microsoft's APIs use
only C (or more specifically a subset) and COM.

How about libs like MSHMTL and JSCRIPT?

MSHTML has a COM interface. And I wouldn't consider it a core library by
any stretch. Dunno about JSCRIPT but I'll bet that it is the same case.
For core (OS) functionality, it is in the best interest of MS to not
block access to other compiler vendors. Also, historically MS promoted
other languages over C++ and that means that its libraries hide its C++
implementation behind a COM/C interface.

To recap: there is no problem using C++ runtimes other than MS on
Windows. MinGW does it, Borland does it...

ok. COM and symbol hiding in DLLs may indeed mean it isn't an issue.

I'm eager to see how it works out. I'm not particularly fond of Microsoft's compiler and standard library. I'd like nothing better than to be able to replace them.

MSHTML has a COM interface. And I wouldn't consider it a core library by
any stretch. Dunno about JSCRIPT but I'll bet that it is the same case.
For core (OS) functionality, it is in the best interest of MS to not
block access to other compiler vendors. Also, historically MS promoted
other languages over C++ and that means that its libraries hide its C++
implementation behind a COM/C interface.

To recap: there is no problem using C++ runtimes other than MS on
Windows. MinGW does it, Borland does it...

Just curious, because I couldn't find much discussion of COM in the
archives...do you know if Clang currently supports enough of the
ms-cxx-abi to use and generate COM objects and interfaces in C++?

It's been awhile since I've used COM so I might be misremembering what
it is, but my understanding is that COM idl files can be used to
generate header files that can either be used in C (using explicit
tables of function pointers to implement interfaces and dynamic
dispatch) or C++ via inheritance, and MSVC's C and C++ ABIs are
designed such that both alternatives will generate code that conforms
to the same ABI using MSVC, which is stable across MSVC versions.

Also, as I understand it, having C++ objects conform to the COM ABI
primarily depends on things like virtual table layout but has no
dependence on things like name mangling, since all dispatch is
indirect through table lookups--is that correct? If so, is COM ABI
support complete or is there anyone working on that an an explicit
subgoal of full MSVC ABI support?

Stephen

1) How can I use libc++ on Windows?
2) Where should I compile the source files?
3) How can I tell clang where I have compilied it?