[Buildroot] Using external toolchain wrapper outside of buildroot

Greg Beresford greg.beresford at zbdsolutions.com
Fri Feb 15 11:22:00 UTC 2013


Hi all,

It looks like making the external toolchain wrapper relocatable may have broken it for use outside of buildroot. If you add the wrapper directory to your path and invoke the wrapper as arm-linux-gcc (for example), execution will enter the 'else' on line 76 of ext-toolchain-wrapper.c. This sets basename to arm-linux-gcc, which is fine, but it also sets absbasedir to whatever $(pwd)/../.. resolves to which then gets used when calculating the sysroot directory, resulting in gcc not having the real sysroot in its search paths.

The above all works fine if the wrapper is invoked with an absolute path. (I've not tried with a relative path with slashes in.)

I've attached a patch with a fix below which calculates absbasedir from /proc/self/exe. (I don't know of any other way of reliably getting the path to the current executable.) My C is rusty though, so it might need to be fixed up before it's applied. (Was there a reason for avoiding the basename and dirname functions from libgen.h?)

Cheers
Greg

zbd
d +44 (0) 1344 292 123  t +44 (0)1344 292 110
w  www.zbdsolutions.com
ZBD Displays Ltd | Building 3 | Kingswood | Kings Ride | Ascot | Berkshire | SL5 8AD | UK

>From 9f0a2566bc15e2f7115dce58db9dec84d98b844b Mon Sep 17 00:00:00 2001
From: Greg Beresford <greg.beresford at zbdsolutions.com>
Date: Thu, 14 Feb 2013 18:25:43 +0000
Subject: [PATCH] Fix toolchain wrapper when used outside of buildroot

---
 .../toolchain-external/ext-toolchain-wrapper.c     | 50 ++++++++++++++--------
 1 file changed, 32 insertions(+), 18 deletions(-)

diff --git a/toolchain/toolchain-external/ext-toolchain-wrapper.c b/toolchain/toolchain-external/ext-toolchain-wrapper.c
index a92bada..f570554 100644
--- a/toolchain/toolchain-external/ext-toolchain-wrapper.c
+++ b/toolchain/toolchain-external/ext-toolchain-wrapper.c
@@ -19,6 +19,7 @@
 #include <limits.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <libgen.h>

 static char path[PATH_MAX];
 static char sysroot[PATH_MAX];
@@ -56,26 +57,37 @@ int main(int argc, char **argv)
 {
        char **args, **cur;
        char *relbasedir, *absbasedir;
-       char *progpath = argv[0];
-       char *basename;
+       char exepath[PATH_MAX + 1] = {0};
+       char *dupbase, *base, *dir;
        int ret;
+       ssize_t ret_size;
+
+       ret_size = readlink("/proc/self/exe", exepath, sizeof(exepath) - 1);
+       if (ret_size < 0)
+       {
+               perror(__FILE__ ": readlink");
+               return 2;
+       }
+       else if (ret_size >= sizeof(exepath))
+       {
+               perror(__FILE__ ": readlink return value out of bounds");
+               return 2;
+       }
+       exepath[ret_size] = '\0';

        /* Calculate the relative paths */
-       basename = strrchr(progpath, '/');
-       if (basename) {
-               *basename = '\0';
-               basename++;
-               relbasedir = malloc(strlen(progpath) + 7);
-               if (relbasedir == NULL) {
-                       perror(__FILE__ ": malloc");
-                       return 2;
-               }
-               sprintf(relbasedir, "%s/../..", argv[0]);
-               absbasedir = realpath(relbasedir, NULL);
-       } else {
-               basename = progpath;
-               absbasedir = realpath("../..", NULL);
+       dupbase = strdup(argv[0]);
+       base = basename(dupbase);
+       dir = dirname(exepath);
+
+       relbasedir = malloc(strlen(dir) + 7);
+       if (relbasedir == NULL) {
+               perror(__FILE__ ": malloc");
+               return 2;
        }
+       sprintf(relbasedir, "%s/../..", dir);
+       absbasedir = realpath(relbasedir, NULL);
+
        if (absbasedir == NULL) {
                perror(__FILE__ ": realpath");
                return 2;
@@ -83,10 +95,12 @@ int main(int argc, char **argv)

        /* Fill in the relative paths */
 #ifdef BR_CROSS_PATH_REL
-       ret = snprintf(path, sizeof(path), "%s/" BR_CROSS_PATH_REL "/%s", absbasedir, basename);
+       ret = snprintf(path, sizeof(path), "%s/" BR_CROSS_PATH_REL "/%s", absbasedir, base);
 #else /* BR_CROSS_PATH_ABS */
-       ret = snprintf(path, sizeof(path), BR_CROSS_PATH_ABS "/%s", basename);
+       ret = snprintf(path, sizeof(path), BR_CROSS_PATH_ABS "/%s", base);
 #endif
+       free(dupbase);
+
        if (ret >= sizeof(path)) {
                perror(__FILE__ ": overflow");
                return 3;
--
1.8.0



Disclaimer: This email contains proprietary information some or all of which may be legally privileged and/or is confidential. It is for the intended recipient only. If an addressing or transmission error has misdirected this email, please notify the author by replying to this email. If you are not the intended recipient, you must not use, disclose, distribute, copy or print this email. Any views expressed in this message are those of the individual sender, except where the message states otherwise. ZBD Displays accepts no responsibility for any computer virus which might be transferred by way of this email. We may monitor all email communication through our networks. If you contact us by email, we may store your name and address to facilitate communication. ZBD Displays Ltd is registered in England and Wales, company registration number: 03929602. Registered Office: Malvern Hills Science Park, Geraldine Road, Malvern,  Worcestershire, WR14 3SZ, UK

______________________________________________________________________
This email has been scanned by the Symantec Email Security.cloud service.
For more information please visit http://www.symanteccloud.com
______________________________________________________________________


More information about the buildroot mailing list