Sun Apr 28 05:58:58 2024 UTC (14d)
lang/ghc98: import ghc-9.8.2

GHC: The Glasgow Haskell Compiler.

The Glasgow Haskell Compiler is a robust, fully-featured, optimising
compiler for the functional programming language Haskell 98
(http://www.haskell.org). GHC compiles Haskell to either native code
or C. It implements numerous experimental language extensions to
Haskell, including concurrency, a foreign language interface, several
type-system extensions, exceptions, and so on. GHC comes with a
generational garbage collector, a space and time profiler, and a
comprehensive set of libraries.

This package provides the 9.8.x release series.


(pho)
diff -r0 -r1.1 pkgsrc/lang/ghc98/DEINSTALL
diff -r0 -r1.1 pkgsrc/lang/ghc98/DESCR
diff -r0 -r1.1 pkgsrc/lang/ghc98/INSTALL
diff -r0 -r1.1 pkgsrc/lang/ghc98/Makefile
diff -r0 -r1.1 pkgsrc/lang/ghc98/bootstrap.mk
diff -r0 -r1.1 pkgsrc/lang/ghc98/buildlink3.mk
diff -r0 -r1.1 pkgsrc/lang/ghc98/distinfo
diff -r0 -r1.1 pkgsrc/lang/ghc98/options.mk
diff -r0 -r1.1 pkgsrc/lang/ghc98/files/BOOTSTRAP.md
diff -r0 -r1.1 pkgsrc/lang/ghc98/files/UserSettings.hs
diff -r0 -r1.1 pkgsrc/lang/ghc98/files/extract-vanilla-package-db
diff -r0 -r1.1 pkgsrc/lang/ghc98/files/hadrian-clock.patch
diff -r0 -r1.1 pkgsrc/lang/ghc98/files/hadrian-shake.patch
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-compiler_GHC_Driver_Pipeline_Execute.hs
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-compiler_GHC_SysTools_Process.hs
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-configure.ac
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-hadrian_bindist_Makefile
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-hadrian_bootstrap_bootstrap.py
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-hadrian_bootstrap_src_Main.hs
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-hadrian_src_Builder.hs
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-hadrian_src_Rules_BinaryDist.hs
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-hadrian_src_Settings_Builders_Ghc.hs
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-hadrian_src_Settings_Default.hs
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-hadrian_src_Settings_Packages.hs
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-libraries_Cabal_Cabal_src_Distribution_Simple_GHC.hs
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-libraries_base_GHC_Event_KQueue.hsc
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-libraries_base_System_CPUTime_Posix_Times.hsc
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-libraries_base_System_Environment.hs
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-libraries_base_configure
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-libraries_terminfo_configure.ac
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-libraries_time_lib_Data_Time_Clock_Internal_CTimespec.hsc
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-libraries_time_lib_Data_Time_Clock_Internal_CTimeval.hs
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-libraries_unix_System_Posix_Env.hsc
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-libraries_unix_System_Posix_Env_ByteString.hsc
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-libraries_unix_System_Posix_Env_PosixString.hsc
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-libraries_unix_System_Posix_Signals.hsc
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-libraries_unix_System_Posix_User.hsc
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-libraries_unix_System_Posix_User_ByteString.hsc
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-m4_fptools__set__haskell__platform__vars.m4
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-utils_haddock_driver_Main.hs
diff -r0 -r1.1 pkgsrc/lang/ghc98/patches/patch-utils_haddock_haddock.cabal
Sun Apr 28 14:58:58 2024
Thu Jan 1 09:00:00 1970
pkgsrc/lang/ghc98/patches/patch-hadrian_src_Settings_Default.hs,v

anoncvs not yet been updated

File Added: pkgsrc/lang/ghc98/DEINSTALL
#!/bin/sh
#
PKGVERSION_NOREV="@PKGVERSION_NOREV@"
RM="@RM@"
RMDIR="@RMDIR@"
TRUE="@TRUE@"

case ${STAGE} in
    DEINSTALL)
        # We can't just remove the entire package.conf.d because then
        # reinstalling GHC would destroy the database and every installed
        # Haskell package breaks.
        ${RM} -f ${PKG_PREFIX}/lib/ghc-${PKGVERSION_NOREV}/lib/package.conf.d/package.cache*
        ${RMDIR} -p ${PKG_PREFIX}/lib/ghc-${PKGVERSION_NOREV}/lib/package.conf.d 2>/dev/null || ${TRUE}
        ;;
esac

File Added: pkgsrc/lang/ghc98/DESCR
GHC: The Glasgow Haskell Compiler.

The Glasgow Haskell Compiler is a robust, fully-featured, optimising
compiler for the functional programming language Haskell 98
(http://www.haskell.org). GHC compiles Haskell to either native code
or C. It implements numerous experimental language extensions to
Haskell, including concurrency, a foreign language interface, several
type-system extensions, exceptions, and so on. GHC comes with a
generational garbage collector, a space and time profiler, and a
comprehensive set of libraries.

This package provides the 9.8.x release series.

File Added: pkgsrc/lang/ghc98/INSTALL
#!/bin/sh
#

case ${STAGE} in
    POST-INSTALL)
        ${PKG_PREFIX}/bin/ghc-pkg recache
        ;;
esac

