diff mbox

[v9] toolchain: create symlink ARCH_LIB_DIR->lib in addition to lib32/lib64->lib

Message ID 1450787734-2547-1-git-send-email-patrickdepinguin@gmail.com
State Superseded
Headers show

Commit Message

Thomas De Schampheleire Dec. 22, 2015, 12:35 p.m. UTC
From: Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>

Currently, following symbolic links are created in both target and
staging directories:
- lib(32|64) --> lib
- usr/lib(32|64) --> lib

The decision for lib32 or lib64 is based on the target architecture
configuration in buildroot (BR2_ARCH_IS_64).

In at least one case this is not correct: when building for a Cavium Octeon
III processor using the toolchain from the Cavium Networks SDK, and
specifying -march=octeon3 in BR2_TARGET_OPTIMIZATION, libraries are expected
in directory 'lib32-fp' rather than 'lib32' (likewise for lib64-fp).

More generally, for external toolchains, the correct symbolic link is
from (usr/)${ARCH_LIB_DIR} to lib. For internal toolchains, current
toolchains always use either lib32 or lib64.

Feedback from Arnout Vandecappelle is that there are packages that do depend
on the lib32/lib64 symlink, even if ARCH_LIB_DIR is different. Hence, these
must be kept.

Fix the problem as follows:
- For internal toolchains: no functional change, but move the symlink
  creation from Makefile to package gcc-initial.
- For external toolchains: create a symlink creation helper in
  toolchain/helpers.mk, which first creates lib32->lib or lib64->lib as
  appropriate, and then creates ARCH_LIB_DIR->lib if that is different from
  lib32/lib64.

Signed-off-by: Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Arnout Vandecappelle <arnout@mind.be>
Cc: "Yann E. Morin" <yann.morin.1998@free.fr>

---
v9:
- remove redundant mkdir's (handled by skeleton) (Yann)
v8:
- use helper only for external toolchain and incorporate ARCH_LIB_DIR
  definition (Arnout)
- keep lib32/lib64->lib symlink anyway
v7: rebase
v6: rebase only
v5:
- move internal toolchain logic into gcc-initial.mk
- also silence the internal toolchain link steps with $(Q)
v4:
- merge both helpers into one
- remove the separate target for the internal toolchain and hook into
  gcc-initial
- re-add deleted comment about MIPS64/n32
v3:
- update commit message wrapping
- change dependency on $(BUILD_DIR) to a order-only dependency
v2:
- fix 'lib32-fp' leftover in toolchain-buildroot
- silence commands creating symlink with $(Q)
- fix case where ARCH_LIB_DIR is 'lib'

Note: in output/staging/usr/ there would still be more directories than I
think are really necessary. This behavior is not changed by this patch, it
was already present before.
For example, with the mentioned Octeon III toolchain, output/staging/usr/
contains:
    bin      bin32      bin32-fp      bin64-fp,
    lib                 lib32-fp      lib64-fp
    libexec  libexec32  libexec32-fp  libexec64-fp
    sbin     sbin32     sbin32-fp     sbin64-fp

where bin/lib/libexec/sbin seem to be the 64-bit equivalents of
bin32/lib32/libexec32/sbin32.
This is related to the behavior of copy_toolchain_sysroot in
toolchain/helpers.mk. It already attempts to filter out lib32 and lib64, but
does not care about any bin/sbin/libexec directories, nor about such names
as lib32-fp.
As the behavior is not changed by this patch, and as I'm not fully aware
about which directories are really needed in all cases, I am not touching
this area.
---
 Makefile                                           |  8 --------
 package/gcc/gcc-initial/gcc-initial.mk             | 12 +++++++++++
 package/skeleton/skeleton.mk                       |  4 ----
 toolchain/helpers.mk                               | 23 ++++++++++++++++++++++
 toolchain/toolchain-external/toolchain-external.mk | 10 ++++++++++
 5 files changed, 45 insertions(+), 12 deletions(-)

Comments

