public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Fabian Groffen" <grobian@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] repo/proj/prefix:master commit in: sys-devel/binutils-config/files/, sys-devel/binutils-config/
Date: Sun, 14 Feb 2016 14:56:08 +0000 (UTC)	[thread overview]
Message-ID: <1455457731.72ebd34b9821ad0b04bc98b7decf07c9588c7191.grobian@gentoo> (raw)

commit:     72ebd34b9821ad0b04bc98b7decf07c9588c7191
Author:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Sun Feb 14 13:48:51 2016 +0000
Commit:     Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Sun Feb 14 13:48:51 2016 +0000
URL:        https://gitweb.gentoo.org/repo/proj/prefix.git/commit/?id=72ebd34b

sys-devel/binutils-config: first version of rewritten ldwrapper, bug #572390

Package-Manager: portage-2.2.20-prefix

 .../binutils-config/binutils-config-5-r2.ebuild    |  40 ++--
 .../files/binutils-config-5-ldwrapper.patch        |  22 ++
 sys-devel/binutils-config/files/ldwrapper.c        | 252 +++++++++++++++++++++
 3 files changed, 297 insertions(+), 17 deletions(-)

diff --git a/sys-devel/binutils-config/binutils-config-5-r2.ebuild b/sys-devel/binutils-config/binutils-config-5-r2.ebuild
index 3af562d..60c601e 100644
--- a/sys-devel/binutils-config/binutils-config-5-r2.ebuild
+++ b/sys-devel/binutils-config/binutils-config-5-r2.ebuild
@@ -8,49 +8,55 @@ inherit eutils prefix
 
 DESCRIPTION="Utility to change the binutils version being used"
 HOMEPAGE="https://www.gentoo.org/"
-W_VER="0.3.1723"
-SRC_URI="http://dev.gentoo.org/~grobian/distfiles/toolchain-prefix-wrapper-${W_VER}.tar.xz"
 
 LICENSE="GPL-2"
 SLOT="0"
 KEYWORDS="~ppc-aix ~x64-freebsd ~x86-freebsd ~hppa-hpux ~ia64-hpux ~x86-interix ~amd64-linux ~ia64-linux ~x86-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-macos ~m68k-mint ~sparc-solaris ~sparc64-solaris ~x64-solaris ~x86-solaris"
-IUSE="sunld"
 
 # We also RDEPEND on sys-apps/findutils which is in base @system
 RDEPEND="sys-apps/gentoo-functions
 	!<app-admin/eselect-1.4.5"
 
-S=${WORKDIR}/toolchain-prefix-wrapper-${W_VER}
+S=${WORKDIR}
 
 # NOTE: the ld wrapper is only enabled on rpath versions of prefix.
 src_prepare() {
 	cp "${FILESDIR}"/${PN}-${PV} ./${PN} || die
 	if use prefix-guest; then
-		epatch "${FILESDIR}/${PN}-4-ldwrapper.patch"
+		epatch "${FILESDIR}/${PN}-5-ldwrapper.patch"
 	fi
 	eprefixify ${PN}
 
-	# fix configure stupidity, until next release
-	sed -i -e 's/x10\.\[3456789\]/x10.*/' configure
-	epatch "${FILESDIR}"/${PN}-4-no-macosx-version-min.patch
-	epatch "${FILESDIR}"/${PN}-4-aix-ld-svr4.patch
+	cp "${FILESDIR}"/ldwrapper.c . || die
 }
 
 src_configure() {
-	if use prefix-guest; then
-		econf --with-macosx-version-min=${MACOSX_DEPLOYMENT_TARGET} \
-			$(use_with sunld native-ld)
-	fi
+	:
 }
 