File Added: pkgsrc/lang/ghc98/Makefile
# $NetBSD: Makefile,v 1.1 2024/04/28 05:58:57 pho Exp $
# -----------------------------------------------------------------------------
# Package metadata
#
DISTNAME=	ghc-9.8.2-src
PKGNAME=	${DISTNAME:S/-src$//}
CATEGORIES=	lang
MASTER_SITES=	https://downloads.haskell.org/~ghc/${PKGVERSION_NOREV}/
EXTRACT_SUFX=	.tar.xz

MAINTAINER=	pkgsrc-users@NetBSD.org
HOMEPAGE=	https://www.haskell.org/ghc/
COMMENT=	Compiler for the functional language Haskell - 9.8 Release Series
LICENSE=	modified-bsd

UNLIMIT_RESOURCES=	cputime datasize virtualsize

# GHC requires GHC to build itself. We have to prepare stripped-down
# binaries sufficient to bootstrap compilers for each platform. If you want
# to build them yourself, follow instructions in files/BOOTSTRAP.md.
BROKEN_EXCEPT_ON_PLATFORM+=	Darwin-*-x86_64
BROKEN_EXCEPT_ON_PLATFORM+=	FreeBSD-*-i386
BROKEN_EXCEPT_ON_PLATFORM+=	FreeBSD-*-x86_64
BROKEN_EXCEPT_ON_PLATFORM+=	NetBSD-*-aarch64
BROKEN_EXCEPT_ON_PLATFORM+=	NetBSD-*-x86_64
BROKEN_EXCEPT_ON_PLATFORM+=	SunOS-*-x86_64

# We are going to do a PIE build on our responsibility. Do not put -pie in
# wrappers, as that would prevent us from building stage-1 compiler.
PKGSRC_OVERRIDE_MKPIE=	yes

.include "options.mk"


# -----------------------------------------------------------------------------
# Distfiles
#
DISTFILES=	${DEFAULT_DISTFILES}
WRKSRC=		${WRKDIR}/${PKGNAME_NOREV}

# We don't want to extract all of the DISTFILEs.
EXTRACT_ONLY=	${DEFAULT_DISTFILES}


# -----------------------------------------------------------------------------
# Tools
#
USE_TOOLS+=			autoconf gmake
USE_LANGUAGES+=			c c++
GNU_CONFIGURE=			yes
USE_GNU_CONFIGURE_HOST=		no
USE_LIBTOOL=			yes
PYTHON_FOR_BUILD_ONLY=		tool
.include "../../lang/python/tool.mk"

# -----------------------------------------------------------------------------
# Configuration
#
HADRIAN_ARGS.common=	# empty
HADRIAN_ARGS.common+=	-j${_MAKE_JOBS_N}
HADRIAN_ARGS=		${HADRIAN_ARGS.common}

# The output from Hadrian is too terse by default. Use at least a single
# --verbose so we can know what's really going on.
HADRIAN_ARGS.common+=	--verbose ${PKG_VERBOSE:D--verbose}

CONFIGURE_ARGS.common+= \
	--with-curses-libraries=${BUILDLINK_PREFIX.curses}/${BUILDLINK_LIBDIRS.curses:Q} \
	--with-gmp-includes=${BUILDLINK_PREFIX.gmp}/${BUILDLINK_INCDIRS.gmp:Q} \
	--with-gmp-libraries=${BUILDLINK_PREFIX.gmp}/${BUILDLINK_LIBDIRS.gmp:Q} \
	--with-iconv-includes=${BUILDLINK_PREFIX.iconv}/${BUILDLINK_INCDIRS.iconv:Q} \
	--with-iconv-libraries=${BUILDLINK_PREFIX.iconv}/${BUILDLINK_LIBDIRS.iconv:Q} \
	--with-ffi-includes=${BUILDLINK_PREFIX.libffi}/${BUILDLINK_INCDIRS.libffi:Q} \
	--with-ffi-libraries=${BUILDLINK_PREFIX.libffi}/${BUILDLINK_LIBDIRS.libffi:Q}

.include "../../mk/bsd.prefs.mk"

# We must pass non-wrapper tools to ./configure because they will be
# embedded in the compiler (actually ${WRKSRC}/settings).
CONFIGURE_ENV+=		ac_cv_prog_fp_prog_ar=${AR:Q}
CONFIGURE_ENV+=		ac_cv_prog_LIBTOOL=libtool
CONFIGURE_ARGS.common+=	LD=${LD:Q}

# While we use binutils ar which supports "@", this appears to be leaking
# somewhere into assuming that SunOS ld also supports "@" which it does not.
CONFIGURE_ENV.SunOS+=	fp_cv_prog_ar_supports_atfile=no

# If there is HsColour in the PATH, GHC's build system tries to use it
# without checking if it really works. That's not what we appreciate.
CONFIGURE_ENV+=		ac_cv_path_HSCOLOUR=

CONFIGURE_ARGS+=	${CONFIGURE_ARGS.common}
CONFIGURE_ARGS+=	--with-system-libffi

# CFLAGS and LDFLAGS are currently not honored by "./configure". Since
# LDFLAGS contains rpath flags it's very important to force GHC to honor
# it. Otherwise neither GHC itself nor executables it produces will have
# any rpaths so users will have to put "${PREFIX}/lib" into their
# "/etc/ld-elf.so.conf". See
# http://hackage.haskell.org/trac/ghc/ticket/2933
.for stage in 0 1 2
CONFIGURE_ENV+=	CONF_GCC_LINKER_OPTS_STAGE${stage}=${LDFLAGS:M*:Q}
# Note that CONF_LD_LINKER_OPTS_STAGE{0,1,2} are only used for
# creating static GHCi libraries (HS*.o). Setting them to ${LDFLAGS}
# does more harm than good because our ${LDFLAGS} contains -Wl,*
# flags. It's true that ../../mk/wrapper/cmd-sink-ld transforms them
# but those flags will also be baked into the compiler (see
# ${WRKSRC}/compiler/ghc.mk) so they cause problems when used outside
# the buildlink.
.endfor

# The use of internal variable ${_PKGSRC_MKPIE} in mk/bsd.prefs.mk is not
# very satisfying, but the current infrastructure does not export a public
# variable indicating whether a PIE build is requested or not. Note that we
# can't build stage-1 compiler as PIE, because our bootkit libraries aren't
# necessarily built as PIC.
.for stage in 0 1 2
.  if ${stage} == 0
CONFIGURE_ENV+=	CONF_CC_OPTS_STAGE${stage}=${CFLAGS:M*:Q}
.  else
.    if ${_PKGSRC_MKPIE} == "yes"
CONFIGURE_ENV+=	CONF_CC_OPTS_STAGE${stage}=${CFLAGS:M*:Q}\ -fPIC
CONFIGURE_ENV+=	CONF_HC_OPTS_STAGE${stage}=-fPIC\ -pie
# Hadrian doesn't honor CONF_HC_OPTS_STAGE${stage}. Possibly a bug?
HADRIAN_ARGS+=	"stage${stage}.*.ghc.c.opts += -fPIC"
HADRIAN_ARGS+=	"stage${stage}.*.ghc.hs.opts += -fPIC"
HADRIAN_ARGS+=	"stage${stage}.*.ghc.link.opts += -pie"
.    else
CONFIGURE_ENV+=	CONF_CC_OPTS_STAGE${stage}=${CFLAGS:M*:Q}
.    endif
.  endif
.endfor
.if ${_PKGSRC_MKPIE} == "yes"
# utils/unlit is a special case. It's built with the stage-0 compiler but
# since it's entirely written in C there's no problem doing a PIE build.
HADRIAN_ARGS+=	"*.unlit.ghc.c.opts += -fPIC"
HADRIAN_ARGS+=	"*.unlit.ghc.link.opts += -pie"
.endif

# MacOS X 10.7 is the oldest OS X version supporting __thread. Although
# ${WRKSRC}/configure has a check for it, the actual build will fail
# without this env.
.if ${OPSYS} == "Darwin"
ALL_ENV+=	MACOSX_DEPLOYMENT_TARGET="10.7"
.endif


# -----------------------------------------------------------------------------
# Security
#
# The runtime system of GHC (rts) has a mechanism called "RTS linker" whose
# job is to load and execute *static* objects (.a and .o files) at run
# time. It cannot survive PaX MPROTECT because preloadObjectFile() in
# rts/linker.c tries to mmap pages with w+x. It doesn't play nice with ASLR
# either because mmapForLinker() in rts/linker.c wants to always mmap pages
# in the lower 32-bit area on 64-bit platforms.
#
# Luckily for us, the RTS linker is only used when the GHC executable (or
# any user programs which uses GHC API as an interpreter, not a compiler)
# is statically linked, which is no longer the case except for ghc-iserv
# and ghc-iesrv-prof. They are launched when ghci is started with
# -fexternal-interpreter without -dynamic, and their purpose is to run
# non-PIC code from within a dynamically linked ghci using the evil RTS
# linker.
.for f in ghc-iserv ghc-iserv-prof
NOT_PAX_MPROTECT_SAFE+=	lib/${PKGNAME_NOREV}/bin/${f}
NOT_PAX_ASLR_SAFE+=	lib/${PKGNAME_NOREV}/bin/${f}
.endfor


# -----------------------------------------------------------------------------
# Build hooks
#

# We patch configure.ac in some directories.
post-patch:
	@${PHASE_MSG} "Regenerating configuration scripts for ${PKGNAME}"
	${RUN}cd ${WRKSRC} && autoconf
	${RUN}cd ${WRKSRC}/libraries/terminfo && autoconf

# Define the target "pre-configure", "pre-build", and non-standard
# "bootstrap".
.include "bootstrap.mk"

# Our pre-configure phase installs a bindist of bootstrapping compiler
# directly into TOOLS_DIR so that ./configure can find it. Our pre-build
# phase bootstraps Hadrian.

# We have a patch to Hadrian so that it uses absolute RPATHs as opposed to
# relative ones (i.e. $ORIGIN). The patch uses --prefix at build time.
HADRIAN_ARGS+=	--prefix=${PREFIX:Q}

# The version restriction on Sphinx in ${WRKSRC}/configure.ac is too
# loose, and building docs/users_guide rarely succeeds. We don't know
# which version is actually required for it.
BUILD_SPHINX_HTML?=	no
HADRIAN_ARGS+=		${${BUILD_SPHINX_HTML:tl} == "no":?--docs=no-sphinx:}

# Don't even think of PDF.
HADRIAN_ARGS+=		--docs=no-sphinx-pdfs

# Enable -fsplit-sections on platforms that support it.
.if ${OPSYS} == "FreeBSD"
#   -fsplit-sections appears to corrupt the symbol table of stage 1
#   libHSghc-*.a(Instances.o) and cause a linkage failure. Either Clang or
#   LLD is doing something wrong, probably the former.
HADRIAN_ARGS+=		--flavour=default
.else
HADRIAN_ARGS+=		--flavour=default+split_sections
.endif

do-build:
	${RUN}cd ${WRKSRC} && ${HADRIAN_CMD} ${HADRIAN_ARGS}
	${RUN}cd ${WRKSRC} && ${HADRIAN_CMD} ${HADRIAN_ARGS} docs


# -----------------------------------------------------------------------------
# Installation/removal hooks
#

# Substitutions for INSTALL and DEINSTALL that handles package.cache.
FILES_SUBST+=	PKGVERSION_NOREV=${PKGVERSION_NOREV}
FILES_SUBST+=	RM=${RM:Q}
FILES_SUBST+=	RMDIR=${RMDIR:Q}
FILES_SUBST+=	TRUE=${TRUE:Q}

# mk/install_script.sh, whose purpose is to generate GHC wrapper scripts to
# be installed, refers to the variable $SHELL. This is bad because our
# $SHELL is in the TOOLDIR.
SUBST_CLASSES+=			ghc-wrapper-sh
SUBST_STAGE.ghc-wrapper-sh=	post-extract
SUBST_FILES.ghc-wrapper-sh=	mk/install_script.sh
SUBST_SED.ghc-wrapper-sh=	-e 's,\#!\$$SHELL,\#!/bin/sh,'

# The "install" target in Hadrian doesn't support DESTDIR so we can't use
# it. We also need to give configure and "make install" some additional env
# vars and args.
do-install:
	${RUN}cd ${WRKSRC} && \
		${HADRIAN_CMD} ${HADRIAN_ARGS} binary-dist-dir
	${RUN}cd ${WRKSRC}/_build/bindist/ghc-* && \
		${PKGSRC_SETENV} ${CONFIGURE_ENV} ${SH} ./configure ${CONFIGURE_ARGS}
	${RUN}cd ${WRKSRC}/_build/bindist/ghc-* && \
		${PKGSRC_SETENV} ${INSTALL_ENV} ${MAKE_ENV} \
			${MAKE_PROGRAM} ${MAKE_FLAGS} ${INSTALL_MAKE_FLAGS} \
			RECACHE_PACKAGE_DB=NO install

INSTALLATION_DIRS+=	share/bash-completion/completions
post-install:
	${INSTALL_DATA} ${WRKSRC}/utils/completion/ghc.bash \
		${DESTDIR}${PREFIX}/share/bash-completion/completions/ghc
# We don't want package.cache to be in the PLIST.
	for f in package.cache package.cache.lock; do \
		${RM} ${DESTDIR}${PREFIX}/lib/${PKGNAME_NOREV}/lib/package.conf.d/$$f; \
	done


# -----------------------------------------------------------------------------
# PLIST
#
# We can't use static PLIST because the package installs files with a
# hashed name.
PLIST_TYPE=	dynamic


# -----------------------------------------------------------------------------
# Sanity checks
#

# These files don't pass our portability checks but we don't use them
# anyway.
CHECK_PORTABILITY_SKIP+=	validate

# ghc57207_0.s: failed to add inputs for merge: Resource temporarily unavailable
# XXX: On which platform? Is it still an issue?
CTF_FILES_SKIP+=		*/libHS*-ghc${PKGVERSION_NOREV}.*

# ld: fatal: relocation error ... relocation requires reference symbol
# XXX: On which platform? Is it still an issue?
STRIP_FILES_SKIP+=		lib/${PKGNAME_NOREV}/libHSrts.a


# -----------------------------------------------------------------------------
# Dependencies
#
.if ${BUILD_SPHINX_HTML} != "no"
TOOL_DEPENDS+=	${PYPKGPREFIX}-sphinx-[0-9]*:../../textproc/py-sphinx
.endif

# NetBSD bootkits are currently built on 9. We need some compat libraries
# to run them on later versions.
#
# In a sandboxed build environment, we have to reach over to the
# installed libraries themselves, since the symlinks compatXX adds
# to the /usr tree can't be applied.
.if ${MACHINE_PLATFORM:MNetBSD-*-*} && ${OPSYS_VERSION} >= 099000
TOOL_DEPENDS+=	compat90-[0-9]*:../../emulators/compat90
ALL_ENV+=	LD_LIBRARY_PATH=${PREFIX}/emul/netbsd/usr/lib
.endif

.include "../../converters/libiconv/buildlink3.mk"
.include "../../devel/libffi/buildlink3.mk"
.include "../../devel/gmp/buildlink3.mk"
.include "../../mk/curses.buildlink3.mk"
.include "../../mk/pthread.buildlink3.mk"
.include "../../mk/bsd.pkg.mk"

# ghc has UTF-8 issues, this is needed to avoid problems during build that
# may manifest from the bootstrap kit.  It comes after bsd.pkg.mk as that
# sets LC_ALL=C first.
#
# XXX I believe those issues have already been sorted out. If you still see
# issues please uncomment this and leave some explanation
# here so that I can look into. [2024-04-27; pho]
#ALL_ENV+=	LC_ALL=en_US.UTF-8

File Added: pkgsrc/lang/ghc98/bootstrap.mk
# $NetBSD: bootstrap.mk,v 1.1 2024/04/28 05:58:57 pho Exp $
# -----------------------------------------------------------------------------
# Select a bindist of bootstrapping compiler on a per-platform basis. See
# ./files/BOOTSTRAP.md for details.
#
# BOOT_ARCHIVE
#   This variable is set to the name of compressed archive file of a
#   bootstrapping compiler for the platform.
#
# BOOT_VERSION
#   Version of the bootstrapping compiler to use.
#
.include "../../mk/bsd.prefs.mk"

# Notes on version dependencies:
# * GHC 9.8.2 requires 9.4 or later to bootstrap.
# * GHC 9.6.3 requires 9.2 or later to bootstrap.
# * GHC 9.4.4 requires 9.0 or later to bootstrap.
# * GHC 9.2.1 requires 8.10 or later to bootstrap.
# * GHC 9.0.1 requires 8.8 or later to bootstrap.
# * GHC 8.8.4 requires 8.4 or later to bootstrap.
# * GHC 8.4.4 requires 8.0 or later to bootstrap.
# * GHC 8.0.2 requires 7.8 or later to bootstrap.
# * GHC 7.10.3 requires 7.6 or later to bootstrap.

# GHC has migrated away from GNU Make to Hadrian as its build system. We
# first need to build it in order to build GHC, but a source tarball
# required for building Hadrian is specific to the version of GHC to use
# for bootstrapping. See ./files/BOOTSTRAP.md for instructions on how to
# create one.
#HADRIAN_BOOT_SOURCE=	ghc-${BOOT_VERSION}-boot-hadrian-${PKGPATH:T}.tar.gz
HADRIAN_BOOT_SOURCE=	ghc-${BOOT_VERSION}-boot-hadrian-ghc9.8.tar.gz
# NOTE: CDN cached a wrong file due to my mistake. On the next major
# version uncomment the first definition and remove the second
# one. [2024-04-27; pho]

.if ${MACHINE_PLATFORM:MDarwin-*-x86_64} || make(distinfo) || make (makesum) || make(mdi)
BOOT_VERSION:=	9.4.7
BOOT_ARCHIVE:=	ghc-${BOOT_VERSION}-boot-x86_64-apple-darwin.tar.xz
DISTFILES:=	${DISTFILES} ${BOOT_ARCHIVE} ${HADRIAN_BOOT_SOURCE} # Available in LOCAL_PORTS
.endif

.if ${MACHINE_PLATFORM:MFreeBSD-*-i386} || make(distinfo) || make (makesum) || make(mdi)
BOOT_VERSION:=	9.4.7
BOOT_ARCHIVE:=	ghc-${BOOT_VERSION}-boot-i386-unknown-freebsd.tar.xz
DISTFILES:=	${DISTFILES} ${BOOT_ARCHIVE} ${HADRIAN_BOOT_SOURCE} # Available in LOCAL_PORTS
.endif

.if ${MACHINE_PLATFORM:MFreeBSD-*-x86_64} || make(distinfo) || make(makesum) || make(mdi)
BOOT_VERSION:=	9.4.7
BOOT_ARCHIVE:=	ghc-${BOOT_VERSION}-boot-x86_64-unknown-freebsd.tar.xz
DISTFILES:=	${DISTFILES} ${BOOT_ARCHIVE} ${HADRIAN_BOOT_SOURCE} # Available in LOCAL_PORTS
.endif

.if ${MACHINE_PLATFORM:MNetBSD-*-aarch64} || make(distinfo) || make(makesum) || make(mdi)
# Cross-compiled from x86_64 on a QEMU guest. It took days to compile...
BOOT_VERSION:=	9.4.7
BOOT_ARCHIVE:=	ghc-${BOOT_VERSION}-boot-aarch64-unknown-netbsd.tar.xz
DISTFILES:=	${DISTFILES} ${BOOT_ARCHIVE} ${HADRIAN_BOOT_SOURCE} # Available in LOCAL_PORTS
.endif

.if ${MACHINE_PLATFORM:MNetBSD-*-x86_64} || make(distinfo) || make(makesum) || make(mdi)
BOOT_VERSION:=	9.4.7
BOOT_ARCHIVE:=	ghc-${BOOT_VERSION}-boot-x86_64-unknown-netbsd.tar.xz
DISTFILES:=	${DISTFILES} ${BOOT_ARCHIVE} ${HADRIAN_BOOT_SOURCE} # Available in LOCAL_PORTS
.endif

.if ${MACHINE_PLATFORM:MSunOS-*-x86_64} || make(distinfo) || make (makesum) || make(mdi)
BOOT_VERSION:=		9.4.7
BOOT_ARCHIVE:=		ghc-${BOOT_VERSION}-boot-x86_64-unknown-solaris2.tar.xz
SITES.${BOOT_ARCHIVE}=	https://us-central.manta.mnx.io/pkgsrc/public/pkg-bootstraps/
DISTFILES:=		${DISTFILES} ${BOOT_ARCHIVE} ${HADRIAN_BOOT_SOURCE} # Available in LOCAL_PORTS
.endif

# DISTFILES contains duplicate HADRIAN_BOOT_SOURCE entries at this
# point. Dedupe them now.
DISTFILES:=	${DISTFILES:O:u}

.if empty(BOOT_ARCHIVE)
BOOT_ARCHIVE:=		ghc-${BOOT_VERSION}-boot-unknown.tar.xz
PKG_FAIL_REASON+=	"internal error: unsupported platform"
.endif

# For package developers, please do not upload any bootkits unsafely
# built. That is, machines shared with someone or on a cloud hosting
# service should be avoided for building bootkits.
.for i in ${DISTFILES:M*-boot-*}
SITES.${i}?=	${MASTER_SITE_LOCAL}
.endfor

.if ${OPSYS} == "SunOS" && ${OS_VARIANT:U} == "OmniOS"
# On this platform cpp(1) is missing from /usr/bin. Why? This leads
# ${WRKSRC}/libffi/configure to fail.
TOOLS_PLATFORM.cpp=	/usr/lib/cpp
.endif


# -----------------------------------------------------------------------------
# The "pre-configure" hook
#
# Install a bootstrapping (stage-0) compiler directly into TOOLS_DIR so
# that ./configure can find it.
#
USE_TOOLS+=	xzcat xz gtar cpp patch # patch is for bootstrap.py

# Bootkits from the pre-Hadrian era has a different name for the top
# directory in their archives. We can eliminate this conditional once all
# of our bootkits are updated to 9.4 or later.
.if ${BOOT_ARCHIVE:M9.2.*}
BOOT_ARCHIVE_TOP_DIR=	ghc-${BOOT_VERSION}-boot
.else
BOOT_ARCHIVE_TOP_DIR=	${BOOT_ARCHIVE:C/\.tar\..z$//}
.endif

pre-configure:
	${RUN}${TEST} -f ${DISTDIR}/${DIST_SUBDIR}/${BOOT_ARCHIVE} || \
	${FAIL_MSG}  "Place your trusted bootkit archive at ${DISTDIR}/${DIST_SUBDIR}/${BOOT_ARCHIVE}"

	@${PHASE_MSG} "Extracting bootstrapping compiler for ${PKGNAME}"
	${RUN}${MKDIR} ${WRKDIR}/bootkit-dist
	${RUN}cd ${WRKDIR}/bootkit-dist && \
		${XZCAT} ${DISTDIR}/${DIST_SUBDIR}/${BOOT_ARCHIVE} | \
		${GTAR} -xf -

	@${PHASE_MSG} "Preparing bootstrapping compiler for ${PKGNAME}"
# <kludge>
# "RTS ways" in "ghc --info" is totally bogus, because GhcRTSWays in
# hadrian/bindist/config.mk.in does not reflect Hadrian user settings at
# all. This leads Hadrian to believe that the stage-0 compiler has threaded
# RTS even if it doesn't. Note that GHC devs are in the process of moving
# the settings file from being generated by configure, to being generated
# by the build system. This workaround is expected to go away in the
# (hopefully near) future.
	${RUN}cd ${WRKDIR}/bootkit-dist/${BOOT_ARCHIVE_TOP_DIR} && \
		${SED} -e '/^GhcRTSWays/d' < mk/config.mk.in > mk/config.mk.in.tmp && \
		${MV} -f mk/config.mk.in.tmp mk/config.mk.in
# </kludge>
	${RUN}cd ${WRKDIR}/bootkit-dist/${BOOT_ARCHIVE_TOP_DIR} && \
		${PKGSRC_SETENV} ${CONFIGURE_ENV} ${SH} ./configure \
			--prefix=${TOOLS_DIR:Q} ${CONFIGURE_ARGS.boot} && \
		${PKGSRC_SETENV} ${MAKE_ENV} ${MAKE_PROGRAM} install


# -----------------------------------------------------------------------------
# The "pre-build" hook
#
# Bootstrap Hadrian with the stage-0 compiler. It is important to do this
# in "pre-build" because we often need to patch Hadrian itself while
# updating our packages and we want it to be rebuilt every time we make
# changes to it.
#
pre-build:
	${RUN}${TEST} -f ${DISTDIR}/${DIST_SUBDIR}/${HADRIAN_BOOT_SOURCE} || \
		${FAIL_MSG} "${HADRIAN_BOOT_SOURCE} not found in ${DISTDIR}/${DIST_SUBDIR}.\
			You first need to create it before building ${PKGNAME}.\
			See ./files/BOOTSTRAP.md for details."

	@${PHASE_MSG} "Building Hadrian for GHC ${BOOT_VERSION}"
	${RUN}cd ${WRKSRC}/hadrian/bootstrap && \
		${PKGSRC_SET_ENV} ${ALL_ENV} \
			python bootstrap.py \
				-j ${_MAKE_JOBS_N} \
				-s ${DISTDIR}/${DIST_SUBDIR}/${HADRIAN_BOOT_SOURCE}

# This defines how to run the Hadrian command. Also used in do-build and
# such.
HADRIAN_CMD=	${PKGSRC_SET_ENV} ${ALL_ENV} ${WRKSRC}/hadrian/bootstrap/_build/bin/hadrian

# -----------------------------------------------------------------------------
# An unusual target "bootstrap"
#
# Build a bootstrapping compiler using an already installed GHC. This is
# certainly impossible if you don't have one. It's absolutely important to
# build it with the fewest possible run-time dependencies, otherwise the
# resulting binary can easily get unusable.

# We don't want our bootkits to have a run-time dependency on libgcc. In
# fact GHC's implementation of Haskell exception handling does not depend
# on libgcc's facilities so it is attractive to do the same for "normal"
# build... but we can't. This is because Haskell programs may call C
# functions via FFI, and those C functions may call C++ functions in turn,
# possibly in a different shared library.
.include "../../mk/compiler.mk"
.if make(bootstrap) && ${CC_VERSION:Mgcc-*}
# But on some platforms gcc automagically inserts a dependency on a shared
# libgcc when -lpthread is given, which is seemingly unavoidable.
LDFLAGS+=	-static-libgcc
.endif

# Gather information about packages on which bootkit depends. It will be
# used in the post-bootstrap phase.
BOOT_GHC_DEPS:=		curses iconv
BOOT_GHC_PKGSRC_DEPS:=	# empty
.for pkg in ${BOOT_GHC_DEPS}

# NOTE: pkglint(1) complains for including these builtin.mk files, telling
# that we must include buildlink3.mk instead. But then how do we get
# variables like USE_BUILTIN.${pkg} defined before including
# ../../mk/bsd.pkg.mk, given that ../../mk/bsd.buildlink3.mk isn't
# protected against multiple inclusion?
CHECK_BUILTIN.${pkg}:=	yes
.  if ${pkg} == "curses"
.    include "../../mk/curses.builtin.mk"
.  elif ${pkg} == "iconv"
.    include "../../converters/libiconv/builtin.mk"
.  endif
CHECK_BUILTIN.${pkg}:=	no

# BOOT_GHC_PKGSRC_DEPS is a list of packages whose pkgsrc version is
# preferred over native one, either by user or ../../mk/platform
.  if ${PREFER.${pkg}} == "pkgsrc"
BOOT_GHC_PKGSRC_DEPS+=	${pkg}
.  endif
.endfor

# Compiler wrappers must not remove -I/-L flags for the installed GHC's
# libdir, otherwise the stage-0 GHC (which we are going to use for building
# our bootstraping kit) will not work. Ideally it should be added to
# BUILDLINK_PASSTHRU_DIRS only .if make(bootstrap), but then running
# "${MAKE} wrapper" before "${MAKE} bootstrap" will result in a cryptic
# error which we can't easily catch.
BOOT_GHC_LIBDIR_CMD=		ghc --print-libdir
.if !defined(BOOT_GHC_LIBDIR)
BOOT_GHC_LIBDIR!=		(${BOOT_GHC_LIBDIR_CMD}) 2>/dev/null || ${ECHO}
.endif
MAKEVARS+=			BOOT_GHC_LIBDIR
BUILDLINK_PASSTHRU_DIRS+=	${BOOT_GHC_LIBDIR}

# Default values for BUILDLINK_INCDIRS.<pkg> are only generated in the
# barrier. See ../../mk/buildlink3/bsd.buildlink3.mk and
# ../../mk/bsd.pkg.barrier.mk
.PHONY: bootstrap
BOOT_ARCHIVE.new=		${BOOT_ARCHIVE:S/-${BOOT_VERSION}-/-${PKGVERSION_NOREV}-/}
.if make(bootstrap)
_BARRIER_CMDLINE_TARGETS+=	bootstrap
.endif
.if !defined(_PKGSRC_BARRIER)
bootstrap: barrier
.else
bootstrap: pre-bootstrap .WAIT ${WRKDIR}/stamp-dist-boot .WAIT post-bootstrap
.endif

# For normal build we use pkgsrc libffi.so, but for bootkits we can't do
# that because that would mean bootkits have run-time dependency on
# it. However, building the bundled one isn't a solution either, because
# pkgsrc libffi tends to be heavily patched to support our exotic
# platforms. So we remove ${BUILDLINK_DIR}/lib/libffi.so just before we
# build our bootkit so that the resulting executables link with the static
# one.
CONFIGURE_ARGS.boot=	${CONFIGURE_ARGS.common}
CONFIGURE_ARGS.boot+=	--with-bindist-prefix="ghc-boot-" --with-system-libffi

# Hadrian arguments to use while building a bootkit.
HADRIAN_ARGS.boot=	${HADRIAN_ARGS.common}
HADRIAN_ARGS.boot+=	--docs=none
.if ${OPSYS} == "FreeBSD"
#   -fsplit-sections appears to corrupt the symbol table of stage 1
#   libHSghc-*.a(Instances.o) and cause a linkage failure. Either Clang or
#   LLD is doing something wrong, probably the former.
HADRIAN_ARGS.boot+=	--flavour=bootkit
.else
HADRIAN_ARGS.boot+=	--flavour=bootkit+split_sections
.endif

# Determine the version of GHC being used to build the bootkit. We will
# need this to bootstrap Hadrian.
.if make(bootstrap)
BOOT_GHC_VERSION_CMD=	ghc --numeric-version
BOOT_GHC_VERSION!=	(${BOOT_GHC_VERSION_CMD}) 2>/dev/null || ${ECHO}
HADRIAN_BOOT_SOURCE:=	ghc-${BOOT_GHC_VERSION}-boot-hadrian.tar.gz
.endif

.PHONY: pre-bootstrap
pre-bootstrap: wrapper
.if empty(BOOT_GHC_LIBDIR)
	${RUN}if ${BOOT_GHC_LIBDIR_CMD} 2>/dev/null 1>&2; then \
		${ERROR_MSG} "Running \"${BOOT_GHC_LIBDIR_CMD}\" has failed during wrapper phase."; \
		${FAIL_MSG}  "Please run \"${MAKE} clean\" and try again."; \
	else \
		${ERROR_MSG} "Failed to run \"${BOOT_GHC_LIBDIR_CMD}\":"; \
		${BOOT_GHC_LIBDIR_CMD}; \
		${ERROR_MSG} "You don't seem to have a working GHC in your PATH."; \
		${FAIL_MSG}  "Please install one and then run \"${MAKE} clean bootstrap\"."; \
	fi
.endif
# ${_COOKIE.configure} is not defined yet so we can't use .if here.
	${RUN}if ${TEST} -f ${_COOKIE.configure}; then \
		${ERROR_MSG} "You have already configured the package in a way\
			that building bootstrapping compiler is impossible."; \
		${FAIL_MSG}  "Please run \"${MAKE} clean\" first."; \
	fi

${WRKDIR}/stamp-configure-boot:
	@${PHASE_MSG} "Configuring bootstrapping compiler ${PKGNAME_NOREV}"
	cd ${WRKSRC} && \
		${PKGSRC_SETENV} ${CONFIGURE_ENV} ${SH} ./configure ${CONFIGURE_ARGS.boot}
	${TOUCH} ${.TARGET}

${WRKDIR}/stamp-build-boot: ${WRKDIR}/stamp-configure-boot
	${RUN}${TEST} -f ${DISTDIR}/${DIST_SUBDIR}/${HADRIAN_BOOT_SOURCE} || \
		${FAIL_MSG} "${HADRIAN_BOOT_SOURCE} not found in ${DISTDIR}/${DIST_SUBDIR}.\
			You first need to create it before building the bootkit.\
			See ./files/BOOTSTRAP.md for details."

	@${PHASE_MSG} "Building Hadrian for ${BOOT_GHC_VERSION}"
	${CP} -f ${FILESDIR}/UserSettings.hs ${WRKSRC}/hadrian/
# ${HADRIAN_BOOT_SOURCE} often contains libraries older than what we have
# in pkgsrc. When that happens bootstrap.py tries to build Hadrian with
# pkgsrc-installed libraries and fails because they aren't buildlinked. So
# we must temporarily disable wrappers while building it.
	saved_IFS="$$IFS"; \
	IFS=":"; \
	set -- $$PATH; \
	IFS="$$saved_IFS"; \
	pruned_path=; \
	while ${TEST} "$$#" -gt 0; do \
		if ${TEST} "$$1" != "${WRAPPER_BINDIR}"; then \
			if ${TEST} "$$pruned_path" = ""; then \
				pruned_path="$$1"; \
			else \
				pruned_path="$$pruned_path:$$1"; \
			fi; \
		fi; \
		shift; \
	done; \
	PATH="$$pruned_path"; \
	cd ${WRKSRC}/hadrian/bootstrap && \
		python bootstrap.py \
			-j ${_MAKE_JOBS_N} \
			-s ${DISTDIR}/${DIST_SUBDIR}/${HADRIAN_BOOT_SOURCE}

	@${PHASE_MSG} "Building bootstrapping compiler ${PKGNAME_NOREV}"
	for f in ${BUILDLINK_DIR:Q}/lib/libffi.*; do \
		case "$$f" in \
			*.a) :;; \
			*)   ${RM} -f "$$f";; \
		esac; \
	done
	cd ${WRKSRC} && ${HADRIAN_CMD} ${HADRIAN_ARGS.boot}
	${TOUCH} ${.TARGET}

