GDC does not build on FreeBSD 14

Iain Buclaw ibuclaw at gdcproject.org
Thu Aug 14 00:13:06 UTC 2025


On Wednesday, 13 August 2025 at 14:58:16 UTC, Brian Callahan 
wrote:
> Hi all --
>
> In writing my new script to make it easy to bootstrap GDC on 
> any platform (https://github.com/ibara/gcc-bootstrap), I 
> discovered that GDC does not build on FreeBSD 14. It's a bit 
> too long to explain in a post, so here's the link to my blog 
> post on the topic: https://briancallahan.net/blog/20250813.html
>
> I don't think there's anything the D team can do about this 
> one; the FreeBSD people will need to implement a proper 
> solution. But it was interesting nonetheless, so I'm sharing it.
>
> ~Brian

You could fix it by removing `pragma(mangle)`, as that is an 
abuse of the pragma. It's unlikely there's going to be any third 
party users of this internal module anyway.

If keeping a backwards compat version is really a must, I reckon 
you could implement it with a shim thunk/function instead.

```d
static if (__FreeBSD_version >= 1400000)
{
     alias extern (C) int function(scope const void*, scope const 
void*, scope void*) Cmp;
     extern (C) void qsort_r(scope void* base, size_t nmemb, 
size_t size, Cmp cmp, scope void* thunk);

     // 
https://cgit.freebsd.org/src/tree/include/stdlib.h?h=stable/14#n350
     alias extern (C) int function(scope void*, scope const void*, 
scope const void*) OldCmp;

     deprecated("In FreeBSD 14, qsort_r's signature was fixed to 
match POSIX. This extern(D) overload has been " ~
                "provided to avoid breaking code, but code should 
be updated to use the POSIX version.")
     extern (D) void qsort_r(scope void* base, size_t nmemb, 
size_t size, scope void* thunk, OldCmp oldcmp)
     {
         static struct Wrap
         {
             void* thunk;
             OldCmp oldcmp;
         }
         auto wrap = Wrap(thunk, oldcmp);

         extern (C) int cmp(scope const void* p1, scope const 
void* p2, scope void* pwrap)
         {
             auto wrap = cast(Wrap*)pwrap;
             return wrap.oldcmp(wrap.thunk, p1, p2);
         }
         qsort_r(base, nmemb, size, &cmp, &wrap);
     }

     extern (C) void[] _adSort(return scope void[] a, TypeInfo ti)
     {
         extern (C) int cmp(scope const void* p1, scope const 
void* p2, scope void* ti)
         {
             return (cast(TypeInfo)ti).compare(p1, p2);
         }
         qsort_r(a.ptr, a.length, ti.tsize, &cmp, cast(void*)ti);
         return a;
     }
}
```


More information about the D.gnu mailing list