Commit befb9a3e authored by Arnout Vandecappelle's avatar Arnout Vandecappelle Committed by Peter Korsgaard
Browse files

Make external toolchain relocatable

The external toolchain wrapper sets sysroot etc. to an absolute path.
By changing this to a relative path, it is possible to move the host
directory to a different location and still have a working build
system.

This only works for a downloaded external toolchain.  For a pre-installed
external toolchain, it is possible to move the host directory to a
different location, but not the external toolchain directory (it does work
if the external toolchain directory lies within the host directory).  For
an internal or crosstool-ng toolchain, there is no wrapper so updating the
sysroot path should be done in a different way.

See http://lists.busybox.net/pipermail/buildroot/2012-February/050371.html


for information about others things to do to make the host directory
relocatable.

Signed-off-by: default avatarArnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Acked-by: default avatarSamuel Martin <s.martin49@gmail.com>
Signed-off-by: default avatarPeter Korsgaard <jacmet@sunsite.dk>
parent 1b2ab4a4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -65,7 +65,8 @@ ifeq ($(BR2_xtensa),y)
TARGET_ABI += -mlongcalls
endif

STAGING_DIR=$(HOST_DIR)/usr/$(GNU_TARGET_NAME)/sysroot
STAGING_SUBDIR = usr/$(GNU_TARGET_NAME)/sysroot
STAGING_DIR    = $(HOST_DIR)/$(STAGING_SUBDIR)

TARGET_OPTIMIZATION:=$(call qstrip,$(BR2_TARGET_OPTIMIZATION))

+12 −4
Original line number Diff line number Diff line
@@ -121,9 +121,17 @@ endif
TOOLCHAIN_EXTERNAL_CROSS=$(TOOLCHAIN_EXTERNAL_BIN)/$(TOOLCHAIN_EXTERNAL_PREFIX)-
TOOLCHAIN_EXTERNAL_CC=$(TOOLCHAIN_EXTERNAL_CROSS)gcc
TOOLCHAIN_EXTERNAL_CXX=$(TOOLCHAIN_EXTERNAL_CROSS)g++
TOOLCHAIN_EXTERNAL_WRAPPER_ARGS = \
	-DBR_CROSS_PATH='"$(TOOLCHAIN_EXTERNAL_BIN)/"' \
	-DBR_SYSROOT='"$(STAGING_DIR)"'
TOOLCHAIN_EXTERNAL_WRAPPER_ARGS = -DBR_SYSROOT='"$(STAGING_SUBDIR)"'

ifeq ($(filter $(HOST_DIR)/%,$(TOOLCHAIN_EXTERNAL_BIN)),)
# TOOLCHAIN_EXTERNAL_BIN points outside HOST_DIR => absolute path
TOOLCHAIN_EXTERNAL_WRAPPER_ARGS += \
	-DBR_CROSS_PATH_ABS='"$(TOOLCHAIN_EXTERNAL_BIN)"'
else
# TOOLCHAIN_EXTERNAL_BIN points inside HOST_DIR => relative path
TOOLCHAIN_EXTERNAL_WRAPPER_ARGS += \
	-DBR_CROSS_PATH_REL='"$(TOOLCHAIN_EXTERNAL_BIN:$(HOST_DIR)/%=%)"'
endif

CC_TARGET_TUNE_:=$(call qstrip,$(BR2_GCC_TARGET_TUNE))
CC_TARGET_CPU_:=$(call qstrip,$(BR2_GCC_TARGET_CPU))
@@ -456,7 +464,7 @@ $(HOST_DIR)/usr/bin/ext-toolchain-wrapper: $(STAMP_DIR)/ext-toolchain-installed
			ln -sf $(@F) $$base; \
			;; \
		*) \
			ln -sf $$i .; \
			ln -sf $$(echo $$i | sed 's%^$(HOST_DIR)%../..%') .; \
			;; \
		esac; \
	done ;
+47 −17
Original line number Diff line number Diff line
@@ -2,9 +2,12 @@
 * Buildroot wrapper for external toolchains. This simply executes the real
 * toolchain with a number of arguments (sysroot/arch/..) hardcoded,
 * to ensure the external toolchain uses the correct configuration.
 * The hardcoded path arguments are defined relative to the actual location
 * of the binary.
 *
 * (C) 2011 Peter Korsgaard <jacmet@sunsite.dk>
 * (C) 2011 Daniel Nyström <daniel.nystrom@timeterminal.se>
 * (C) 2012 Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
 *
 * This file is licensed under the terms of the GNU General Public License
 * version 2.  This program is licensed "as is" without any warranty of any
@@ -17,11 +20,12 @@
#include <unistd.h>
#include <stdlib.h>

static char path[PATH_MAX] = BR_CROSS_PATH;
static char path[PATH_MAX];
static char sysroot[PATH_MAX];

static char *predef_args[] = {
	path,
	"--sysroot", BR_SYSROOT,
	"--sysroot", sysroot,
#ifdef BR_ARCH
	"-march=" BR_ARCH,
#endif /* BR_ARCH */
@@ -48,22 +52,50 @@ static char *predef_args[] = {
#endif
};

static const char *get_basename(const char *name)
int main(int argc, char **argv)
{
	const char *base;

	base = strrchr(name, '/');
	if (base)
		base++;
	else
		base = name;
	char **args, **cur;
	char *relbasedir, *absbasedir;
	char *progpath = argv[0];
	char *basename;
	int ret;

	return base;
	/* 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);
	}
	if (absbasedir == NULL) {
		perror(__FILE__ ": realpath");
		return 2;
	}

int main(int argc, char **argv)
{
	char **args, **cur;
	/* Fill in the relative paths */
#ifdef BR_CROSS_PATH_REL
	ret = snprintf(path, sizeof(path), "%s/" BR_CROSS_PATH_REL "/%s", absbasedir, basename);
#else /* BR_CROSS_PATH_ABS */
	ret = snprintf(path, sizeof(path), BR_CROSS_PATH_ABS "/%s", basename);
#endif
	if (ret >= sizeof(path)) {
		perror(__FILE__ ": overflow");
		return 3;
	}
	ret = snprintf(sysroot, sizeof(sysroot), "%s/" BR_SYSROOT, absbasedir);
	if (ret >= sizeof(sysroot)) {
		perror(__FILE__ ": overflow");
		return 3;
	}

	cur = args = malloc(sizeof(predef_args) + (sizeof(char *) * argc));
	if (args == NULL) {
@@ -82,8 +114,6 @@ int main(int argc, char **argv)
	/* finish with NULL termination */
	*cur = NULL;

	strcat(path, get_basename(argv[0]));

	if (execv(path, args))
		perror(path);