${WRKDIR}/stamp-dist-boot: ${WRKDIR}/stamp-build-boot
	@${PHASE_MSG} "Creating binary distribution of bootstrapping ${PKGNAME_NOREV}"
	cd ${WRKSRC} && ${HADRIAN_CMD} ${HADRIAN_ARGS.boot} binary-dist
	${MV} -f ${WRKSRC}/_build/bindist/${BOOT_ARCHIVE.new} ${WRKDIR}/${BOOT_ARCHIVE.new}

.PHONY: post-bootstrap
post-bootstrap:
	@${ECHO} "=========================================================================="
	@${ECHO} "Done creating ${BOOT_ARCHIVE.new}"
	@${ECHO} "  in ${WRKDIR}"
	@${ECHO}
	@${ECHO} "Now you can copy it into ${DISTDIR}/${DIST_SUBDIR} to use as your"
	@${ECHO} "bootstrap kit. You may want to take a backup in case \"lintpkgsrc -r\""
	@${ECHO} "removes it."
	@${ECHO}
	@${ECHO} "Your bootstrap kit has the following run-time dependencies:"
.for pkg in ${BOOT_GHC_DEPS}
	@${PRINTF} "  * %-8s" "${pkg}:"
.  if ${USE_BUILTIN.${pkg}:tl} == no
	@${ECHO_N} " pkgsrc ${BUILDLINK_PKGNAME.${pkg}}"
.  else
	@${ECHO_N} " native"
.    if empty(BUILTIN_PKG.${pkg})
	@${ECHO_N} " (version/variant unknown)"
.    else
	@${ECHO_N} " ${BUILTIN_PKG.${pkg}}"
.    endif
.  endif
	@${ECHO}
.endfor
.if !empty(BOOT_GHC_PKGSRC_DEPS)
	@${ECHO}
	@${ECHO} "Please note that it is generally not a good idea for a bootkit to depend"
	@${ECHO} "on pkgsrc packages, as pkgsrc tends to move faster than operating systems"
	@${ECHO} "so your bootkit will bitrot more quickly. You may want to rebuild it"
	@${ECHO} "without setting PREFER_PKGSRC to \"yes\"."
