-
d8dd0703
by Julian Ospald at 2025-11-21T14:06:02+08:00
Use libffi-clib
Previously, we would build libffi via hadrian
and bundle it manually with the GHC bindist.
This now moves all that logic out of hadrian
and allows us to have a clean Haskell package
to build and link against and ship it without
extra logic.
This patch still retains the ability to link
against a system libffi.
The main reason of bundling libffi was that on
some platforms (e.g. FreeBSD and Mac), system libffi
is not visible to the C toolchain by default,
so users would require settings in e.g. cabal
to be able to compile anything.
This adds the submodule libffi-clib to the repository.
-
8ba3e6ee
by Matthew Pickering at 2025-11-21T14:06:18+08:00
hadrian: Use a response file to invoke GHC for dep gathering.
In some cases we construct an argument list too long for GHC to
handle directly on windows. This happens when we generate
the dependency file because the command line will contain
references to a large number of .hs files.
To avoid this we now invoke GHC using a response file when
generating dependencies to sidestep length limitations.
Note that we only pass the actual file names in the dependency
file. Why? Because this side-steps #26560
-
c4c5cc8d
by Duncan Coutts at 2025-12-05T12:05:51+00:00
Make cmm 'import "package" name;' syntax use consistent label types
There is a little-used syntactic form in cmm imports:
import "package" foo;
Which means to import foo from the given package (unit id, specified as
a string). This syntax is somewhat reminiscent of GHC's package import
extension.
This syntax form is not used in the rts cmm code, nor any of the boot
libraries. It may not be used at all. Unclear.
Change the kind of CLabel this syntax generates to be consistent with
the others. The other cmm imports use ForeignLabel with
ForeignLabelInExternalPackage. For some reason this form was using
CmmLabel. Change that to also be ForeignLabel but with
ForeignLabelInPackage. This specifies a specific package, rather
than an unnamed external package.
-
089becd4
by Duncan Coutts at 2025-12-05T12:06:09+00:00
Change default cmm import statements to be internal
Previously a cmm statement like:
import foo;
meant to expect the symbol from a different shared library than the
current one.
Now it means to expect the symbol from the same shared library as the
current one. We'll add explicit syntax to indicate that it's a foreign
import. Most existing uses are in fact intenal (rts to rts), so few
imports will need to be annotated foreign. Examples would include cmm
code in libraries (other than the rts) that need to access RTS APIs.
In practice, this makes no difference whatsoever at the moment on any
platform other than windows (where building Haskell libs as shared libs
does not fully work yet), since the 'labelDynamic' treats all such
labels as foreign, irrespective of the foreign label source.
-
ebbfa6d3
by Duncan Coutts at 2025-12-05T12:06:16+00:00
Add cmm import syntax 'import DATA foo;' as better name for CLOSURE
The existing syntax is:
import CLOSURE foo;
The new syntax is
import DATA foo;
This means to interpret the symbol foo as refering to data (i.e. a
global constant or variable) rather than to code (a function). The
historical syntax for this uses CLOSURE, which is rather misleading.
Presumably this was done to avoid introducing new reserved words.
Be less squemish about new reserved words and add DATA and use that.
Keep the existing CLOSURE syntax as an alias for compatibility.
-
244b8b2b
by Duncan Coutts at 2025-12-05T12:10:27+00:00
Add cmm 'import extern name;' syntax
Since the default for cmm imports is now for symbols within the same
shared object, we need a way to indicate we want a symbol from an
external shared object:
import extern foo; -- for a function
import extern DATA foo; -- for data
This adds a new reserved word 'extern'.
We don't expect to have to use this much. Most cmm imports are
intra-DSO.
This makes no difference currently on ELF and MachO platforms, but does
make a difference to the linking conventions on PE (Windows).
In future it's plausible we could take make distinctions on ELF or
MachO, so it's worth trying to get it right. Windows can be the guinea
pig.
-
06a95576
by Duncan Coutts at 2025-12-05T12:28:04+00:00
Add cmm syntax 'import "package" DATA foo;' for completeness
We already have:
import DATA foo; -- for data imports
import "package" foo; -- for imports from a given unitid
There's no reason not to have both at once:
import "package" DATA foo;
So add that.
-
2e4c159b
by Duncan Coutts at 2025-12-05T12:28:04+00:00
Improve the commentary for the cmm import grammar.
AFAIK, this is the only place where GHC-style Cmm syntax is documented.
-
fd2954cd
by Duncan Coutts at 2025-12-10T14:59:29+00:00
Add minimal dlltool support to ghc-toolchain
We will need dlltool to build ghc itself dynamically on windows, and
probably we will end up needing dlltool for ghc to build Haskell
packages dynamically as well.
The dlltool is a tool that can create dll import libraries from .def
files. These .def files list the exported symbols of dlls. Its somewhat
like gnu linker scripts, but more limited.
-
df3d4fab
by Duncan Coutts at 2025-12-10T14:59:29+00:00
Add minimal dlltool support into ./configure
Find dlltool, and hopefully support finding it within the bundled llvm
toolchain on windows.
-
0855b657
by Duncan Coutts at 2025-12-10T14:59:29+00:00
Update the default host and target files for dlltool support
-
371dfa49
by Duncan Coutts at 2025-12-10T14:59:29+00:00
Add dlltool as a hadrian builder
Optional except on windows.
-
2818cd89
by Duncan Coutts at 2025-12-10T14:59:29+00:00
Update and generate libHSghc-internal.def from .def.in file
The only symbol that the rts imports from the ghc-internal package now
is init_ghc_hs_iface. So the rts only needs an import lib that defines
that one symbol.
Also, remove the libHSghc-prim.def because it is redundant. The rts no
longer imports anything from ghc-prim.
Keep libHSffi.def for now. We may yet need it once it is clear how
libffi is going to be built/used for ghc.
-
d22ed63b
by Duncan Coutts at 2025-12-10T14:59:29+00:00
Add rule to build libHSghc-internal.dll.a and link into the rts
On windows only, with dynamic linking.
This is needed because on windows, all symbols in dlls must be resolved.
No dangling symbols allowed. References to external symbols must be
explicit. We resolve this with an import library. We create an import
library for ghc-internal, a .dll.a file. This is a static archive
containing .o files that define the symbols we need, and crucially have
".idata" sections that specifies the symbols the dll imports and from
where.
Note that we do not install this libHSghc-internal.dll.a, and it does
not need to list all the symbols exported by that package. We create a
special purpose import lib and only use it when linking the rts dll, so
it only has to list the symbols that the rts uses from ghc-internal
(which is exactly one symbol: init_ghc_hs_iface).
-
4131292d
by Duncan Coutts at 2025-12-11T11:41:27+00:00
Merge branch 'wip/dcoutts/cmm-imports' into wip/dcoutts/windows-dlls
-
36d06c50
by Duncan Coutts at 2025-12-11T11:48:27+00:00
Merge branch 'wip/dcoutts/windows-rts-dll' into wip/dcoutts/windows-dlls
-
863db4f4
by Duncan Coutts at 2026-01-06T17:42:12+00:00
Enable dynamic lib support on Windows
This does not mean it works, it means the build system will now try to
build dynamic libs. We'll find out what breaks!
-
c4f9fe0c
by Duncan Coutts at 2026-01-06T17:43:28+00:00
Hadrian: remove legacy rts .so symlinks
For compatibility with the old makefile based build system, hadrian had
rules to generate symlinks from unversioned to versioned names for the
rts .so/.dynlib file, like libHSrts-ghcx.y.so -> libHSrts-1.0.3-ghcx.y.so
We no longer need these symlinks since the makefile build system has
been retired some time ago. The need for these symlinks is awkward on
windows where we cannot (in practice) create symlinks. So rather than
make them conditional (non-windows), just remove them entirely.
-
ec1fa7ff
by Duncan Coutts at 2026-01-06T17:59:07+00:00
Try enabling -dynamic-too on Windows
It ought to work, and otherwise we have to teach hadrian how to build
without using -dynamic-too.
-
8f9918c5
by Duncan Coutts at 2026-02-02T10:05:41+00:00
Try using response files for hadrian linking with ghc.
On windows, the link command line for ghc-internal is well over 32kb.
We did not encounter this before for static libs, since we already use
ar's @file feature (if available, which it is for the llvm toolchain).
We encounter this now on windows for linking dll files (which uses ghc
calling (l)ld rather than ar).
-
0d53e47b
by Duncan Coutts at 2026-02-02T10:05:42+00:00
Use __attribute__(dllimport)) for external RTS symbol declarations
This is needed to be hygenic about DLL symbol imports and exports.
The attribute is ignored on platforms other than Windows.
Use of the attribute however means that external data symbols do not
have a compile-time constant address (they are loaded using an
indirection). This means we have to adjust the rtsSyms initial linker
table so that it is a local constant in a function, rather than a global
constant. We now define it within a function that pre-populates the
symbol table with the RTS symbols.
-
c07584ba
by Duncan Coutts at 2026-02-02T10:05:42+00:00
Experiment with listing RTS symbols
-
48f4736b
by Duncan Coutts at 2026-02-02T10:14:56+00:00
Experimental mingw .refptr mechanism support
-
b4011a99
by David Eichmann at 2026-05-21T16:14:16+01:00
Hadrian: create a ghc-internal .def file per ghc-internal dll
The .def file generated from rts/win32/libHSghc-internal.def.in contains
the name of the ghc-internal dll, but that differs based on if the dll
is inplace/final and what way it is. Previously, this was not accounted
for and inconsistent dlls names where used. That led to failure when
loading dlls are runtime in experiments with windows dynamic linking.