[PATCH] build.sh: Wrap host toolchain for rump builds

Damien Zammit <[email protected]>
Newsgroups gmane.os.netbsd.devel.toolchain
Message-ID <[email protected]>
This enables host tool wrappers to be built with
'-V TOOLS_BUILDRUMP=yes tools' when built on non-NetBSD.
It enables rump and rumptest targets to work and libs
to be linked without building gcc on the other system without
breaking the targets on NetBSD.

TESTED on NetBSD:

	./build.sh -V TOOLS_BUILDRUMP=yes -V MKGROFF=no \
		-u -U -T ../tooldir tools rumptest

	./build.sh -V TOOLS_BUILDRUMP=yes -V MKGROFF=no \
		-u -U -T ../tooldir tools rump

TESTED on GNU/Hurd:

HOST_CC=gcc LDADD="-L/usr/lib/i386-gnu -L/usr/lib/gcc/i686-gnu/10" \
	_GCC_CRTENDS= _GCC_CRTBEGINS= _GCC_CRTI= _GCC_CRTN= \
	CFLAGS=-Wno-error=stack-protector \
	./build.sh -V TOOLS_BUILDRUMP=yes -V MKGROFF=no \
		-U -u -T ../tools -m i386 tools rumptest

HOST_CC=gcc LDADD="-L/usr/lib/i386-gnu -L/usr/lib/gcc/i686-gnu/10" \
	_GCC_CRTENDS= _GCC_CRTBEGINS= _GCC_CRTI= _GCC_CRTN= \
	CFLAGS=-Wno-error=stack-protector \
	./build.sh -V TOOLS_BUILDRUMP=yes -V MKGROFF=no \
		-U -u -T ../tools -m i386 tools rump
---
 build.sh       | 141 +++++++++++++++++++++++++++++++++++++++++++++----
 tools/Makefile |   4 +-
 2 files changed, 134 insertions(+), 11 deletions(-)

diff --git a/build.sh b/build.sh
index be70b3bfc4e5..deabe7c801d6 100755
--- a/build.sh
+++ b/build.sh
@@ -2195,6 +2195,121 @@ installworld()
 	statusmsg "Successful installworld to ${dir}"
 }
 
