pkgsrc-Changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
CVS commit: pkgsrc/lang/ghc98
Module Name: pkgsrc
Committed By: pho
Date: Wed Jan 8 10:17:27 UTC 2025
Modified Files:
pkgsrc/lang/ghc98: Makefile bootstrap.mk buildlink3.mk
Added Files:
pkgsrc/lang/ghc98/files: iconv-bridge.c inject-iconv-bridge.awk
Log Message:
lang/ghc98: A better workaround for the native vs. GNU iconv mixture problem
Instead of disallowing the existence of pkgsrc libiconv, we can have a
bridge between two implementations and use it during the build of the
stage-1 compiler. This way bootkits built with native iconv can co-exist
with GNU libiconv in ${BUILDLINK_DIR}/lib.
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 pkgsrc/lang/ghc98/Makefile
cvs rdiff -u -r1.5 -r1.6 pkgsrc/lang/ghc98/bootstrap.mk
cvs rdiff -u -r1.3 -r1.4 pkgsrc/lang/ghc98/buildlink3.mk
cvs rdiff -u -r0 -r1.1 pkgsrc/lang/ghc98/files/iconv-bridge.c \
pkgsrc/lang/ghc98/files/inject-iconv-bridge.awk
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: pkgsrc/lang/ghc98/Makefile
diff -u pkgsrc/lang/ghc98/Makefile:1.6 pkgsrc/lang/ghc98/Makefile:1.7
--- pkgsrc/lang/ghc98/Makefile:1.6 Tue Jul 30 11:38:42 2024
+++ pkgsrc/lang/ghc98/Makefile Wed Jan 8 10:17:27 2025
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.6 2024/07/30 11:38:42 wiz Exp $
+# $NetBSD: Makefile,v 1.7 2025/01/08 10:17:27 pho Exp $
# -----------------------------------------------------------------------------
# Package metadata
#
@@ -33,14 +33,6 @@ PKGSRC_OVERRIDE_MKPIE= yes
.include "options.mk"
-# The bootstrap kits are built with native iconv, and unfortunately ghc looks
-# in places it should not, so we have to do everything we can to avoid libiconv
-# being installed as it breaks the build due to iconv_*() vs libiconv_*().
-#
-.if ${OPSYS} == "Darwin"
-PREFER.iconv= native
-.endif
-
# -----------------------------------------------------------------------------
# Distfiles
#
Index: pkgsrc/lang/ghc98/bootstrap.mk
diff -u pkgsrc/lang/ghc98/bootstrap.mk:1.5 pkgsrc/lang/ghc98/bootstrap.mk:1.6
--- pkgsrc/lang/ghc98/bootstrap.mk:1.5 Thu Jun 20 12:49:39 2024
+++ pkgsrc/lang/ghc98/bootstrap.mk Wed Jan 8 10:17:27 2025
@@ -1,4 +1,4 @@
-# $NetBSD: bootstrap.mk,v 1.5 2024/06/20 12:49:39 jperkin Exp $
+# $NetBSD: bootstrap.mk,v 1.6 2025/01/08 10:17:27 pho Exp $
# -----------------------------------------------------------------------------
# Select a bindist of bootstrapping compiler on a per-platform basis. See
# ./files/BOOTSTRAP.md for details.
@@ -107,18 +107,13 @@ TOOLS_PLATFORM.cpp= /usr/lib/cpp
# Install a bootstrapping (stage-0) compiler directly into TOOLS_DIR so
# that ./configure can find it.
#
-USE_TOOLS+= xzcat xz cpp patch # patch is for bootstrap.py
-
-# We must avoid gtar on Darwin because it ends up pulling in libiconv (see
-# Makefile for why that breaks things). It's possible this is no longer
-# required anyway and has just been cargo-culted around since 2019.
-#
-.if ${OPSYS} == "Darwin"
-GHC_TAR= ${TAR}
-.else
-USE_TOOLS+= gtar
-GHC_TAR= ${GTAR}
-.endif
+USE_TOOLS+= xzcat xz cpp gtar patch
+# - patch is for bootstrap.py
+# - gtar isn't strictly necessary, but we need a tar(1) implementation
+# supporting --use-compress-program (see
+# patches/patch-hadrian_src_Rules_BinaryDist.hs). Since the option isn't
+# guaranteed to be available everywhere, it's safer to explicitly pull in
+# gtar.
BOOT_ARCHIVE_TOP_DIR= ${BOOT_ARCHIVE:C/\.tar\..z$//}
pre-configure:
@@ -129,7 +124,7 @@ pre-configure:
${RUN}${MKDIR} ${WRKDIR}/bootkit-dist
${RUN}cd ${WRKDIR}/bootkit-dist && \
${XZCAT} ${DISTDIR}/${DIST_SUBDIR}/${BOOT_ARCHIVE} | \
- ${GHC_TAR} -xf -
+ ${GTAR} -xf -
@${PHASE_MSG} "Preparing bootstrapping compiler for ${PKGNAME}"
# <kludge>
@@ -148,6 +143,21 @@ pre-configure:
${PKGSRC_SETENV} ${CONFIGURE_ENV} ${SH} ./configure \
--prefix=${TOOLS_DIR:Q} ${CONFIGURE_ARGS.boot} && \
${PKGSRC_SETENV} ${MAKE_ENV} ${MAKE_PROGRAM} install
+# <kludge>
+# A workaround for possible native iconv vs. GNU libiconv mismatch between
+# bootkits and the user's choice. See comments in ./files/iconv-bridge.c
+ ${RUN}${PKGSRC_SETENV} ${ALL_ENV} \
+ ${CC} -c ${FILESDIR}/iconv-bridge.c -o ${WRKDIR}/iconv-bridge-native.o -DNATIVE; \
+ ${CC} -c ${FILESDIR}/iconv-bridge.c -o ${WRKDIR}/iconv-bridge-gnu.o; \
+ ${AR} cr ${WRKDIR}/libiconv-bridge.a \
+ ${WRKDIR}/iconv-bridge-native.o \
+ ${WRKDIR}/iconv-bridge-gnu.o; \
+ ${RANLIB} ${WRKDIR}/libiconv-bridge.a
+ ${RUN}${AWK} -v WRKDIR=${WRKDIR} -f ${FILESDIR}/inject-iconv-bridge.awk \
+ < ${TOOLS_DIR}/bin/ghc > ${TOOLS_DIR}/bin/ghc.tmp
+ ${RUN}${MV} -f ${TOOLS_DIR}/bin/ghc.tmp ${TOOLS_DIR}/bin/ghc
+ ${RUN}${CHMOD} +x ${TOOLS_DIR}/bin/ghc
+# </kludge>
# -----------------------------------------------------------------------------
Index: pkgsrc/lang/ghc98/buildlink3.mk
diff -u pkgsrc/lang/ghc98/buildlink3.mk:1.3 pkgsrc/lang/ghc98/buildlink3.mk:1.4
--- pkgsrc/lang/ghc98/buildlink3.mk:1.3 Sat Jun 22 12:16:40 2024
+++ pkgsrc/lang/ghc98/buildlink3.mk Wed Jan 8 10:17:27 2025
@@ -1,4 +1,4 @@
-# $NetBSD: buildlink3.mk,v 1.3 2024/06/22 12:16:40 jperkin Exp $
+# $NetBSD: buildlink3.mk,v 1.4 2025/01/08 10:17:27 pho Exp $
BUILDLINK_TREE+= ghc
@@ -9,13 +9,7 @@ BUILDLINK_API_DEPENDS.ghc+= ghc>=9.8.2
BUILDLINK_ABI_DEPENDS.ghc+= ghc>=9.8.2nb1
BUILDLINK_PKGSRCDIR.ghc?= ../../lang/ghc98
-.include "../../mk/bsd.fast.prefs.mk"
-
-# A regrettable hack. See Makefile for background.
-.if ${OPSYS} != "Darwin"
.include "../../converters/libiconv/buildlink3.mk"
-.endif
-
.include "../../devel/libffi/buildlink3.mk"
.include "../../devel/gmp/buildlink3.mk"
.include "../../mk/curses.buildlink3.mk"
Added files:
Index: pkgsrc/lang/ghc98/files/iconv-bridge.c
diff -u /dev/null pkgsrc/lang/ghc98/files/iconv-bridge.c:1.1
--- /dev/null Wed Jan 8 10:17:27 2025
+++ pkgsrc/lang/ghc98/files/iconv-bridge.c Wed Jan 8 10:17:27 2025
@@ -0,0 +1,96 @@
+/* $NetBSD: iconv-bridge.c,v 1.1 2025/01/08 10:17:27 pho Exp $
+ *
+ * Our bootkits are built with native iconv, which means their
+ * libHSbase-*.a have references to native iconv symbols (iconv_open,
+ * iconv, ...). However, when PREFER.iconv is set to "pkgsrc", our
+ * infrastructure pulls in GNU libiconv in ${BUILDLINK_DIR}/lib. The
+ * stage-0 compiler (from bootkit) then attempts to link its libHSbase with
+ * GNU libiconv because the "base" library has metadata that instructs the
+ * compiler to link it with "-liconv"[*1], but this fails because they
+ * don't provide the same set of symbols[*2]. The same would happen when a
+ * bootkit is built with GNU libiconv but the user prefers native iconv.
+ *
+ * As a workaround we build a library containing symbols for both of them,
+ * and inject it into the command line of the stage-0 compiler to resolve
+ * missing symbols of the opposite side[*3]. We abuse the fact that
+ * <iconv.h> headers don't really affect ABI (aside from symbols names
+ * getting renamed) because the only type they define is iconv_t, which is
+ * just a pointer type. In theory implementations might provide iconv_t of
+ * different sizes and thus introducing ABI incompatibility, but in
+ * practice all of existing implementations define it as a pointer, so
+ * calling iconv() from libiconv() should be okay as long as we don't try
+ * to use two implementations at once.
+ *
+ * Note that this problem only affects the stage-0 compiler. The final
+ * product to be installed (stage-2) uses whatever implementation the user
+ * prefers, that is, this library is only used while building stage-1 but
+ * never used nor installed after that.
+ *
+ * [*1]: Only on platforms where native iconv is in a separate library but
+ * not a part of libc. Darwin is one of such platforms, while NetBSD
+ * is not.
+ *
+ * [*2]: jperkin@ reported this happened even if GNU libiconv was *not*
+ * buildlinked. The mere existence of pkgsrc libiconv caused the same
+ * issue. This is plausible, because GHC needs to record whatever
+ * {C,CPP,LD}FLAGS used during build so that it can link user
+ * programs with external libraries from pkgsrc, such as libffi and
+ * libgmp. Though pho@ could not reproduce this exact failure mode.
+ *
+ * [*3]: -liconv-bridge must not appear before -lc, otherwise this breaks
+ * platforms where native iconv is a part of libc, because dummy
+ * definitions in the bridge gets preferred over the real ones.
+ */
+#include <sys/types.h>
+
+typedef void* iconv_t;
+
+/* Native iconv */
+iconv_t iconv_open(const char* tocode, const char* fromcode);
+int iconv_close(iconv_t cd);
+size_t iconv(iconv_t cd,
+ char** restrict src, size_t* restrict srcleft,
+ char** restrict dst, size_t* restrict dstleft);
+
+/* GNU iconv */
+iconv_t libiconv_open(const char* tocode, const char* fromcode);
+int libiconv_close(iconv_t cd);
+size_t libiconv(iconv_t cd,
+ char** restrict src, size_t* restrict srcleft,
+ char** restrict dst, size_t* restrict dstleft);
+
+/* These two variants cannot both be in the same module so we have to
+ * compile this file twice. Otherwise they will infinitely call each other
+ * and eventually segfault.
+ */
+#if NATIVE
+iconv_t iconv_open(const char* tocode, const char* fromcode) {
+ return libiconv_open(tocode, fromcode);
+}
+
+int iconv_close(iconv_t cd) {
+ return libiconv_close(cd);
+}
+
+size_t iconv(iconv_t cd,
+ char** restrict src, size_t* restrict srcleft,
+ char** restrict dst, size_t* restrict dstleft) {
+ return libiconv(cd, src, srcleft, dst, dstleft);
+}
+
+#else /* NATIVE */
+iconv_t libiconv_open(const char* tocode, const char* fromcode) {
+ return iconv_open(tocode, fromcode);
+}
+
+int libiconv_close(iconv_t cd) {
+ return iconv_close(cd);
+}
+
+size_t libiconv(iconv_t cd,
+ char** restrict src, size_t* restrict srcleft,
+ char** restrict dst, size_t* restrict dstleft) {
+ return iconv(cd, src, srcleft, dst, dstleft);
+}
+
+#endif /* NATIVE */
Index: pkgsrc/lang/ghc98/files/inject-iconv-bridge.awk
diff -u /dev/null pkgsrc/lang/ghc98/files/inject-iconv-bridge.awk:1.1
--- /dev/null Wed Jan 8 10:17:27 2025
+++ pkgsrc/lang/ghc98/files/inject-iconv-bridge.awk Wed Jan 8 10:17:27 2025
@@ -0,0 +1,22 @@
+# $NetBSD: inject-iconv-bridge.awk,v 1.1 2025/01/08 10:17:27 pho Exp $
+
+BEGIN {
+ replaced = 0;
+}
+
+/^exec / {
+ print $0 " -optl-lc -optl-L" WRKDIR " -optl-liconv-bridge";
+ replaced = 1;
+ next;
+}
+
+{
+ print $0;
+}
+
+END {
+ if (!replaced) {
+ print "[inject-iconv-bridge.awk] cannot find where to inject args" > "/dev/stderr";
+ exit 1;
+ }
+}
Home |
Main Index |
Thread Index |
Old Index