diff options
Diffstat (limited to 'toolchain/toolchain-external')
-rw-r--r-- | toolchain/toolchain-external/ext-tool.mk | 84 | ||||
-rw-r--r-- | toolchain/toolchain-external/ext-toolchain-wrapper.c | 75 |
2 files changed, 152 insertions, 7 deletions
diff --git a/toolchain/toolchain-external/ext-tool.mk b/toolchain/toolchain-external/ext-tool.mk index f6249ef9c..0034ddfb3 100644 --- a/toolchain/toolchain-external/ext-tool.mk +++ b/toolchain/toolchain-external/ext-tool.mk @@ -41,8 +41,16 @@ # packages when using external toolchains. So in the end, only the # cross-compiler binaries remains external, all libraries and headers # are imported into the Buildroot tree. +# +# 4. Build a toolchain wrapper which executes the external toolchain +# with a number of arguments (sysroot/march/mtune/..) hardcoded, +# so we're sure the correct configuration is always used and the +# toolchain behaves similar to an internal toolchain. +# This toolchain wrapper and symlinks are installed into +# $(HOST_DIR)/usr/bin like for the internal toolchains, and the rest +# of Buildroot is handled identical for the 2 toolchain types. -uclibc: dependencies $(STAMP_DIR)/ext-toolchain-installed +uclibc: dependencies $(HOST_DIR)/usr/bin/ext-toolchain-wrapper LIB_EXTERNAL_LIBS=ld*.so libc.so libcrypt.so libdl.so libgcc_s.so libm.so libnsl.so libresolv.so librt.so libutil.so ifeq ($(BR2_TOOLCHAIN_EXTERNAL_GLIBC),y) @@ -97,7 +105,51 @@ endif # ! no threads # present in the main sysroot, and only the libraries are available in # each variant-specific sysroot directory. -TARGET_CC_NO_SYSROOT=$(filter-out --sysroot=%,$(TARGET_CC_NOCCACHE)) + +TOOLCHAIN_EXTERNAL_PREFIX=$(call qstrip,$(BR2_TOOLCHAIN_EXTERNAL_PREFIX)) +ifeq ($(BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD),y) +TOOLCHAIN_EXTERNAL_DIR=$(HOST_DIR)/opt/ext-toolchain +else +TOOLCHAIN_EXTERNAL_DIR=$(call qstrip,$(BR2_TOOLCHAIN_EXTERNAL_PATH)) +endif + +ifeq ($(TOOLCHAIN_EXTERNAL_DIR),) +# if no path set, figure it out from path +TOOLCHAIN_EXTERNAL_BIN:=$(shell dirname $(shell which $(TOOLCHAIN_EXTERNAL_PREFIX)-gcc)) +else +TOOLCHAIN_EXTERNAL_BIN:=$(TOOLCHAIN_EXTERNAL_DIR)/bin +endif + +TOOLCHAIN_EXTERNAL_CROSS=$(TOOLCHAIN_EXTERNAL_BIN)/$(TOOLCHAIN_EXTERNAL_PREFIX)- +TOOLCHAIN_EXTERNAL_CC=$(TOOLCHAIN_EXTERNAL_CROSS)gcc +TOOLCHAIN_EXTERNAL_WRAPPER_ARGS = \ + -DBR_CROSS_PATH='"$(TOOLCHAIN_EXTERNAL_BIN)/"' \ + -DBR_SYSROOT='"$(STAGING_DIR)"' + +# march/mtune/floating point mode needs to be passed to the external toolchain +# to select the right multilib variant +ifneq ($(CC_TARGET_TUNE_),) +TOOLCHAIN_EXTERNAL_CFLAGS += -mtune=$(CC_TARGET_TUNE_) +TOOLCHAIN_EXTERNAL_WRAPPER_ARGS += -DBR_TUNE='"$(CC_TARGET_TUNE_)"' +endif +ifneq ($(CC_TARGET_ARCH_),) +TOOLCHAIN_EXTERNAL_CFLAGS += -march=$(CC_TARGET_ARCH_) +TOOLCHAIN_EXTERNAL_WRAPPER_ARGS += -DBR_ARCH='"$(CC_TARGET_ARCH_)"' +endif +ifneq ($(CC_TARGET_ABI_),) +TOOLCHAIN_EXTERNAL_CFLAGS += -mabi=$(CC_TARGET_ABI_) +TOOLCHAIN_EXTERNAL_WRAPPER_ARGS += -DBR_ABI='"$(CC_TARGET_ABI_)"' +endif + +ifeq ($(BR2_SOFT_FLOAT),y) +TOOLCHAIN_EXTERNAL_CFLAGS += -msoft-float +TOOLCHAIN_EXTERNAL_WRAPPER_ARGS += -DBR_SOFTFLOAT=1 +endif + +ifeq ($(BR2_VFP_FLOAT),y) +TOOLCHAIN_EXTERNAL_CFLAGS += -mfpu=vfp +TOOLCHAIN_EXTERNAL_WRAPPER_ARGS += -DBR_VFPFLOAT=1 +endif ifeq ($(BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD),y) TOOLCHAIN_EXTERNAL_DEPENDENCIES = $(TOOLCHAIN_EXTERNAL_DIR)/.extracted @@ -146,9 +198,9 @@ $(TOOLCHAIN_EXTERNAL_DIR)/.extracted: $(DL_DIR)/$(TOOLCHAIN_EXTERNAL_SOURCE) $(STAMP_DIR)/ext-toolchain-checked: @echo "Checking external toolchain settings" $(Q)$(call check_cross_compiler_exists) - $(Q)SYSROOT_DIR=`$(TARGET_CC_NO_SYSROOT) -print-sysroot 2>/dev/null` ; \ + $(Q)SYSROOT_DIR=`$(TOOLCHAIN_EXTERNAL_CC) -print-sysroot 2>/dev/null` ; \ if test -z "$${SYSROOT_DIR}" ; then \ - SYSROOT_DIR=`readlink -f $$(LANG=C $(TARGET_CC_NO_SYSROOT) -print-file-name=libc.a) |sed -r -e 's:usr/lib/libc\.a::;'` ; \ + SYSROOT_DIR=`readlink -f $$(LANG=C $(TOOLCHAIN_EXTERNAL_CC) -print-file-name=libc.a) |sed -r -e 's:usr/lib/libc\.a::;'` ; \ fi ; \ if test -z "$${SYSROOT_DIR}" ; then \ @echo "External toolchain doesn't support --sysroot. Cannot use." ; \ @@ -172,15 +224,15 @@ $(STAMP_DIR)/ext-toolchain-checked: # the $(TARGET_DIR) and copy the whole sysroot (libraries and headers) # to $(STAGING_DIR). $(STAMP_DIR)/ext-toolchain-installed: $(TOOLCHAIN_EXTERNAL_DEPENDENCIES) - $(Q)SYSROOT_DIR=`$(TARGET_CC_NO_SYSROOT) -print-sysroot 2>/dev/null` ; \ + $(Q)SYSROOT_DIR=`$(TOOLCHAIN_EXTERNAL_CC) -print-sysroot 2>/dev/null` ; \ if test -z "$${SYSROOT_DIR}" ; then \ - SYSROOT_DIR=`readlink -f $$(LANG=C $(TARGET_CC_NO_SYSROOT) -print-file-name=libc.a) |sed -r -e 's:usr/lib/libc\.a::;'` ; \ + SYSROOT_DIR=`readlink -f $$(LANG=C $(TOOLCHAIN_EXTERNAL_CC) -print-file-name=libc.a) |sed -r -e 's:usr/lib/libc\.a::;'` ; \ fi ; \ if test -z "$${SYSROOT_DIR}" ; then \ @echo "External toolchain doesn't support --sysroot. Cannot use." ; \ exit 1 ; \ fi ; \ - ARCH_SUBDIR=`$(TARGET_CC_NO_SYSROOT) $(TARGET_CFLAGS) -print-multi-directory` ; \ + ARCH_SUBDIR=`$(TOOLCHAIN_EXTERNAL_CC) $(TOOLCHAIN_EXTERNAL_CFLAGS) -print-multi-directory` ; \ ARCH_SYSROOT_DIR=$${SYSROOT_DIR}/$${ARCH_SUBDIR} ; \ mkdir -p $(TARGET_DIR)/lib ; \ echo "Copy external toolchain libraries to target..." ; \ @@ -196,3 +248,21 @@ $(STAMP_DIR)/ext-toolchain-installed: $(TOOLCHAIN_EXTERNAL_DEPENDENCIES) $(call create_lib64_symlinks) ; \ fi ; \ touch $@ + +# Build toolchain wrapper for preprocessor, C and C++ compiler, and setup +# symlinks for everything else +$(HOST_DIR)/usr/bin/ext-toolchain-wrapper: $(STAMP_DIR)/ext-toolchain-installed + mkdir -p $(HOST_DIR)/usr/bin; cd $(HOST_DIR)/usr/bin; \ + for i in $(TOOLCHAIN_EXTERNAL_CROSS)*; do \ + case "$$i" in \ + *cc|*cc-*|*++|*++-*|*cpp) \ + base=$${i##*/}; \ + ln -sf $(@F) $$base; \ + ;; \ + *) \ + ln -sf $$i .; \ + ;; \ + esac; \ + done ; + $(HOSTCC) $(HOST_CFLAGS) $(TOOLCHAIN_EXTERNAL_WRAPPER_ARGS) -s \ + toolchain/toolchain-external/ext-toolchain-wrapper.c -o $@ diff --git a/toolchain/toolchain-external/ext-toolchain-wrapper.c b/toolchain/toolchain-external/ext-toolchain-wrapper.c new file mode 100644 index 000000000..a485e740d --- /dev/null +++ b/toolchain/toolchain-external/ext-toolchain-wrapper.c @@ -0,0 +1,75 @@ +/** + * 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. + * + * (C) 2011 Peter Korsgaard <jacmet@sunsite.dk> + * + * 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 + * kind, whether express or implied. + */ + +#include <stdio.h> +#include <string.h> +#include <limits.h> +#include <unistd.h> + +#define MAXARGS 1000 + +static char path[PATH_MAX] = BR_CROSS_PATH; + +static char *args[MAXARGS] = { + path, + "--sysroot", BR_SYSROOT, +#ifdef BR_ARCH + "-march=" BR_ARCH, +#endif /* BR_ARCH */ +#ifdef BR_TUNE + "-mtune=" BR_TUNE, +#endif /* BR_TUNE */ +#ifdef BR_ABI + "-mabi=" BR_ABI, +#endif +#ifdef BR_SOFTFLOAT + "-msoft-float", +#endif /* BR_SOFTFLOAT */ +#ifdef BR_VFPFLOAT + "-mfpu=vfp", +#endif /* BR_VFPFLOAT */ +}; + +static const char *get_basename(const char *name) +{ + const char *base; + + base = strrchr(name, '/'); + if (base) + base++; + else + base = name; + + return base; +} + +int main(int argc, char **argv) +{ + int i; + + for (i=0; args[i]; i++); + + if ((argc+i) >= MAXARGS) { + fputs("Too many arguments\n", stderr); + return 1; + } + + /* forward args */ + memcpy(&args[i], &argv[1], sizeof(argv[0]) * (argc - 1)); + + strcat(path, get_basename(argv[0])); + + if (execv(path, args)) + perror(path); + + return 2; +} |