+printoneconfig ()
+{
+
+	[ -z "${2}" ] || printf "%-5s %-18s: %s\n" "${1}" "${2}" "${3}"
+}
+
+WRAPPERBODY='int
+main(int argc, const char *argv[])
+{
+	int i, j, k;
+
+	for (i = 1; i < argc; i++) {
+		for (j = 0; j < sizeof(mngl_from)/sizeof(mngl_from[0]); j++) {
+			if (strcmp(argv[i], mngl_from[j]) == 0) {
+				if (strlen(mngl_to[j]) == 0) {
+					for (k = i; k < argc; k++) {
+						argv[k] = argv[k+1];
+					}
+					argv[k] = '\0';
+					argc--;
+				} else {
+					argv[i] = mngl_to[j];
+				}
+				break;
+			}
+		}
+	}
+'
+
+maketoolwrapper ()
+{
+
+	musthave=$1
+	tool=$2
+
+	if [ "${tool}" = "CC" ]; then
+		lctool=gcc
+	elif [ "${tool}" = "CXX" ]; then
+		lctool=g++
+	else
+		lctool=$(echo ${tool} | tr '[A-Z]' '[a-z]')
+	fi
+	fptool=$(command -v ${lctool})
+	if [ ! -x ${fptool} ]; then
+		if ! ${musthave}; then
+			return
+		else
+			bomb "Internal error: mandatory tool ${tool} not found"
+		fi
+	fi
+
+	eval ttool=\'\${${tool}}\'
+	tname=`${runcmd} "${makewrapper}" -V "${ttool}"`
+	printoneconfig 'Tool' "${fptool}" "${tname}"
+
+	# Mangle wrapper arguments from what NetBSD does to what the
+	# toolchain we use supports.  In case we need mangling, do it
+	# with a C wrapper to preserve all quoting etc. (couldn't
+	# figure out how to get that right with a shell.
+	rm -f ${TOOLDIR}/wrapper.c
+	exec 3>&1 1>${TOOLDIR}/wrapper.c
+	printf '#include <inttypes.h>\n'
+	printf '#include <string.h>\n'
+	printf '#include <unistd.h>\n\n'
+	printf 'static const char *mngl_from[] = {\n'
+	(
+		IFS=:
+		for xf in ${CCWRAPPER_MANGLE}; do
+			IFS=' '
+			set -- ${xf}
+			printf '\t"%s",\n' ${1}
+		done
+	)
+	printf '};\nstatic const char *mngl_to[] ={\n'
+	(
+		IFS=:
+		for xf in ${CCWRAPPER_MANGLE}; do
+			IFS=' '
+			set -- ${xf}
+			printf '\t"%s",\n' ${2:-}
+		done
+	)
+	printf '};\n\n'
+	( IFS=' ' printf '%s' "${WRAPPERBODY}" )
+	printf '\targv[0] = "%s";\n' ${fptool}
+	printf '\texecvp(argv[0], (void *)(uintptr_t)argv);\n'
+	printf '\treturn 0;\n}\n'
+	exec 1>&3 3>&-
+
+	${HOST_CC} ${TOOLDIR}/wrapper.c -o ${tname} \
+	    || bomb "failed to build wrapper for ${tool}"
+	rm -f ${TOOLDIR}/wrapper.c
+
+	chmod 755 ${tname}
+}
+
+makerumptools ()
+{
+	[ -n "${TOOLDIR}" ] || bomb "TOOLDIR not set"
+
+	# Create external toolchain wrappers.
+	mkdir -p ${TOOLDIR}/bin || bomb "cannot create ${TOOLDIR}/bin"
+	for x in CC AR NM OBJCOPY; do
+		maketoolwrapper true $x
+	done
+	for x in AS LD OBJDUMP RANLIB READELF SIZE STRINGS STRIP CXX; do
+		maketoolwrapper false $x
+	done
+
+	# create a cpp wrapper, but run it via cc -E
+	tname=`${runcmd} "${makewrapper}" -V '${CPP}'`
+	printf '#!/bin/sh\n\nexec %s -E -x c "${@}"\n' ${CC} > ${tname}
+	chmod 755 ${tname}
+}
+
 # Run rump build&link tests.
 #
 # To make this feasible for running without having to install includes and
@@ -2260,14 +2375,14 @@ dorump()
 	# one little, two little, three little backslashes ...
 	md_quirks="$(echo ${md_quirks} | sed 's,\\,\\\\,g'";s/'//g" )"
 	${runcmd} cd "${TOP}" || bomb "cd to ${TOP} failed"
-	tool_ld=`${runcmd} "${makewrapper}" -V '${LD}'`
+	tool_cc=`${runcmd} "${makewrapper}" -V '${CC}'`
 
 	local oIFS="${IFS}"
 	IFS=","
 	for set in ${RUMP_LIBSETS} ; do
 		IFS="${oIFS}"
-		${runcmd} ${tool_ld} -nostdlib -L${DESTDIR}/usr/lib	\
-		    -static --whole-archive -lpthread -lc ${set} 2>&1 -o /tmp/rumptest.$$ | \
+		${runcmd} ${tool_cc} -nostdlib -L${DESTDIR}/usr/lib 	\
+		    -static --whole-archive -lpthread -lc -lgcc ${set} 2>&1 -o /tmp/rumptest.$$ | \
 		      awk -v quirks="${md_quirks}" '
 			/undefined reference/ &&
 			    !/more undefined references.*follow/{
@@ -2485,16 +2600,24 @@ main()
 			;;
 
 		rump)
-			make_in_dir . do-distrib-dirs
-			make_in_dir . includes
-			make_in_dir lib/csu dependall
-			make_in_dir lib/csu install
-			make_in_dir external/gpl3/gcc/lib/libgcc dependall
-			make_in_dir external/gpl3/gcc/lib/libgcc install
+			if [ "${uname_s}" != "NetBSD" ] || \
+				[ "${uname_m}" != "${MACHINE}" ]; then
+				makerumptools
+			else
+				make_in_dir . includes
+				make_in_dir lib/csu dependall
+				make_in_dir lib/csu install
+				make_in_dir external/gpl3/gcc/lib/libgcc dependall
+				make_in_dir external/gpl3/gcc/lib/libgcc install
+			fi
 			dorump "${op}"
 			;;
 
 		rumptest)
+			if [ "${uname_s}" != "NetBSD" ] || \
+				[ "${uname_m}" != "${MACHINE}" ]; then
+				makerumptools
+			fi
 			dorump "${op}"
 			;;
 
diff --git a/tools/Makefile b/tools/Makefile
index 177cd1846cda..1ab0135b59f3 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -100,10 +100,10 @@ SUBDIR=	host-mkdep compat binstall date \
 .if ${TOOLS_BUILDRUMP} == "no"
 SUBDIR+= cap_mkdb crunchgen ctags gencat hexdump \
 		${LINT_BITS} \
-		makewhatis mtree nbperf .WAIT uudecode
+		makewhatis nbperf .WAIT uudecode
 .endif
 
-SUBDIR+= cat rpcgen join lorder m4 mkdep tsort .WAIT yacc .WAIT awk .WAIT lex
+SUBDIR+= mtree cat rpcgen join lorder m4 mkdep tsort .WAIT yacc .WAIT awk .WAIT lex
 .if ${TOOLS_BUILDRUMP} == "no"
 SUBDIR+= xz-include .WAIT grep xz-lib pax .WAIT libprop
 
-- 
2.25.2
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.