I just tried building D on Solaris 11/SPARC and x86 and ran into a
couple of issues. The following patch is at least enough to have the
build finish on Solaris 11/x86, but on SPARC d21 runs into several BUS
errors (probably due to alignment issues).
One comment up front: I believe it would be good if libphobos had a
configure.tgt like several other target libraries so users won't run
into D related build failures with --enable-languages=all for targets
known not to work.
Here are the issues I ran into:
* On sparc, the build first aborted with
In file included from ./tm_d.h:7,
from /vol/gcc/src/hg/trunk/local/gcc/config/default-d.c:21:
/vol/gcc/src/hg/trunk/local/gcc/config/sparc/sparc-protos.h:45:47: error: use
of enum 'memmodel' without previous declaration
45 | extern void sparc_emit_membar_for_model (enum memmodel, int, int);
| ^~~~~~~~
Unlike glibc-d.c, default-d.c fails to include memmodel.h. The patch
below fixes that.
* However, default-d.c isn't very useful for Solaris. Instead, I've
added sol2-d.c which implements a proper TARGET_D_OS_VERSIONS.
* Next, the sparc build ran into
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/stdc/fenv.d:700:9:
error: static assert "Unimplemented architecture"
700 | static assert(0, "Unimplemented architecture");
| ^
and indeed the file lacked SPARC definitions. However, even the x86
ones are really Linux/x86, so I added apropriate definitions for
Solaris/x86, too.
* Next, I ran into
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/rt/sections.d:70:5: error:
static assert (is(typeof(&pinLoadedLibraries) == void* function() nothrow
@nogc)) is false
70 | static assert(is(typeof(&pinLoadedLibraries) == void* function()
nothrow @nogc));
| ^
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/rt/sections.d:70:5: error:
static assert (is(typeof(&pinLoadedLibraries) == void* function() nothrow
@nogc)) is false
70 | static assert(is(typeof(&pinLoadedLibraries) == void* function()
nothrow @nogc));
| ^
To get me further along, I added dummy definitions to
sections_solaris.d. However, I wonder if it wouldn't be better to
adapt sections_elf_shared.d to Solaris instead?
* Next error on sparc:
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/sys/posix/ucontext.d:951:26:
error: undefined identifier '_NGREG'
951 | alias greg_t[_NGREG] gregset_t;
| ^
d21: internal compiler error: Bus Error
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/sys/posix/ucontext.d:1017:21:
error: undefined identifier 'fpregset_t', did you mean alias 'gregset_t'?
1017 | fpregset_t fpregs;
| ^
ucontext.d lacked several SPARC and SPARC64 definitions here. While
adding D version of system types manually in a few cases is workable
if tedious, I wonder if there isn't an easier way to do this. Imagine
a new port when there are many more definitions to add...
* Next error:
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/thread.d:989:21: error:
cannot modify immutable expression m_isRTClass
989 | m_isRTClass = true;
| ^
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/thread.d:997:21: error:
cannot modify immutable expression m_isRTClass
997 | m_isRTClass = false;
| ^
It seems weird to assign to an immutable variable, so I removed that
attribute.
* Next:
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/rt/sections_solaris.d:63:5:
error: @nogc function 'rt.sections_solaris.initSections' cannot call non-@nogc
function 'rt.sections_solaris.SectionGroup.moduleGroup'
63 | _sections.moduleGroup = ModuleGroup(mbeg[0 .. mend - mbeg]);
| ^
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/rt/sections_solaris.d:63:5:
error: function 'rt.sections_solaris.SectionGroup.moduleGroup' is not nothrow
63 | _sections.moduleGroup = ModuleGroup(mbeg[0 .. mend - mbeg]);
| ^
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/rt/sections_solaris.d:59:6:
error: nothrow function 'rt.sections_solaris.initSections' may throw
59 | void initSections() nothrow @nogc
| ^
Adding nothrow @nogc to moduleGroup definition fixed that.
* Next:
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/sys/posix/aio.d:127:5:
error: static assert "Unsupported platform"
127 | static assert(false, "Unsupported platform");
| ^
The file needed a definition of the Solaris versions. The one I added
is enough to get the build to continue, but may well need an
additional largefile version...
* Next and final build error:
/vol/gcc/src/hg/trunk/local/libphobos/src/std/datetime/systime.d:229:25:
error:undefined identifier ‘clock_gettime’
229 | if (clock_gettime(clockArg, &ts) != 0)
| ^
/vol/gcc/src/hg/trunk/local/libphobos/src/std/datetime/systime.d:66:24: error:
template instance std.datetime.systime.Clock.currStdTime!cast(ClockType)0 error
instantiating
66 | return SysTime(currStdTime!clockType, tz);
| ^
/vol/gcc/src/hg/trunk/local/libphobos/src/std/datetime/timezone.d:795:63:
note:instantiated from here: currTime!cast(ClockType)0
795 | auto currYear = (cast(Date) Clock.currTime()).year;
|
The file needs to import clock_gettime on Solaris.
* Initially, I did the Solaris/x86 build with /bin/as. However, that
ran into
Input string too long, limit 10240
make[2]: *** [std/datetime/timezone.lo] Error 1
I haven't yet checked which string exceeds that hard limit, but
continued with gas instead.
* With the patches described above, the x86 build using gas finished,
but every single link test FAILs with
FAIL: gdc.dg/gdc283.d -O0 (test for excess errors)
Excess errors:
Undefined first referenced
symbol in file
_tlsstart
/var/gcc/regression/trunk/11.5-gcc-gas/build/i386-pc-solaris2.11/./libphobos/libdruntime/.libs/libgdruntime.a(sections_solaris.o)
_tlsend
/var/gcc/regression/trunk/11.5-gcc-gas/build/i386-pc-solaris2.11/./libphobos/libdruntime/.libs/libgdruntime.a(sections_solaris.o)
__start_deh
/var/gcc/regression/trunk/11.5-gcc-gas/build/i386-pc-solaris2.11/./libphobos/libdruntime/.libs/libgdruntime.a(sections_solaris.o)
__stop_deh
/var/gcc/regression/trunk/11.5-gcc-gas/build/i386-pc-solaris2.11/./libphobos/libdruntime/.libs/libgdruntime.a(sections_solaris.o)
_d_dso_registry /var/tmp//ccVc7Kgd.o
I've yet no idea what I'm supposed to do about those. As I mentioned,
it may be better to try and get sections_elf_shared.d to support
Solaris instead? It seems some of the Solaris support has
bitrotted...
* On sparc, I didn't get that far, unfortunately: as I mentioned, many
compilations die with SIGBUS:
libtool: compile: /var/gcc/regression/trunk/11.5-gcc/build/./gcc/gdc
-B/var/gcc/regression/trunk/11.5-gcc/build/./gcc/
-B/vol/gcc/sparc-sun-solaris2.11/bin/ -B/vol/gcc/sparc-sun-solaris2.11/lib/
-isystem /vol/gcc/sparc-sun-solaris2.11/include -isystem
/vol/gcc/sparc-sun-solaris2.11/sys-include -fno-checking -fPIC -O2 -g -nostdinc
-I /vol/gcc/src/hg/trunk/local/libphobos/libdruntime -I . -c
/vol/gcc/src/hg/trunk/local/libphobos/libdruntime/core/thread.d
-fversion=Shared -o core/.libs/thread.o
d21: internal compiler error: Bus Error
0xbb5507 crash_signal
/vol/gcc/src/hg/trunk/local/gcc/toplev.c:325
0x518700 IntegerExp::toInteger()
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.c:2943
0x4d05c3 interpret
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
0x4d1543 interpret
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6017
0x4d1543 interpret(Statement*, InterState*)
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6024
0x4d263b interpretFunction
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:906
0x4d263b interpretFunction
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:726
0x4d05c3 interpret
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
0x4d14df interpret(Expression*, InterState*, CtfeGoal)
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994
0x4d05c3 interpret
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
0x4d14df interpret(Expression*, InterState*, CtfeGoal)
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994
0x5243d7 DeclarationExp::accept(Visitor*)
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/expression.h:661
0x4d05c3 interpret
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
0x4d1543 interpret
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6017
0x4d1543 interpret(Statement*, InterState*)
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:6024
0x4d263b interpretFunction
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:906
0x4d263b interpretFunction
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:726
0x4d05c3 interpret
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
0x4d14df interpret(Expression*, InterState*, CtfeGoal)
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5994
0x4d05c3 interpret
/vol/gcc/src/hg/trunk/local/gcc/d/dmd/dinterpret.c:5984
Will need to dig further here.
Anyway, please find attached the patch that got me to this point.
Honestly, I've no idea how the ChangeLog is supposed to be formatted for
D yet.
Rainer
--
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
2018-10-29 Rainer Orth <[email protected]>
gcc:
* config/default-d.c: Include memmodel.h.
* config/sol2-d.c: New file.
* config/t-sol2 (sol2-d.o): New rule.
* config.gcc <*-*-solaris2*>: Set d_target_objs,
target_has_targetdm.
libphobos:
* libdruntime/core/stdc/fenv.d [SPARC, SPARC64]: Set SPARC_Any.
[X86, X86_64]: Set X86_Any.
[Solaris]: Provide FE_* constants.
* libdruntime/core/sys/posix/aio.d [Solaris] (struct aio_result,
struct aiocb): New types.
* libdruntime/core/sys/posix/ucontext.d [SPARC64, SPARC] (_NGREG,
greg_t): Define.
[SPARC64, SPARC] (struct _fpq, struct fq, struct fpregset_t): New
types.
* libdruntime/core/thread.d (Class Thread) [Solaris]
(m_isRTClass): Don't declare immutable.
* libdruntime/rt/sections_solaris.d (SectionGroup.moduleGroup):
Declare nothrow @nogc.
(pinLoadedLibraries, unpinLoadedLibraries, inheritLoadedLibraries)
(cleanupLoadedLibraries): New functions.
* src/std/datetime/systime.d (class Clock) [Solaris]
(clock_gettime): Import.
# HG changeset patch
# Parent 21c0e7e50f9c14ddadbc6c3102da8956fb19e01f
Fix D compilation on Solaris
diff --git a/gcc/config.gcc b/gcc/config.gcc
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -918,6 +918,7 @@ case ${target} in
target_gtfiles="$target_gtfiles \$(srcdir)/config/sol2.c"
c_target_objs="${c_target_objs} sol2-c.o"
cxx_target_objs="${cxx_target_objs} sol2-c.o sol2-cxx.o"
+ d_target_objs="${d_target_objs} sol2-d.o"
extra_objs="${extra_objs} sol2.o sol2-stubs.o"
extra_options="${extra_options} sol2.opt"
case ${enable_threads}:${have_pthread_h}:${have_thread_h} in
@@ -925,6 +926,7 @@ case ${target} in
thread_file=posix
;;
esac
+ target_has_targetdm=yes
;;
*-*-*vms*)
extra_options="${extra_options} vms/vms.opt"
diff --git a/gcc/config/default-d.c b/gcc/config/default-d.c
--- a/gcc/config/default-d.c
+++ b/gcc/config/default-d.c
@@ -18,6 +18,7 @@ along with GCC; see the file COPYING3.
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "memmodel.h"
#include "tm_d.h"
#include "d/d-target.h"
#include "d/d-target-def.h"
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
new file mode 100644
--- /dev/null
+++ b/gcc/config/sol2-d.c
@@ -0,0 +1,39 @@
+/* Solaris support needed only by D front-end.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "memmodel.h"
+#include "tm_p.h"
+#include "d/d-target.h"
+#include "d/d-target-def.h"
+
+/* Implement TARGET_D_OS_VERSIONS for Solaris targets. */
+
+static void
+solaris_d_os_builtins (void)
+{
+ d_add_builtin_version ("Posix");
+ d_add_builtin_version ("Solaris"); \
+}
+
+#undef TARGET_D_OS_VERSIONS
+#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+
+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/t-sol2 b/gcc/config/t-sol2
--- a/gcc/config/t-sol2
+++ b/gcc/config/t-sol2
@@ -16,7 +16,7 @@
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
-# Solaris-specific format checking and pragmas
+# Solaris-specific format checking and pragmas.
sol2-c.o: $(srcdir)/config/sol2-c.c
$(COMPILE) $<
$(POSTCOMPILE)
@@ -26,6 +26,11 @@ sol2-cxx.o: $(srcdir)/config/sol2-cxx.c
$(COMPILE) $<
$(POSTCOMPILE)
+# Solaris-specific D support.
+sol2-d.o: $(srcdir)/config/sol2-d.c
+ $(COMPILE) $<
+ $(POSTCOMPILE)
+
# Corresponding stub routines.
sol2-stubs.o: $(srcdir)/config/sol2-stubs.c
$(COMPILE) $<
diff --git a/libphobos/libdruntime/core/stdc/fenv.d b/libphobos/libdruntime/core/stdc/fenv.d
--- a/libphobos/libdruntime/core/stdc/fenv.d
+++ b/libphobos/libdruntime/core/stdc/fenv.d
@@ -33,6 +33,16 @@ version (PPC)
else version (PPC64)
version = PPC_Any;
+version (SPARC)
+ version = SPARC_Any;
+version (SPARC64)
+ version = SPARC_Any;
+
+version (X86)
+ version = X86_Any;
+version (X86_64)
+ version = X86_Any;
+
version (MinGW)
version = GNUFP;
version (CRuntime_Glibc)
@@ -451,6 +461,50 @@ version (CRuntime_Microsoft)
FE_TOWARDZERO = 0x300, ///
}
}
+else version (Solaris)
+{
+ version (SPARC_Any)
+ {
+ enum
+ {
+ FE_TONEAREST = 0,
+ FE_TOWARDZERO = 1,
+ FE_UPWARD = 2,
+ FE_DOWNWARD = 3,
+ }
+
+ enum
+ {
+ FE_INEXACT = 0x01,
+ FE_DIVBYZERO = 0x02,
+ FE_UNDERFLOW = 0x04,
+ FE_OVERFLOW = 0x08,
+ FE_INVALID = 0x10,
+ FE_ALL_EXCEPT = 0x1f,
+ }
+
+ }
+ else version (X86_Any)
+ {
+ enum
+ {
+ FE_TONEAREST = 0,
+ FE_DOWNWARD = 1,
+ FE_UPWARD = 2,
+ FE_TOWARDZERO = 3,
+ }
+
+ enum
+ {
+ FE_INVALID = 0x01,
+ FE_DIVBYZERO = 0x04,
+ FE_OVERFLOW = 0x08,
+ FE_UNDERFLOW = 0x10,
+ FE_INEXACT = 0x20,
+ FE_ALL_EXCEPT = 0x3d,
+ }
+ }
+}
else
{
version (X86)
diff --git a/libphobos/libdruntime/core/sys/posix/aio.d b/libphobos/libdruntime/core/sys/posix/aio.d
--- a/libphobos/libdruntime/core/sys/posix/aio.d
+++ b/libphobos/libdruntime/core/sys/posix/aio.d
@@ -123,6 +123,32 @@ else version (DragonFlyBSD)
version = BSD_Posix;
}
+else version (Solaris)
+{
+ struct aio_result_t
+ {
+ ssize_t aio_return;
+ int aio_errno;
+ };
+
+ struct aiocb
+ {
+ int aio_fildes;
+ void* aio_buf; // volatile
+ size_t aio_nbytes;
+ off_t aio_offset;
+ int aio_reqprio;
+ sigevent aio_sigevent;
+ int aio_lio_opcode;
+ aio_result_t aio_result;
+ byte aio_state;
+ byte aio_returned;
+ byte[2] aio__pad1;
+ int aio_flags;
+ }
+
+ version = BSD_Posix;
+}
else
static assert(false, "Unsupported platform");
diff --git a/libphobos/libdruntime/core/sys/posix/ucontext.d b/libphobos/libdruntime/core/sys/posix/ucontext.d
--- a/libphobos/libdruntime/core/sys/posix/ucontext.d
+++ b/libphobos/libdruntime/core/sys/posix/ucontext.d
@@ -937,7 +937,17 @@ else version (Solaris)
{
alias uint[4] upad128_t;
- version (X86_64)
+ version (SPARC64)
+ {
+ enum _NGREG = 21;
+ alias long greg_t;
+ }
+ else version (SPARC)
+ {
+ enum _NGREG = 19;
+ alias int greg_t;
+ }
+ else version (X86_64)
{
enum _NGREG = 28;
alias long greg_t;
@@ -950,7 +960,70 @@ else version (Solaris)
alias greg_t[_NGREG] gregset_t;
- version (X86_64)
+ version (SPARC64)
+ {
+ struct _fpq
+ {
+ uint *fpq_addr;
+ uint fpq_instr;
+ }
+
+ struct fq
+ {
+ union FQu
+ {
+ double whole;
+ _fpq fpq;
+ };
+ }
+
+ struct fpregset_t
+ {
+ union fpu_fr
+ {
+ uint32_t[32] fpu_regs;
+ double[32] fpu_dregs;
+ /* long double[16] fpu_qregs; */
+ };
+ fq *fpu_q;
+ ulong fpu_fsr;
+ ubyte fpu_qcnt;
+ ubyte fpu_q_entrysize;
+ ubyte fpu_en;
+ }
+ }
+ else version (SPARC)
+ {
+ struct _fpq
+ {
+ uint *fpq_addr;
+ uint fpq_instr;
+ }
+
+ struct fq
+ {
+ union FQu
+ {
+ double whole;
+ _fpq fpq;
+ };
+ }
+
+ struct fpregset_t
+ {
+ union
+ {
+ uint[32] fpu_regs;
+ double[16] fpu_dregs;
+ };
+ fq *fpu_q;
+ uint fpu_fsr;
+ ubyte fpu_qcnt;
+ ubyte fpu_q_entrysize;
+ ubyte fpu_en;
+ }
+ }
+ else version (X86_64)
{
union _u_st
{
diff --git a/libphobos/libdruntime/core/thread.d b/libphobos/libdruntime/core/thread.d
--- a/libphobos/libdruntime/core/thread.d
+++ b/libphobos/libdruntime/core/thread.d
@@ -1547,7 +1547,7 @@ private:
version (Solaris)
{
- __gshared immutable bool m_isRTClass;
+ __gshared bool m_isRTClass;
}
private:
diff --git a/libphobos/libdruntime/rt/sections_solaris.d b/libphobos/libdruntime/rt/sections_solaris.d
--- a/libphobos/libdruntime/rt/sections_solaris.d
+++ b/libphobos/libdruntime/rt/sections_solaris.d
@@ -34,7 +34,7 @@ struct SectionGroup
return _moduleGroup.modules;
}
- @property ref inout(ModuleGroup) moduleGroup() inout
+ @property ref inout(ModuleGroup) moduleGroup() inout nothrow @nogc
{
return _moduleGroup;
}
@@ -87,6 +87,24 @@ void scanTLSRanges(void[] rng, scope voi
dg(rng.ptr, rng.ptr + rng.length);
}
+// interface for core.thread to inherit loaded libraries
+void* pinLoadedLibraries() nothrow @nogc
+{
+ return null;
+}
+
+void unpinLoadedLibraries(void* p) nothrow @nogc
+{
+}
+
+void inheritLoadedLibraries(void* p) nothrow @nogc
+{
+}
+
+void cleanupLoadedLibraries() nothrow @nogc
+{
+}
+
private:
__gshared SectionGroup _sections;
diff --git a/libphobos/src/std/datetime/systime.d b/libphobos/src/std/datetime/systime.d
--- a/libphobos/src/std/datetime/systime.d
+++ b/libphobos/src/std/datetime/systime.d
@@ -221,6 +221,7 @@ public:
else
{
import core.sys.solaris.time : CLOCK_REALTIME;
+ import core.sys.posix.time : clock_gettime;
static if (clockType == ClockType.coarse) alias clockArg = CLOCK_REALTIME;
else static if (clockType == ClockType.normal) alias clockArg = CLOCK_REALTIME;
else static if (clockType == ClockType.precise) alias clockArg = CLOCK_REALTIME;