cosmopolitan
cosmopolitan copied to clipboard
C++ STL Integration
First of all, great work hacking your way to platform independence!
Been just wondering if anyone made any attempts to use it in conjunction with the c++ standard library and if so, what does work and what doesn't ? - I'd expect that the standard library depends on some platform specific code, however it would be great if I could get started somewhere so I can start refactoring those bits.
I would love to package cosmopolitan for https://github.com/loopperfect/buckaroo or even built a beginner friendly SDK around this library.
My naive attempt to use cosmopolitan.h in a c++ project failed with a couple errors:
clang++ -std=c++20 \
-I/usr/include/c++/10 \
-I/usr/include/x86_64-linux-gnu/c++/10/ \
-I/usr/include/x86_64-linux-gnu/ \
-I/usr/include \
-Io\
-g -O -static -fno-pie -mno-red-zone -nostdlib -nostdinc -U__cplusplus -o hello.com main.cpp \
-Wl,--oformat=binary -Wl,--gc-sections -Wl,-z,max-page-size=0x1000 -fuse-ld=bfd \
-Wl,-T,o/ape.lds -include o/cosmopolitan.h o/libc/crt/crt.o o/ape/ape.o o/cosmopolitan.a
// hello.cpp
#include<cosmopolitan.h>
#include<vector>
int main() {
return 0;
}
errors:
In file included from <built-in>:1:
./o/cosmopolitan.h:284:24: error: cannot combine with previous 'int' declaration specifier
typedef __WCHAR_TYPE__ wchar_t;
^
./o/cosmopolitan.h:284:1: warning: typedef requires a name [-Wmissing-declarations]
typedef __WCHAR_TYPE__ wchar_t;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./o/cosmopolitan.h:285:9: error: 'char16_t' cannot be signed or unsigned
typedef __CHAR16_TYPE__ char16_t;
^
<built-in>:157:25: note: expanded from here
#define __CHAR16_TYPE__ unsigned short
^
In file included from <built-in>:1:
./o/cosmopolitan.h:285:9: error: 'short char16_t' is invalid
<built-in>:157:34: note: expanded from here
#define __CHAR16_TYPE__ unsigned short
^
In file included from <built-in>:1:
./o/cosmopolitan.h:285:1: warning: typedef requires a name [-Wmissing-declarations]
typedef __CHAR16_TYPE__ char16_t;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./o/cosmopolitan.h:286:25: error: cannot combine with previous 'int' declaration specifier
typedef __CHAR32_TYPE__ char32_t;
^
./o/cosmopolitan.h:286:1: warning: typedef requires a name [-Wmissing-declarations]
typedef __CHAR32_TYPE__ char32_t;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./o/cosmopolitan.h:7712:35: error: unknown type name 'int128_t'
int sleb128(const void *, size_t, int128_t);
^
./o/cosmopolitan.h:7713:37: error: unknown type name 'int128_t'
int unsleb128(const void *, size_t, int128_t *);
^
./o/cosmopolitan.h:21493:16: error: unknown type name 'jmp_buf'
void gclongjmp(jmp_buf, int) nothrow wontreturn paramsnonnull();
^
./o/cosmopolitan.h:21525:3: error: unknown type name 'jmp_buf'
jmp_buf jb;
^
In file included from main.cpp:2:
In file included from /usr/include/c++/10/vector:60:
In file included from /usr/include/c++/10/bits/stl_algobase.h:60:
/usr/include/c++/10/bits/functexcept.h:44:1: error: unknown type name '_GLIBCXX_BEGIN_NAMESPACE_VERSION'
_GLIBCXX_BEGIN_NAMESPACE_VERSION
^
/usr/include/c++/10/bits/functexcept.h:112:1: error: unknown type name '_GLIBCXX_END_NAMESPACE_VERSION'
_GLIBCXX_END_NAMESPACE_VERSION
^
/usr/include/c++/10/bits/functexcept.h:113:1: error: expected unqualified-id
} // namespace
^
In file included from main.cpp:2:
In file included from /usr/include/c++/10/vector:60:
In file included from /usr/include/c++/10/bits/stl_algobase.h:61:
/usr/include/c++/10/bits/cpp_type_traits.h:71:1: error: unknown type name '_GLIBCXX_BEGIN_NAMESPACE_VERSION'
_GLIBCXX_BEGIN_NAMESPACE_VERSION
^
/usr/include/c++/10/bits/cpp_type_traits.h:214:12: error: redefinition of '__is_integer<int>'
struct __is_integer<int>
^~~~~~~~~~~~~~~~~
/usr/include/c++/10/bits/cpp_type_traits.h:138:12: note: previous definition is here
struct __is_integer<bool>
^
/usr/include/c++/10/bits/cpp_type_traits.h:542:5: error: unknown type name '_GLIBCXX20_CONSTEXPR'
_GLIBCXX20_CONSTEXPR
^
/usr/include/c++/10/bits/cpp_type_traits.h:543:21: error: expected ';' at end of declaration
inline _Iterator
^
/usr/include/c++/10/bits/cpp_type_traits.h:544:18: error: unknown type name '_Iterator'
__miter_base(_Iterator __it)
^
/usr/include/c++/10/bits/cpp_type_traits.h:544:5: error: C++ requires a type specifier for all declarations
__miter_base(_Iterator __it)
^
/usr/include/c++/10/bits/cpp_type_traits.h:547:1: error: unknown type name '_GLIBCXX_END_NAMESPACE_VERSION'
_GLIBCXX_END_NAMESPACE_VERSION
^
/usr/include/c++/10/bits/cpp_type_traits.h:548:1: error: expected unqualified-id
} // namespace
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
4 warnings and 20 errors generated.
``
Cosmopolitan works great with C++ but very little effort has been made to integrate it with an existing STL.
Examples of C++ programs in this codebase are here:
- https://github.com/jart/cosmopolitan/blob/master/examples/nesemu1.cc
- https://github.com/jart/cosmopolitan/blob/master/examples/cplusplus.cc
The existing barebones C++ integration code is here:
- https://github.com/jart/cosmopolitan/blob/master/libc/ohmyplus/vector.h
- https://github.com/jart/cosmopolitan/blob/master/libc/ohmyplus/vector.c
- https://github.com/jart/cosmopolitan/blob/master/libc/mem/cxx/malloc.S
- https://github.com/jart/cosmopolitan/blob/master/libc/mem/cxx/free.S
- https://github.com/jart/cosmopolitan/blob/master/libc/mem/cxx/memalign.S
It'd be great to have libc++ integration since the llvm project currently doesn't put out a c library and I'm not even sure how it's possible to use libc++ outside a corporation like google or apple. There's also libstdcxx from the gnu project but it's licensed in such a way that makes it a dealbreaker for many people, plus it bloats hello world binaries by a few megs.
The path of least resistance for me so far has simply been rewriting the parts of STL I've needed, which so far has only been std::vector. But like I said, it'd be much better if we could somehow convince the LLVM project to adopt this cosmopolitan as their preferred C library.
It's also worth mentioning that compiler_rt is integrated already! See third_party/compiler_rt/
I've had a bit of a look into what this would involve. I'm not sure that I'm going to have the time to attempt this. I thought I'd post some findings so far;
- LLVM now maintains an implementation of libc, which seems to be compatible with libcxx. A section in the docs mentions the possibility of layering over another libc, this could be a really nice approach where it might be possible to use llvm-libc as a bit of a shim layer over cosmopolitan in a way that is compatible with libcxx. The source code can be found here.
- There is a port for libcxx targetted at microcontrollers that provides all the necessary backend functions to make libcxx work. This implementation is based on a custom libc implementation targeted at microcontrollers. It might be doable to replicate the same approach used there.
Also I'm genuinely impressed with this project! It all seems like magic to me :).
Thanks for the report! Glad you like the project.
I'd be very excited about such a contribution. If you have time to do this, then here's some recommendations:
-
We use a 2+ commit style so provenance is clear. The first commit should be line-for-line identical with whatevence tarball you imported the sources from (as noted in README.cosmo). Then the second commit, you get it to build. For example https://github.com/jart/cosmopolitan/commit/0c4c56ff3970fe6bb0efcc73f1bbe6b3bc3cb9eb and https://github.com/jart/cosmopolitan/commit/5ef64dbcdb8a2ade2684a6be6fc8969be752ffbc
-
Once it's in the codebase, you can change and refactor as much code as you want. I am willing to pay the cost of manually integrating upstream updates, if it means we have the freedom to readily change whatever we need to change here.
-
Be sure to copy over libcxx's .clang-format file since we use it too. That'll reduce diff noise.
Marking as complete as of the 2.0 release. https://github.com/jart/cosmopolitan/releases/tag/2.0