Thomas De Schampheleire Jan. 5, 2016, 12:37 p.m. UTC | #1
On Tue, Dec 22, 2015 at 1:35 PM, Thomas De Schampheleire
<patrickdepinguin@gmail.com> wrote:
> From: Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>
>
> Currently, following symbolic links are created in both target and
> staging directories:
> - lib(32|64) --> lib
> - usr/lib(32|64) --> lib
>
> The decision for lib32 or lib64 is based on the target architecture
> configuration in buildroot (BR2_ARCH_IS_64).
>
> In at least one case this is not correct: when building for a Cavium Octeon
> III processor using the toolchain from the Cavium Networks SDK, and
> specifying -march=octeon3 in BR2_TARGET_OPTIMIZATION, libraries are expected
> in directory 'lib32-fp' rather than 'lib32' (likewise for lib64-fp).
>
> More generally, for external toolchains, the correct symbolic link is
> from (usr/)${ARCH_LIB_DIR} to lib. For internal toolchains, current
> toolchains always use either lib32 or lib64.
>
> Feedback from Arnout Vandecappelle is that there are packages that do depend
> on the lib32/lib64 symlink, even if ARCH_LIB_DIR is different. Hence, these
> must be kept.
>
> Fix the problem as follows:
> - For internal toolchains: no functional change, but move the symlink
>   creation from Makefile to package gcc-initial.
> - For external toolchains: create a symlink creation helper in
>   toolchain/helpers.mk, which first creates lib32->lib or lib64->lib as
>   appropriate, and then creates ARCH_LIB_DIR->lib if that is different from
>   lib32/lib64.
>
> Signed-off-by: Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>
> Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> Cc: Arnout Vandecappelle <arnout@mind.be>
> Cc: "Yann E. Morin" <yann.morin.1998@free.fr>
>
> ---
> v9:
> - remove redundant mkdir's (handled by skeleton) (Yann)
> v8:
> - use helper only for external toolchain and incorporate ARCH_LIB_DIR
>   definition (Arnout)
> - keep lib32/lib64->lib symlink anyway
> v7: rebase
> v6: rebase only
> v5:
> - move internal toolchain logic into gcc-initial.mk
> - also silence the internal toolchain link steps with $(Q)
> v4:
> - merge both helpers into one
> - remove the separate target for the internal toolchain and hook into
>   gcc-initial
> - re-add deleted comment about MIPS64/n32
> v3:
> - update commit message wrapping
> - change dependency on $(BUILD_DIR) to a order-only dependency
> v2:
> - fix 'lib32-fp' leftover in toolchain-buildroot
> - silence commands creating symlink with $(Q)
> - fix case where ARCH_LIB_DIR is 'lib'
>
> Note: in output/staging/usr/ there would still be more directories than I
> think are really necessary. This behavior is not changed by this patch, it
> was already present before.
> For example, with the mentioned Octeon III toolchain, output/staging/usr/
> contains:
>     bin      bin32      bin32-fp      bin64-fp,
>     lib                 lib32-fp      lib64-fp
>     libexec  libexec32  libexec32-fp  libexec64-fp
>     sbin     sbin32     sbin32-fp     sbin64-fp
>
> where bin/lib/libexec/sbin seem to be the 64-bit equivalents of
> bin32/lib32/libexec32/sbin32.
> This is related to the behavior of copy_toolchain_sysroot in
> toolchain/helpers.mk. It already attempts to filter out lib32 and lib64, but
> does not care about any bin/sbin/libexec directories, nor about such names
> as lib32-fp.
> As the behavior is not changed by this patch, and as I'm not fully aware
> about which directories are really needed in all cases, I am not touching
> this area.
> ---
>  Makefile                                           |  8 --------
>  package/gcc/gcc-initial/gcc-initial.mk             | 12 +++++++++++
>  package/skeleton/skeleton.mk                       |  4 ----
>  toolchain/helpers.mk                               | 23 ++++++++++++++++++++++
>  toolchain/toolchain-external/toolchain-external.mk | 10 ++++++++++
>  5 files changed, 45 insertions(+), 12 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index dc657d9..63f4c54 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -448,14 +448,6 @@ world: target-post-image
>  $(BUILD_DIR) $(TARGET_DIR) $(HOST_DIR) $(BINARIES_DIR) $(LEGAL_INFO_DIR) $(REDIST_SOURCES_DIR_TARGET) $(REDIST_SOURCES_DIR_HOST):
>         @mkdir -p $@
>
> -# We make a symlink lib32->lib or lib64->lib as appropriate
> -# MIPS64/n32 requires lib32 even though it's a 64-bit arch.
> -ifeq ($(BR2_ARCH_IS_64)$(BR2_MIPS_NABI32),y)
> -LIB_SYMLINK = lib64
> -else
> -LIB_SYMLINK = lib32
> -endif
> -
>  # Populating the staging with the base directories is handled by the skeleton package
>  $(STAGING_DIR):
>         @mkdir -p $(STAGING_DIR)
> diff --git a/package/gcc/gcc-initial/gcc-initial.mk b/package/gcc/gcc-initial/gcc-initial.mk
> index 1e58d8b..cf441ed 100644
> --- a/package/gcc/gcc-initial/gcc-initial.mk
> +++ b/package/gcc/gcc-initial/gcc-initial.mk
> @@ -64,4 +64,16 @@ HOST_GCC_INITIAL_TOOLCHAIN_WRAPPER_ARGS += $(HOST_GCC_COMMON_TOOLCHAIN_WRAPPER_A
>  HOST_GCC_INITIAL_POST_BUILD_HOOKS += TOOLCHAIN_BUILD_WRAPPER
>  HOST_GCC_INITIAL_POST_INSTALL_HOOKS += HOST_GCC_INSTALL_WRAPPER_AND_SIMPLE_SYMLINKS
>
> +# The creation of lib32/lib64 symlinks into target and staging directories
> +# needs to be done before the C library is installed. Hooking into the libc
> +# hooks directly is tricky because there are multiple C libraries supported.
> +# Instead, hook into the install step of host-gcc-initial.
> +define HOST_GCC_INITIAL_CREATE_STAGING_TARGET_SYMLINK
> +       $(Q)ln -snf lib $(STAGING_DIR)/$(TOOLCHAIN_LIB_SYMLINK)
> +       $(Q)ln -snf lib $(STAGING_DIR)/usr/$(TOOLCHAIN_LIB_SYMLINK)
> +       $(Q)ln -snf lib $(TARGET_DIR)/$(TOOLCHAIN_LIB_SYMLINK)
> +       $(Q)ln -snf lib $(TARGET_DIR)/usr/$(TOOLCHAIN_LIB_SYMLINK)
> +endef
> +HOST_GCC_INITIAL_POST_INSTALL_HOOKS += HOST_GCC_INITIAL_CREATE_STAGING_TARGET_SYMLINK
> +
>  $(eval $(host-autotools-package))
> diff --git a/package/skeleton/skeleton.mk b/package/skeleton/skeleton.mk
> index 790afaf..b1395b5 100644
> --- a/package/skeleton/skeleton.mk
> +++ b/package/skeleton/skeleton.mk
> @@ -82,8 +82,6 @@ define SKELETON_INSTALL_TARGET_CMDS
>                 --chmod=u=rwX,go=rX --exclude .empty --exclude '*~' \
>                 $(SKELETON_PATH)/ $(TARGET_DIR)/
>         $(call SKELETON_USR_SYMLINKS_OR_DIRS,$(TARGET_DIR))
> -       ln -snf lib $(TARGET_DIR)/$(LIB_SYMLINK)
> -       ln -snf lib $(TARGET_DIR)/usr/$(LIB_SYMLINK)
>         $(INSTALL) -m 0644 support/misc/target-dir-warning.txt \
>                 $(TARGET_DIR_WARNING_FILE)
>  endef
> @@ -99,8 +97,6 @@ define SKELETON_INSTALL_STAGING_CMDS
>         $(INSTALL) -d -m 0755 $(STAGING_DIR)/usr/sbin
>         $(INSTALL) -d -m 0755 $(STAGING_DIR)/usr/include
>         $(call SKELETON_USR_SYMLINKS_OR_DIRS,$(STAGING_DIR))
> -       ln -snf lib $(STAGING_DIR)/$(LIB_SYMLINK)
> -       ln -snf lib $(STAGING_DIR)/usr/$(LIB_SYMLINK)
>  endef
>
>  SKELETON_TARGET_GENERIC_HOSTNAME = $(call qstrip,$(BR2_TARGET_GENERIC_HOSTNAME))
> diff --git a/toolchain/helpers.mk b/toolchain/helpers.mk
> index 1452ec6..f582ce9 100644
> --- a/toolchain/helpers.mk
> +++ b/toolchain/helpers.mk
> @@ -1,5 +1,28 @@
>  # This Makefile fragment declares toolchain related helper functions.
>
> +# Create the necessary symlink from (usr/)lib32|lib64|lib32-fp|... to lib
> +# In general, for external toolchains, the correct link name is $ARCH_LIB_DIR.
> +# However, there are some broken packages that expect lib32/lib64 anyway.
> +# Therefore, create lib32->lib or lib64->lib (as appropriate) and additionally
> +# $(ARCH_LIB_DIR)->lib.
> +#
> +# MIPS64/n32 requires lib32 even though it's a 64-bit arch.
> +ifeq ($(BR2_ARCH_IS_64)$(BR2_MIPS_NABI32),y)
> +TOOLCHAIN_LIB_SYMLINK = lib64
> +else
> +TOOLCHAIN_LIB_SYMLINK = lib32
> +endif
> +# $1: destination directory (TARGET_DIR / STAGING_DIR)
> +create_lib_symlinks = \
> +       DESTDIR="$(strip $1)" ; \
> +       ARCH_LIB_DIR="$(call toolchain_find_libdir,$(TOOLCHAIN_EXTERNAL_CC) $(TOOLCHAIN_EXTERNAL_CFLAGS))" ; \
> +       ln -snf lib "$${DESTDIR}/$(TOOLCHAIN_LIB_SYMLINK)" ; \
> +       ln -snf lib "$${DESTDIR}/usr/$(TOOLCHAIN_LIB_SYMLINK)" ; \
> +       if [ "$${ARCH_LIB_DIR}" != "lib" -a "$${ARCH_LIB_DIR}" != "$(TOOLCHAIN_LIB_SYMLINK)" ]; then \
> +               ln -snf lib "$${DESTDIR}/$${ARCH_LIB_DIR}" ; \
> +               ln -snf lib "$${DESTDIR}/usr/$${ARCH_LIB_DIR}" ; \
> +       fi
> +
>  # The copy_toolchain_lib_root function copies a toolchain library and
>  # its symbolic links from the sysroot directory to the target
>  # directory. Note that this function is used both by the external
> diff --git a/toolchain/toolchain-external/toolchain-external.mk b/toolchain/toolchain-external/toolchain-external.mk
> index 745b685..e20268e 100644
> --- a/toolchain/toolchain-external/toolchain-external.mk
> +++ b/toolchain/toolchain-external/toolchain-external.mk
> @@ -689,6 +689,14 @@ define TOOLCHAIN_EXTERNAL_INSTALL_SYSROOT_LIBS
>         $(call copy_toolchain_sysroot,$${SYSROOT_DIR},$${ARCH_SYSROOT_DIR},$${ARCH_SUBDIR},$${ARCH_LIB_DIR},$${SUPPORT_LIB_DIR})
>  endef
>
> +define TOOLCHAIN_EXTERNAL_CREATE_STAGING_LIB_SYMLINK
> +       $(call create_lib_symlinks,$(STAGING_DIR))
> +endef
> +
> +define TOOLCHAIN_EXTERNAL_CREATE_TARGET_LIB_SYMLINK
> +       $(call create_lib_symlinks,$(TARGET_DIR))
> +endef
> +
>  # Special installation target used on the Blackfin architecture when
>  # FDPIC is not the primary binary format being used, but the user has
>  # nonetheless requested the installation of the FDPIC libraries to the
> @@ -803,6 +811,7 @@ endef
>  TOOLCHAIN_EXTERNAL_BUILD_CMDS = $(TOOLCHAIN_BUILD_WRAPPER)
>
>  define TOOLCHAIN_EXTERNAL_INSTALL_STAGING_CMDS
> +       $(TOOLCHAIN_EXTERNAL_CREATE_STAGING_LIB_SYMLINK)
>         $(TOOLCHAIN_EXTERNAL_INSTALL_SYSROOT_LIBS)
>         $(TOOLCHAIN_EXTERNAL_INSTALL_WRAPPER)
>         $(TOOLCHAIN_EXTERNAL_INSTALL_GDBINIT)
> @@ -812,6 +821,7 @@ endef
>  # and the target directory, we do everything within the
>  # install-staging step, arbitrarily.
>  define TOOLCHAIN_EXTERNAL_INSTALL_TARGET_CMDS
> +       $(TOOLCHAIN_EXTERNAL_CREATE_TARGET_LIB_SYMLINK)
>         $(TOOLCHAIN_EXTERNAL_INSTALL_TARGET_LIBS)
>         $(TOOLCHAIN_EXTERNAL_INSTALL_BFIN_FDPIC)
>         $(TOOLCHAIN_EXTERNAL_INSTALL_BFIN_FLAT)
> --
> 1.9.5
>

bump
Romain Naour Jan. 12, 2016, 11:12 p.m. UTC | #2
Hi Thomas, All,

Le 22/12/2015 13:35, Thomas De Schampheleire a écrit :
> From: Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>
> 
> Currently, following symbolic links are created in both target and
> staging directories:
> - lib(32|64) --> lib
> - usr/lib(32|64) --> lib
> 
> The decision for lib32 or lib64 is based on the target architecture
> configuration in buildroot (BR2_ARCH_IS_64).
> 
> In at least one case this is not correct: when building for a Cavium Octeon
> III processor using the toolchain from the Cavium Networks SDK, and
> specifying -march=octeon3 in BR2_TARGET_OPTIMIZATION, libraries are expected
> in directory 'lib32-fp' rather than 'lib32' (likewise for lib64-fp).
> 
> More generally, for external toolchains, the correct symbolic link is
> from (usr/)${ARCH_LIB_DIR} to lib. For internal toolchains, current
> toolchains always use either lib32 or lib64.
> 
> Feedback from Arnout Vandecappelle is that there are packages that do depend
> on the lib32/lib64 symlink, even if ARCH_LIB_DIR is different. Hence, these
> must be kept.
> 
> Fix the problem as follows:
> - For internal toolchains: no functional change, but move the symlink
>   creation from Makefile to package gcc-initial.
> - For external toolchains: create a symlink creation helper in
>   toolchain/helpers.mk, which first creates lib32->lib or lib64->lib as
>   appropriate, and then creates ARCH_LIB_DIR->lib if that is different from
>   lib32/lib64.

Not so related to your patch though...
I reviewed some patches about x32 and ilp32 toolchains support and it seems that
we need to handle at least two more weird libraries location: libx32 and
libilp32. Each of these series try to define LIB_SYMLINK with their own specific
value (libilp32 and libx32).

See:
x86-64 x32 ABI:
http://patchwork.ozlabs.org/patch/561904/

aarch64 ilp32 ABI:
http://patchwork.ozlabs.org/patch/506803/
http://patchwork.ozlabs.org/patch/506800/
http://patchwork.ozlabs.org/patch/506801/

In your patch, I like create_lib_symlinks helper function which avoid to define
TOOLCHAIN_LIB_SYMLINK with a different value than lib32 and lib64. Instead we
rely on the ARCH_LIB_DIR returned by the arch-sysroot to create additional
symlinks with the correct name.

Obviously, we need to adjust the sed "magic" in toolchain_find_libdir and
toolchain_find_sysroot for libilp32 and libx32 but we can do that in a followup
patch series.

So, I think this patch make it easier to add the support of theses specific
toolchains:

Reviewed-by: Romain Naour <romain.naour@gmail.com>

Best regards,
Romain

> 
> Signed-off-by: Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>
> Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> Cc: Arnout Vandecappelle <arnout@mind.be>
> Cc: "Yann E. Morin" <yann.morin.1998@free.fr>
> 
> ---
> v9:
> - remove redundant mkdir's (handled by skeleton) (Yann)
> v8:
> - use helper only for external toolchain and incorporate ARCH_LIB_DIR
>   definition (Arnout)
> - keep lib32/lib64->lib symlink anyway
> v7: rebase
> v6: rebase only
> v5:
> - move internal toolchain logic into gcc-initial.mk
> - also silence the internal toolchain link steps with $(Q)
> v4:
> - merge both helpers into one
> - remove the separate target for the internal toolchain and hook into
>   gcc-initial
> - re-add deleted comment about MIPS64/n32
> v3:
> - update commit message wrapping
> - change dependency on $(BUILD_DIR) to a order-only dependency
> v2:
> - fix 'lib32-fp' leftover in toolchain-buildroot
> - silence commands creating symlink with $(Q)
> - fix case where ARCH_LIB_DIR is 'lib'
> 
> Note: in output/staging/usr/ there would still be more directories than I
> think are really necessary. This behavior is not changed by this patch, it
> was already present before.
> For example, with the mentioned Octeon III toolchain, output/staging/usr/
> contains:
>     bin      bin32      bin32-fp      bin64-fp,
>     lib                 lib32-fp      lib64-fp
>     libexec  libexec32  libexec32-fp  libexec64-fp
>     sbin     sbin32     sbin32-fp     sbin64-fp
> 
> where bin/lib/libexec/sbin seem to be the 64-bit equivalents of
> bin32/lib32/libexec32/sbin32.
> This is related to the behavior of copy_toolchain_sysroot in
> toolchain/helpers.mk. It already attempts to filter out lib32 and lib64, but
> does not care about any bin/sbin/libexec directories, nor about such names
> as lib32-fp.
> As the behavior is not changed by this patch, and as I'm not fully aware
> about which directories are really needed in all cases, I am not touching
> this area.
> ---
>  Makefile                                           |  8 --------
>  package/gcc/gcc-initial/gcc-initial.mk             | 12 +++++++++++
>  package/skeleton/skeleton.mk                       |  4 ----
>  toolchain/helpers.mk                               | 23 ++++++++++++++++++++++
>  toolchain/toolchain-external/toolchain-external.mk | 10 ++++++++++
>  5 files changed, 45 insertions(+), 12 deletions(-)
> 
> diff --git a/Makefile b/Makefile
> index dc657d9..63f4c54 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -448,14 +448,6 @@ world: target-post-image
>  $(BUILD_DIR) $(TARGET_DIR) $(HOST_DIR) $(BINARIES_DIR) $(LEGAL_INFO_DIR) $(REDIST_SOURCES_DIR_TARGET) $(REDIST_SOURCES_DIR_HOST):
>  	@mkdir -p $@
>  
> -# We make a symlink lib32->lib or lib64->lib as appropriate
> -# MIPS64/n32 requires lib32 even though it's a 64-bit arch.
> -ifeq ($(BR2_ARCH_IS_64)$(BR2_MIPS_NABI32),y)
> -LIB_SYMLINK = lib64
> -else
> -LIB_SYMLINK = lib32
> -endif
> -
>  # Populating the staging with the base directories is handled by the skeleton package
>  $(STAGING_DIR):
>  	@mkdir -p $(STAGING_DIR)
> diff --git a/package/gcc/gcc-initial/gcc-initial.mk b/package/gcc/gcc-initial/gcc-initial.mk
> index 1e58d8b..cf441ed 100644
> --- a/package/gcc/gcc-initial/gcc-initial.mk
> +++ b/package/gcc/gcc-initial/gcc-initial.mk
> @@ -64,4 +64,16 @@ HOST_GCC_INITIAL_TOOLCHAIN_WRAPPER_ARGS += $(HOST_GCC_COMMON_TOOLCHAIN_WRAPPER_A
>  HOST_GCC_INITIAL_POST_BUILD_HOOKS += TOOLCHAIN_BUILD_WRAPPER
>  HOST_GCC_INITIAL_POST_INSTALL_HOOKS += HOST_GCC_INSTALL_WRAPPER_AND_SIMPLE_SYMLINKS
>  
> +# The creation of lib32/lib64 symlinks into target and staging directories
> +# needs to be done before the C library is installed. Hooking into the libc
> +# hooks directly is tricky because there are multiple C libraries supported.
> +# Instead, hook into the install step of host-gcc-initial.
> +define HOST_GCC_INITIAL_CREATE_STAGING_TARGET_SYMLINK
> +	$(Q)ln -snf lib $(STAGING_DIR)/$(TOOLCHAIN_LIB_SYMLINK)
> +	$(Q)ln -snf lib $(STAGING_DIR)/usr/$(TOOLCHAIN_LIB_SYMLINK)
> +	$(Q)ln -snf lib $(TARGET_DIR)/$(TOOLCHAIN_LIB_SYMLINK)
> +	$(Q)ln -snf lib $(TARGET_DIR)/usr/$(TOOLCHAIN_LIB_SYMLINK)
> +endef
> +HOST_GCC_INITIAL_POST_INSTALL_HOOKS += HOST_GCC_INITIAL_CREATE_STAGING_TARGET_SYMLINK
> +
>  $(eval $(host-autotools-package))
> diff --git a/package/skeleton/skeleton.mk b/package/skeleton/skeleton.mk
> index 790afaf..b1395b5 100644
> --- a/package/skeleton/skeleton.mk
> +++ b/package/skeleton/skeleton.mk
> @@ -82,8 +82,6 @@ define SKELETON_INSTALL_TARGET_CMDS
>  		--chmod=u=rwX,go=rX --exclude .empty --exclude '*~' \
>  		$(SKELETON_PATH)/ $(TARGET_DIR)/
>  	$(call SKELETON_USR_SYMLINKS_OR_DIRS,$(TARGET_DIR))
> -	ln -snf lib $(TARGET_DIR)/$(LIB_SYMLINK)
> -	ln -snf lib $(TARGET_DIR)/usr/$(LIB_SYMLINK)
>  	$(INSTALL) -m 0644 support/misc/target-dir-warning.txt \
>  		$(TARGET_DIR_WARNING_FILE)
>  endef
> @@ -99,8 +97,6 @@ define SKELETON_INSTALL_STAGING_CMDS
>  	$(INSTALL) -d -m 0755 $(STAGING_DIR)/usr/sbin
>  	$(INSTALL) -d -m 0755 $(STAGING_DIR)/usr/include
>  	$(call SKELETON_USR_SYMLINKS_OR_DIRS,$(STAGING_DIR))
> -	ln -snf lib $(STAGING_DIR)/$(LIB_SYMLINK)
> -	ln -snf lib $(STAGING_DIR)/usr/$(LIB_SYMLINK)
>  endef
>  
>  SKELETON_TARGET_GENERIC_HOSTNAME = $(call qstrip,$(BR2_TARGET_GENERIC_HOSTNAME))
> diff --git a/toolchain/helpers.mk b/toolchain/helpers.mk
> index 1452ec6..f582ce9 100644
> --- a/toolchain/helpers.mk
> +++ b/toolchain/helpers.mk
> @@ -1,5 +1,28 @@
>  # This Makefile fragment declares toolchain related helper functions.
>  
> +# Create the necessary symlink from (usr/)lib32|lib64|lib32-fp|... to lib
> +# In general, for external toolchains, the correct link name is $ARCH_LIB_DIR.
> +# However, there are some broken packages that expect lib32/lib64 anyway.
> +# Therefore, create lib32->lib or lib64->lib (as appropriate) and additionally
> +# $(ARCH_LIB_DIR)->lib.
> +#
> +# MIPS64/n32 requires lib32 even though it's a 64-bit arch.
> +ifeq ($(BR2_ARCH_IS_64)$(BR2_MIPS_NABI32),y)
> +TOOLCHAIN_LIB_SYMLINK = lib64
> +else
> +TOOLCHAIN_LIB_SYMLINK = lib32
> +endif
> +# $1: destination directory (TARGET_DIR / STAGING_DIR)
> +create_lib_symlinks = \
> +	DESTDIR="$(strip $1)" ; \
> +	ARCH_LIB_DIR="$(call toolchain_find_libdir,$(TOOLCHAIN_EXTERNAL_CC) $(TOOLCHAIN_EXTERNAL_CFLAGS))" ; \
> +	ln -snf lib "$${DESTDIR}/$(TOOLCHAIN_LIB_SYMLINK)" ; \
> +	ln -snf lib "$${DESTDIR}/usr/$(TOOLCHAIN_LIB_SYMLINK)" ; \
> +	if [ "$${ARCH_LIB_DIR}" != "lib" -a "$${ARCH_LIB_DIR}" != "$(TOOLCHAIN_LIB_SYMLINK)" ]; then \
> +		ln -snf lib "$${DESTDIR}/$${ARCH_LIB_DIR}" ; \
> +		ln -snf lib "$${DESTDIR}/usr/$${ARCH_LIB_DIR}" ; \
> +	fi
> +
>  # The copy_toolchain_lib_root function copies a toolchain library and
>  # its symbolic links from the sysroot directory to the target
>  # directory. Note that this function is used both by the external
> diff --git a/toolchain/toolchain-external/toolchain-external.mk b/toolchain/toolchain-external/toolchain-external.mk
> index 745b685..e20268e 100644
> --- a/toolchain/toolchain-external/toolchain-external.mk
> +++ b/toolchain/toolchain-external/toolchain-external.mk
> @@ -689,6 +689,14 @@ define TOOLCHAIN_EXTERNAL_INSTALL_SYSROOT_LIBS
>  	$(call copy_toolchain_sysroot,$${SYSROOT_DIR},$${ARCH_SYSROOT_DIR},$${ARCH_SUBDIR},$${ARCH_LIB_DIR},$${SUPPORT_LIB_DIR})
>  endef
>  
> +define TOOLCHAIN_EXTERNAL_CREATE_STAGING_LIB_SYMLINK
> +	$(call create_lib_symlinks,$(STAGING_DIR))
> +endef
> +
> +define TOOLCHAIN_EXTERNAL_CREATE_TARGET_LIB_SYMLINK
> +	$(call create_lib_symlinks,$(TARGET_DIR))
> +endef
> +
>  # Special installation target used on the Blackfin architecture when
>  # FDPIC is not the primary binary format being used, but the user has
>  # nonetheless requested the installation of the FDPIC libraries to the
> @@ -803,6 +811,7 @@ endef
>  TOOLCHAIN_EXTERNAL_BUILD_CMDS = $(TOOLCHAIN_BUILD_WRAPPER)
>  
>  define TOOLCHAIN_EXTERNAL_INSTALL_STAGING_CMDS
> +	$(TOOLCHAIN_EXTERNAL_CREATE_STAGING_LIB_SYMLINK)
>  	$(TOOLCHAIN_EXTERNAL_INSTALL_SYSROOT_LIBS)
>  	$(TOOLCHAIN_EXTERNAL_INSTALL_WRAPPER)
>  	$(TOOLCHAIN_EXTERNAL_INSTALL_GDBINIT)
> @@ -812,6 +821,7 @@ endef
>  # and the target directory, we do everything within the
>  # install-staging step, arbitrarily.
>  define TOOLCHAIN_EXTERNAL_INSTALL_TARGET_CMDS
> +	$(TOOLCHAIN_EXTERNAL_CREATE_TARGET_LIB_SYMLINK)
>  	$(TOOLCHAIN_EXTERNAL_INSTALL_TARGET_LIBS)
>  	$(TOOLCHAIN_EXTERNAL_INSTALL_BFIN_FDPIC)
>  	$(TOOLCHAIN_EXTERNAL_INSTALL_BFIN_FLAT)
>
Thomas De Schampheleire Jan. 14, 2016, 7:35 p.m. UTC | #3
On Wed, Jan 13, 2016 at 12:12 AM, Romain Naour <romain.naour@gmail.com> wrote:
> Hi Thomas, All,
>
> Le 22/12/2015 13:35, Thomas De Schampheleire a écrit :
>> From: Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>
>>
>> Currently, following symbolic links are created in both target and
>> staging directories:
>> - lib(32|64) --> lib
>> - usr/lib(32|64) --> lib
>>
>> The decision for lib32 or lib64 is based on the target architecture
>> configuration in buildroot (BR2_ARCH_IS_64).
>>
>> In at least one case this is not correct: when building for a Cavium Octeon
>> III processor using the toolchain from the Cavium Networks SDK, and
>> specifying -march=octeon3 in BR2_TARGET_OPTIMIZATION, libraries are expected
>> in directory 'lib32-fp' rather than 'lib32' (likewise for lib64-fp).
>>
>> More generally, for external toolchains, the correct symbolic link is
>> from (usr/)${ARCH_LIB_DIR} to lib. For internal toolchains, current
>> toolchains always use either lib32 or lib64.
>>
>> Feedback from Arnout Vandecappelle is that there are packages that do depend
>> on the lib32/lib64 symlink, even if ARCH_LIB_DIR is different. Hence, these
>> must be kept.
>>
>> Fix the problem as follows:
>> - For internal toolchains: no functional change, but move the symlink
>>   creation from Makefile to package gcc-initial.
>> - For external toolchains: create a symlink creation helper in
>>   toolchain/helpers.mk, which first creates lib32->lib or lib64->lib as
>>   appropriate, and then creates ARCH_LIB_DIR->lib if that is different from
>>   lib32/lib64.
>
> Not so related to your patch though...
> I reviewed some patches about x32 and ilp32 toolchains support and it seems that
> we need to handle at least two more weird libraries location: libx32 and
> libilp32. Each of these series try to define LIB_SYMLINK with their own specific
> value (libilp32 and libx32).
>
> See:
> x86-64 x32 ABI:
> http://patchwork.ozlabs.org/patch/561904/
>
> aarch64 ilp32 ABI:
> http://patchwork.ozlabs.org/patch/506803/
> http://patchwork.ozlabs.org/patch/506800/
> http://patchwork.ozlabs.org/patch/506801/
>
> In your patch, I like create_lib_symlinks helper function which avoid to define
> TOOLCHAIN_LIB_SYMLINK with a different value than lib32 and lib64. Instead we
> rely on the ARCH_LIB_DIR returned by the arch-sysroot to create additional
> symlinks with the correct name.
>
> Obviously, we need to adjust the sed "magic" in toolchain_find_libdir and
> toolchain_find_sysroot for libilp32 and libx32 but we can do that in a followup
> patch series.
>
> So, I think this patch make it easier to add the support of theses specific
> toolchains:
>
> Reviewed-by: Romain Naour <romain.naour@gmail.com>
>

Thank you, Romain.

With the upcoming Febuary stabilization month and subsequent release,
I would like to kindly ask (almost beg, really) that this patch be
included in the release. I know that toolchain patches are not sexy,
but they are important. This patch has been around for a very long
time, and the associated rebasing and retesting on my part is
time-consuming and very demotivating.

Thanks,
Thomas
Thomas Petazzoni Jan. 17, 2016, 2:45 p.m. UTC | #4
Thomas,

On Tue, 22 Dec 2015 13:35:34 +0100, Thomas De Schampheleire wrote:

> Currently, following symbolic links are created in both target and
> staging directories:
> - lib(32|64) --> lib
> - usr/lib(32|64) --> lib
> 
> The decision for lib32 or lib64 is based on the target architecture
> configuration in buildroot (BR2_ARCH_IS_64).
> 
> In at least one case this is not correct: when building for a Cavium Octeon
> III processor using the toolchain from the Cavium Networks SDK, and
> specifying -march=octeon3 in BR2_TARGET_OPTIMIZATION, libraries are expected
> in directory 'lib32-fp' rather than 'lib32' (likewise for lib64-fp).
> 
> More generally, for external toolchains, the correct symbolic link is
> from (usr/)${ARCH_LIB_DIR} to lib. For internal toolchains, current
> toolchains always use either lib32 or lib64.
> 
> Feedback from Arnout Vandecappelle is that there are packages that do depend
> on the lib32/lib64 symlink, even if ARCH_LIB_DIR is different. Hence, these
> must be kept.
> 
> Fix the problem as follows:
> - For internal toolchains: no functional change, but move the symlink
>   creation from Makefile to package gcc-initial.
> - For external toolchains: create a symlink creation helper in
>   toolchain/helpers.mk, which first creates lib32->lib or lib64->lib as
>   appropriate, and then creates ARCH_LIB_DIR->lib if that is different from
>   lib32/lib64.

I don't quite understand the benefit of duplicating the code that
creates the lib32/lib64 symlinks. It used to be part of the skeleton,
which ensures the code is common to all cases (i.e internal or external
cases). And now with this change, you are duplicating it in the
external toolchain code and the host-gcc-initial code. What's the
benefit of doing this?

Unless I missed something, this patch should be simplified to leave the
creation of lib32/lib64 as is (i.e in skeleton.mk), and only the
external toolchain code should be changed to create the $(ARCH_LIB_DIR)
symlink when needed.

Note that the move of the LIB_SYMLINK definition from the main Makefile
to toolchain/helpers.mk remains a good change IMO (I like when things
are removed from the main Makefile). Or it could be moved to
skeleton.mk just above where it is used. But it should be a separate
change.

Best regards,

Thomas
Thomas De Schampheleire Jan. 19, 2016, 2:15 p.m. UTC | #5
Hi Thomas,

Thanks for your response.

On Sun, Jan 17, 2016 at 3:45 PM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:
> Thomas,
>
> On Tue, 22 Dec 2015 13:35:34 +0100, Thomas De Schampheleire wrote:
>
>> Currently, following symbolic links are created in both target and
>> staging directories:
>> - lib(32|64) --> lib
>> - usr/lib(32|64) --> lib
>>
>> The decision for lib32 or lib64 is based on the target architecture
>> configuration in buildroot (BR2_ARCH_IS_64).
>>
>> In at least one case this is not correct: when building for a Cavium Octeon
>> III processor using the toolchain from the Cavium Networks SDK, and
>> specifying -march=octeon3 in BR2_TARGET_OPTIMIZATION, libraries are expected
>> in directory 'lib32-fp' rather than 'lib32' (likewise for lib64-fp).
>>
>> More generally, for external toolchains, the correct symbolic link is
>> from (usr/)${ARCH_LIB_DIR} to lib. For internal toolchains, current
>> toolchains always use either lib32 or lib64.
>>
>> Feedback from Arnout Vandecappelle is that there are packages that do depend
>> on the lib32/lib64 symlink, even if ARCH_LIB_DIR is different. Hence, these
>> must be kept.
>>
>> Fix the problem as follows:
>> - For internal toolchains: no functional change, but move the symlink
>>   creation from Makefile to package gcc-initial.
>> - For external toolchains: create a symlink creation helper in
>>   toolchain/helpers.mk, which first creates lib32->lib or lib64->lib as
>>   appropriate, and then creates ARCH_LIB_DIR->lib if that is different from
>>   lib32/lib64.
>
> I don't quite understand the benefit of duplicating the code that
> creates the lib32/lib64 symlinks. It used to be part of the skeleton,
> which ensures the code is common to all cases (i.e internal or external
> cases). And now with this change, you are duplicating it in the
> external toolchain code and the host-gcc-initial code. What's the
> benefit of doing this?
>
> Unless I missed something, this patch should be simplified to leave the
> creation of lib32/lib64 as is (i.e in skeleton.mk), and only the
> external toolchain code should be changed to create the $(ARCH_LIB_DIR)
> symlink when needed.

In earlier versions of the patch, I stated that the symlink creation
needs to happen before gcc-initial is built. This is the reason we are
hooking into gcc-initial. This was also effectively the case before
the skeleton package was introduced.
However, with the introduction of the skeleton package, the symlinks
are (today, without my patch) created after the toolchain is built.
This puzzles me, as it does not match my earlier observations and
statements. Do you know if anything else has changed in this respect?

If there is no need to create the symlink at gcc-initial time, then
yes this patch can be simplified.

/Thomas
Thomas De Schampheleire Jan. 19, 2016, 2:17 p.m. UTC | #6
On Tue, Jan 19, 2016 at 3:15 PM, Thomas De Schampheleire
<patrickdepinguin@gmail.com> wrote:
> Hi Thomas,
>
> Thanks for your response.
>
> On Sun, Jan 17, 2016 at 3:45 PM, Thomas Petazzoni
> <thomas.petazzoni@free-electrons.com> wrote:
>> Thomas,
>>
>> On Tue, 22 Dec 2015 13:35:34 +0100, Thomas De Schampheleire wrote:
>>
>>> Currently, following symbolic links are created in both target and
>>> staging directories:
>>> - lib(32|64) --> lib
>>> - usr/lib(32|64) --> lib
>>>
>>> The decision for lib32 or lib64 is based on the target architecture
>>> configuration in buildroot (BR2_ARCH_IS_64).
>>>
>>> In at least one case this is not correct: when building for a Cavium Octeon
>>> III processor using the toolchain from the Cavium Networks SDK, and
>>> specifying -march=octeon3 in BR2_TARGET_OPTIMIZATION, libraries are expected
>>> in directory 'lib32-fp' rather than 'lib32' (likewise for lib64-fp).
>>>
>>> More generally, for external toolchains, the correct symbolic link is
>>> from (usr/)${ARCH_LIB_DIR} to lib. For internal toolchains, current
>>> toolchains always use either lib32 or lib64.
>>>
>>> Feedback from Arnout Vandecappelle is that there are packages that do depend
>>> on the lib32/lib64 symlink, even if ARCH_LIB_DIR is different. Hence, these
>>> must be kept.
>>>
>>> Fix the problem as follows:
>>> - For internal toolchains: no functional change, but move the symlink
>>>   creation from Makefile to package gcc-initial.
>>> - For external toolchains: create a symlink creation helper in
>>>   toolchain/helpers.mk, which first creates lib32->lib or lib64->lib as
>>>   appropriate, and then creates ARCH_LIB_DIR->lib if that is different from
>>>   lib32/lib64.
>>
>> I don't quite understand the benefit of duplicating the code that
>> creates the lib32/lib64 symlinks. It used to be part of the skeleton,
>> which ensures the code is common to all cases (i.e internal or external
>> cases). And now with this change, you are duplicating it in the
>> external toolchain code and the host-gcc-initial code. What's the
>> benefit of doing this?
>>
>> Unless I missed something, this patch should be simplified to leave the
>> creation of lib32/lib64 as is (i.e in skeleton.mk), and only the
>> external toolchain code should be changed to create the $(ARCH_LIB_DIR)
>> symlink when needed.
>
> In earlier versions of the patch, I stated that the symlink creation
> needs to happen before gcc-initial is built. This is the reason we are
> hooking into gcc-initial. This was also effectively the case before
> the skeleton package was introduced.

Small correction, the statement is:
+# The creation of lib32/lib64 symlinks into target and staging directories
+# needs to be done before the C library is installed.
Peter Korsgaard Jan. 19, 2016, 2:26 p.m. UTC | #7
>>>>> "Thomas" == Thomas De Schampheleire <patrickdepinguin@gmail.com> writes:

Hi,

>> In earlier versions of the patch, I stated that the symlink creation
 >> needs to happen before gcc-initial is built. This is the reason we are
 >> hooking into gcc-initial. This was also effectively the case before
 >> the skeleton package was introduced.

 > Small correction, the statement is:
 > +# The creation of lib32/lib64 symlinks into target and staging directories
 > +# needs to be done before the C library is installed.

And that's already the case, right? E.G. all packages depend on
skeleton, including the glibc/uclibc/musl packages.

E.G. from a build with an external toolchain:

1453212927:start:extract             : linux
1453212938:end  :extract             : linux
1453212938:start:patch               : linux
1453212939:end  :patch               : linux
1453213000:start:extract             : skeleton
1453213000:end  :extract             : skeleton
1453213000:start:patch               : skeleton
1453213000:end  :patch               : skeleton
1453213000:start:configure           : skeleton
1453213000:end  :configure           : skeleton
1453213000:start:build               : skeleton
1453213000:end  :build               : skeleton
1453213000:start:install-staging     : skeleton
1453213000:end  :install-staging     : skeleton
1453213000:start:install-target      : skeleton
1453213001:end  :install-target      : skeleton
1453213002:start:extract             : toolchain-external
Thomas De Schampheleire Jan. 19, 2016, 4:01 p.m. UTC | #8
On Tue, Jan 19, 2016 at 3:26 PM, Peter Korsgaard <peter@korsgaard.com> wrote:
>>>>>> "Thomas" == Thomas De Schampheleire <patrickdepinguin@gmail.com> writes:
>
> Hi,
>
>>> In earlier versions of the patch, I stated that the symlink creation
>  >> needs to happen before gcc-initial is built. This is the reason we are
>  >> hooking into gcc-initial. This was also effectively the case before
>  >> the skeleton package was introduced.
>
>  > Small correction, the statement is:
>  > +# The creation of lib32/lib64 symlinks into target and staging directories
>  > +# needs to be done before the C library is installed.
>
> And that's already the case, right? E.G. all packages depend on
> skeleton, including the glibc/uclibc/musl packages.

Ok, so that is the missing part of the puzzle.

On 2015.05, where skeleton was not yet a package, and so the situation
upon which the original patch was based, the symlinks were made in the
.root target. To allow for this new symlink behavior, it had to be
moved, but it had to be before the C library. The toolchain target was
too late, gcc-initial was voted the 'best' place at the time.

I was not aware that glibc already depends on skeleton. Then indeed
ThomasP's reasoning is correct and the patch should be simplified. I
will investigate that further and resubmit.

Thanks for the feedback,
Thomas
Yann E. MORIN Jan. 19, 2016, 6:29 p.m. UTC | #9
Thomas², Peter, All,

On 2016-01-19 17:01 +0100, Thomas De Schampheleire spake thusly:
> On Tue, Jan 19, 2016 at 3:26 PM, Peter Korsgaard <peter@korsgaard.com> wrote:
> >>>>>> "Thomas" == Thomas De Schampheleire <patrickdepinguin@gmail.com> writes:
> >
> > Hi,
> >
> >>> In earlier versions of the patch, I stated that the symlink creation
> >  >> needs to happen before gcc-initial is built. This is the reason we are
> >  >> hooking into gcc-initial. This was also effectively the case before
> >  >> the skeleton package was introduced.
> >
> >  > Small correction, the statement is:
> >  > +# The creation of lib32/lib64 symlinks into target and staging directories
> >  > +# needs to be done before the C library is installed.
> >
> > And that's already the case, right? E.G. all packages depend on
> > skeleton, including the glibc/uclibc/musl packages.
> 
> Ok, so that is the missing part of the puzzle.
> 
> On 2015.05, where skeleton was not yet a package, and so the situation
> upon which the original patch was based, the symlinks were made in the
> .root target. To allow for this new symlink behavior, it had to be
> moved, but it had to be before the C library. The toolchain target was
> too late, gcc-initial was voted the 'best' place at the time.
> 
> I was not aware that glibc already depends on skeleton. Then indeed
> ThomasP's reasoning is correct and the patch should be simplified. I
> will investigate that further and resubmit.

Skeleton is currently not a dependency of host-gcc-initial, so you'd
have to make it so.

Regards,
Yann E. MORIN.
Peter Korsgaard Jan. 19, 2016, 6:35 p.m. UTC | #10
>>>>> "Yann" == Yann E MORIN <yann.morin.1998@free.fr> writes:

Hi,

>> I was not aware that glibc already depends on skeleton. Then indeed
 >> ThomasP's reasoning is correct and the patch should be simplified. I
 >> will investigate that further and resubmit.

 > Skeleton is currently not a dependency of host-gcc-initial, so you'd
 > have to make it so.

Ahh yes, we only add it for target packages.
Thomas De Schampheleire Jan. 19, 2016, 7:40 p.m. UTC | #11
On Jan 19, 2016 19:35, "Peter Korsgaard" <peter@korsgaard.com> wrote:
>
> >>>>> "Yann" == Yann E MORIN <yann.morin.1998@free.fr> writes:
>
> Hi,
>
> >> I was not aware that glibc already depends on skeleton. Then indeed
>  >> ThomasP's reasoning is correct and the patch should be simplified. I
>  >> will investigate that further and resubmit.
>
>  > Skeleton is currently not a dependency of host-gcc-initial, so you'd
>  > have to make it so.
>
> Ahh yes, we only add it for target packages.

I did 'make clean toolchain' on x86-64 qemu defconfig but with glibc, and
at the end I noticed that skeleton was built and the symlinks were
correctly created.
So which package had the skeleton dependency? (Don't have a buildroot near
me ATM)

/Thomas
Thomas Petazzoni Jan. 19, 2016, 8:03 p.m. UTC | #12
Hello,

On Tue, 19 Jan 2016 19:29:47 +0100, Yann E. MORIN wrote:

> > I was not aware that glibc already depends on skeleton. Then indeed
> > ThomasP's reasoning is correct and the patch should be simplified. I
> > will investigate that further and resubmit.
> 
> Skeleton is currently not a dependency of host-gcc-initial, so you'd
> have to make it so.

Why? As explained on IRC, the only reason why Thomas DS did create the
symlinks in host-gcc-initial is to avoid duplicating this logic in all
three C library packages. But the symlinks are really only needed
before building/installing the C libraries, as far as I'm aware. So
creating them in the skeleton is OK.

Remember: in the current situation (i.e before Thomas DS patch), the
symlinks *are* created in the skeleton. And things are working fine
today, right ?

Thomas
Arnout Vandecappelle Jan. 19, 2016, 10:57 p.m. UTC | #13
On 19-01-16 20:40, Thomas De Schampheleire wrote:
> 
> On Jan 19, 2016 19:35, "Peter Korsgaard" <peter@korsgaard.com
> <mailto:peter@korsgaard.com>> wrote:
>>
>> >>>>> "Yann" == Yann E MORIN <yann.morin.1998@free.fr
> <mailto:yann.morin.1998@free.fr>> writes:
>>
>> Hi,
>>
>> >> I was not aware that glibc already depends on skeleton. Then indeed
>>  >> ThomasP's reasoning is correct and the patch should be simplified. I
>>  >> will investigate that further and resubmit.
>>
>>  > Skeleton is currently not a dependency of host-gcc-initial, so you'd
>>  > have to make it so.
>>
>> Ahh yes, we only add it for target packages.
> 
> I did 'make clean toolchain' on x86-64 qemu defconfig but with glibc, and at the
> end I noticed that skeleton was built and the symlinks were correctly created.
> So which package had the skeleton dependency? (Don't have a buildroot near me ATM)

 glibc is a target package so depends on skeleton (see pkg-generic.mk, search
for skeleton).

 Regards,
 Arnout

> 
> /Thomas
> 
> 
> 
> _______________________________________________
> buildroot mailing list
> buildroot@busybox.net
> http://lists.busybox.net/mailman/listinfo/buildroot
>
Yann E. MORIN Jan. 19, 2016, 11:02 p.m. UTC | #14
Arnout, Thomas, All,

On 2016-01-19 23:57 +0100, Arnout Vandecappelle spake thusly:
> On 19-01-16 20:40, Thomas De Schampheleire wrote:
> > 
> > On Jan 19, 2016 19:35, "Peter Korsgaard" <peter@korsgaard.com
> > <mailto:peter@korsgaard.com>> wrote:
> >>
> >> >>>>> "Yann" == Yann E MORIN <yann.morin.1998@free.fr
> > <mailto:yann.morin.1998@free.fr>> writes:
> >>
> >> Hi,
> >>
> >> >> I was not aware that glibc already depends on skeleton. Then indeed
> >>  >> ThomasP's reasoning is correct and the patch should be simplified. I
> >>  >> will investigate that further and resubmit.
> >>
> >>  > Skeleton is currently not a dependency of host-gcc-initial, so you'd
> >>  > have to make it so.
> >>
> >> Ahh yes, we only add it for target packages.
> > 
> > I did 'make clean toolchain' on x86-64 qemu defconfig but with glibc, and at the
> > end I noticed that skeleton was built and the symlinks were correctly created.
> > So which package had the skeleton dependency? (Don't have a buildroot near me ATM)
> 
>  glibc is a target package so depends on skeleton (see pkg-generic.mk, search
> for skeleton).

And even before glibc, linux-headers is a target package. ;-)

Regards,
Yann E. MORIN.
diff mbox

Patch

diff --git a/Makefile b/Makefile
index dc657d9..63f4c54 100644
--- a/Makefile
+++ b/Makefile
@@ -448,14 +448,6 @@  world: target-post-image
 $(BUILD_DIR) $(TARGET_DIR) $(HOST_DIR) $(BINARIES_DIR) $(LEGAL_INFO_DIR) $(REDIST_SOURCES_DIR_TARGET) $(REDIST_SOURCES_DIR_HOST):
 	@mkdir -p $@
 
-# We make a symlink lib32->lib or lib64->lib as appropriate
-# MIPS64/n32 requires lib32 even though it's a 64-bit arch.
-ifeq ($(BR2_ARCH_IS_64)$(BR2_MIPS_NABI32),y)
-LIB_SYMLINK = lib64
-else
-LIB_SYMLINK = lib32
-endif
-
 # Populating the staging with the base directories is handled by the skeleton package
 $(STAGING_DIR):
 	@mkdir -p $(STAGING_DIR)
diff --git a/package/gcc/gcc-initial/gcc-initial.mk b/package/gcc/gcc-initial/gcc-initial.mk
index 1e58d8b..cf441ed 100644
--- a/package/gcc/gcc-initial/gcc-initial.mk
+++ b/package/gcc/gcc-initial/gcc-initial.mk
@@ -64,4 +64,16 @@  HOST_GCC_INITIAL_TOOLCHAIN_WRAPPER_ARGS += $(HOST_GCC_COMMON_TOOLCHAIN_WRAPPER_A
 HOST_GCC_INITIAL_POST_BUILD_HOOKS += TOOLCHAIN_BUILD_WRAPPER
 HOST_GCC_INITIAL_POST_INSTALL_HOOKS += HOST_GCC_INSTALL_WRAPPER_AND_SIMPLE_SYMLINKS
 
+# The creation of lib32/lib64 symlinks into target and staging directories
+# needs to be done before the C library is installed. Hooking into the libc
+# hooks directly is tricky because there are multiple C libraries supported.
+# Instead, hook into the install step of host-gcc-initial.
+define HOST_GCC_INITIAL_CREATE_STAGING_TARGET_SYMLINK
+	$(Q)ln -snf lib $(STAGING_DIR)/$(TOOLCHAIN_LIB_SYMLINK)
+	$(Q)ln -snf lib $(STAGING_DIR)/usr/$(TOOLCHAIN_LIB_SYMLINK)
+	$(Q)ln -snf lib $(TARGET_DIR)/$(TOOLCHAIN_LIB_SYMLINK)
+	$(Q)ln -snf lib $(TARGET_DIR)/usr/$(TOOLCHAIN_LIB_SYMLINK)
+endef
+HOST_GCC_INITIAL_POST_INSTALL_HOOKS += HOST_GCC_INITIAL_CREATE_STAGING_TARGET_SYMLINK
+
 $(eval $(host-autotools-package))
diff --git a/package/skeleton/skeleton.mk b/package/skeleton/skeleton.mk
index 790afaf..b1395b5 100644
--- a/package/skeleton/skeleton.mk
+++ b/package/skeleton/skeleton.mk
@@ -82,8 +82,6 @@  define SKELETON_INSTALL_TARGET_CMDS
 		--chmod=u=rwX,go=rX --exclude .empty --exclude '*~' \
 		$(SKELETON_PATH)/ $(TARGET_DIR)/
 	$(call SKELETON_USR_SYMLINKS_OR_DIRS,$(TARGET_DIR))
-	ln -snf lib $(TARGET_DIR)/$(LIB_SYMLINK)
-	ln -snf lib $(TARGET_DIR)/usr/$(LIB_SYMLINK)
 	$(INSTALL) -m 0644 support/misc/target-dir-warning.txt \
 		$(TARGET_DIR_WARNING_FILE)
 endef
@@ -99,8 +97,6 @@  define SKELETON_INSTALL_STAGING_CMDS
 	$(INSTALL) -d -m 0755 $(STAGING_DIR)/usr/sbin
 	$(INSTALL) -d -m 0755 $(STAGING_DIR)/usr/include
 	$(call SKELETON_USR_SYMLINKS_OR_DIRS,$(STAGING_DIR))
-	ln -snf lib $(STAGING_DIR)/$(LIB_SYMLINK)
-	ln -snf lib $(STAGING_DIR)/usr/$(LIB_SYMLINK)
 endef
 
 SKELETON_TARGET_GENERIC_HOSTNAME = $(call qstrip,$(BR2_TARGET_GENERIC_HOSTNAME))
diff --git a/toolchain/helpers.mk b/toolchain/helpers.mk
index 1452ec6..f582ce9 100644
--- a/toolchain/helpers.mk
+++ b/toolchain/helpers.mk
@@ -1,5 +1,28 @@ 
 # This Makefile fragment declares toolchain related helper functions.
 
+# Create the necessary symlink from (usr/)lib32|lib64|lib32-fp|... to lib
+# In general, for external toolchains, the correct link name is $ARCH_LIB_DIR.
+# However, there are some broken packages that expect lib32/lib64 anyway.
+# Therefore, create lib32->lib or lib64->lib (as appropriate) and additionally
+# $(ARCH_LIB_DIR)->lib.
+#
+# MIPS64/n32 requires lib32 even though it's a 64-bit arch.
+ifeq ($(BR2_ARCH_IS_64)$(BR2_MIPS_NABI32),y)
+TOOLCHAIN_LIB_SYMLINK = lib64
+else
+TOOLCHAIN_LIB_SYMLINK = lib32
+endif
+# $1: destination directory (TARGET_DIR / STAGING_DIR)
+create_lib_symlinks = \
+	DESTDIR="$(strip $1)" ; \
+	ARCH_LIB_DIR="$(call toolchain_find_libdir,$(TOOLCHAIN_EXTERNAL_CC) $(TOOLCHAIN_EXTERNAL_CFLAGS))" ; \
+	ln -snf lib "$${DESTDIR}/$(TOOLCHAIN_LIB_SYMLINK)" ; \
+	ln -snf lib "$${DESTDIR}/usr/$(TOOLCHAIN_LIB_SYMLINK)" ; \
+	if [ "$${ARCH_LIB_DIR}" != "lib" -a "$${ARCH_LIB_DIR}" != "$(TOOLCHAIN_LIB_SYMLINK)" ]; then \
+		ln -snf lib "$${DESTDIR}/$${ARCH_LIB_DIR}" ; \
+		ln -snf lib "$${DESTDIR}/usr/$${ARCH_LIB_DIR}" ; \
+	fi
+
 # The copy_toolchain_lib_root function copies a toolchain library and
 # its symbolic links from the sysroot directory to the target
 # directory. Note that this function is used both by the external
diff --git a/toolchain/toolchain-external/toolchain-external.mk b/toolchain/toolchain-external/toolchain-external.mk
index 745b685..e20268e 100644
--- a/toolchain/toolchain-external/toolchain-external.mk
+++ b/toolchain/toolchain-external/toolchain-external.mk
@@ -689,6 +689,14 @@  define TOOLCHAIN_EXTERNAL_INSTALL_SYSROOT_LIBS
 	$(call copy_toolchain_sysroot,$${SYSROOT_DIR},$${ARCH_SYSROOT_DIR},$${ARCH_SUBDIR},$${ARCH_LIB_DIR},$${SUPPORT_LIB_DIR})
 endef
 
+define TOOLCHAIN_EXTERNAL_CREATE_STAGING_LIB_SYMLINK
+	$(call create_lib_symlinks,$(STAGING_DIR))
+endef
+
+define TOOLCHAIN_EXTERNAL_CREATE_TARGET_LIB_SYMLINK
+	$(call create_lib_symlinks,$(TARGET_DIR))
+endef
+
 # Special installation target used on the Blackfin architecture when
 # FDPIC is not the primary binary format being used, but the user has
 # nonetheless requested the installation of the FDPIC libraries to the
@@ -803,6 +811,7 @@  endef
 TOOLCHAIN_EXTERNAL_BUILD_CMDS = $(TOOLCHAIN_BUILD_WRAPPER)
 
 define TOOLCHAIN_EXTERNAL_INSTALL_STAGING_CMDS
+	$(TOOLCHAIN_EXTERNAL_CREATE_STAGING_LIB_SYMLINK)
 	$(TOOLCHAIN_EXTERNAL_INSTALL_SYSROOT_LIBS)
 	$(TOOLCHAIN_EXTERNAL_INSTALL_WRAPPER)
 	$(TOOLCHAIN_EXTERNAL_INSTALL_GDBINIT)
@@ -812,6 +821,7 @@  endef
 # and the target directory, we do everything within the
 # install-staging step, arbitrarily.
 define TOOLCHAIN_EXTERNAL_INSTALL_TARGET_CMDS
+	$(TOOLCHAIN_EXTERNAL_CREATE_TARGET_LIB_SYMLINK)
 	$(TOOLCHAIN_EXTERNAL_INSTALL_TARGET_LIBS)
 	$(TOOLCHAIN_EXTERNAL_INSTALL_BFIN_FDPIC)
 	$(TOOLCHAIN_EXTERNAL_INSTALL_BFIN_FLAT)