.endif
	@${ECHO} "=========================================================================="

File Added: pkgsrc/lang/ghc98/buildlink3.mk
# $NetBSD: buildlink3.mk,v 1.1 2024/04/28 05:58:57 pho Exp $

BUILDLINK_TREE+=	ghc

.if !defined(GHC_BUILDLINK3_MK)
GHC_BUILDLINK3_MK:=

BUILDLINK_API_DEPENDS.ghc+=	ghc>=9.8.2
BUILDLINK_ABI_DEPENDS.ghc+=	ghc>=9.8.2
BUILDLINK_PKGSRCDIR.ghc?=	../../lang/ghc98

.include "../../converters/libiconv/buildlink3.mk"
.include "../../devel/libffi/buildlink3.mk"
.include "../../devel/gmp/buildlink3.mk"
.include "../../mk/curses.buildlink3.mk"
.endif	# GHC_BUILDLINK3_MK

BUILDLINK_TREE+=	-ghc

File Added: pkgsrc/lang/ghc98/distinfo
$NetBSD: distinfo,v 1.1 2024/04/28 05:58:57 pho Exp $

BLAKE2s (ghc-9.4.7-boot-aarch64-unknown-netbsd.tar.xz) = a691117b405b9f7954b954acc382b3357a9ff8c98151514c82d18d83da397940
SHA512 (ghc-9.4.7-boot-aarch64-unknown-netbsd.tar.xz) = 1c917a52a020be3a1878f9d7e8e4c47d31180e54248c127a60706c1053a95b2d8a487f79e7fb5daa725178f271a7cc17e4e7b47ce2119f8546e259c63b9864d8
Size (ghc-9.4.7-boot-aarch64-unknown-netbsd.tar.xz) = 90305900 bytes
BLAKE2s (ghc-9.4.7-boot-hadrian-ghc9.8.tar.gz) = ac74fdc6f8a5d4a75bda0c6501902c2c160d3780b41b739129b5a36773c295cd
SHA512 (ghc-9.4.7-boot-hadrian-ghc9.8.tar.gz) = e086a40eb6b655fcb22744a32247ab596adf649179681d6203514d66cbc0989e6b59430de5f02e18419b27584e2dbac5a418fb40f66bcdc76e8776d1e315a332
Size (ghc-9.4.7-boot-hadrian-ghc9.8.tar.gz) = 1527081 bytes
BLAKE2s (ghc-9.4.7-boot-i386-unknown-freebsd.tar.xz) = f81c97f117156e8d4f1e7cec33a0e969a78ff1be7c9a5ebf212b9e521c1c23f4
SHA512 (ghc-9.4.7-boot-i386-unknown-freebsd.tar.xz) = b32a9d4c6423cd858dcbd4f07e68d3ef49b879323b9eee36c6495574e15881ea70ff2aa3c02897165d6d9872693f4ee11c4fe86b613b49a7864ca4730ebbc865
Size (ghc-9.4.7-boot-i386-unknown-freebsd.tar.xz) = 78875476 bytes
BLAKE2s (ghc-9.4.7-boot-x86_64-apple-darwin.tar.xz) = 2ee9f0deb331b7ac3fbbb8dd6acb595b23329bfc3ee95c16faf9dba378f11525
SHA512 (ghc-9.4.7-boot-x86_64-apple-darwin.tar.xz) = 5abedf9427a73b229beffdd6b1085bb11db100e7222b1e66b46a2cce72235d9c0152c4fd5c433676b3e132db277adf9f6a4267e60fcf48d1902ba50dbac81fa5
Size (ghc-9.4.7-boot-x86_64-apple-darwin.tar.xz) = 111036360 bytes
BLAKE2s (ghc-9.4.7-boot-x86_64-unknown-freebsd.tar.xz) = 9356f28874c23beb64472241f301079b66ad0de010af186c75c5f05d7df91206
SHA512 (ghc-9.4.7-boot-x86_64-unknown-freebsd.tar.xz) = b40be23acea89133d2ec5049b920d3de9585c5cef7913a3b15623a00fa34f1ef51aafc33e7294b031621bcde2f3996c9a8c43f1b0f680903bbf1b1ba48e107fb
Size (ghc-9.4.7-boot-x86_64-unknown-freebsd.tar.xz) = 77145928 bytes
BLAKE2s (ghc-9.4.7-boot-x86_64-unknown-netbsd.tar.xz) = b920b6b54f5c1c6ab5fcbad14298ae742942e14da8105831df535926b9b9f529
SHA512 (ghc-9.4.7-boot-x86_64-unknown-netbsd.tar.xz) = 4821dbf8f50c42a3427322c7488a07738d41da2236102571fc3051fd4d41a7a75754a1b27769365fc7f9d01ba0af65b87e51933077b3c36c2084ee3053479040
Size (ghc-9.4.7-boot-x86_64-unknown-netbsd.tar.xz) = 77029664 bytes
BLAKE2s (ghc-9.4.7-boot-x86_64-unknown-solaris2.tar.xz) = 82abea5431d6d106c7eb4388c196594a050446f8164aecd5c76e263a96114a03
SHA512 (ghc-9.4.7-boot-x86_64-unknown-solaris2.tar.xz) = c6dd73fce67dd8a4933a7f31318af662bc3fd873e3d96fa6aa2e0c72282c554cc2e13abdecc29919231c3cf346d878f5f738bb72f2db53d63dd79bf07a1e2d91
Size (ghc-9.4.7-boot-x86_64-unknown-solaris2.tar.xz) = 128747936 bytes
BLAKE2s (ghc-9.8.2-src.tar.xz) = 4d903dc828e46d12ad4dc8be912e2996666351ecf8b7a5e1c85790f1fb7eaa5a
SHA512 (ghc-9.8.2-src.tar.xz) = 9b677d5ead5ebb5df7bc960055a76ef00e68ed8102844997b12154bf71bdbfafdfff9ca31edce86b3df759242a7c98f52a464887973b53985f54ecd9fc4b4627
Size (ghc-9.8.2-src.tar.xz) = 32432564 bytes
SHA1 (patch-compiler_GHC_Driver_Pipeline_Execute.hs) = 8a86aabddfa4cc5dcff3bb9812010696fb6a16df
SHA1 (patch-compiler_GHC_SysTools_Process.hs) = ceb26657516e207e22d555ec6f87f735344b0d08
SHA1 (patch-configure.ac) = 985482ae70830ddbf1334c9c82a2cec78a34bb4c
SHA1 (patch-hadrian_bindist_Makefile) = 3a91d56be4f1b59c6534eceb5b1a4f8e86d49c68
SHA1 (patch-hadrian_bootstrap_bootstrap.py) = 7a03b6cf4b07348c7ab8f2ecbb2f234b0817c1f6
SHA1 (patch-hadrian_bootstrap_src_Main.hs) = 2e0a7ae2ef195013ca07313c150a7e48b6985e32
SHA1 (patch-hadrian_src_Builder.hs) = bbfb1ddc30af900c89ca3cf649a32da2a1c83174
SHA1 (patch-hadrian_src_Rules_BinaryDist.hs) = fb908f74b8b619bccd673fbdb40b1c53ab7a51d8
SHA1 (patch-hadrian_src_Settings_Builders_Ghc.hs) = e2913e9f83bb36bb0b432a24518c9b6ca2990c6a
SHA1 (patch-hadrian_src_Settings_Default.hs) = b8b1564fa7941f3c7c737f4115b5f4d7d0e0125a
SHA1 (patch-hadrian_src_Settings_Packages.hs) = d7dce5ff44a3dc05efc6c31aed7234c235594231
SHA1 (patch-libraries_Cabal_Cabal_src_Distribution_Simple_GHC.hs) = 9e6028dd6ffc2d3c71493fbb7336adcec9f08f78
SHA1 (patch-libraries_base_GHC_Event_KQueue.hsc) = 8ee5da667a241a05fde3c580d3dc9bdc05aa5f00
SHA1 (patch-libraries_base_System_CPUTime_Posix_Times.hsc) = 2bfb779d534d12073287274ce5e90b99e457a860
SHA1 (patch-libraries_base_System_Environment.hs) = 7d79a91f295915b4408d5f41d5405739d7189215
SHA1 (patch-libraries_base_configure) = 4e02082cdfde8d927d12f3d2f3d98ace6d4ee116
SHA1 (patch-libraries_terminfo_configure.ac) = 068c2b89fc997a433709ec171c685654598781d7
SHA1 (patch-libraries_time_lib_Data_Time_Clock_Internal_CTimespec.hsc) = 588270767f8a9cbde0648fc99807891fef65d721
SHA1 (patch-libraries_time_lib_Data_Time_Clock_Internal_CTimeval.hs) = 68914d012a98cc4a4a245efeabcb9143dba0246a
SHA1 (patch-libraries_unix_System_Posix_Env.hsc) = 414f0310793bf184cdac7546e3f81fee4821a05f
SHA1 (patch-libraries_unix_System_Posix_Env_ByteString.hsc) = a579c00d7d5d7ffbb73f6499e09588d6417be123
SHA1 (patch-libraries_unix_System_Posix_Env_PosixString.hsc) = 40d464638eb11cb832f93d9892818655f4d70e00
SHA1 (patch-libraries_unix_System_Posix_Signals.hsc) = ee59a04571881382bcfd9fc82bf196ff86a40ed5
SHA1 (patch-libraries_unix_System_Posix_User.hsc) = b583f591838fe2d7f42241787e02c5385d336939
SHA1 (patch-libraries_unix_System_Posix_User_ByteString.hsc) = 2a331de2292835ae6904980facd8201705fa63e8
SHA1 (patch-m4_fptools__set__haskell__platform__vars.m4) = 8c7a7ab965f4df8a68bedb35c32ee32c59ac2c94
SHA1 (patch-utils_haddock_driver_Main.hs) = 26b015d3aef9fdff66e66c8e3d9a370a2dbd7067
SHA1 (patch-utils_haddock_haddock.cabal) = c8a244f2f341b736b65b218590d1a3a8309f55ba

File Added: pkgsrc/lang/ghc98/options.mk
# $NetBSD: options.mk,v 1.1 2024/04/28 05:58:57 pho Exp $

PKG_OPTIONS_VAR=	PKG_OPTIONS.ghc

.include "../../mk/bsd.prefs.mk"

# GHC has a native implementation of codegen (NCG) for some platforms. On
# those platforms LLVM is optional. It's a requirement anywhere else. See
# compiler/GHC/Driver/Backend.hs
#
# The LLVM backend tends to produce slightly faster code than what NCG
# produces, but it is much slower than NCG. It is therefore not the default
# backend on platforms where NCG is available. On platforms where NCG is
# available, LLVM should be disabled by default because it's a huge
# dependency that takes hours to compile.
#
# Note that bootkits also require LLVM/Clang on platforms lacking NCG. This
# can cause a transitional problem when a new compiler arrives with NCG for
# a platform which used to lack one. In this case we have to either (1)
# build a new bootkit for the platform with LLVM backend disabled, or (2)
# reuse the old bootkit by putting llvm/clang in TOOL_DEPENDS (regardless
# of user choice) and arrange parameters so that they are used only by the
# stage-0 compiler. We don't have an infrastructure for (2), as it's not
# worth the additional complexity, so (1) is the only option atm.

GHC_NCG_SUPPORTED=	aarch64 i386 x86_64 powerpc powerpc64 sparc
.if !empty(GHC_NCG_SUPPORTED:M${MACHINE_ARCH})
PKG_SUPPORTED_OPTIONS+=	llvm
GHC_LLVM_REQUIRED=	no
.else
GHC_LLVM_REQUIRED=	yes
.endif

.if !empty(PKG_SUPPORTED_OPTIONS)
.  include "../../mk/bsd.options.mk"
.endif

.if !empty(PKG_OPTIONS:Mllvm) || ${GHC_LLVM_REQUIRED} == "yes"
DEPENDS+=		llvm-[0-9]*:../../lang/llvm
CONFIGURE_ARGS.common+=	LLC=${PREFIX:Q}/bin/llc
CONFIGURE_ARGS.common+=	OPT=${PREFIX:Q}/bin/opt

# When we use the LLVM backend, we *have* to use Clang's integrated
# assembler because llc emits assembly source files incompatible with
# Binutils < 2.36 (see https://reviews.llvm.org/D97448). It also requires
# Clang on Darwin (see runClang in compiler/GHC/SysTools/Tasks.hs).
DEPENDS+=		clang-[0-9]*:../../lang/clang
CONFIGURE_ARGS.common+=	CLANG=${PREFIX:Q}/bin/clang
CONFIGURE_ARGS.common+=	CC=${PREFIX:Q}/bin/clang

# Maybe GHC doesn't like this but it's the only option available to us.
LLVM_VERSION_CMD=	${PKG_INFO} -E llvm | ${SED} -E 's/^llvm-([0-9]*)\..*/\1/'
LLVM_MAX_VERSION_CMD=	${EXPR} ${LLVM_VERSION_CMD:sh} + 1
SUBST_CLASSES+=		llvm
SUBST_STAGE.llvm=	post-extract
SUBST_MESSAGE.llvm=	Modifying configure.ac to accept whichever version of LLVM installed via pkgsrc
SUBST_FILES.llvm=	configure.ac
SUBST_SED.llvm=		-e 's/LlvmMaxVersion=[0-9]*/LlvmMaxVersion=${LLVM_MAX_VERSION_CMD:sh}/'

.else
CONFIGURE_ARGS.common+=	LLC=${FALSE:Q}
CONFIGURE_ARGS.common+=	OPT=${FALSE:Q}
CONFIGURE_ARGS.common+=	CLANG=${FALSE:Q}
CONFIGURE_ARGS.common+=	CC=${CC:Q}
.endif

File Added: pkgsrc/lang/ghc98/files/BOOTSTRAP.md
<!-- $NetBSD: BOOTSTRAP.md,v 1.1 2024/04/28 05:58:57 pho Exp $ -->

# We need GHC to build GHC

GHC requires itself to build, and unfortunately the only way to get a
working GHC for a foreign target is to do a cross-compilation.

