diff --git a/Makefile b/Makefile
index fcfc0be..e51875a 100644
--- a/Makefile
+++ b/Makefile
@@ -424,8 +424,6 @@ $(BUILD_DIR) $(HOST_DIR) $(BINARIES_DIR) $(STAMP_DIR) $(LEGAL_INFO_DIR) $(REDIST
 
 $(STAGING_DIR):
 	@mkdir -p $(STAGING_DIR)/bin
-	@mkdir -p $(STAGING_DIR)/lib
-	@mkdir -p $(STAGING_DIR)/usr/lib
 	@mkdir -p $(STAGING_DIR)/usr/include
 	@mkdir -p $(STAGING_DIR)/usr/bin
 	@ln -snf $(STAGING_DIR) $(BASE_DIR)/staging
diff --git a/arch/Config.in b/arch/Config.in
index 0b5b218..690c723 100644
--- a/arch/Config.in
+++ b/arch/Config.in
@@ -1,6 +1,10 @@
 config BR2_ARCH_IS_64
 	bool
 
+config BR2_ARCH_64_NEEDS_LIB32
+	bool
+	depends on BR2_ARCH_IS_64
+
 config BR2_SOFT_FLOAT
 	bool
 
diff --git a/arch/Config.in.mips b/arch/Config.in.mips
index 6242bcc..9054146 100644
--- a/arch/Config.in.mips
+++ b/arch/Config.in.mips
@@ -47,6 +47,7 @@ config BR2_MIPS_OABI32
 config BR2_MIPS_NABI32
 	bool "n32"
 	depends on BR2_ARCH_IS_64
+	select BR2_ARCH_64_NEEDS_LIB32
 config BR2_MIPS_NABI64
 	bool "n64"
 	depends on BR2_ARCH_IS_64
diff --git a/package/gcc/gcc-final/gcc-final.mk b/package/gcc/gcc-final/gcc-final.mk
index 9f54c68..bb821b7 100644
--- a/package/gcc/gcc-final/gcc-final.mk
+++ b/package/gcc/gcc-final/gcc-final.mk
@@ -57,14 +57,10 @@ HOST_GCC_FINAL_CONF_OPT += \
 
 # Handle lib64
 define HOST_GCC_FINAL_HANDLE_LIB64
-	if [ -d "$(STAGING_DIR)/lib64" ]; then \
-		if [ ! -e "$(STAGING_DIR)/lib" ]; then \
-			mkdir -p "$(STAGING_DIR)/lib"; \
-		fi; \
-		mv "$(STAGING_DIR)/lib64/"* "$(STAGING_DIR)/lib/"; \
-		rmdir "$(STAGING_DIR)/lib64"; \
-		rm "$(STAGING_DIR)/usr/$(GNU_TARGET_NAME)/lib64";\
-	fi
+	case "$(BR2_ARCH_IS_64)-$(BR2_ARCH_64_NEEDS_LIB32)" in \
+		y-)  $(call create_lib64_symlinks) ;; \
+		y-y) $(call create_lib32_symlinks) ;; \
+	esac ;
 endef
 
 HOST_GCC_FINAL_POST_INSTALL_HOOKS += HOST_GCC_FINAL_HANDLE_LIB64
diff --git a/toolchain/helpers.mk b/toolchain/helpers.mk
index 4c988a5..525fa47 100644
--- a/toolchain/helpers.mk
+++ b/toolchain/helpers.mk
@@ -129,6 +129,16 @@ copy_toolchain_lib_root = \
 # $5: support lib directories (for toolchains storing libgcc_s,
 #     libstdc++ and other gcc support libraries outside of the
 #     sysroot)
+ifeq ($(BR2_ARCH_IS_64),y)
+ifeq ($(BR2_ARCH_64_NEEDS_LIB32),y)
+TOOLCHAIN_LIBDIR_FILTER = usr/lib usr/lib64
+else
+TOOLCHAIN_LIBDIR_FILTER = usr/lib usr/lib32
+endif
+else
+TOOLCHAIN_LIBDIR_FILTER = usr/lib32 usr/lib64
+endif
+
 copy_toolchain_sysroot = \
 	SYSROOT_DIR="$(strip $1)"; \
 	ARCH_SYSROOT_DIR="$(strip $2)"; \
@@ -137,7 +147,12 @@ copy_toolchain_sysroot = \
 	SUPPORT_LIB_DIR="$(strip $5)" ; \
 	for i in etc $${ARCH_LIB_DIR} sbin usr ; do \
 		if [ -d $${ARCH_SYSROOT_DIR}/$$i ] ; then \
-			rsync -au --chmod=Du+w --exclude 'usr/lib/locale' $${ARCH_SYSROOT_DIR}/$$i $(STAGING_DIR)/ ; \
+			rsync -au --chmod=Du+w --exclude 'usr/lib/locale' \
+				`for d in $(TOOLCHAIN_LIBDIR_FILTER) ; do \
+					test "$${d} = "usr/$${ARCH_LIB_DIR}" || \
+						echo "--exclude '$${d}'" ; \
+				done` \
+				$${ARCH_SYSROOT_DIR}/$$i $(STAGING_DIR)/ ; \
 		fi ; \
 	done ; \
 	if [ `readlink -f $${SYSROOT_DIR}` != `readlink -f $${ARCH_SYSROOT_DIR}` ] ; then \