-src_install() {
-	if use prefix-guest; then
-		emake install DESTDIR="${D}"
-	fi
+src_compile() {
+	use prefix-guest || return
+	local args=(
+		$(tc-getCC)
+		${CPPFLAGS}
+		${CFLAGS}
+		-o ldwrapper ldwrapper.c
+		-DEPREFIX=\"${EPREFIX}\"
+		-DCHOST=\"${CHOST}\"
+		$([[ ${CHOST} == *-darwin* ]] && echo -DTARGET_DARWIN)
+		${LDFLAGS}
+	)
+	echo ${args[*]}
+	"${args[@]}" || die
+}
 
+src_install() {
 	newbin "${S}"/${PN} ${PN}
 	doman "${FILESDIR}"/${PN}.8
 
+	dodir /usr/$(get_libdir)/misc/binutils-config
+	mv "${S}"/ldwrapper "${ED}"/usr/$(get_libdir)/misc/binutils-config/
+
 	insinto /usr/share/eselect/modules
 	doins "${FILESDIR}"/binutils.eselect
 }

diff --git a/sys-devel/binutils-config/files/binutils-config-5-ldwrapper.patch b/sys-devel/binutils-config/files/binutils-config-5-ldwrapper.patch
new file mode 100644
index 0000000..f184c20
--- /dev/null
+++ b/sys-devel/binutils-config/files/binutils-config-5-ldwrapper.patch
@@ -0,0 +1,22 @@
+diff --git a/binutils-config b/binutils-config
+index 7454527..570a6b0 100755
+--- a/binutils-config
++++ b/binutils-config
+@@ -121,7 +121,16 @@ switch_profile() {
+ 	cd "${ROOT}/${BINPATH}" || exit 1
+ 	mkdir -p "${ROOT}/${BINPATH_LINKS}" "${EROOT}/usr/bin"
+ 	for x in * ; do
+-		atomic_ln "${BINPATH}/${x}" "${ROOT}/${BINPATH_LINKS}" "${x}"
++		case ${x} in
++			ld*)
++				# put ldwrapper in place
++				atomic_ln "${EROOT}/usr/lib/misc/binutils-config/ldwrapper" "${ROOT}/${BINPATH_LINKS}" "${x}"
++			;;
++			*)
++				atomic_ln "${BINPATH}/${x}" "${ROOT}/${BINPATH_LINKS}" "${x}"
++			;;
++		esac
++		
+ 		atomic_ln "${BINPATH_LINKS}/${x}" "${EROOT}/usr/bin" "${TARGET}-${x}"
+ 		if [[ ${TARGET} == ${HOST} ]] ; then
+ 			atomic_ln "${TARGET}-${x}" "${EROOT}/usr/bin" "${x}"

