<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-15">
</head>
<body bgcolor="#FFFFFF" text="#000000">
This is probably less a problem for DMDs druntime, but we hit this
issue with gdc and the android port now, so I thought I'll also post
this message here, maybe someone has a good idea.<br>
<br>
Android uses a custom C library (Bionic) which is not 100% Posix
compatible. With the current approach of supporting different
systems using version() blocks, this will lead to lots of changes in
all the core/* files. And it will get much worse once we try to
support other C libraries (newlib for DS/Wii homebrew,
uclibc/dietlibc/eglibc for embedded linux, etc). The current aproach
is already broken for Android, as druntime assumes version(linux)
--> glibc which is not true. One such broken example is the usage
of the glibc "backtrace" function.<br>
<br>
Here's the original message sent to the D.gnu newsgroup:<br>
<br>
<hr size="2" width="100%">As recently discussed in a pull request it
would be great if we could<br>
make it easier to port druntime to different architectures. Special<br>
casing every C library, every architecture and every OS using
version<br>
blocks could lead to difficult to maintain code, so we need a better<br>
solution.<br>
<br>
As far as I can see, the biggest differences are caused by different
C<br>
libraries, not by different architectures (except 32bit vs 64 bit<br>
differences). For example glibc headers seem to be very similar for
arm<br>
and x86, but bionic vs. glibc brings more differences. Bionic
initially<br>
didn't support anything wchar_t related, so core.stdc.wchar_ and<br>
core.stdc.wctype couldn't work with android at all. And C libraries<br>
vary even more in the subset of posix functionality they support.<br>
<br>
We need a directory scheme to support<br>
* Different C libraries<br>
* on different OS (glibc/bsd glibc/linux)<br>
* on the same OS (glibc on linux, bionic on linux, uclibc on<br>
linux, ...)<br>
* Different architectures (ARM, X86, MIPS, PPC, SH4, ...)<br>
<br>
I propose the following directory layout, but of course<br>
better solutions are appreciated:<br>
<br>
druntime<br>
|-core<br>
|---stdc<br>
|---sync<br>
|---sys<br>
|-----posix<br>
|-gc<br>
|-gcstub<br>
|-rt<br>
|-gcc<br>
|---arch<br>
|-----glibc<br>
|-------core<br>
|---------stdc<br>
|---------sync<br>
|---------sys<br>
|-----------posix<br>
|-----bionic<br>
|-------stdc<br>
|-------sync<br>
|-------core<br>
|---------sys<br>
|-----------posix<br>
|-----newlib<br>
|-------stdc<br>
|-------sync<br>
|-------core<br>
|---------sys<br>
|-----------posix<br>
<br>
Code in the gc, gcstub and rt directories shouldn't depend on
special C<br>
libraries, small differences can be solved using version() blocks.<br>
<br>
Every C library get's it's own bindings in the gcc.arch package.
I'm<br>
not sure if those bindings should only provide functionality
included<br>
in core, or whether these bindings should include additional, C
library<br>
specific bindings.<br>
<br>
The files in core.* would reference the corresponding files in<br>
gcc.arch.core.*<br>
<br>
The downside of that approach is that we'll have some code
duplication,<br>
especially for similar C libraries. And merging changes is therefore<br>
not that easy as well. However, as the C and Posix headers don't
change<br>
often, that's probably neglectable.<br>
<br>
Here are some examples for that directory scheme:<br>
<br>
core/stdc/config.d (Should be shared with dmd druntime?)<br>
-----------------------------------------------<br>
enum LibC<br>
{<br>
GlibC,<br>
uClibc,<br>
dietlibc,<br>
newlib,<br>
dmc, //digitalmars, windows<br>
msvcrt,<br>
...,<br>
unknown<br>
}<br>
<br>
//Need some way to define this correctly<br>
enum libC = LibC.GlibC;<br>
enum string libCVersion = ""; //Free form version number<br>
-----------------------------------------------<br>
<br>
core/stdc/math.d<br>
-----------------------------------------------<br>
import core.stdc.config;<br>
<br>
static if(libC == LibC.GlibC)<br>
{<br>
public import gcc.arch.glibc.core.stdc.math;<br>
}<br>
else<br>
{<br>
static assert(false, "C library '" ~ libC ~ "' not supported in
" ~<br>
__FILE__);<br>
}<br>
<br>
//Maybe put generic parts here?<br>
-----------------------------------------------<br>
<br>
core/sys/posix/dirent.d<br>
-----------------------------------------------<br>
import core.stdc.config;<br>
<br>
static if(libC == LibC.GlibC)<br>
{<br>
/*<br>
* I admit this looks horrible. We can probably remove the core<br>
* part, maybe even gcc, so arch.glibc.sys.posix.dirent?<br>
* or glibc[.core].sys.posix.dirent?<br>
*/<br>
public import gcc.arch.glibc.core.sys.posix.dirent;<br>
}<br>
else static if(libC == LibC.GlibC)<br>
{<br>
public import gcc.arch.glibc.core.sys.posix.dirent;<br>
}<br>
else<br>
{<br>
static assert(false, "C library '" ~ libC ~ "' not supported in
" ~<br>
__FILE__);<br>
}<br>
-----------------------------------------------<br>
<br>
Maybe we could use pragma(msg) warnings instead of static asserts,
so<br>
it'd be possible to import the modules in any case and use<br>
traits(__compiles) to check for specific symbols/functions.<br>
<pre class="moz-signature" cols="72">--
Johannes Pfau</pre>
</body>
</html>