[Buildroot] [PATCH v3 3/3] toolchain-external: calculation of the symlink to the arch sysroot
Romain Naour
romain.naour at openwide.fr
Sat Nov 29 12:49:36 UTC 2014
Hi Yann, all,
Le 14/11/2014 00:03, Romain Naour a écrit :
> When copying external toolchain sysroot to staging, we need to
> create the symbolic link that matches the name of the subdirectory
> for the architecture variant in the original sysroot.
> (ex: sgxx-glibc for CodeSourcery Standard edition)
> To do that, SYSROOT_DIR must be different than ARCH_SYSROOT_DIR.
>
> In the case where ARCH_SYSROOT_DIR is used as SYSROOT_DIR we need
> to check again the path to the main sysroot directory.
> if SYSROOT_DIR returned by toolchain_find_sysroot without
> TOOLCHAIN_EXTERNAL_CFLAGS is empty/invalid, then compute the common
> part between SYSROOT_DIR and ARCH_SYSROOT_DIR returned by
> toolchain_print_sysroot in order to get the "base sysroot".
> This "base sysroot" is used as SYSROOT_DIR to create the symlink
> in the staging directory.
>
> Signed-off-by: Romain Naour <romain.naour at openwide.fr>
>
> ---
> v3: Rework the end of string detection (Yann E. Morin)
> Handle a second argument in toolchain_print_sysroot
> Detect if the main sysroot is the same as arch sysroot,
> then return the main_sysroot
>
> v2: new patch
> ---
> toolchain/helpers.mk | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 51 insertions(+)
>
> diff --git a/toolchain/helpers.mk b/toolchain/helpers.mk
> index 7d7af5f..dd7bcac 100644
> --- a/toolchain/helpers.mk
> +++ b/toolchain/helpers.mk
> @@ -97,6 +97,36 @@ toolchain_create_arch_sysroot_symlink = \
> ln -s $${relpath} $(STAGING_DIR)/$${ARCH_SUBDIR} ; \
> echo "Symlinking $(STAGING_DIR)/$${ARCH_SUBDIR} -> $${relpath}"
>
> +# Returns the location of the sysroot for the given compiler + flags using
> +# -print-sysroot gcc option (gcc > 4.3 is needed)
> +define toolchain_print_sysroot
> +$$(readlink -f $$(LANG=C $(1) $(2) -print-sysroot))
> +endef
For now, we can't use -print-sysroot gcc option (which is available since gcc
4.4) for toolchain_find_arch_sysroot() and toolchain_find_sysroot() because we
need to support toolchains that use gcc < 4.4 (avr32 targets).
But the support for these toolchains can be dropped after avr32 removal which
is planned for the 2015.02 release, so toolchain_print_sysroot() can be replaced
by toolchain_find_arch_sysroot() or toolchain_find_sysroot().
> +
> +# Returns the common path between the main sysroot and arch sysroot returned by
> +# toolchain_print_sysroot. This is required to calculate the depth of the symlink
> +# in the staging directory when the main sysroot directory is empty/bogus.
> +define toolchain_calculate_base_sysroot
> +$$(common_sysroot_path="" ; \
> +main_sysroot_path=$(call toolchain_print_sysroot,$(TOOLCHAIN_EXTERNAL_CC)); \
> +arch_sysroot_path=$(call toolchain_print_sysroot,$(TOOLCHAIN_EXTERNAL_CC),$(TOOLCHAIN_EXTERNAL_CFLAGS)); \
So:
main_sysroot_path=$(call toolchain_find_sysroot,$(TOOLCHAIN_EXTERNAL_CC)); \
arch_sysroot_path=$(call toolchain_find_arch_sysroot,$(TOOLCHAIN_EXTERNAL_CC),$(TOOLCHAIN_EXTERNAL_CFLAGS)); \
> +if [ "$${main_sysroot_path}" = "$${arch_sysroot_path}" ]; then \
> + common_sysroot_path="$${main_sysroot_path}"; \
> +else \
> + index=0 ; \
> + while [ "$${main_sysroot_path:$${index}:1}" = "$${arch_sysroot_path:$${index}:1}" ] ; do \
> + if [ "$${main_sysroot_path:$${index}:1}" = "/" ]; then \
> + common_sysroot_path="$${main_sysroot_path:0:$${index}+1}"; \
> + fi ; \
> + if [ $${index} -gt $${#main_sysroot_path} ] || [ $${index} -gt $${#arch_sysroot_path} ]; then \
> + break; \
> + fi ; \
> + : $$((index++)) ; \
> + done ; \
> +fi ; \
> +echo -n $${common_sysroot_path})
> +endef
> +
> #
> # Copy the full external toolchain sysroot directory to the staging
> # dir. The operation of this function is rendered a little bit
> @@ -130,6 +160,17 @@ toolchain_create_arch_sysroot_symlink = \
> # non-default architecture variant is used. Without this, the
> # compiler fails to find libraries and headers.
> #
> +# Some toolchain (i.e CodeSourcery Standard edition) doesn't have
> +# a main sysroot directory and use the arch sysroot as fallback.
> +# In this case we need to check again the path to the main sysroot
> +# directory when SYSROOT_DIR == ARCH_SYSROOT_DIR.
> +# if SYSROOT_DIR returned by toolchain_find_sysroot without
> +# TOOLCHAIN_EXTERNAL_CFLAGS point to valid directory.
> +# If SYSROOT_DIR is empty/invalid, compute the common part between
> +# SYSROOT_DIR and ARCH_SYSROOT_DIR returned by toolchain_print_sysroot
> +# in order to get the "base sysroot". This "base sysroot" is used
> +# to create the symlink in the staging directory.
> +#
> # Some toolchains (i.e Linaro binary toolchains) store support
> # libraries (libstdc++, libgcc_s) outside of the sysroot, so we simply
> # copy all the libraries from the "support lib directory" into our
> @@ -163,6 +204,16 @@ copy_toolchain_sysroot = \
> cp -a $${SYSROOT_DIR}/usr/include $(STAGING_DIR)/usr ; \
> fi ; \
> $(call toolchain_create_arch_sysroot_symlink,$${ARCH_SUBDIR}) ; \
> + else \
Question by Yann on IRC:
"y_morin: I was wondering why you would re-do the sysroot detection in copy_toolchain_sysroot,
and why you would not do it in TOOLCHAIN_EXTERNAL_INSTALL_CORE."
You're right I can do it in TOOLCHAIN_EXTERNAL_INSTALL_CORE but, as discussed during the meeting
at Dusseldorf, we don't want to use a "dummy" path as SYSROOT_DIR like I did previously in this
series (v1).
http://lists.busybox.net/pipermail/buildroot/2014-October/108641.html
"y_morin: Why is it not possible to set SYSROOT_DIR to the "default" sysroot for the CS toolchain,
and set ARCH_SYSROOT_DIR to the one you want ?"
I can't use the default/base sysroot as SYSROOT_DIR everywhere because it will break, for example,
during toolchain checks check_kernel_headers_version() or check_glibc() (find -maxdepth 2).
So, to be safe, we need to check if it's really the main_sysroot that is used as SYSROOT_DIR, and
that why $(TOOLCHAIN_EXTERNAL_CFLAGS) is not passed.
> + if ! test -d "$(call toolchain_find_sysroot,$(TOOLCHAIN_EXTERNAL_CC))" ; then \
Here, the main_sysroot doesn't exist, ARCH_SYSROOT was used as SYSROOT_DIR.
> + SYSROOT_DIR="$(call toolchain_calculate_base_sysroot)"; \
I think it would be better if toolchain_calculate_base_sysroot() can use the $${ARCH_SYSROOT_DIR}
and the path returned by "$(call toolchain_find_sysroot,$(TOOLCHAIN_EXTERNAL_CC))" as arguments,
instead of recall toolchain_find_arch_sysroot() and toolchain_find_sysroot() internally.
> + if ! test -d $${SYSROOT_DIR} ; then \
> + echo "ERROR: Unable to find the main sysroot directory." ; \
> + exit 1; \
> + fi ; \
Here, we need to overwrite ARCH_SUBDIR since SYSROOT_DIR may have been modified by
toolchain_calculate_base_sysroot()
> + ARCH_SUBDIR=`echo $${ARCH_SYSROOT_DIR} | sed -r -e "s:^$${SYSROOT_DIR}(.*)/$$:\1:"` ; \
> + $(call toolchain_create_arch_sysroot_symlink,$${ARCH_SUBDIR}) ; \
> + fi ; \
> fi ; \
> if test -n "$${SUPPORT_LIB_DIR}" ; then \
> cp -a $${SUPPORT_LIB_DIR}/* $(STAGING_DIR)/lib/ ; \
>
Best regards,
--
Romain Naour
OPEN WIDE Ingénierie - Paris
23/25, rue Daviel| 75013 PARIS
http://ingenierie.openwide.fr
Le blog des technologies libres et embarquées :
http://www.linuxembedded.fr
More information about the buildroot
mailing list