@@ -159,17 +174,34 @@ copy_toolchain_sysroot = \
 	find $(STAGING_DIR) -type d | xargs chmod 755
 
 #
-# Create lib64 -> lib and usr/lib64 -> usr/lib symbolic links in the
-# target and staging directories. This is needed for some 64 bits
-# toolchains such as the Crosstool-NG toolchains, for which the path
-# to the dynamic loader and other libraries is /lib64, but the
-# libraries are stored in /lib.
+# Create lib -> libXX or libXX -> lib as needed
+#  argument 1: bitwise or lib-suffix (32 or 64)
+#  argument 2: directory in which the symlink will be created
+#
+define create_libxx_symlink
+	( src=`test -d $(2)/lib$(1) && echo $(1)` ; \
+	  dst=`test -d $(2)/lib$(1) || echo $(1)` ; \
+	  ln -s "lib$${src}" "$(2)/lib$${dst}" )
+endef
+
+#
+# Create lib(32|64) -> lib and usr/lib(32|64) -> usr/lib symbolic
+# links in the target and staging directories. This is needed for
+# some 64 bits toolchains (with and without 32-bit ABI) for which the
+# path to the dynamic loader and other libraries is /lib64 or /lib32,
+# but the libraries are stored in /lib.
 #
 create_lib64_symlinks = \
-	(cd $(TARGET_DIR) ;      ln -s lib lib64) ; \
-	(cd $(TARGET_DIR)/usr ;  ln -s lib lib64) ; \
-	(cd $(STAGING_DIR) ;     ln -s lib lib64) ; \
-	(cd $(STAGING_DIR)/usr ; ln -s lib lib64)
+	$(call create_libxx_symlink,64,$(TARGET_DIR)) ; \
+	$(call create_libxx_symlink,64,$(TARGET_DIR)/usr) ; \
+	$(call create_libxx_symlink,64,$(STAGING_DIR)) ; \
+	$(call create_libxx_symlink,64,$(STAGING_DIR)/usr)
+
+create_lib32_symlinks = \
+	$(call create_libxx_symlink,32,$(TARGET_DIR)) ; \
+	$(call create_libxx_symlink,32,$(TARGET_DIR)/usr) ; \
+	$(call create_libxx_symlink,32,$(STAGING_DIR)) ; \
+	$(call create_libxx_symlink,32,$(STAGING_DIR)/usr)
 
 #
 # Check the availability of a particular glibc feature. This function
diff --git a/toolchain/toolchain-external/ext-tool.mk b/toolchain/toolchain-external/ext-tool.mk
index 01be85c..73967e5 100644
--- a/toolchain/toolchain-external/ext-tool.mk
+++ b/toolchain/toolchain-external/ext-tool.mk
@@ -449,7 +449,6 @@ $(STAMP_DIR)/ext-toolchain-installed: $(STAMP_DIR)/ext-toolchain-checked
 		fi ; \
 	fi ; \
 	ARCH_SUBDIR=`echo $${ARCH_SYSROOT_DIR} | sed -r -e "s:^$${SYSROOT_DIR}(.*)/$$:\1:"` ; \
-	mkdir -p $(TARGET_DIR)/lib ; \
 	if test -z "$(BR2_PREFER_STATIC_LIB)" ; then \
 		$(call MESSAGE,"Copying external toolchain libraries to target...") ; \
 		for libs in $(LIB_EXTERNAL_LIBS); do \
@@ -461,9 +460,10 @@ $(STAMP_DIR)/ext-toolchain-installed: $(STAMP_DIR)/ext-toolchain-checked
 	fi ; \
 	$(call MESSAGE,"Copying external toolchain sysroot to staging...") ; \
 	$(call copy_toolchain_sysroot,$${SYSROOT_DIR},$${ARCH_SYSROOT_DIR},$${ARCH_SUBDIR},$${ARCH_LIB_DIR},$${SUPPORT_LIB_DIR}) ; \
-	if [ -L $${ARCH_SYSROOT_DIR}/lib64 -o -d $${ARCH_SYSROOT_DIR}/lib64 ] ; then \
-		$(call create_lib64_symlinks) ; \
-	fi ; \
+	case "$(BR2_ARCH_IS_64)-$(BR2_ARCH_64_NEEDS_LIB32)" in \
+		y-)  $(call create_lib64_symlinks) ;; \
+		y-y) $(call create_lib32_symlinks) ;; \
+	esac ; \
 	if test "$(BR2_TOOLCHAIN_EXTERNAL_GDB_SERVER_COPY)" = "y"; then \
 		$(call MESSAGE,"Copying gdbserver") ; \
 		gdbserver_found=0 ; \
