<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>