diff --git a/sys-devel/binutils-config/files/ldwrapper.c b/sys-devel/binutils-config/files/ldwrapper.c
new file mode 100644
index 0000000..355840f
--- /dev/null
+++ b/sys-devel/binutils-config/files/ldwrapper.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright 1999-2013 Gentoo Foundation
+ * Distributed under the terms of the GNU General Public License v2
+ * Authors: Fabian Groffen <grobian@gentoo.org>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <strings.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+/**
+ * ldwrapper: Prefix helper to inject -L and -R flags to the invocation
+ * of ld.
+ *
+ * On Darwin it adds -search_path_first to make sure the given paths are
+ * searched before the default search path.
+ * The wrapper will inject -L entries for:
+ *   - EPREFIX/usr/CHOST/lib/gcc (when gcc)
+ *   - EPREFIX/usr/CHOST/lib     (when binutils)
+ *   - EPREFIX/usr/lib
+ *   - EPREFIX/lib 
+ * On ELF platforms, the wrapper will then add -R (-rpath) entries for
+ * all -L entries found in the invocation to ensure the libraries found
+ * at link time will be found at runtime too.
+ */
+
+#ifndef EPREFIX
+# error EPREFIX must be defined!
+#endif
+#ifndef CHOST
+# error CHOST must be defined!
+#endif
+
+
+static inline void
+find_real_ld(char **ld, char verbose, char *wrapper)
+{
+	FILE *f = NULL;
+	char *ldoveride;
+	char *path;
+#define ESIZ 1024
+	char *e;
+	struct stat lde;
+
+	/* respect the override in environment */
+	ldoveride = getenv("BINUTILS_CONFIG_LD");
+	if (ldoveride != NULL && *ldoveride != '\0') {
+		if (verbose)
+			fprintf(stdout, "%s: using BINUTILS_CONFIG_LD=%s "
+					"from environment\n", wrapper, ldoveride);
+		*ld = ldoveride;
+		return;
+	}
+	if (verbose)
+		fprintf(stdout, "%s: BINUTILS_CONFIG_LD not found in environment\n",
+				wrapper);
+	
+	if ((e = malloc(sizeof(char) * ESIZ)) == NULL) {
+		fprintf(stderr, "%s: out of memory allocating string for path to ld\n",
+				wrapper);
+		exit(1);
+	}
+
+	/* find ld in PATH, allowing easy PATH overrides */
+	path = getenv("PATH");
+	if (path != NULL && *path != '\0') {
+		char *p;
+		char *q;
+
+		for (p = path; (q = strchr(p, ':')) != NULL; p = q + 1) {
+			if (q)
+				*q = '\0';
+			if (strstr(p, "/" CHOST "/binutils-bin/") != NULL) {
+				snprintf(e, ESIZ, "%s/%s", p, wrapper);
+				if (stat(e, &lde) == 0) {
+					*ld = e;
+					return;
+				}
+			}
+			if (!q)
+				break;
+		}
+	}
+	if (verbose)
+		fprintf(stdout, "%s: linker not found in PATH\n", wrapper);
+
+	/* parse EPREFIX/etc/env.d/binutils/config-CHOST to get CURRENT, then
+	 * consider $EPREFIX/usr/CHOST/binutils-bin/CURRENT where we should
+	 * be able to find ld */
+	if ((f = fopen(EPREFIX "/etc/env.d/binutils/config-" CHOST, "r")) != NULL) {
+		char p[ESIZ];
+		while (fgets(p, ESIZ, f) != NULL) {
+			if (strncmp(p, "CURRENT=", strlen("CURRENT=")) == 0) {
+				char *q = p + strlen(p);
+				/* strip trailing whitespace (fgets at least includes
+				 * the \n) */
+				for (q--; isspace(*q); q--)
+					*q = '\0';
+					;
+				snprintf(e, ESIZ, EPREFIX "/usr/" CHOST "/binutils-bin/%s/%s",
+						p + strlen("CURRENT="), wrapper);
+				break;
+			}
+		}
+		fclose(f);
+		if (stat(e, &lde) == 0) {
+			*ld = e;
+			return;
+		}
+	}
+	if (verbose)
+		fprintf(stdout, "%s: linker not found via " EPREFIX
+				"/etc/env.d/binutils/config-" CHOST "\n", wrapper);
+	
+	/* last try, call binutils-config to tell us what the linker is
+	 * supposed to be */
+	if ((f = popen("binutils-config -c", "r")) != NULL) {
+		char p[ESIZ];
+		if (fgets(p, ESIZ, f) != NULL) {
+			snprintf(e, ESIZ, EPREFIX "/usr/" CHOST "/binutils-bin/%s/%s",
+					p, wrapper);
+		} else {
+			*p = '\0';
+		}
+		fclose(f);
+		if (*p && stat(e, &lde) == 0) {
+			*ld = e;
+			return;
+		}
+	}
+	if (verbose)
+		fprintf(stdout, "%s: linker not found via binutils-config -c\n",
+				wrapper);
+
+	/* we didn't succeed finding the linker */
+	*ld = NULL;
+}
+
+int
+main(int argc, char *argv[])
+{
+	char *ld = NULL;
+	int newargc = 0;
+	char **newargv = NULL;
+	char *wrapper = argc > 0 ? argv[0] : "ld-wrapper";
+	char verbose = getenv("BINUTILS_CONFIG_VERBOSE") != NULL;
+	char *p;
+	int i;
+	int j;
+
+	/* cannonicanise wrapper, stripping path and CHOST */
+	if ((p = strrchr(wrapper, '/')) != NULL) {
+		wrapper = p + 1;
+		p = CHOST "-";
+		if (strncmp(wrapper, p, strlen(p)) == 0)
+			wrapper += strlen(p);
+	}
+
+	/* walk over the arguments to see if there's anything interesting
+	 * for us and calculate the final number of arguments */
+	for (i = 1; i < argc; i++) {
+		/* -L: account space for the matching -R */
+		if (argv[i][0] == '-') {
+			if (argv[i][1] == 'L')
+				newargc++;
+			if (argv[i][1] == 'v' || argv[i][1] == 'V')
+				verbose = 1;
+		}
+	}
+	/* account the original arguments */
+	newargc += argc > 0 ? argc : 1;
+#ifdef TARGET_DARWIN
+	/* add the 2 prefix paths (-L), -search_paths_first and a
+	 * null-terminator */
+	newargc += 2 + 1 + 1;
+#else
+	/* add the 4 paths we want (-L + -R) and a null-terminator */
+	newargc += 8 + 1;
+#endif
+
+	/* let's first try to find the real ld */
+	find_real_ld(&ld, verbose, wrapper);
+	if (ld == NULL) {
+		fprintf(stderr, "%s: failed to locate the real ld!\n", wrapper);
+		exit(1);
+	}
+
+	newargv = malloc(sizeof(char *) * newargc);
+	if (newargv == NULL) {
+		fprintf(stderr, "%s: failed to allocate memory for new arguments\n",
+				wrapper);
+		exit(1);
+	}
+
+	/* construct the new argv */
+	j = 0;
+	if ((p = strrchr(ld, '/')) != NULL) {
+		newargv[j++] = p + 1;
+	} else {
+		newargv[j++] = ld;
+	}
+#ifdef TARGET_DARWIN
+	/* inject this first to make the intention clear */
+	newargv[j++] = "-search_paths_first";
+#endif
+	for (i = 1; i < argc; i++, j++) {
+		newargv[j] = argv[i];
+#ifndef TARGET_DARWIN
+		/* on ELF targets we add runpaths for all found search paths */
+		if (argv[i][0] == '-' && argv[i][1] == 'L') {
+			newargv[++j] = strdup(argv[i]);
+			if (newargv[j] == NULL) {
+				fprintf(stderr, "%s: failed to allocate memory for "
+						"'%s' -R argument\n", wrapper, argv[i]);
+				exit(1);
+			}
+			newargv[j][1] = 'R';
+		}
+#endif
+	}
+	/* add the custom paths */
+#ifdef TARGET_DARWIN
+	newargv[j++] = "-L" EPREFIX "/usr/lib";
+	newargv[j++] = "-L" EPREFIX "/lib";
+#else
+	newargv[j++] = "-L" EPREFIX "/usr/" CHOST "/lib/gcc";
+	newargv[j++] = "-R" EPREFIX "/usr/" CHOST "/lib/gcc";
+	newargv[j++] = "-L" EPREFIX "/usr/" CHOST "/lib";
+	newargv[j++] = "-R" EPREFIX "/usr/" CHOST "/lib";
+	newargv[j++] = "-L" EPREFIX "/usr/lib";
+	newargv[j++] = "-R" EPREFIX "/usr/lib";
+	newargv[j++] = "-L" EPREFIX "/lib";
+	newargv[j++] = "-R" EPREFIX "/lib";
+#endif
+	newargv[j] = NULL;
+
+	if (verbose) {
+		fprintf(stdout, "%s: invoking %s with arguments:\n", wrapper, ld);
+		for (j = 0; newargv[j] != NULL; j++)
+			fprintf(stdout, "  %s\n", newargv[j]);
+	}
+
+	/* finally, execute the real ld */
+	execv(ld, newargv);
+	fprintf(stderr, "%s: failed to execute %s: %s\n",
+			wrapper, ld, strerror(errno));
+	exit(1);
+}


             reply	other threads:[~2016-02-14 14:56 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-14 14:56 Fabian Groffen [this message]
  -- strict thread matches above, loose matches on Subject: below --
2017-11-25 18:33 [gentoo-commits] repo/proj/prefix:master commit in: sys-devel/binutils-config/files/, sys-devel/binutils-config/ Fabian Groffen
2018-04-07 19:43 Fabian Groffen
2019-10-13 18:12 Fabian Groffen
2020-11-27 13:39 Fabian Groffen
2020-12-22 21:30 Fabian Groffen
2024-01-21  9:46 Fabian Groffen
2024-04-06 14:36 Fabian Groffen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1455457731.72ebd34b9821ad0b04bc98b7decf07c9588c7191.grobian@gentoo \
    --to=grobian@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox