public inbox for crossgcc@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 3/3] {e}glibc: Fix various multilib build bugs
@ 2014-02-04  8:44 Ray Donnelly
  0 siblings, 0 replies; 5+ messages in thread
From: Ray Donnelly @ 2014-02-04  8:44 UTC (permalink / raw)
  To: crossgcc

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: 0003-_e_glibc__Fix_various_multilib_build_bugs.patch --]
[-- Type: application/octet-stream, Size: 13588 bytes --]

# HG changeset patch
# User Ray Donnelly <mingw.android@gmail.com>
# Date 1391501320 0
#      Tue Feb 04 08:08:40 2014 +0000
# Node ID 8f8b94c987feadc63f23ca72b6de87d404c7cca7
# Parent  45760158aca33981b5bb882191043bd708b57dbb
{e}glibc: Fix various multilib build bugs

--host=${CT_TARGET} with eg -m32 is not right.
The arch part must be correct (i686 for 32-bit
and x86_64 for 64-bit). Un-fortunately GCC has
no mechanism for returning each arches triplet
so instead some hacks are used. Debian can ask
"gcc -m32 -print-multiarch" but this flag isnt
provided on other GCC builds.

The old symlinks from lib32/64 to lib are only
made if CT_MULTILIB=n, and the comment that we
are not multilib on the target side corrected.

The stub libc.so is compiled with extra_cflags
so that it is for the correct multilib arch.

The stub libc.so and crt*.o files are moved to
the multilib os directory and not the multilib
directory if gcc arg -print-multi-os-directory
is supported.

--libdir=<> is passed to libc's configure such
that it is made inplace in the multilib-os dir
and 'Fixing up multilib location' is no longer
required.

The multilib directories are sorted in reverse
order so that x86_64 is built finally. This is
because x86_64 headers are multilib-capable as
far back as glibc-2.15 (at least) whereas i686
headers were not multilib-capable until 2.16.

Signed-off-by: Ray Donnelly <mingw.android@gmail.com>

diff -r 45760158aca3 -r 8f8b94c987fe scripts/build/cc/gcc.sh
--- a/scripts/build/cc/gcc.sh	Tue Feb 04 07:55:11 2014 +0000
+++ b/scripts/build/cc/gcc.sh	Tue Feb 04 08:08:40 2014 +0000
@@ -375,6 +375,7 @@
 
     if [ "${CT_MULTILIB}" = "y" ]; then
         extra_config+=("--enable-multilib")
+        extra_config+=("--enable-targets=all")
     else
         extra_config+=("--disable-multilib")
     fi
diff -r 45760158aca3 -r 8f8b94c987fe scripts/build/libc/glibc-eglibc.sh-common
--- a/scripts/build/libc/glibc-eglibc.sh-common	Tue Feb 04 07:55:11 2014 +0000
+++ b/scripts/build/libc/glibc-eglibc.sh-common	Tue Feb 04 08:08:40 2014 +0000
@@ -76,6 +76,9 @@
     local multilib
     local multi_dir
     local multi_flags
+    local multi_arch
+    local native_arch
+    local rest_of_triplet
     local extra_dir
     local libc_headers libc_startfiles libc_full
     local hdr
@@ -85,6 +88,9 @@
         eval "${arg// /\\ }"
     done
 
+    native_arch=$(echo "${CT_TARGET}" | ${sed} "s,\(^[^\-]*\).*,\1,g")
+    rest_of_triplet=$(echo "${CT_TARGET}" | ${sed} "s,^[^\-]*\(.*\),\1,g")
+
     case "${libc_mode}" in
         startfiles)
             CT_DoStep INFO "Installing C library headers & start files"
@@ -103,8 +109,16 @@
 
     # If gcc is not configured for multilib, it still prints
     # a single line for the default settings
-    multilibs=( $("${CT_TARGET}-gcc" -print-multi-lib 2>/dev/null) )
+    # sort -r is a hack so that x86_64 gets built last because
+    # pre-2.16 only the x86_64 headers were applicable to both
+    # i686 and x86_64.
+    # The headers were unified (x86-64 won!) between 2.15 and
+    # 2.16 (BZ14117). This hack makes too many of assumptions
+    # and needs to be replaced with more robust logic. We need
+    # to force x86_64 arch to be last element in the array.
+    multilibs=( $("${CT_TARGET}-gcc" -print-multi-lib 2>/dev/null | sort -r) )
     for multilib in "${multilibs[@]}"; do
+        multi_arch="${native_arch}"
         multi_dir="${multilib%%;*}"
         if [ "${multi_dir}" != "." ]; then
             CT_DoStep INFO "Building for multilib subdir='${multi_dir}'"
@@ -114,6 +128,14 @@
                           )"
             extra_dir="/${multi_dir}"
 
+            # If more substitutions are needed then they
+            # should be added here, AArch64 for example?
+            if [ "${extra_flags}" = " -m32" ]; then
+              multi_arch=${native_arch/x86_64/i686}
+            elif [ "${extra_flags}" = " -m64" ]; then
+              multi_arch=${native_arch/i686/x86_64}
+            fi
+
             # glibc install its files in ${extra_dir}/{usr/,}lib
             # while gcc expects them in {,usr/}lib/${extra_dir}.
             # Prepare some symlinks so glibc installs in fact in
@@ -140,36 +162,15 @@
 
         CT_mkdir_pushd "${CT_BUILD_DIR}/build-libc-${libc_mode}${extra_dir//\//_}"
 
-        do_libc_backend_once extra_dir="${extra_dir}"               \
-                             extra_flags="${extra_flags}"           \
-                             libc_headers="${libc_headers}"         \
-                             libc_startfiles="${libc_startfiles}"   \
+        do_libc_backend_once extra_dir="${extra_dir}"                           \
+                             extra_flags="${extra_flags}"                       \
+                             libc_headers="${libc_headers}"                     \
+                             libc_startfiles="${libc_startfiles}"               \
+                             libc_triplet="${multi_arch}${rest_of_triplet}"     \
                              libc_full="${libc_full}"
 
         CT_Popd
 
-        if [ "${multi_dir}" != "." ]; then
-            if [ "${libc_mode}" = "final" ]; then
-                CT_DoLog EXTRA "Fixing up multilib location"
-
-                # rewrite the library multiplexers
-                for d in "lib/${multi_dir}" "usr/lib/${multi_dir}"; do
-                    for l in libc libpthread libgcc_s; do
-                        if [    -f "${CT_SYSROOT_DIR}/${d}/${l}.so"    \
-                             -a ! -L ${CT_SYSROOT_DIR}/${d}/${l}.so    ]
-                        then
-                            CT_DoExecLog DEBUG ${sed} -r -i                                 \
-                                                      -e "s:/lib/:/lib/${multi_dir}/:g;"    \
-                                                      "${CT_SYSROOT_DIR}/${d}/${l}.so"
-                        fi
-                    done
-                done
-                # Remove the multi_dir now it is no longer useful
-                CT_DoExecLog DEBUG rm -rf "${CT_SYSROOT_DIR}/${multi_dir}"
-            fi # libc_mode == final
-
-            CT_EndStep
-        fi
     done
 
     CT_EndStep
@@ -180,6 +181,7 @@
 #   Parameter           : Definition                            : Type      : Default
 #   libc_headers        : Build libc headers                    : bool      : n
 #   libc_startfiles     : Build libc start-files                : bool      : n
+#   libc_triplet        : Build libc triplet                    : string    : ${CT_TARGET}
 #   libc_full           : Build full libc                       : bool      : n
 #   extra_flags         : Extra CFLAGS to use (for multilib)    : string    : (empty)
 #   extra_dir           : Extra subdir for multilib             : string    : (empty)
@@ -189,6 +191,9 @@
     local libc_full
     local extra_flags
     local extra_dir
+    local extraos_dir
+    local lib_dir
+    local install_root
     local src_dir="${CT_SRC_DIR}/${CT_LIBC}-${CT_LIBC_VERSION}"
     local extra_cc_args
     local -a extra_config
@@ -196,6 +201,7 @@
     local glibc_cflags
     local float_extra
     local endian_extra
+    local libc_triplet="${CT_TARGET}"
     local arg
 
     for arg in "$@"; do
@@ -328,6 +334,29 @@
     # or even after they get installed...
     echo "ac_cv_path_BASH_SHELL=/bin/bash" >>config.cache
 
+    # GCC makes the distinction between multilib directories
+    # (gotten via -print-multilib or -print-multi-directory)
+    # and multilib-os directories (via -print-multi-os-directory)
+    # They are also often horribly mis-aligned, such as:
+    # multilib:    -m32=32      -m64=.
+    # multilib-os: -m32=../lib  -m64=../lib64
+    # it is important that multilib sub-folders of the sysroot use
+    # the multilib-os directory and *not* the multilib directory.
+    # The multilib directory is a GCC implementation detail rather
+    # than something that users need to be concerned about. Older
+    # GCCs do not understand -print-multi-os-directory so we fall
+    # back on some simple transformations (that are wrong in the
+    # above example!)
+    if "${cross_cc}" -print-multi-os-directory ${extra_cc_args} > /dev/null 2>&1; then
+        lib_dir=/usr/lib/$("${cross_cc}" -print-multi-os-directory ${extra_cc_args})
+        install_root="${CT_SYSROOT_DIR}"
+    else
+        # maintain the previous behaviour if -print-multi-os-directory doesn't work.
+        lib_dir=/usr/lib
+        install_root="${CT_SYSROOT_DIR}${extra_dir}"
+    fi
+    extraos_dir="${install_root}${lib_dir}"
+
     # Configure with --prefix the way we want it on the target...
     # There are a whole lot of settings here.  You'll probably want
     # to read up on what they all mean, and customize a bit, possibly by setting GLIBC_EXTRA_CONFIG_ARRAY
@@ -338,11 +367,14 @@
     # Run explicitly through CONFIG_SHELL, or the build breaks badly (loop-of-death)
     # when the shell is not bash... Sigh... :-(
 
-    CT_DoLog DEBUG "Using gcc for target    : '${cross_cc}'"
-    CT_DoLog DEBUG "Configuring with addons : '$(do_libc_add_ons_list ,)'"
-    CT_DoLog DEBUG "Extra config args passed: '${extra_config[*]}'"
-    CT_DoLog DEBUG "Extra CC args passed    : '${glibc_cflags}'"
-    CT_DoLog DEBUG "Extra flags (multilib)  : '${extra_flags}'"
+    CT_DoLog DEBUG "Using gcc for target     : '${cross_cc}'"
+    CT_DoLog DEBUG "Configuring with addons  : '$(do_libc_add_ons_list ,)'"
+    CT_DoLog DEBUG "Extra config args passed : '${extra_config[*]}'"
+    CT_DoLog DEBUG "Extra CC args passed     : '${glibc_cflags}'"
+    CT_DoLog DEBUG "Extra flags (multilib)   : '${extra_flags}'"
+    CT_DoLog DEBUG "Multilib os dir          : '${extraos_dir}'"
+    CT_DoLog DEBUG "Configuring with --host  : '${libc_triplet}'"
+    CT_DoLog DEBUG "Configuring with --libdir: '${lib_dir}'"
 
     CT_DoExecLog CFG                                                \
     BUILD_CC="${CT_BUILD}-gcc"                                      \
@@ -354,12 +386,13 @@
     "${src_dir}/configure"                                          \
         --prefix=/usr                                               \
         --build=${CT_BUILD}                                         \
-        --host=${CT_TARGET}                                         \
+        --host=${libc_triplet}                                      \
         --cache-file="$(pwd)/config.cache"                          \
         --without-cvs                                               \
         --disable-profile                                           \
         --without-gd                                                \
         --with-headers="${CT_HEADERS_DIR}"                          \
+        --libdir=${lib_dir}                                         \
         "${extra_config[@]}"                                        \
         "${CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY[@]}"
 
@@ -378,7 +411,7 @@
         # use the 'install-headers' makefile target to install the
         # headers
         CT_DoExecLog ALL make ${JOBSFLAGS}                          \
-                         install_root=${CT_SYSROOT_DIR}${extra_dir} \
+                         install_root="${install_root}"             \
                          install-bootstrap-headers=yes              \
                          "${extra_make_args[@]}"                    \
                          install-headers
@@ -427,22 +460,23 @@
 
             # there are a few object files needed to link shared libraries,
             # which we build and install by hand
-            CT_DoExecLog ALL mkdir -p "${CT_SYSROOT_DIR}${extra_dir}/usr/lib"
+            CT_DoExecLog ALL mkdir -p "${extraos_dir}"
             CT_DoExecLog ALL make ${JOBSFLAGS}  \
                         "${extra_make_args[@]}" \
                         csu/subdir_lib
             CT_DoExecLog ALL cp csu/crt1.o csu/crti.o csu/crtn.o    \
-                                "${CT_SYSROOT_DIR}${extra_dir}/usr/lib"
+                                "${extraos_dir}"
 
             # Finally, 'libgcc_s.so' requires a 'libc.so' to link against.
             # However, since we will never actually execute its code,
             # it doesn't matter what it contains.  So, treating '/dev/null'
             # as a C source file, we produce a dummy 'libc.so' in one step
-            CT_DoExecLog ALL "${cross_cc}" -nostdlib        \
+            CT_DoExecLog ALL "${cross_cc}" ${extra_flags}   \
+                                            -nostdlib       \
                                            -nostartfiles    \
                                            -shared          \
                                            -x c /dev/null   \
-                                           -o "${CT_SYSROOT_DIR}${extra_dir}/usr/lib/libc.so"
+                                           -o "${extraos_dir}/libc.so"
         fi # threads == nptl
     fi # libc_headers == y
 
@@ -453,9 +487,9 @@
                               all
 
         CT_DoLog EXTRA "Installing C library"
-        CT_DoExecLog ALL make ${JOBSFLAGS}                                  \
-                              "${extra_make_args[@]}"                       \
-                              install_root="${CT_SYSROOT_DIR}${extra_dir}"  \
+        CT_DoExecLog ALL make ${JOBSFLAGS}                    \
+                              "${extra_make_args[@]}"         \
+                              install_root="${install_root}"  \
                               install
 
         if [ "${CT_BUILD_MANUALS}" = "y" ]; then

[-- Attachment #3: Type: text/plain, Size: 71 bytes --]

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 3/3] {e}glibc: Fix various multilib build bugs
  2014-02-04 20:14 ` Bryan Hundven
@ 2014-02-04 21:33   ` Ray Donnelly
  0 siblings, 0 replies; 5+ messages in thread
From: Ray Donnelly @ 2014-02-04 21:33 UTC (permalink / raw)
  To: Bryan Hundven; +Cc: crossgcc

I'm not having the best time of it today! Bryan, I forgot to CC the ML
(so most of this you got already) but also, there's a dumb error in my
patch:

target = $(get_multilib_target "${extra_flags}")

needs to be changed to:

target=$(get_multilib_target "${extra_flags}")

On Tue, Feb 4, 2014 at 8:14 PM, Bryan Hundven <bryanhundven@gmail.com> wrote:
> Ray, Cody, list,
>
> On Tue, Feb 4, 2014 at 10:49 AM, Ray Donnelly <mingw.android@gmail.com> wrote:
>> Here is the new version using Cody's get_multilib_target () function.
>>
>> Cheers,
>>
>> Ray.
>
> I have some comments on this commit, but it's attached :(
> I recommend using the patchbomb method:
> http://crosstool-ng.org/hg/crosstool-ng/file/529a71ea091e/docs/C%20-%20Misc.%20tutorials.txt#l183
>

Sorry about the attachments, I've only submitted a few minor patches
so far and nothing that needed much discussion.
Is patchbomb easy to setup with gmail? If you can point me at some
instructions that'd be appreciated.
IMHO ctng should move to Git and use Gerrit (or failing that maybe
just github) for these code reviews, but I understand that this would
be quite a significant time drain to implement.

> Anyways, it seems to me that get_multilib_target should be stubbed in
> scripts/build/arch/multilib.sh, and implemented in the respective
> scripts/build/arch/<architecture>.sh
> Source multilib.sh after this line:
> http://crosstool-ng.org/hg/crosstool-ng/file/529a71ea091e/scripts/crosstool-NG.sh.in#l140
>

I agree we could move get_multilib_target somewhere more general
purpose, but I'd put it into multilib.sh and leave it at that.
Personally, I prefer having the full gory details available in (and
easily testable from) a single function rather than splitting it up.

> That way, any package - beyond (e)glibc - can obtain the multilib
> target info if needed.
>
> Other points are easier to discuss inline. Cody, Ray; what are your thoughts?
>
> -Bryan

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 3/3] {e}glibc: Fix various multilib build bugs
  2014-02-04 18:49 Ray Donnelly
@ 2014-02-04 20:14 ` Bryan Hundven
  2014-02-04 21:33   ` Ray Donnelly
  0 siblings, 1 reply; 5+ messages in thread
From: Bryan Hundven @ 2014-02-04 20:14 UTC (permalink / raw)
  To: Ray Donnelly; +Cc: crossgcc

Ray, Cody, list,

On Tue, Feb 4, 2014 at 10:49 AM, Ray Donnelly <mingw.android@gmail.com> wrote:
> Here is the new version using Cody's get_multilib_target () function.
>
> Cheers,
>
> Ray.

I have some comments on this commit, but it's attached :(
I recommend using the patchbomb method:
http://crosstool-ng.org/hg/crosstool-ng/file/529a71ea091e/docs/C%20-%20Misc.%20tutorials.txt#l183

Anyways, it seems to me that get_multilib_target should be stubbed in
scripts/build/arch/multilib.sh, and implemented in the respective
scripts/build/arch/<architecture>.sh
Source multilib.sh after this line:
http://crosstool-ng.org/hg/crosstool-ng/file/529a71ea091e/scripts/crosstool-NG.sh.in#l140

That way, any package - beyond (e)glibc - can obtain the multilib
target info if needed.

Other points are easier to discuss inline. Cody, Ray; what are your thoughts?

-Bryan

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 3/3] {e}glibc: Fix various multilib build bugs
@ 2014-02-04 18:49 Ray Donnelly
  2014-02-04 20:14 ` Bryan Hundven
  0 siblings, 1 reply; 5+ messages in thread
From: Ray Donnelly @ 2014-02-04 18:49 UTC (permalink / raw)
  To: crossgcc

[-- Attachment #1: Type: text/plain, Size: 85 bytes --]

Here is the new version using Cody's get_multilib_target () function.

Cheers,

Ray.

[-- Attachment #2: 0003-_e_glibc__Fix_various_multilib_build_bugs.patch --]
[-- Type: application/octet-stream, Size: 15299 bytes --]

# HG changeset patch
# User Ray Donnelly <mingw.android@gmail.com>
# Date 1391501320 0
#      Tue Feb 04 08:08:40 2014 +0000
# Node ID c1090b01b5b41ab3a346cb946b3a51a16109b876
# Parent  56f50b772982bc99cd1a7b1c8fc5afa5e8d7c751
{e}glibc: Fix various multilib build bugs

--host=${CT_TARGET} with eg -m32 is not right.
The arch part must be correct (i686 for 32-bit
and x86_64 for 64-bit). Un-fortunately GCC has
no mechanism for returning each arches triplet
so instead some hacks are used. Debian can ask
"gcc -m32 -print-multiarch" but this flag isnt
provided on other GCC builds.

The old symlinks from lib32/64 to lib are only
made if CT_MULTILIB=n, and the comment that we
are not multilib on the target side corrected.

The stub libc.so is compiled with extra_cflags
so that it is for the correct multilib arch.

The stub libc.so and crt*.o files are moved to
the multilib os directory and not the multilib
directory if gcc arg -print-multi-os-directory
is supported.

--libdir=<> is passed to libc's configure such
that it is made inplace in the multilib-os dir
and 'Fixing up multilib location' is no longer
required.

The multilib directories are sorted in reverse
order so that x86_64 is built finally. This is
because x86_64 headers are multilib-capable as
far back as glibc-2.15 (at least) whereas i686
headers were not multilib-capable until 2.16.

Utilizes get_multilib_target by Cody P Schafer

Signed-off-by: Ray Donnelly <mingw.android@gmail.com>
Signed-off-by: Cody P Schafer <dev@codyps.com>

diff -r 56f50b772982 -r c1090b01b5b4 scripts/build/cc/gcc.sh
--- a/scripts/build/cc/gcc.sh	Tue Feb 04 07:55:11 2014 +0000
+++ b/scripts/build/cc/gcc.sh	Tue Feb 04 08:08:40 2014 +0000
@@ -375,6 +375,7 @@
 
     if [ "${CT_MULTILIB}" = "y" ]; then
         extra_config+=("--enable-multilib")
+        extra_config+=("--enable-targets=all")
     else
         extra_config+=("--disable-multilib")
     fi
diff -r 56f50b772982 -r c1090b01b5b4 scripts/build/libc/glibc-eglibc.sh-common
--- a/scripts/build/libc/glibc-eglibc.sh-common	Tue Feb 04 07:55:11 2014 +0000
+++ b/scripts/build/libc/glibc-eglibc.sh-common	Tue Feb 04 08:08:40 2014 +0000
@@ -65,6 +65,64 @@
     do_libc_backend libc_mode=final
 }
 
+
+# Usage: get_multilib_target <multilib-flags>
+# Credit: Cody Schafer
+get_multilib_target () {
+    local multi_flags="$1"
+    local target="${CT_TARGET}"
+    local m32=false
+    local m31=false
+    local m64=false
+    local mx32=false
+    local mlittle=false
+    local mbig=flase
+
+    case "$multi_flags" in
+    *-m32*) m32=true;;
+    *-m64*) m64=true;;
+    *-m31*) m31=true;; # s390
+    *-mx32*) mx32=true ;; # x86_64
+
+    # powerpc
+    *-mbig*) mbig=true ;;
+    *-mlittle*) mlittle=true ;;
+
+    # mips
+    *-EL*) mlittle=true ;;
+    *-EB*) mbig=true ;;
+
+    esac
+
+    # TODO: actually run $CC with the multi_flags and check things out
+    # Right now we make some assumptions about bitness based on the target if
+    # _not_ overriden by multiflags. triplets in CT_TARGET that indicate they
+    # 64bit are assumed to not be hiding any funky configure options to change
+    # that. Similar for 32bit.
+
+    case "${CT_TARGET}" in
+    # FIXME: do we need to adjust the target for le vs be?
+    powerpc-*|powerpcle-*)     $m64 && target=${target/powerpc-/powerpc64-} ;;
+    powerpc64-*|powerpc64le-*) $m32 && target=${target/powerpc64-/powerpc-} ;;
+
+    x86_64-*gnux32)     $m64  && target=${target/%-gnux32/-gnu} ;;
+    x86_64-*)           $m32  && target=${target/x86_64-/i686-} ;;
+    x86_64-*)           $mx32 && target=${target/%-gnux32/-gnu} ;;
+
+    i[34567]86-*gnux32) die "Invalid target \"${CT_TARGET}\"" ;; # Nope
+    i[34567]86-*)       $mx32 && {
+                                        target=${target/%-gnu/-gnux32}
+                                        target=${target/i[34567]86-/x86_64-}
+                        } ;; # This is also very questionable (and probably wrong)
+    i[34567]86-*)       $m64 && target=${target/i[34567]86-/x86_64-} ;;
+
+    # TODO: mips, arm, spark
+
+    esac
+
+    echo "$target"
+}
+
 # This backend builds the C library once for each multilib
 # variant the compiler gives us
 # Usage: do_libc_backend param=value [...]
@@ -76,6 +134,8 @@
     local multilib
     local multi_dir
     local multi_flags
+    local multi_arch
+    local target
     local extra_dir
     local libc_headers libc_startfiles libc_full
     local hdr
@@ -103,8 +163,16 @@
 
     # If gcc is not configured for multilib, it still prints
     # a single line for the default settings
-    multilibs=( $("${CT_TARGET}-gcc" -print-multi-lib 2>/dev/null) )
+    # sort -r is a hack so that x86_64 gets built last because
+    # pre-2.16 only the x86_64 headers were applicable to both
+    # i686 and x86_64.
+    # The headers were unified (x86-64 won!) between 2.15 and
+    # 2.16 (BZ14117). This hack makes too many of assumptions
+    # and needs to be replaced with more robust logic. We need
+    # to force x86_64 arch to be last element in the array.
+    multilibs=( $("${CT_TARGET}-gcc" -print-multi-lib 2>/dev/null | sort -r) )
     for multilib in "${multilibs[@]}"; do
+        multi_arch="${native_arch}"
         multi_dir="${multilib%%;*}"
         if [ "${multi_dir}" != "." ]; then
             CT_DoStep INFO "Building for multilib subdir='${multi_dir}'"
@@ -114,6 +182,10 @@
                           )"
             extra_dir="/${multi_dir}"
 
+            # If more substitutions are needed then they
+            # should be added here, AArch64 for example?
+            target = $(get_multilib_target "${extra_flags}")
+
             # glibc install its files in ${extra_dir}/{usr/,}lib
             # while gcc expects them in {,usr/}lib/${extra_dir}.
             # Prepare some symlinks so glibc installs in fact in
@@ -136,40 +208,20 @@
             extra_dir=
             extra_flags=
             libc_headers="${hdr}"
+            target="${CT_TARGET}"
         fi
 
         CT_mkdir_pushd "${CT_BUILD_DIR}/build-libc-${libc_mode}${extra_dir//\//_}"
 
-        do_libc_backend_once extra_dir="${extra_dir}"               \
-                             extra_flags="${extra_flags}"           \
-                             libc_headers="${libc_headers}"         \
-                             libc_startfiles="${libc_startfiles}"   \
+        do_libc_backend_once extra_dir="${extra_dir}"              \
+                             extra_flags="${extra_flags}"          \
+                             libc_headers="${libc_headers}"        \
+                             libc_startfiles="${libc_startfiles}"  \
+                             libc_triplet="${target}"              \
                              libc_full="${libc_full}"
 
         CT_Popd
 
-        if [ "${multi_dir}" != "." ]; then
-            if [ "${libc_mode}" = "final" ]; then
-                CT_DoLog EXTRA "Fixing up multilib location"
-
-                # rewrite the library multiplexers
-                for d in "lib/${multi_dir}" "usr/lib/${multi_dir}"; do
-                    for l in libc libpthread libgcc_s; do
-                        if [    -f "${CT_SYSROOT_DIR}/${d}/${l}.so"    \
-                             -a ! -L ${CT_SYSROOT_DIR}/${d}/${l}.so    ]
-                        then
-                            CT_DoExecLog DEBUG ${sed} -r -i                                 \
-                                                      -e "s:/lib/:/lib/${multi_dir}/:g;"    \
-                                                      "${CT_SYSROOT_DIR}/${d}/${l}.so"
-                        fi
-                    done
-                done
-                # Remove the multi_dir now it is no longer useful
-                CT_DoExecLog DEBUG rm -rf "${CT_SYSROOT_DIR}/${multi_dir}"
-            fi # libc_mode == final
-
-            CT_EndStep
-        fi
     done
 
     CT_EndStep
@@ -180,6 +232,7 @@
 #   Parameter           : Definition                            : Type      : Default
 #   libc_headers        : Build libc headers                    : bool      : n
 #   libc_startfiles     : Build libc start-files                : bool      : n
+#   libc_triplet        : Build libc triplet                    : string    : ${CT_TARGET}
 #   libc_full           : Build full libc                       : bool      : n
 #   extra_flags         : Extra CFLAGS to use (for multilib)    : string    : (empty)
 #   extra_dir           : Extra subdir for multilib             : string    : (empty)
@@ -189,6 +242,9 @@
     local libc_full
     local extra_flags
     local extra_dir
+    local extraos_dir
+    local lib_dir
+    local install_root
     local src_dir="${CT_SRC_DIR}/${CT_LIBC}-${CT_LIBC_VERSION}"
     local extra_cc_args
     local -a extra_config
@@ -196,6 +252,7 @@
     local glibc_cflags
     local float_extra
     local endian_extra
+    local libc_triplet="${CT_TARGET}"
     local arg
 
     for arg in "$@"; do
@@ -328,6 +385,29 @@
     # or even after they get installed...
     echo "ac_cv_path_BASH_SHELL=/bin/bash" >>config.cache
 
+    # GCC makes the distinction between multilib directories
+    # (gotten via -print-multilib or -print-multi-directory)
+    # and multilib-os directories (via -print-multi-os-directory)
+    # They are also often horribly mis-aligned, such as:
+    # multilib:    -m32=32      -m64=.
+    # multilib-os: -m32=../lib  -m64=../lib64
+    # it is important that multilib sub-folders of the sysroot use
+    # the multilib-os directory and *not* the multilib directory.
+    # The multilib directory is a GCC implementation detail rather
+    # than something that users need to be concerned about. Older
+    # GCCs do not understand -print-multi-os-directory so we fall
+    # back on some simple transformations (that are wrong in the
+    # above example!)
+    if "${cross_cc}" -print-multi-os-directory ${extra_cc_args} > /dev/null 2>&1; then
+        lib_dir=/usr/lib/$("${cross_cc}" -print-multi-os-directory ${extra_cc_args})
+        install_root="${CT_SYSROOT_DIR}"
+    else
+        # maintain the previous behaviour if -print-multi-os-directory doesn't work.
+        lib_dir=/usr/lib
+        install_root="${CT_SYSROOT_DIR}${extra_dir}"
+    fi
+    extraos_dir="${install_root}${lib_dir}"
+
     # Configure with --prefix the way we want it on the target...
     # There are a whole lot of settings here.  You'll probably want
     # to read up on what they all mean, and customize a bit, possibly by setting GLIBC_EXTRA_CONFIG_ARRAY
@@ -338,11 +418,14 @@
     # Run explicitly through CONFIG_SHELL, or the build breaks badly (loop-of-death)
     # when the shell is not bash... Sigh... :-(
 
-    CT_DoLog DEBUG "Using gcc for target    : '${cross_cc}'"
-    CT_DoLog DEBUG "Configuring with addons : '$(do_libc_add_ons_list ,)'"
-    CT_DoLog DEBUG "Extra config args passed: '${extra_config[*]}'"
-    CT_DoLog DEBUG "Extra CC args passed    : '${glibc_cflags}'"
-    CT_DoLog DEBUG "Extra flags (multilib)  : '${extra_flags}'"
+    CT_DoLog DEBUG "Using gcc for target     : '${cross_cc}'"
+    CT_DoLog DEBUG "Configuring with addons  : '$(do_libc_add_ons_list ,)'"
+    CT_DoLog DEBUG "Extra config args passed : '${extra_config[*]}'"
+    CT_DoLog DEBUG "Extra CC args passed     : '${glibc_cflags}'"
+    CT_DoLog DEBUG "Extra flags (multilib)   : '${extra_flags}'"
+    CT_DoLog DEBUG "Multilib os dir          : '${extraos_dir}'"
+    CT_DoLog DEBUG "Configuring with --host  : '${libc_triplet}'"
+    CT_DoLog DEBUG "Configuring with --libdir: '${lib_dir}'"
 
     CT_DoExecLog CFG                                                \
     BUILD_CC="${CT_BUILD}-gcc"                                      \
@@ -354,12 +437,13 @@
     "${src_dir}/configure"                                          \
         --prefix=/usr                                               \
         --build=${CT_BUILD}                                         \
-        --host=${CT_TARGET}                                         \
+        --host=${libc_triplet}                                      \
         --cache-file="$(pwd)/config.cache"                          \
         --without-cvs                                               \
         --disable-profile                                           \
         --without-gd                                                \
         --with-headers="${CT_HEADERS_DIR}"                          \
+        --libdir=${lib_dir}                                         \
         "${extra_config[@]}"                                        \
         "${CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY[@]}"
 
@@ -378,7 +462,7 @@
         # use the 'install-headers' makefile target to install the
         # headers
         CT_DoExecLog ALL make ${JOBSFLAGS}                          \
-                         install_root=${CT_SYSROOT_DIR}${extra_dir} \
+                         install_root="${install_root}"             \
                          install-bootstrap-headers=yes              \
                          "${extra_make_args[@]}"                    \
                          install-headers
@@ -427,22 +511,23 @@
 
             # there are a few object files needed to link shared libraries,
             # which we build and install by hand
-            CT_DoExecLog ALL mkdir -p "${CT_SYSROOT_DIR}${extra_dir}/usr/lib"
+            CT_DoExecLog ALL mkdir -p "${extraos_dir}"
             CT_DoExecLog ALL make ${JOBSFLAGS}  \
                         "${extra_make_args[@]}" \
                         csu/subdir_lib
             CT_DoExecLog ALL cp csu/crt1.o csu/crti.o csu/crtn.o    \
-                                "${CT_SYSROOT_DIR}${extra_dir}/usr/lib"
+                                "${extraos_dir}"
 
             # Finally, 'libgcc_s.so' requires a 'libc.so' to link against.
             # However, since we will never actually execute its code,
             # it doesn't matter what it contains.  So, treating '/dev/null'
             # as a C source file, we produce a dummy 'libc.so' in one step
-            CT_DoExecLog ALL "${cross_cc}" -nostdlib        \
+            CT_DoExecLog ALL "${cross_cc}" ${extra_flags}   \
+                                            -nostdlib       \
                                            -nostartfiles    \
                                            -shared          \
                                            -x c /dev/null   \
-                                           -o "${CT_SYSROOT_DIR}${extra_dir}/usr/lib/libc.so"
+                                           -o "${extraos_dir}/libc.so"
         fi # threads == nptl
     fi # libc_headers == y
 
@@ -453,9 +538,9 @@
                               all
 
         CT_DoLog EXTRA "Installing C library"
-        CT_DoExecLog ALL make ${JOBSFLAGS}                                  \
-                              "${extra_make_args[@]}"                       \
-                              install_root="${CT_SYSROOT_DIR}${extra_dir}"  \
+        CT_DoExecLog ALL make ${JOBSFLAGS}                    \
+                              "${extra_make_args[@]}"         \
+                              install_root="${install_root}"  \
                               install
 
         if [ "${CT_BUILD_MANUALS}" = "y" ]; then

[-- Attachment #3: Type: text/plain, Size: 71 bytes --]

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 3/3] {e}glibc: Fix various multilib build bugs
@ 2014-02-04  8:35 Ray Donnelly
  0 siblings, 0 replies; 5+ messages in thread
From: Ray Donnelly @ 2014-02-04  8:35 UTC (permalink / raw)
  To: crossgcc

# HG changeset patch
# User Ray Donnelly <mingw.android@gmail.com>
# Date 1391501320 0
#      Tue Feb 04 08:08:40 2014 +0000
# Node ID 8f8b94c987feadc63f23ca72b6de87d404c7cca7
# Parent  45760158aca33981b5bb882191043bd708b57dbb
{e}glibc: Fix various multilib build bugs

--host=${CT_TARGET} with eg -m32 is not right.
The arch part must be correct (i686 for 32-bit
and x86_64 for 64-bit). Un-fortunately GCC has
no mechanism for returning each arches triplet
so instead some hacks are used. Debian can ask
"gcc -m32 -print-multiarch" but this flag isnt
provided on other GCC builds.

The old symlinks from lib32/64 to lib are only
made if CT_MULTILIB=n, and the comment that we
are not multilib on the target side corrected.

The stub libc.so is compiled with extra_cflags
so that it is for the correct multilib arch.

The stub libc.so and crt*.o files are moved to
the multilib os directory and not the multilib
directory if gcc arg -print-multi-os-directory
is supported.

--libdir=<> is passed to libc's configure such
that it is made inplace in the multilib-os dir
and 'Fixing up multilib location' is no longer
required.

The multilib directories are sorted in reverse
order so that x86_64 is built finally. This is
because x86_64 headers are multilib-capable as
far back as glibc-2.15 (at least) whereas i686
headers were not multilib-capable until 2.16.

Signed-off-by: Ray Donnelly <mingw.android@gmail.com>

diff -r 45760158aca3 -r 8f8b94c987fe scripts/build/cc/gcc.sh
--- a/scripts/build/cc/gcc.sh Tue Feb 04 07:55:11 2014 +0000
+++ b/scripts/build/cc/gcc.sh Tue Feb 04 08:08:40 2014 +0000
@@ -375,6 +375,7 @@

     if [ "${CT_MULTILIB}" = "y" ]; then
         extra_config+=("--enable-multilib")
+        extra_config+=("--enable-targets=all")
     else
         extra_config+=("--disable-multilib")
     fi
diff -r 45760158aca3 -r 8f8b94c987fe scripts/build/libc/glibc-eglibc.sh-common
--- a/scripts/build/libc/glibc-eglibc.sh-common Tue Feb 04 07:55:11 2014 +0000
+++ b/scripts/build/libc/glibc-eglibc.sh-common Tue Feb 04 08:08:40 2014 +0000
@@ -76,6 +76,9 @@
     local multilib
     local multi_dir
     local multi_flags
+    local multi_arch
+    local native_arch
+    local rest_of_triplet
     local extra_dir
     local libc_headers libc_startfiles libc_full
     local hdr
@@ -85,6 +88,9 @@
         eval "${arg// /\\ }"
     done

+    native_arch=$(echo "${CT_TARGET}" | ${sed} "s,\(^[^\-]*\).*,\1,g")
+    rest_of_triplet=$(echo "${CT_TARGET}" | ${sed} "s,^[^\-]*\(.*\),\1,g")
+
     case "${libc_mode}" in
         startfiles)
             CT_DoStep INFO "Installing C library headers & start files"
@@ -103,8 +109,16 @@

     # If gcc is not configured for multilib, it still prints
     # a single line for the default settings
-    multilibs=( $("${CT_TARGET}-gcc" -print-multi-lib 2>/dev/null) )
+    # sort -r is a hack so that x86_64 gets built last because
+    # pre-2.16 only the x86_64 headers were applicable to both
+    # i686 and x86_64.
+    # The headers were unified (x86-64 won!) between 2.15 and
+    # 2.16 (BZ14117). This hack makes too many of assumptions
+    # and needs to be replaced with more robust logic. We need
+    # to force x86_64 arch to be last element in the array.
+    multilibs=( $("${CT_TARGET}-gcc" -print-multi-lib 2>/dev/null | sort -r) )
     for multilib in "${multilibs[@]}"; do
+        multi_arch="${native_arch}"
         multi_dir="${multilib%%;*}"
         if [ "${multi_dir}" != "." ]; then
             CT_DoStep INFO "Building for multilib subdir='${multi_dir}'"
@@ -114,6 +128,14 @@
                           )"
             extra_dir="/${multi_dir}"

+            # If more substitutions are needed then they
+            # should be added here, AArch64 for example?
+            if [ "${extra_flags}" = " -m32" ]; then
+              multi_arch=${native_arch/x86_64/i686}
+            elif [ "${extra_flags}" = " -m64" ]; then
+              multi_arch=${native_arch/i686/x86_64}
+            fi
+
             # glibc install its files in ${extra_dir}/{usr/,}lib
             # while gcc expects them in {,usr/}lib/${extra_dir}.
             # Prepare some symlinks so glibc installs in fact in
@@ -140,36 +162,15 @@

         CT_mkdir_pushd
"${CT_BUILD_DIR}/build-libc-${libc_mode}${extra_dir//\//_}"

-        do_libc_backend_once extra_dir="${extra_dir}"               \
-                             extra_flags="${extra_flags}"           \
-                             libc_headers="${libc_headers}"         \
-                             libc_startfiles="${libc_startfiles}"   \
+        do_libc_backend_once extra_dir="${extra_dir}"
          \
+                             extra_flags="${extra_flags}"
          \
+                             libc_headers="${libc_headers}"
          \
+                             libc_startfiles="${libc_startfiles}"
          \
+
libc_triplet="${multi_arch}${rest_of_triplet}"     \
                              libc_full="${libc_full}"

         CT_Popd

-        if [ "${multi_dir}" != "." ]; then
-            if [ "${libc_mode}" = "final" ]; then
-                CT_DoLog EXTRA "Fixing up multilib location"
-
-                # rewrite the library multiplexers
-                for d in "lib/${multi_dir}" "usr/lib/${multi_dir}"; do
-                    for l in libc libpthread libgcc_s; do
-                        if [    -f "${CT_SYSROOT_DIR}/${d}/${l}.so"    \
-                             -a ! -L ${CT_SYSROOT_DIR}/${d}/${l}.so    ]
-                        then
-                            CT_DoExecLog DEBUG ${sed} -r -i
                      \
-                                                      -e
"s:/lib/:/lib/${multi_dir}/:g;"    \
-
"${CT_SYSROOT_DIR}/${d}/${l}.so"
-                        fi
-                    done
-                done
-                # Remove the multi_dir now it is no longer useful
-                CT_DoExecLog DEBUG rm -rf "${CT_SYSROOT_DIR}/${multi_dir}"
-            fi # libc_mode == final
-
-            CT_EndStep
-        fi
     done

     CT_EndStep
@@ -180,6 +181,7 @@
 #   Parameter           : Definition                            :
Type      : Default
 #   libc_headers        : Build libc headers                    : bool      : n
 #   libc_startfiles     : Build libc start-files                : bool      : n
+#   libc_triplet        : Build libc triplet                    :
string    : ${CT_TARGET}
 #   libc_full           : Build full libc                       : bool      : n
 #   extra_flags         : Extra CFLAGS to use (for multilib)    :
string    : (empty)
 #   extra_dir           : Extra subdir for multilib             :
string    : (empty)
@@ -189,6 +191,9 @@
     local libc_full
     local extra_flags
     local extra_dir
+    local extraos_dir
+    local lib_dir
+    local install_root
     local src_dir="${CT_SRC_DIR}/${CT_LIBC}-${CT_LIBC_VERSION}"
     local extra_cc_args
     local -a extra_config
@@ -196,6 +201,7 @@
     local glibc_cflags
     local float_extra
     local endian_extra
+    local libc_triplet="${CT_TARGET}"
     local arg

     for arg in "$@"; do
@@ -328,6 +334,29 @@
     # or even after they get installed...
     echo "ac_cv_path_BASH_SHELL=/bin/bash" >>config.cache

+    # GCC makes the distinction between multilib directories
+    # (gotten via -print-multilib or -print-multi-directory)
+    # and multilib-os directories (via -print-multi-os-directory)
+    # They are also often horribly mis-aligned, such as:
+    # multilib:    -m32=32      -m64=.
+    # multilib-os: -m32=../lib  -m64=../lib64
+    # it is important that multilib sub-folders of the sysroot use
+    # the multilib-os directory and *not* the multilib directory.
+    # The multilib directory is a GCC implementation detail rather
+    # than something that users need to be concerned about. Older
+    # GCCs do not understand -print-multi-os-directory so we fall
+    # back on some simple transformations (that are wrong in the
+    # above example!)
+    if "${cross_cc}" -print-multi-os-directory ${extra_cc_args} >
/dev/null 2>&1; then
+        lib_dir=/usr/lib/$("${cross_cc}" -print-multi-os-directory
${extra_cc_args})
+        install_root="${CT_SYSROOT_DIR}"
+    else
+        # maintain the previous behaviour if
-print-multi-os-directory doesn't work.
+        lib_dir=/usr/lib
+        install_root="${CT_SYSROOT_DIR}${extra_dir}"
+    fi
+    extraos_dir="${install_root}${lib_dir}"
+
     # Configure with --prefix the way we want it on the target...
     # There are a whole lot of settings here.  You'll probably want
     # to read up on what they all mean, and customize a bit, possibly
by setting GLIBC_EXTRA_CONFIG_ARRAY
@@ -338,11 +367,14 @@
     # Run explicitly through CONFIG_SHELL, or the build breaks badly
(loop-of-death)
     # when the shell is not bash... Sigh... :-(

-    CT_DoLog DEBUG "Using gcc for target    : '${cross_cc}'"
-    CT_DoLog DEBUG "Configuring with addons : '$(do_libc_add_ons_list ,)'"
-    CT_DoLog DEBUG "Extra config args passed: '${extra_config[*]}'"
-    CT_DoLog DEBUG "Extra CC args passed    : '${glibc_cflags}'"
-    CT_DoLog DEBUG "Extra flags (multilib)  : '${extra_flags}'"
+    CT_DoLog DEBUG "Using gcc for target     : '${cross_cc}'"
+    CT_DoLog DEBUG "Configuring with addons  : '$(do_libc_add_ons_list ,)'"
+    CT_DoLog DEBUG "Extra config args passed : '${extra_config[*]}'"
+    CT_DoLog DEBUG "Extra CC args passed     : '${glibc_cflags}'"
+    CT_DoLog DEBUG "Extra flags (multilib)   : '${extra_flags}'"
+    CT_DoLog DEBUG "Multilib os dir          : '${extraos_dir}'"
+    CT_DoLog DEBUG "Configuring with --host  : '${libc_triplet}'"
+    CT_DoLog DEBUG "Configuring with --libdir: '${lib_dir}'"

     CT_DoExecLog CFG                                                \
     BUILD_CC="${CT_BUILD}-gcc"                                      \
@@ -354,12 +386,13 @@
     "${src_dir}/configure"                                          \
         --prefix=/usr                                               \
         --build=${CT_BUILD}                                         \
-        --host=${CT_TARGET}                                         \
+        --host=${libc_triplet}                                      \
         --cache-file="$(pwd)/config.cache"                          \
         --without-cvs                                               \
         --disable-profile                                           \
         --without-gd                                                \
         --with-headers="${CT_HEADERS_DIR}"                          \
+        --libdir=${lib_dir}                                         \
         "${extra_config[@]}"                                        \
         "${CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY[@]}"

@@ -378,7 +411,7 @@
         # use the 'install-headers' makefile target to install the
         # headers
         CT_DoExecLog ALL make ${JOBSFLAGS}                          \
-                         install_root=${CT_SYSROOT_DIR}${extra_dir} \
+                         install_root="${install_root}"             \
                          install-bootstrap-headers=yes              \
                          "${extra_make_args[@]}"                    \
                          install-headers
@@ -427,22 +460,23 @@

             # there are a few object files needed to link shared libraries,
             # which we build and install by hand
-            CT_DoExecLog ALL mkdir -p "${CT_SYSROOT_DIR}${extra_dir}/usr/lib"
+            CT_DoExecLog ALL mkdir -p "${extraos_dir}"
             CT_DoExecLog ALL make ${JOBSFLAGS}  \
                         "${extra_make_args[@]}" \
                         csu/subdir_lib
             CT_DoExecLog ALL cp csu/crt1.o csu/crti.o csu/crtn.o    \
-                                "${CT_SYSROOT_DIR}${extra_dir}/usr/lib"
+                                "${extraos_dir}"

             # Finally, 'libgcc_s.so' requires a 'libc.so' to link against.
             # However, since we will never actually execute its code,
             # it doesn't matter what it contains.  So, treating '/dev/null'
             # as a C source file, we produce a dummy 'libc.so' in one step
-            CT_DoExecLog ALL "${cross_cc}" -nostdlib        \
+            CT_DoExecLog ALL "${cross_cc}" ${extra_flags}   \
+                                            -nostdlib       \
                                            -nostartfiles    \
                                            -shared          \
                                            -x c /dev/null   \
-                                           -o
"${CT_SYSROOT_DIR}${extra_dir}/usr/lib/libc.so"
+                                           -o "${extraos_dir}/libc.so"
         fi # threads == nptl
     fi # libc_headers == y

@@ -453,9 +487,9 @@
                               all

         CT_DoLog EXTRA "Installing C library"
-        CT_DoExecLog ALL make ${JOBSFLAGS}                                  \
-                              "${extra_make_args[@]}"                       \
-                              install_root="${CT_SYSROOT_DIR}${extra_dir}"  \
+        CT_DoExecLog ALL make ${JOBSFLAGS}                    \
+                              "${extra_make_args[@]}"         \
+                              install_root="${install_root}"  \
                               install

         if [ "${CT_BUILD_MANUALS}" = "y" ]; then

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-02-04 21:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-04  8:44 [PATCH 3/3] {e}glibc: Fix various multilib build bugs Ray Donnelly
  -- strict thread matches above, loose matches on Subject: below --
2014-02-04 18:49 Ray Donnelly
2014-02-04 20:14 ` Bryan Hundven
2014-02-04 21:33   ` Ray Donnelly
2014-02-04  8:35 Ray Donnelly

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).