In order to build a bootkit for a new platform, you need to manually set up
a cross-building C compiler and binutils, libc, libterminfo, and libiconv
for the target. Then you can follow instructions in
https://gitlab.haskell.org/ghc/ghc/wikis/building/cross-compiling

Once you get a working GHC for the target platform, install it somewhere in
your PATH, run "bmake clean; bmake bootstrap" on the target platform and
you'll have a bootkit for the target. *But read a note below on the build
system.*


## The build system "Hadrian" is also written in Haskell

[Migrating from Make to Hadrian (for
packagers)](https://www.haskell.org/ghc/blog/20220805-make-to-hadrian.html)

GHC devs had used GNU Make to build GHC for decades, but its Makefiles had
grown unwieldy to the point where maintenance was virtually
impossible. They were in need of something more expressive than Make and
eventually developed their own build system named Hadrian, which is written
in Haskell. Unfortunately to us, this makes our lives harder for three
reasons:

1. Haskell libraries required to build Hadrian isn't bundled with GHC. We
   either need to use `misc/cabal-install` to fetch them (which isn't an
   option because we can't build cabal-install without GHC), or use a
   separate source tarball to bootstrap Hadrian.
2. The source tarball of Hadrian dependencies is specific to bootkit
   version. That is, if we are to use GHC 9.2.1 as our bootkit, we need a
   source tarball specific to GHC 9.2.1.
3. The required tarballs aren't distributed officially. We must roll them
   in our own hand. But in order to do it you need a working instance of
   `misc/cabal-install`.

So we must provide not only GHC bootkits but also Hadrian deps tarballs in
our LOCAL_PORTS.


### How to create `HADRIAN_BOOT_SOURCE` for your bootkit

The name of Hadrian deps tarball is defined as `${HADRIAN_BOOT_SOURCE}` in
`bootstrap.mk`. If you find one in our LOCAL_PORTS it means someone has
already created it and you don't need to do anything special. It is
platform-independent. It's only tied with a specific version of GHC. Just
do `bmake` and it will first bootstrap Hadrian and then use it to build the
entire package. If not, you have to create a tarball specific to your
bootkit version.

First, check if GHC has a so-called "build plan" in
`${WRKSRC}/hadrian/bootstrap`. If you find
`plan-bootstrap-${BOOT_VERSION}.json` for your bootkit version then you can
skip this step. If not, install `misc/cabal-install` and do:

```
% cd ${WRKSRC}/hadrian
% ../../../files/extract-vanilla-package-db ./packages.conf
(The next command fails with an error but you can safely ignore it.)
% cabal build --package-db=clear --package-db=./packages.conf --only-configure
% cp dist-newstyle/cache/plan.json bootstrap/plan-${BOOT_VERSION}.json
% cd ./bootstrap
% cabal build --allow-newer
% cabal run -v0 --allow-newer hadrian-bootstrap-gen \
      -- plan-${BOOT_VERSION}.json | \
      tee plan-bootstrap-${BOOT_VERSION}.json
```

Now you have a build plan. Create a tarball like so:

```
% cd ${WRKSRC}/hadrian/bootstrap
% ./bootstrap.py --deps plan-bootstrap-${BOOT_VERSION}.json fetch \
      -o ghc-${BOOT_VERSION}-boot-hadrian-${PKGPATH:T}
```

Now you have `ghc-${BOOT_VERSION}-boot-hadrian-${PKGPATH:T}.tar.gz` that is
necessary to bootstrap Hadrian with your bootkit. Copy it to `${DISTDIR}`,
and if you're a pkgsrc developer place it in LOCAL_PORTS.


## HC files in ancient times, where have they gone?

GHC in fact has never supported bootstrapping only with a C compiler.
Prior to GHC 7, it had a thing called "HC source", which was a set of C
source files compiled from Haskell source, but it wasn't actually
cross-platform. It was because HC files were generated with many
assumptions about the platform, such as the layout of libc structs, the
size of `off_t` and `time_t`, byte-order, word size, etc.

File Added: pkgsrc/lang/ghc98/files/UserSettings.hs
-- $NetBSD: UserSettings.hs,v 1.1 2024/04/28 05:58:57 pho Exp $
--
-- This is a Hadrian settings file to override some defaults in a way which
-- isn't possible through command-line options. It is only used during the
-- build of bootkits. Options for regular builds are passed via command
-- line.

module UserSettings (
    userFlavours, userPackages, userDefaultFlavour,
    verboseCommand, buildProgressColour, successColour, finalStage
    ) where

import Flavour.Type
import Expression
import {-# SOURCE #-} Settings.Default

-- See ${WRKSRIC}/hadrian/doc/user-settings.md for instructions.

userDefaultFlavour :: String
userDefaultFlavour = "default"

userFlavours :: [Flavour]
userFlavours = [bootkitFlavour]

-- It is preferred to use this flavour with "split_sections" transformer,
-- e.g. --flavour=bootkit+split_sections
bootkitFlavour :: Flavour
bootkitFlavour =
  defaultFlavour
  { name               = "bootkit"
    -- We don't want in-tree GMP to be statically linked as it increases
    -- the bindist size. Dynamic linkage is even worse.
  , bignumBackend      = "native"
    -- We only want vanilla libraries and RTS. No profiling, no shared
    -- libraries, no debugging.
  , libraryWays        = pure [vanilla]
  , rtsWays            = pure [vanilla]
    -- Don't build or use dynamic Haskell libraries.
  , dynamicGhcPrograms = pure False
    -- Build GHC as minimally as possible.
  , ghciWithDebugger   = False
  , ghcProfiled        = False
  , ghcDebugged        = False
  , ghcDebugAssertions = False
  , ghcThreaded        = False
    -- This is a bootstrap compiler. We don't want any kinds of
    -- documentation.
  , ghcDocs            = pure mempty
  }

userPackages :: [Package]
userPackages = []

verboseCommand :: Predicate
verboseCommand = do
    verbosity <- expr getVerbosity
    return $ verbosity >= Verbose

buildProgressColour :: BuildProgressColour
buildProgressColour = mkBuildProgressColour (Dull Magenta)

successColour :: SuccessColour
successColour = mkSuccessColour (Dull Green)

finalStage :: Stage
finalStage = Stage2

File Added: pkgsrc/lang/ghc98/files/extract-vanilla-package-db
#!/bin/sh
set -eu

# This script extracts the package DB originally came from GHC you are
# using. Only needed when you create a hadrian bootstrap archive.

if [ "$#" -lt 1 ]; then
    echo >&2 "Usage: $0 PKG_DB_DIR"
    exit
fi
PKG_DB_DIR="$1"

mkdir -p "$PKG_DB_DIR"
pkg_info -qL ghc | {
    conf_dir_path=
    while read path; do
        conf_dir_removed="${path#*/package.conf.d/}"
        if [ "$conf_dir_removed" != "$path" ]; then
            echo "Copying ${path}..."
            if [ "$conf_dir_path" = "" ]; then
                conf_dir_path="${path%/${conf_dir_removed}}"
            fi
            sed -e "s|\\\${pkgroot}|${conf_dir_path}/..|g" \
                < "${path}" \
                > "${PKG_DB_DIR}/${conf_dir_removed}"
        fi
    done
}
ghc-pkg --package-db="$PKG_DB_DIR" recache

File Added: pkgsrc/lang/ghc98/files/hadrian-clock.patch
$NetBSD: hadrian-clock.patch,v 1.1 2024/04/28 05:58:57 pho Exp $

Building "clock" needs patching on NetBSD due to its ccall to
clock_gettime(2) and clock_getres(2).

This hack can be removed if we upstream this patch and GHC adopts it in
hadrian/bootstrap/*.json. This incurs a small runtime cost but it's what
GHC devs recommend:
https://www.haskell.org/ghc/blog/20210709-capi-usage.html

--- clock-0.8.3/System/Clock.hsc.orig	2024-04-27 16:18:19.639792537 +0000
+++ clock-0.8.3/System/Clock.hsc
@@ -1,3 +1,4 @@
+{-# LANGUAGE CApiFFI #-}
 -- | High-resolution, realtime clock and timer functions for Posix
 --   systems. This module is being developed according to IEEE Std
 --   1003.1-2008: <http://www.opengroup.org/onlinepubs/9699919799/>,
@@ -132,8 +133,8 @@ foreign import ccall unsafe hs_clock_win
 foreign import ccall unsafe hs_clock_win32_getres_processtime :: Ptr TimeSpec -> IO ()
 foreign import ccall unsafe hs_clock_win32_getres_threadtime :: Ptr TimeSpec -> IO ()
 #else
-foreign import ccall unsafe clock_gettime :: #{type clockid_t} -> Ptr TimeSpec -> IO CInt
-foreign import ccall unsafe clock_getres  :: #{type clockid_t} -> Ptr TimeSpec -> IO CInt
+foreign import capi unsafe "time.h clock_gettime" clock_gettime :: #{type clockid_t} -> Ptr TimeSpec -> IO CInt
+foreign import capi unsafe "time.h clock_getres" clock_getres  :: #{type clockid_t} -> Ptr TimeSpec -> IO CInt
 #endif
 
 #if !defined(_WIN32)

File Added: pkgsrc/lang/ghc98/files/hadrian-shake.patch
$NetBSD: hadrian-shake.patch,v 1.1 2024/04/28 05:58:57 pho Exp $

This file is used by bootstrap.py.

The shake package tries to build an unneeded executable with hard-coded
"-thread". The only way to disable it is to modify its .cabal file.

This hack can be removed when GHC adopts the version containing this commit
in hadrian/bootstrap/*.json:
https://github.com/ndmitchell/shake/pull/836

--- shake-0.19.7/shake.cabal.orig	2024-04-27 16:15:52.267668874 +0000
+++ shake-0.19.7/shake.cabal
@@ -204,6 +204,7 @@ library
 
 
 executable shake
+    buildable: False
     default-language: Haskell2010
     hs-source-dirs:   src
     ghc-options: -main-is Run.main -rtsopts -threaded "-with-rtsopts=-I0 -qg"

File Added: pkgsrc/lang/ghc98/patches/patch-compiler_GHC_Driver_Pipeline_Execute.hs
$NetBSD: patch-compiler_GHC_Driver_Pipeline_Execute.hs,v 1.1 2024/04/28 05:58:57 pho Exp $

This is pkgsrc-specific. Do not use -Xpreprocessor to pass options to
CPP. Our tool wrappers may remove some of them, and if that happens an
unpaired -Xpreprocessor will be left behind and confuses CC.

--- compiler/GHC/Driver/Pipeline/Execute.hs.orig	2022-12-23 16:19:02.000000000 +0000
+++ compiler/GHC/Driver/Pipeline/Execute.hs
@@ -373,7 +373,7 @@ runCcPhase cc_phase pipe_env hsc_env inp
       aug_imports = augmentImports dflags opts
 
       more_preprocessor_opts = concat
-        [ ["-Xpreprocessor", i]
+        [ [ i ]
         | not hcc
         , i <- aug_imports
         ]

File Added: pkgsrc/lang/ghc98/patches/patch-compiler_GHC_SysTools_Process.hs
$NetBSD: patch-compiler_GHC_SysTools_Process.hs,v 1.1 2024/04/28 05:58:57 pho Exp $

This is more like pkgsrc-specific than an upstream issue. Unless we
are on Windows, don't use "response file", the @FILE syntax while
invoking CC or LD. Our tool wrappers don't look into response files,
and therefore can't detect mistakes like depending on Cabal packages
that aren't declared as pkgsrc dependency.

Note that this patch would break GHC if we didn't have its $ORIGIN use
eliminated because our wrappers hate relative rpaths.

--- compiler/GHC/SysTools/Process.hs.orig	2022-12-23 16:19:02.000000000 +0000
+++ compiler/GHC/SysTools/Process.hs
@@ -160,6 +160,7 @@ runSomethingResponseFile
   -> [Option]
   -> Maybe [(String,String)]
   -> IO ()
+#if defined(mingw32_HOST_OS)
 runSomethingResponseFile logger tmpfs dflags filter_fn phase_name pgm args mb_env =
     runSomethingWith logger phase_name pgm args $ \real_args -> do
         fp <- getResponseFile real_args
@@ -198,6 +199,10 @@ runSomethingResponseFile logger tmpfs df
             x
         , "\""
         ]
+#else
+runSomethingResponseFile logger tmpfs dflags filter_fn phase_name pgm args mb_env =
+  runSomethingFiltered logger filter_fn phase_name pgm args Nothing mb_env
+#endif
 
 runSomethingFiltered
   :: Logger -> (String->String) -> String -> String -> [Option]

File Added: pkgsrc/lang/ghc98/patches/patch-configure.ac
$NetBSD: patch-configure.ac,v 1.1 2024/04/28 05:58:57 pho Exp $

Hunk #0:
    Disable DTrace support on solaris2.
    XXX: But why?

--- configure.ac.orig	2022-12-23 16:19:02.000000000 +0000
+++ configure.ac
@@ -800,7 +800,7 @@ if test "x$EnableDtrace" = "xyes"; then
   if test -n "$DtraceCmd"; then
     if test "x$TargetOS_CPP-$TargetVendor_CPP" = "xdarwin-apple" \
       -o "x$TargetOS_CPP-$TargetVendor_CPP" = "xfreebsd-portbld" \
-      -o "x$TargetOS_CPP-$TargetVendor_CPP" = "xsolaris2-unknown"; then
+      ; then
       HaveDtrace=YES
     fi
   fi

File Added: pkgsrc/lang/ghc98/patches/patch-hadrian_bindist_Makefile
$NetBSD: patch-hadrian_bindist_Makefile,v 1.1 2024/04/28 05:58:57 pho Exp $

Don't run `ghc-pkg recache' while installing a binary distribution. See
also "do-install" in Makefile. This is pkgsrc-specific.

--- hadrian/bindist/Makefile.orig	2024-02-22 20:59:45.000000000 +0000
+++ hadrian/bindist/Makefile
@@ -242,7 +242,9 @@ update_package_db: install_bin install_l
 	@echo "Updating the package DB"
 	$(foreach p, $(PKG_CONFS),\
 		$(call patchpackageconf,$(shell echo $(notdir $p) | sed 's/-[0-9.]*-[0-9a-zA-Z]*\.conf//g'),$(shell echo "$p" | sed 's:\0xxx\0:   :g'),$(docdir),$(shell mk/relpath.sh "$(ActualLibsDir)" "$(docdir)"),$(shell echo $(notdir $p) | sed 's/.conf//g')))
+ifneq "$(RECACHE_PACKAGE_DB)" "NO"
 	'$(DESTDIR)$(ActualBinsDir)/$(CrossCompilePrefix)ghc-pkg' --global-package-db "$(DESTDIR)$(ActualLibsDir)/package.conf.d" recache
+endif
 
 install_mingw:
 	@echo "Installing MingGW"

File Added: pkgsrc/lang/ghc98/patches/patch-hadrian_bootstrap_bootstrap.py
$NetBSD: patch-hadrian_bootstrap_bootstrap.py,v 1.1 2024/04/28 05:58:57 pho Exp $

Hunk #0:
    bootstrap.py assumes that GHC always has a threaded RTS but our
    bootkits don't. It is debatable at least as to whether this should be
    upstreamed.

    We also need to patch some packages to bootstrap hadrian. Those patch
    files are in ${FILESDIR}.

Hunk #0, #1, #2, #3, #4, #5, #6:
    Support --jobs=N for parallel compilation. This makes bootstrapping
    hadrian a lot faster.
    TODO: Upstream this.

--- hadrian/bootstrap/bootstrap.py.orig	2024-02-22 20:59:45.000000000 +0000
+++ hadrian/bootstrap/bootstrap.py
@@ -180,24 +180,42 @@ def resolve_dep(dep : BootstrapDep) -> P
     return sdist_dir
 
 
-def install_dep(dep: BootstrapDep, ghc: Compiler) -> None:
+def install_dep(dep: BootstrapDep, ghc: Compiler, jobs: int) -> None:
     dist_dir = (DISTDIR / f'{dep.package}-{dep.version}').resolve()
 
     sdist_dir = resolve_dep(dep)
 
-    install_sdist(dist_dir, sdist_dir, ghc, dep.flags)
+    # Some packages are going to be built with threaded RTS, which is
+    # impossible in our case.
+    flags = [flag.replace("+threaded", "-threaded") for flag in dep.flags]
+
+    # pkgsrc has local patches that need to be applied for bootstrapping
+    # hadrian.
+    patch_path = Path('..') / '..' / '..' / '..' / 'files' / f'hadrian-{dep.package}.patch'
+    if patch_path.is_file():
+        with open(patch_path) as patch_file:
+            patch = patch_file.read()
+        subprocess_run(
+            ['patch', '-p1', '-b'], cwd=sdist_dir, input=patch, check=True, encoding='UTF-8')
+
+    # If it's from Hackage and we've already installed it, don't do it
+    # twice. That only wastes time.
+    stamp = sdist_dir / 'bootstrap-done'
+    if dep.source == PackageSource.LOCAL or not stamp.exists():
+        install_sdist(dist_dir, sdist_dir, ghc, flags, jobs)
+        stamp.touch()
 
-def install_sdist(dist_dir: Path, sdist_dir: Path, ghc: Compiler, flags: List[str]):
+def install_sdist(dist_dir: Path, sdist_dir: Path, ghc: Compiler, flags: List[str], jobs: int):
     prefix = PSEUDOSTORE.resolve()
     flags_option = ' '.join(flags)
     setup_dist_dir = dist_dir / 'setup'
     setup = setup_dist_dir / 'Setup'
 
-    build_args = [
+    common_args = [
         f'--builddir={dist_dir}',
     ]
 
-    configure_args = build_args + [
+    configure_args = common_args + [
         f'--package-db={PKG_DB.resolve()}',
         f'--prefix={prefix}',
         f'--bindir={BINDIR.resolve()}',
@@ -207,6 +225,12 @@ def install_sdist(dist_dir: Path, sdist_
         f'--flags={flags_option}',
     ]
 
+    build_args = common_args + [
+        f'--jobs={jobs}',
+    ]
+
+    install_args = common_args
+
     def check_call(args: List[str]) -> None:
         subprocess_run(args, cwd=sdist_dir, check=True)
 
@@ -223,7 +247,7 @@ def install_sdist(dist_dir: Path, sdist_
     check_call([str(ghc.ghc_path), '--make', '-package-env=-', '-i', f'-odir={setup_dist_dir}', f'-hidir={setup_dist_dir}', '-o', setup, 'Setup'])
     check_call([setup, 'configure'] + configure_args)
     check_call([setup, 'build'] + build_args)
-    check_call([setup, 'install'] + build_args)
+    check_call([setup, 'install'] + install_args)
 
 def hash_file(h, f: BinaryIO) -> SHA256Hash:
     while True:
@@ -238,7 +262,7 @@ def hash_file(h, f: BinaryIO) -> SHA256H
 UnitId = NewType('UnitId', str)
 PlanUnit = NewType('PlanUnit', dict)
 
-def bootstrap(info: BootstrapInfo, ghc: Compiler) -> None:
+def bootstrap(info: BootstrapInfo, ghc: Compiler, jobs: int) -> None:
     if not PKG_DB.exists():
         print(f'Creating package database {PKG_DB}')
         PKG_DB.parent.mkdir(parents=True, exist_ok=True)
@@ -248,7 +272,7 @@ def bootstrap(info: BootstrapInfo, ghc: 
         check_builtin(dep, ghc)
 
     for dep in info.dependencies:
-        install_dep(dep, ghc)
+        install_dep(dep, ghc, jobs)
 
 # Steps
 #######################################################################
@@ -374,6 +398,8 @@ def main() -> None:
                        help='produce a Hadrian distribution archive (default)')
     parser.add_argument('--no-archive', dest='want_archive', action='store_false',
                        help='do not produce a Hadrian distribution archive')
+    parser.add_argument('-j', '--jobs', type=int,
+                        help='the number of jobs to run simultaneously')
     parser.set_defaults(want_archive=True)
 
     subparsers = parser.add_subparsers(dest="command")
@@ -480,7 +506,8 @@ Alternatively, you could use `bootstrap.
           plan = gen_fetch_plan(info)
           fetch_from_plan(plan, TARBALLS)
 
-        bootstrap(info, ghc)
+        bootstrap(info, ghc, args.jobs)
+        return # Don't waste time by creating an archive.
         hadrian_path = (BINDIR / 'hadrian').resolve()
 
         print(dedent(f'''

File Added: pkgsrc/lang/ghc98/patches/patch-hadrian_bootstrap_src_Main.hs
$NetBSD: patch-hadrian_bootstrap_src_Main.hs,v 1.1 2024/04/28 05:58:57 pho Exp $

Fix build with cabal-install-parsers >= 0.6. This doesn't affect normal
builds. It's only for creating Hadrian bootstrap source archives.

https://gitlab.haskell.org/ghc/ghc/-/merge_requests/11546

--- hadrian/bootstrap/src/Main.hs.orig	2023-09-21 11:30:31.000000000 +0000
+++ hadrian/bootstrap/src/Main.hs
@@ -1,3 +1,5 @@
+{-# Language CPP #-}
+
 module Main (main) where
 
 import Control.Monad      (when)
@@ -85,7 +87,11 @@ main2 meta plan = do
                         return
                             ( Hackage
                             , Just $ fromIntegral (I.riRevision relInfo)
+#if MIN_VERSION_cabal_install_parsers(0, 6, 0)
+                            , P.sha256FromByteString $ I.getSHA256 $ I.riCabalHash relInfo
+#else
                             , P.sha256FromByteString $ I.getSHA256 $ I.riCabal relInfo
+#endif
                             )
 
                     Nothing -> case P.uType unit of

File Added: pkgsrc/lang/ghc98/patches/patch-hadrian_src_Builder.hs
$NetBSD: patch-hadrian_src_Builder.hs,v 1.1 2024/04/28 05:58:58 pho Exp $

This is pkgsrc-specific. We build haddock as a dynamically-linked
executable but it doesn't contain an rpath to our not-yet-installed shared
libraries. This is usually not a problem because Hadrian embeds relative
rpaths (i.e. $ORIGIN) in dynamically-linked objects but we patch Hadrian
not to do that.

--- hadrian/src/Builder.hs.orig	2024-02-22 20:59:45.000000000 +0000
+++ hadrian/src/Builder.hs
@@ -31,6 +31,7 @@ import Hadrian.Utilities
 import Oracles.Setting (bashPath)
 import System.Exit
 import System.IO (stderr)
+import System.Directory (makeAbsolute)
 
 import Base
 import Context
@@ -386,8 +387,20 @@ instance H.Builder Builder where
                   when (code /= ExitSuccess) $ do
                     fail "tests failed"
 
+                Haddock _ -> do
+                  envs <- haddockEnvs
+                  cmd' envs [path] buildArgs
+
                 _  -> cmd' [path] buildArgs
 
+haddockEnvs :: Action [CmdOption]
+haddockEnvs = do
+    libPath'  <- libPath (vanillaContext Stage1 haddock)
+    distDir'  <- distDir Stage1
+    shlibPath <- liftIO $ makeAbsolute (libPath' -/- distDir')
+    return [ AddEnv "LD_LIBRARY_PATH" shlibPath
+           , AddEnv "DYLD_LIBRARY_PATH" shlibPath ] -- Darwin
+
 -- | Invoke @haddock@ given a path to it and a list of arguments. The arguments
 -- are passed in a response file.
 runHaddock :: FilePath    -- ^ path to @haddock@
@@ -396,7 +409,8 @@ runHaddock :: FilePath    -- ^ path to @
       -> Action ()
 runHaddock haddockPath flagArgs fileInputs = withTempFile $ \tmp -> do
     writeFile' tmp $ escapeArgs fileInputs
-    cmd [haddockPath] flagArgs ('@' : tmp)
+    envs <- haddockEnvs
+    cmd' envs [haddockPath] flagArgs ('@' : tmp)
 
 -- TODO: Some builders are required only on certain platforms. For example,
 -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform

File Added: pkgsrc/lang/ghc98/patches/patch-hadrian_src_Rules_BinaryDist.hs
$NetBSD: patch-hadrian_src_Rules_BinaryDist.hs,v 1.1 2024/04/28 05:58:58 pho Exp $

Hunk #0, #1, #3:
    Distinguish bootstrapping bindists from regular ones. This is
    pkgsrc-specific.

Hunk #2:
    Do not run `ghc-pkg recache' while creating a binary distribution. We
    don't want a package cache to be installed because we do it in our
    INSTALL script. Also it's not possible to run ghc-pkg in the first
    place without setting LD_LIBRARY_PATH since we don't build relocatable
    executables. This is pkgsrc-specific.

Hunk #4:
    We want our bootkits to be as small as possible, even though `xz -9e'
    is very slow and consumes about 680 MiB of memory. This is
    pkgsrc-specific.

--- hadrian/src/Rules/BinaryDist.hs.orig	2022-12-23 16:19:02.000000000 +0000
+++ hadrian/src/Rules/BinaryDist.hs
@@ -113,7 +113,7 @@ bindistRules = do
         need ["binary-dist-dir"]
         version        <- setting ProjectVersion
         targetPlatform <- setting TargetPlatformFull
-        let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
+        let ghcVersionPretty = "ghc-" ++ version ++ "-boot-" ++ targetPlatform
             bindistFilesDir  = root -/- "bindist" -/- ghcVersionPretty
             prefixErr = "You must specify a path with --prefix when using the"
                      ++ " 'install' rule"
@@ -136,7 +136,7 @@ bindistRules = do
 
         let ghcBuildDir      = root -/- stageString Stage1
             bindistFilesDir  = root -/- "bindist" -/- ghcVersionPretty
-            ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
+            ghcVersionPretty = "ghc-" ++ version ++ "-boot-" ++ targetPlatform
             rtsIncludeDir    = ghcBuildDir -/- "lib" -/- distDir -/- rtsDir
                                -/- "include"
 
@@ -194,16 +194,6 @@ bindistRules = do
         copyDirectory (rtsIncludeDir)         bindistFilesDir
         when windowsHost $ createGhcii (bindistFilesDir -/- "bin")
 
-        -- Call ghc-pkg recache, after copying so the package.cache is
-        -- accurate, then it's on the distributor to use `cp -a` to install
-        -- a relocatable bindist.
-        --
-        -- N.B. the ghc-pkg executable may be prefixed with a target triple
-        -- (c.f. #20267).
-        ghcPkgName <- programName (vanillaContext Stage1 ghcPkg)
-        cmd_ (bindistFilesDir -/- "bin" -/- ghcPkgName) ["recache"]
-
-
         -- The settings file must be regenerated by the bindist installation
         -- logic to account for the environment discovered by the bindist
         -- configure script on the host. Not on Windows, however, where
@@ -279,7 +269,7 @@ bindistRules = do
             version        <- setting ProjectVersion
             targetPlatform <- setting TargetPlatformFull
 
-            let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
+            let ghcVersionPretty = "ghc-" ++ version ++ "-boot-" ++ targetPlatform
 
             -- Finally, we create the archive <root>/bindist/ghc-X.Y.Z-platform.tar.xz
             tarPath <- builderPath (Tar Create)
@@ -332,7 +322,7 @@ data Compressor = Gzip | Bzip2 | Xz
 -- | Flag to pass to tar to use the given 'Compressor'.
 compressorTarFlag :: Compressor -> String
 compressorTarFlag Gzip  = "--gzip"
-compressorTarFlag Xz    = "--xz"
+compressorTarFlag Xz    = "--use-compress-program=xz --verbose -9 --extreme"
 compressorTarFlag Bzip2 = "--bzip"
 
 -- | File extension to use for archives compressed with the given 'Compressor'.

File Added: pkgsrc/lang/ghc98/patches/patch-hadrian_src_Settings_Builders_Ghc.hs
$NetBSD: patch-hadrian_src_Settings_Builders_Ghc.hs,v 1.1 2024/04/28 05:58:58 pho Exp $

Don't use rpaths relative to $ORIGIN. Use the final installation path. This
is pkgsrc-specific.

--- hadrian/src/Settings/Builders/Ghc.hs.orig	2022-12-23 16:19:02.000000000 +0000
+++ hadrian/src/Settings/Builders/Ghc.hs
@@ -5,6 +5,7 @@ module Settings.Builders.Ghc (ghcBuilder
 import Hadrian.Haskell.Cabal
 import Hadrian.Haskell.Cabal.Type
 
+import CommandLine
 import Flavour
 import Packages
 import Settings.Builders.Common
@@ -104,10 +105,10 @@ ghcLinkArgs = builder (Ghc LinkHs) ? do
     fmwks   <- getContextData frameworks
     way     <- getWay
 
-    -- Relative path from the output (rpath $ORIGIN).
-    originPath <- dropFileName <$> getOutput
-    context <- getContext
-    libPath' <- expr (libPath context)
+    -- Absolute rpath to the final destination.
+    fileName <- takeFileName <$> getOutput
+    prefix   <- fromMaybe (error "--prefix missing from the command line") <$> expr cmdPrefix
+    projVer  <- getSetting ProjectVersion
     st <- getStage
     distDir <- expr (Context.distDir st)
 
@@ -121,17 +122,8 @@ ghcLinkArgs = builder (Ghc LinkHs) ? do
 
     let
         dynamic = Dynamic `wayUnit` way
-        distPath = libPath' -/- distDir
-        originToLibsDir = makeRelativeNoSysLink originPath distPath
-        rpath
-            -- Programs will end up in the bin dir ($ORIGIN) and will link to
-            -- libraries in the lib dir.
-            | isProgram pkg = metaOrigin -/- originToLibsDir
-            -- libraries will all end up in the lib dir, so just use $ORIGIN
-            | otherwise     = metaOrigin
-            where
-                metaOrigin | osxTarget = "@loader_path"
-                           | otherwise = "$ORIGIN"
+        ghclibdir = prefix -/- "lib" -/- ("ghc-" ++ projVer)
+        rpath     = ghclibdir -/- "lib" -/- distDir
 
         -- TODO: an alternative would be to generalize by linking with extra
         -- bundled libraries, but currently the rts is the only use case. It is
@@ -144,23 +136,13 @@ ghcLinkArgs = builder (Ghc LinkHs) ? do
             , arg ("-l" ++ libffiName')
             ]
 
-        -- This is the -rpath argument that is required for the bindist scenario
-        -- to work. Indeed, when you install a bindist, the actual executables
-        -- end up nested somewhere under $libdir, with the wrapper scripts
-        -- taking their place in $bindir, and 'rpath' therefore doesn't seem
-        -- to give us the right paths for such a case.
-        -- TODO: Could we get away with just one rpath...?
-        bindistRpath = "$ORIGIN" -/- ".." -/- ".." -/- originToLibsDir
-
     mconcat [ dynamic ? mconcat
                 [ arg "-dynamic"
                 -- TODO what about windows?
                 , isLibrary pkg ? pure [ "-shared", "-dynload", "deploy" ]
                 , hostSupportsRPaths ? mconcat
                       [ arg ("-optl-Wl,-rpath," ++ rpath)
-                      , isProgram pkg ? arg ("-optl-Wl,-rpath," ++ bindistRpath)
-                      -- The darwin and Windows linkers don't support/require the -zorigin option
-                      , not (osxTarget || winTarget) ? arg "-optl-Wl,-zorigin"
+                      , isLibrary pkg ? pure ["-dylib-install-name", rpath -/- fileName]
                       -- We set RPATH directly (relative to $ORIGIN). There's
                       -- no reason for GHC to inject further RPATH entries.
                       -- See #19485.

File Added: pkgsrc/lang/ghc98/patches/patch-hadrian_src_Settings_Default.hs

File Added: pkgsrc/lang/ghc98/patches/patch-hadrian_src_Settings_Packages.hs
$NetBSD: patch-hadrian_src_Settings_Packages.hs,v 1.1 2024/04/28 05:58:58 pho Exp $

Hunk #0, #1:
  Don't assume we always build the threaded RTS.
  TODO: Upstream this.

Hunk #2:
  Hadrian does something unholy on i386 to gain speed but it seems to be
  incompatible with LLD. Disable the speed hack to work around a linkage
  failure. Ideally we should do this by detecting the type of linker but
  not the OS. (Don't upstream this as-is. Do detect the linker type.)

--- hadrian/src/Settings/Packages.hs.orig	2024-02-22 20:59:45.000000000 +0000
+++ hadrian/src/Settings/Packages.hs
@@ -29,6 +29,7 @@ packageArgs = do
     cursesLibraryDir <- getSetting CursesLibDir
     ffiIncludeDir  <- getSetting FfiIncludeDir
     ffiLibraryDir  <- getSetting FfiLibDir
+    rtsWays          <- getRtsWays
 
     mconcat
         --------------------------------- base ---------------------------------
@@ -166,7 +167,17 @@ packageArgs = do
 
         -------------------------------- haddock -------------------------------
         , package haddock ?
-          builder (Cabal Flags) ? arg "in-ghc-tree"
+          builder (Cabal Flags) ? mconcat
+          [ arg "in-ghc-tree"
+          , ifM stage0
+                -- We build a threaded haddock on stage 1 if the
+                -- bootstrapping compiler supports it.
+                (threadedBootstrapper `cabalFlag` "threaded")
+
+                -- We build a threaded haddock on stage N, N>1 if the
+                -- configuration calls for it.
+                (any (wayUnit Threaded) rtsWays `cabalFlag` "threaded")
+          ]
 
         ---------------------------------- text --------------------------------
         , package text ? mconcat
@@ -441,7 +452,7 @@ rtsPackageArgs = package rts ? do
 speedHack :: Action Bool
 speedHack = do
     i386   <- anyTargetArch ["i386"]
-    goodOS <- not <$> anyTargetOs ["darwin", "solaris2"]
+    goodOS <- not <$> anyTargetOs ["darwin", "solaris2", "freebsd"]
     return $ i386 && goodOS
 
 -- See @rts/ghc.mk@.

File Added: pkgsrc/lang/ghc98/patches/patch-libraries_Cabal_Cabal_src_Distribution_Simple_GHC.hs
$NetBSD: patch-libraries_Cabal_Cabal_src_Distribution_Simple_GHC.hs,v 1.1 2024/04/28 05:58:58 pho Exp $

Hunk #0, #1, #2:
  Revert the change introduced in https://github.com/haskell/cabal/issues/1660

  Do not use @rpath on Darwin, instead use the final destination path as a
  library install name. This is pkgsrc-specific.

  See also https://github.com/haskell/cabal/pull/7076
  And https://github.com/haskell/cabal/issues/7339

Hunk #2:
  Enable Cabal's rpath overriding functionality on all the platforms known
  to use ELF.

  When a Cabal package which defines both a library and an executable to be
  built, GHC by default embeds an rpath to the *build* directory into the
  executable. This may sound like a bug in GHC but is actually not, because
  GHC doesn't know the fact that the said library is going to be installed
  elsewhere. To overcome this issue, Cabal has a functionality to disable
  the default rpath handling of GHC and construct the correct set of
  rpaths... but only on certain platforms for some reason.

  Pull request: https://github.com/haskell/cabal/pull/7382

--- libraries/Cabal/Cabal/src/Distribution/Simple/GHC.hs.orig	2023-09-21 11:31:40.000000000 +0000
+++ libraries/Cabal/Cabal/src/Distribution/Simple/GHC.hs
@@ -836,7 +836,7 @@ buildOrReplLib mReplFlags verbosity numJ
                                mkStaticLibName (hostPlatform lbi) compiler_id uid
         ghciLibFilePath      = relLibTargetDir </> Internal.mkGHCiLibName uid
         ghciProfLibFilePath  = relLibTargetDir </> Internal.mkGHCiProfLibName uid
-        libInstallPath       = libdir $
+        libInstallPath       = dynlibdir $
                                absoluteComponentInstallDirs
                                pkg_descr lbi uid NoCopyDest
         sharedLibInstallPath = libInstallPath </>
@@ -900,7 +900,6 @@ buildOrReplLib mReplFlags verbosity numJ
                 -- at build time. This only applies to GHC < 7.8 - see the
                 -- discussion in #1660.
                 ghcOptDylibName          = if hostOS == OSX
-                                              && ghcVersion < mkVersion [7,8]
                                             then toFlag sharedLibInstallPath
                                             else mempty,
                 ghcOptHideAllPackages    = toFlag True,
@@ -1813,15 +1812,15 @@ getRPaths lbi clbi | supportRPaths hostO
     -- 'False', while those operating systems themselves do support RPATH.
     supportRPaths Linux       = True
     supportRPaths Windows     = False
-    supportRPaths OSX         = True
+    supportRPaths OSX         = False
     supportRPaths FreeBSD     =
       case compid of
         CompilerId GHC ver | ver >= mkVersion [7,10,2] -> True
         _                                              -> False
-    supportRPaths OpenBSD     = False
-    supportRPaths NetBSD      = False
-    supportRPaths DragonFly   = False
-    supportRPaths Solaris     = False
+    supportRPaths OpenBSD     = True
+    supportRPaths NetBSD      = True
+    supportRPaths DragonFly   = True
+    supportRPaths Solaris     = True
     supportRPaths AIX         = False
     supportRPaths HPUX        = False
     supportRPaths IRIX        = False

File Added: pkgsrc/lang/ghc98/patches/patch-libraries_base_GHC_Event_KQueue.hsc
$NetBSD: patch-libraries_base_GHC_Event_KQueue.hsc,v 1.1 2024/04/28 05:58:58 pho Exp $

Suppress linker warnings about compatibility syscall wrappers by using
"capi" instead of "ccall".

--- libraries/base/GHC/Event/KQueue.hsc.orig	2019-12-26 18:05:56.276488590 +0000
+++ libraries/base/GHC/Event/KQueue.hsc
@@ -284,7 +284,7 @@ foreign import capi safe "sys/event.h ke
     c_kevent :: KQueueFd -> Ptr Event -> CInt -> Ptr Event -> CInt
              -> Ptr TimeSpec -> IO CInt
 
-foreign import ccall unsafe "kevent"
+foreign import capi unsafe "sys/event.h kevent"
     c_kevent_unsafe :: KQueueFd -> Ptr Event -> CInt -> Ptr Event -> CInt
                     -> Ptr TimeSpec -> IO CInt
 #else

File Added: pkgsrc/lang/ghc98/patches/patch-libraries_base_System_CPUTime_Posix_Times.hsc
$NetBSD: patch-libraries_base_System_CPUTime_Posix_Times.hsc,v 1.1 2024/04/28 05:58:58 pho Exp $

Suppress linker warnings about compatibility syscall wrappers by using
"capi" instead of "ccall".

--- libraries/base/System/CPUTime/Posix/Times.hsc.orig	2020-01-04 12:08:39.515726533 +0000
+++ libraries/base/System/CPUTime/Posix/Times.hsc
@@ -27,7 +27,7 @@ getCPUTime = allocaBytes (#const sizeof(
                         `div` fromIntegral clockTicks)
 
 type CTms = ()
-foreign import ccall unsafe times :: Ptr CTms -> IO CClock
+foreign import capi unsafe "sys/times.h times" times :: Ptr CTms -> IO CClock
 
 getCpuTimePrecision :: IO Integer
 getCpuTimePrecision =

File Added: pkgsrc/lang/ghc98/patches/patch-libraries_base_System_Environment.hs
$NetBSD: patch-libraries_base_System_Environment.hs,v 1.1 2024/04/28 05:58:58 pho Exp $

Suppress linker warnings about compatibility syscall wrappers by using
"capi" instead of "ccall".

--- libraries/base/System/Environment.hs.orig	2018-02-25 20:02:28.000000000 +0000
+++ libraries/base/System/Environment.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE Safe #-}
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE CApiFFI #-}
 
 -----------------------------------------------------------------------------
 -- |
@@ -246,7 +247,7 @@ putEnv keyvalue = do
   -- environment.
   throwErrnoIf_ (/= 0) "putenv" (c_putenv s)
 
-foreign import ccall unsafe "putenv" c_putenv :: CString -> IO CInt
+foreign import capi unsafe "stdlib.h putenv" c_putenv :: CString -> IO CInt
 #endif
 
 -- | @unsetEnv name@ removes the specified environment variable from the

File Added: pkgsrc/lang/ghc98/patches/patch-libraries_base_configure
$NetBSD: patch-libraries_base_configure,v 1.1 2024/04/28 05:58:58 pho Exp $

Ensure libiconv can be found at runtime.

XXX: I don't think this is needed because rpath flags are handled by
Cabal. LDFLAGS is not used anyway. (pho@)

--- libraries/base/configure.orig	2021-10-28 20:43:03.000000000 +0000
+++ libraries/base/configure
@@ -4209,7 +4209,7 @@ fi
 
 # Check whether --with-iconv-libraries was given.
 if test "${with_iconv_libraries+set}" = set; then :
-  withval=$with_iconv_libraries; ICONV_LIB_DIRS=$withval; LDFLAGS="-L$withval $LDFLAGS"
+  withval=$with_iconv_libraries; ICONV_LIB_DIRS=$withval; LDFLAGS="-L$withval ${COMPILER_RPATH_FLAG}$withval $LDFLAGS"
 else
   ICONV_LIB_DIRS=
 fi

File Added: pkgsrc/lang/ghc98/patches/patch-libraries_terminfo_configure.ac
$NetBSD: patch-libraries_terminfo_configure.ac,v 1.1 2024/04/28 05:58:58 pho Exp $

Don't use "==" as it's a Bash-ism:
https://github.com/judah/terminfo/commit/09fe6ebe02d439c507c0bad6e500c9212f56e8e3

--- libraries/terminfo/configure.ac.orig	2023-10-23 02:48:49.253512773 +0000
+++ libraries/terminfo/configure.ac
@@ -18,7 +18,7 @@ if test "x$curses_libraries" != "xNONE";
   TERMINFO_LIB_DIRS=$curses_libraries
 fi
 
-if test "x$curses_library" == "xNONE"; then
+if test "x$curses_library" = "xNONE"; then
 AC_PROG_CC()
 
 AC_CHECK_LIB(tinfow, setupterm, HaveLibCurses=YES; LibCurses=tinfow,

File Added: pkgsrc/lang/ghc98/patches/patch-libraries_time_lib_Data_Time_Clock_Internal_CTimespec.hsc
$NetBSD: patch-libraries_time_lib_Data_Time_Clock_Internal_CTimespec.hsc,v 1.1 2024/04/28 05:58:58 pho Exp $

Suppress linker warnings about compatibility symbols.

--- libraries/time/lib/Data/Time/Clock/Internal/CTimespec.hsc.orig	2020-01-04 02:21:30.506303962 +0000
+++ libraries/time/lib/Data/Time/Clock/Internal/CTimespec.hsc
@@ -1,3 +1,4 @@
+{-# LANGUAGE CApiFFI #-}
 module Data.Time.Clock.Internal.CTimespec where
 
 #include "HsTimeConfig.h"
@@ -29,9 +30,9 @@ instance Storable CTimespec where
         #{poke struct timespec, tv_sec } p s
         #{poke struct timespec, tv_nsec} p ns
 
-foreign import ccall unsafe "time.h clock_gettime"
+foreign import capi unsafe "time.h clock_gettime"
     clock_gettime :: ClockID -> Ptr CTimespec -> IO CInt
-foreign import ccall unsafe "time.h clock_getres"
+foreign import capi unsafe "time.h clock_getres"
     clock_getres :: ClockID -> Ptr CTimespec -> IO CInt
 
 -- | Get the resolution of the given clock.

File Added: pkgsrc/lang/ghc98/patches/patch-libraries_time_lib_Data_Time_Clock_Internal_CTimeval.hs
$NetBSD: patch-libraries_time_lib_Data_Time_Clock_Internal_CTimeval.hs,v 1.1 2024/04/28 05:58:58 pho Exp $

Suppress linker warnings about compatibility syscall wrappers by using
"capi" instead of "ccall". In Haskell FFI, "ccall" is actually an
interface to C ABI rather than C API. That is, GHC generates direct
references to the symbol even if it's actually defined as a cpp macro
or something like that, because GHC knows nothing about those macros
in foreign headers. Hence the following warnings:

  .../libHStime-1.4.0.1.a(CTimeval.o): In function `s1Kp_info':
  (.text+0x2f): warning: warning: reference to compatibility
  gettimeofday(); include <sys/time.h> to generate correct reference

In other words, you can safely use "ccall" only when you are sure the
symbol you want to import is actually a symbol in the ABI sense, which
is not always the case for the POSIX API.

--- libraries/time/lib/Data/Time/Clock/Internal/CTimeval.hs.orig	2021-10-28 20:42:10.000000000 +0000
+++ libraries/time/lib/Data/Time/Clock/Internal/CTimeval.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CApiFFI #-}
 {-# LANGUAGE Safe #-}
 
 module Data.Time.Clock.Internal.CTimeval where
@@ -21,7 +22,7 @@ instance Storable CTimeval where
         pokeElemOff (castPtr p) 0 s
         pokeElemOff (castPtr p) 1 mus
 
-foreign import ccall unsafe "time.h gettimeofday" gettimeofday :: Ptr CTimeval -> Ptr () -> IO CInt
+foreign import capi unsafe "sys/time.h gettimeofday" gettimeofday :: Ptr CTimeval -> Ptr () -> IO CInt
 
 -- | Get the current POSIX time from the system clock.
 getCTimeval :: IO CTimeval

File Added: pkgsrc/lang/ghc98/patches/patch-libraries_unix_System_Posix_Env.hsc
$NetBSD: patch-libraries_unix_System_Posix_Env.hsc,v 1.1 2024/04/28 05:58:58 pho Exp $

Suppress linker warnings about compatibility symbols by using "capi"
instead of "ccall".

--- libraries/unix/System/Posix/Env.hsc.orig	2023-09-21 11:31:41.000000000 +0000
+++ libraries/unix/System/Posix/Env.hsc
@@ -141,7 +141,7 @@ putEnv keyvalue = do s <- newFilePath ke
                      -- becomes part of the environment. #7342
                      throwErrnoIfMinus1_ "putenv" (c_putenv s)
 
-foreign import ccall unsafe "putenv"
+foreign import capi unsafe "stdlib.h putenv"
    c_putenv :: CString -> IO CInt
 
 {- |The 'setEnv' function inserts or resets the environment variable name in

File Added: pkgsrc/lang/ghc98/patches/patch-libraries_unix_System_Posix_Env_ByteString.hsc
$NetBSD: patch-libraries_unix_System_Posix_Env_ByteString.hsc,v 1.1 2024/04/28 05:58:58 pho Exp $

Suppress linker warnings about compatibility symbols by using "capi"
instead of "ccall".

--- libraries/unix/System/Posix/Env/ByteString.hsc.orig	2022-12-23 16:19:54.000000000 +0000
+++ libraries/unix/System/Posix/Env/ByteString.hsc
@@ -153,7 +153,7 @@ putEnv (PS fp o l) = withForeignPtr fp $
   pokeByteOff buf l (0::Word8)
   throwErrnoIfMinus1_ "putenv" (c_putenv (castPtr buf))
 
-foreign import ccall unsafe "putenv"
+foreign import capi unsafe "HsUnix.h putenv"
    c_putenv :: CString -> IO CInt
 
 {- |The 'setEnv' function inserts or resets the environment variable name in

File Added: pkgsrc/lang/ghc98/patches/patch-libraries_unix_System_Posix_Env_PosixString.hsc
$NetBSD: patch-libraries_unix_System_Posix_Env_PosixString.hsc,v 1.1 2024/04/28 05:58:58 pho Exp $

Suppress linker warnings about compatibility symbols by using "capi"
instead of "ccall".

--- libraries/unix/System/Posix/Env/PosixString.hsc.orig	2023-10-23 10:24:23.010158238 +0000
+++ libraries/unix/System/Posix/Env/PosixString.hsc
@@ -146,7 +146,7 @@ putEnv (PS sbs) = do
  where l = B.length sbs
 
 
-foreign import ccall unsafe "putenv"
+foreign import capi unsafe "HsUnix.h putenv"
    c_putenv :: CString -> IO CInt
 
 {- |The 'setEnv' function inserts or resets the environment variable name in

File Added: pkgsrc/lang/ghc98/patches/patch-libraries_unix_System_Posix_Signals.hsc
$NetBSD: patch-libraries_unix_System_Posix_Signals.hsc,v 1.1 2024/04/28 05:58:58 pho Exp $

Suppress linker warnings about compatibility symbols.

--- libraries/unix/System/Posix/Signals.hsc.orig	2023-09-21 11:31:41.000000000 +0000
+++ libraries/unix/System/Posix/Signals.hsc
@@ -848,7 +848,7 @@ awaitSignal maybe_sigset = do
 
 #if defined(HAVE_SIGNAL_H)
 
-foreign import ccall unsafe "sigsuspend"
+foreign import capi unsafe "signal.h sigsuspend"
   c_sigsuspend :: Ptr CSigset -> IO CInt
 
 foreign import capi unsafe "signal.h sigdelset"
@@ -860,7 +860,7 @@ foreign import capi unsafe "signal.h sig
 foreign import capi unsafe "signal.h sigismember"
   c_sigismember :: Ptr CSigset -> CInt -> IO CInt
 
-foreign import ccall unsafe "sigpending"
+foreign import capi unsafe "signal.h sigpending"
   c_sigpending :: Ptr CSigset -> IO CInt
 
 #endif // HAVE_SIGNAL_H

File Added: pkgsrc/lang/ghc98/patches/patch-libraries_unix_System_Posix_User.hsc
$NetBSD: patch-libraries_unix_System_Posix_User.hsc,v 1.1 2024/04/28 05:58:58 pho Exp $

Suppress linker warnings about compatibility symbols by using "capi"
instead of "ccall".

--- libraries/unix/System/Posix/User.hsc.orig	2023-10-23 10:26:54.941601450 +0000
+++ libraries/unix/System/Posix/User.hsc
@@ -605,9 +605,9 @@ getAllUserEntries = lockpw GETALL $ brac
             else do thisentry <- unpackUserEntry ppw
                     worker (thisentry : accum)
 
-foreign import ccall safe "getpwent" c_getpwent :: IO (Ptr CPasswd)
-foreign import ccall safe "setpwent" c_setpwent :: IO ()
-foreign import ccall safe "endpwent" c_endpwent :: IO ()
+foreign import capi safe "HsUnix.h getpwent" c_getpwent :: IO (Ptr CPasswd)
+foreign import capi safe "HsUnix.h setpwent" c_setpwent :: IO ()
+foreign import capi safe "HsUnix.h endpwent" c_endpwent :: IO ()
 #else
 {-# WARNING getAllUserEntries "System.Posix.User.getAllUserEntries: not supported" #-}
 getAllUserEntries = error "System.Posix.User.getAllUserEntries: not supported"

File Added: pkgsrc/lang/ghc98/patches/patch-libraries_unix_System_Posix_User_ByteString.hsc
$NetBSD: patch-libraries_unix_System_Posix_User_ByteString.hsc,v 1.1 2024/04/28 05:58:58 pho Exp $

Suppress linker warnings about compatibility symbols by using "capi"
instead of "ccall".

--- libraries/unix/System/Posix/User/ByteString.hsc.orig	2023-10-24 03:45:34.747217813 +0000
+++ libraries/unix/System/Posix/User/ByteString.hsc
@@ -522,9 +522,9 @@ getAllUserEntries = lockpw GETALL $ brac
             else do thisentry <- unpackUserEntry ppw
                     worker (thisentry : accum)
 
-foreign import ccall safe "getpwent" c_getpwent :: IO (Ptr CPasswd)
-foreign import ccall safe "setpwent" c_setpwent :: IO ()
-foreign import ccall safe "endpwent" c_endpwent :: IO ()
+foreign import capi safe "HsUnix.h getpwent" c_getpwent :: IO (Ptr CPasswd)
+foreign import capi safe "HsUnix.h setpwent" c_setpwent :: IO ()
+foreign import capi safe "HsUnix.h endpwent" c_endpwent :: IO ()
 #else
 {-# WARNING getAllUserEntries "System.Posix.User.getAllUserEntries: not supported" #-}
 getAllUserEntries = error "System.Posix.User.getAllUserEntries: not supported"

File Added: pkgsrc/lang/ghc98/patches/patch-m4_fptools__set__haskell__platform__vars.m4
$NetBSD: patch-m4_fptools__set__haskell__platform__vars.m4,v 1.1 2024/04/28 05:58:58 pho Exp $

Pretend the toolchain doesn't support .note.GNU-stack on NetBSD. This is a
temporary workaround and shouldn't live forever. See:
https://mail-index.netbsd.org/tech-toolchain/2023/01/15/msg004188.html

--- m4/fptools_set_haskell_platform_vars.m4.orig	2023-01-15 14:19:38.638967614 +0000
+++ m4/fptools_set_haskell_platform_vars.m4
@@ -180,6 +180,11 @@ AC_DEFUN([GHC_IDENT_DIRECTIVE],
 # so we empty CFLAGS while running this test
 AC_DEFUN([GHC_GNU_NONEXEC_STACK],
 [
+    case $TargetOS in
+      netbsd)
+        TargetHasGnuNonexecStack=NO;;
+      *)
+
     CFLAGS2="$CFLAGS"
     CFLAGS=
     case $TargetArch in
@@ -206,6 +211,8 @@ AC_DEFUN([GHC_GNU_NONEXEC_STACK],
         [AC_MSG_RESULT(no)
          TargetHasGnuNonexecStack=NO])
     CFLAGS="$CFLAGS2"
+
+    esac
 ])
 
 # FPTOOLS_SET_HASKELL_PLATFORM_VARS

File Added: pkgsrc/lang/ghc98/patches/patch-utils_haddock_driver_Main.hs
$NetBSD: patch-utils_haddock_driver_Main.hs,v 1.1 2024/04/28 05:58:58 pho Exp $

Workaround for haddock dying when the locale isn't "*.UTF-8". Of course
this isn't a real fix. Haddock is very fragile when it comes to locale
setting, and fixing it properly would be seriously a lot of work.

--- utils/haddock/driver/Main.hs.orig	2020-07-28 17:05:24.000000000 +0000
+++ utils/haddock/driver/Main.hs
@@ -1,7 +1,9 @@
 module Main where
 
 import Documentation.Haddock (haddock)
+import GHC.IO.Encoding (setLocaleEncoding, utf8)
 import GHC.ResponseFile (getArgsWithResponseFiles)
 
 main :: IO ()
-main = getArgsWithResponseFiles >>= haddock
+main = do setLocaleEncoding utf8
+          getArgsWithResponseFiles >>= haddock

File Added: pkgsrc/lang/ghc98/patches/patch-utils_haddock_haddock.cabal
$NetBSD: patch-utils_haddock_haddock.cabal,v 1.1 2024/04/28 05:58:58 pho Exp $

Don't assume we always build the threaded RTS.

Pull request:
https://github.com/haskell/haddock/pull/1575

--- utils/haddock/haddock.cabal.orig	2023-01-11 07:37:47.265320221 +0000
+++ utils/haddock/haddock.cabal
@@ -59,12 +59,16 @@ flag in-ghc-tree
   description: Are we in a GHC tree?
   default: False
   manual: True
+flag threaded
+  default: False
 
 executable haddock
   default-language:     Haskell2010
   main-is:              Main.hs
   hs-source-dirs:       driver
-  ghc-options:          -funbox-strict-fields -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -O2 -threaded
+  ghc-options:          -funbox-strict-fields -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -O2
+  if flag(threaded)
+    ghc-options: -threaded
 
   -- haddock typically only supports a single GHC major version
   build-depends: