diff mbox

RFC: Proposal for a patch that changes multilib linker scripts.

Message ID a8a553fd-24b9-406d-8450-732dadd118e7@BAMAIL02.ba.imgtec.org
State New
Headers show

Commit Message

Steve Ellcey March 11, 2014, 3:59 p.m. UTC
I am building a GCC cross compiler tool chain with uclibc and noticed a
difference between libc.so from glibc and from uclibc when building a
multilib toolchain.  As an example, on glibc, compiling for mips64r2,
N64 ABI, little endian; I put libraries like libc.so in
<root>/mips64r2/64/el/usr/lib/libc.so and the contents of libc.so are:


/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf64-tradlittlemips)
GROUP ( /usr/lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /usr/lib/ld.so
.1 ) )


But when I build with uclibc and put libc.so in the same location by setting
the MULTILIB_DIR, its libc.so contents are:


/* GNU ld script
 * Use the shared library, but some functions are only in
 * the static library, so try that secondarily. */
OUTPUT_FORMAT("elf64-tradlittlemips", "elf64-tradbigmips",
	      "elf64-tradlittlemips")
GROUP ( /mips64r2/64/el/usr/lib/libc.so.0 /mips64r2/64/el/usr/lib/uclibc_nonshar
ed.a AS_NEEDED ( /mips64r2/64/el/usr/lib/ld64-uClibc.so.0 ) )


Then when I try to compile things with this multilib GCC I get errors like:

/local/home/sellcey/gcc/uclibc_err/install-mips-mti-linux-uclibc/mips-mti-linux-uclibc/bin/ld: cannot find /mips64r2/64/el/usr/lib/uclibc_nonshared.a inside /local/home/sellcey/gcc/uclibc_err/install-mips-mti-linux-uclibc/sysroot/mips64r2/64/el
/local/home/sellcey/gcc/uclibc_err/install-mips-mti-linux-uclibc/mips-mti-linux-uclibc/bin/ld: cannot find /mips64r2/64/el/usr/lib/ld-uClibc.so.0 inside /local/home/sellcey/gcc/uclibc_err/install-mips-mti-linux-uclibc/sysroot/mips64r2/64/el

I believe this is because I am running GCC with sysroot option and that is
adding the '/mips64r2/64/el' prefix on to paths, but then that path is also
in the libc.so ld script.  I would like to modify uclibc so I can make the
ld script for uclibc look more like the glibc one and have come up with
attached changes.

If it looks OK, I will submit a proper patch but I thought I would get some
feedback on this approach first and make sure it is considered a reasonable
change to propose.  My idea is to add a new variable (GROUP_DIR) that can
be set to change the contents of libc.so.  By default it would be set to
MULTILIB_DIR so that anyone who does not set this variable is not affected.
But if it is set then it is used to set the contents of libc.so while
MULTILIB_DIR is still used when determining where to install the actual
libraries.

Steve Ellcey
sellcey@mips.com


Here is a diff of my current idea for a patch:

Comments

Bernhard Reutner-Fischer April 8, 2014, 2:07 p.m. UTC | #1
On Tue, Mar 11, 2014 at 08:59:03AM -0700, Steve Ellcey  wrote:
> 
> I am building a GCC cross compiler tool chain with uclibc and noticed a
> difference between libc.so from glibc and from uclibc when building a
> multilib toolchain.  As an example, on glibc, compiling for mips64r2,
> N64 ABI, little endian; I put libraries like libc.so in
> <root>/mips64r2/64/el/usr/lib/libc.so and the contents of libc.so are:

so you install the final target libc by issuing:
make realclean > /dev/null
TARCH=mips
sed -i -e '/^MULTILIB_DIR=/s/\(MULTILIB_DIR=\).*/\1"lib"/' \
	-e 's/^TARGET_\([^=]*\)=y/# TARGET_\1 is not set/' \
	-e "s/# \(TARGET_${TARCH}\) is not set/\1=y/"      \
	-e "s/^\(TARGET_ARCH\)=\"[^\"]*\"/\1=\"${TARCH}\"/"\
	.config
make silentoldconfig
make realclean > /dev/null
d="/opt/${TARCH}-mine-linux-uclibc/tc-sysroot"
export PATH="$d/usr/bin:$d/bin:$PATH"
make ${MAKEFLAGS} \
V=2 \
  CROSS_COMPILE=${TARCH}-mine-linux-uclibc- \
  AR=${TARCH}-mine-linux-uclibc-gcc-ar \
  NM=${TARCH}-mine-linux-uclibc-gcc-nm \
  RANLIB=${TARCH}-mine-linux-uclibc-gcc-ranlib \
  MULTILIB_DIR="lib" \
  PREFIX="/opt/${TARCH}-mine-linux-uclibc/" \
  RUNTIME_PREFIX="/" \
  DEVEL_PREFIX="/usr/" \
  AWK=/opt/${TARCH}-mine-linux-uclibc/tc-sysroot/usr/bin/awk \
  SED=/opt/${TARCH}-mine-linux-uclibc/tc-sysroot/bin/sed \
  all install install_utils || exit 1

except your PREFIX is more like "<root>/mips64r2/64/el/"
i suppose?

i.e. your PREFIX is not correct WRT your --with-build-sysroot and/or
--with-sysroot=

MULTILIB_DIR is supposed to be used for mulitilib setups (in the gcc
sense) but since it was apparent back than that we (gcc) 'd also need
something like multi-arch support we (uClibc) did not implement looping
make over multilib- or multiarch- configs internally in the buildsys but
(currently) rely on the user to configure, build and install all the
multilib/multiarch variants she wants on their own.

Our install-path setup follows what debian needs, see defaults in
extra/Configs/Config.in for RUNTIME_PREFIX, DEVEL_PREFIX, MULTILIB_DIR.

I hope that clarifies the purpose of the MULTILIB_DIR.
Does that answer your question?

thanks,
> 
> 
> /* GNU ld script
>    Use the shared library, but some functions are only in
>    the static library, so try that secondarily.  */
> OUTPUT_FORMAT(elf64-tradlittlemips)
> GROUP ( /usr/lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /usr/lib/ld.so
> .1 ) )
> 
> 
> But when I build with uclibc and put libc.so in the same location by setting
> the MULTILIB_DIR, its libc.so contents are:
> 
> 
> /* GNU ld script
>  * Use the shared library, but some functions are only in
>  * the static library, so try that secondarily. */
> OUTPUT_FORMAT("elf64-tradlittlemips", "elf64-tradbigmips",
> 	      "elf64-tradlittlemips")
> GROUP ( /mips64r2/64/el/usr/lib/libc.so.0 /mips64r2/64/el/usr/lib/uclibc_nonshar
> ed.a AS_NEEDED ( /mips64r2/64/el/usr/lib/ld64-uClibc.so.0 ) )
> 
> 
> Then when I try to compile things with this multilib GCC I get errors like:
> 
> /local/home/sellcey/gcc/uclibc_err/install-mips-mti-linux-uclibc/mips-mti-linux-uclibc/bin/ld: cannot find /mips64r2/64/el/usr/lib/uclibc_nonshared.a inside /local/home/sellcey/gcc/uclibc_err/install-mips-mti-linux-uclibc/sysroot/mips64r2/64/el
> /local/home/sellcey/gcc/uclibc_err/install-mips-mti-linux-uclibc/mips-mti-linux-uclibc/bin/ld: cannot find /mips64r2/64/el/usr/lib/ld-uClibc.so.0 inside /local/home/sellcey/gcc/uclibc_err/install-mips-mti-linux-uclibc/sysroot/mips64r2/64/el
> 
> I believe this is because I am running GCC with sysroot option and that is
> adding the '/mips64r2/64/el' prefix on to paths, but then that path is also
> in the libc.so ld script.  I would like to modify uclibc so I can make the
> ld script for uclibc look more like the glibc one and have come up with
> attached changes.
> 
> If it looks OK, I will submit a proper patch but I thought I would get some
> feedback on this approach first and make sure it is considered a reasonable
> change to propose.  My idea is to add a new variable (GROUP_DIR) that can
> be set to change the contents of libc.so.  By default it would be set to
> MULTILIB_DIR so that anyone who does not set this variable is not affected.
> But if it is set then it is used to set the contents of libc.so while
> MULTILIB_DIR is still used when determining where to install the actual
> libraries.
> 
> Steve Ellcey
> sellcey@mips.com
> 
> 
> Here is a diff of my current idea for a patch:
> 
> 
> diff --git a/Makefile.in b/Makefile.in
> index 5419704..ccd7729 100644
> --- a/Makefile.in
> +++ b/Makefile.in
> @@ -361,6 +361,11 @@ install_startfiles: startfiles | $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)
>  	-$(INSTALL) -m 644 $(startfiles) $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/
>  
>  # Installs development library links.
> +
> +ifeq ($(GROUP_DIR),)
> +GROUP_DIR=$(MULTILIB_DIR)
> +endif
> +
>  install_dev: install_headers install_runtime install_startfiles | $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)
>  	-$(INSTALL) -m 644 $(top_builddir)lib/*.a $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/
>  ifeq ($(HAVE_SHARED),y)
> @@ -372,9 +377,9 @@ ifeq ($(HAVE_SHARED),y)
>  ifeq ($(HARDWIRED_ABSPATH),y)
>  	if [ -f $(top_builddir)lib/libc.so -a -f $(PREFIX)$(RUNTIME_PREFIX)$(MULTILIB_DIR)/$(SHARED_LIBNAME) ] ; then \
>  		$(RM) $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libc.so; \
> -		$(SED) -e 's:$(NONSHARED_LIBNAME):$(DEVEL_PREFIX)$(MULTILIB_DIR)/$(NONSHARED_LIBNAME):' \
> -		    -e 's:$(SHARED_LIBNAME):$(RUNTIME_PREFIX)$(MULTILIB_DIR)/$(SHARED_LIBNAME):' \
> -		    -e 's:$(UCLIBC_LDSO):$(RUNTIME_PREFIX)$(MULTILIB_DIR)/$(UCLIBC_LDSO):' \
> +		$(SED) -e 's:$(NONSHARED_LIBNAME):$(DEVEL_PREFIX)$(GROUP_DIR)/$(NONSHARED_LIBNAME):' \
> +		    -e 's:$(SHARED_LIBNAME):$(RUNTIME_PREFIX)$(GROUP_DIR)/$(SHARED_LIBNAME):' \
> +		    -e 's:$(UCLIBC_LDSO):$(RUNTIME_PREFIX)$(GROUP_DIR)/$(UCLIBC_LDSO):' \
>  		    $(top_builddir)lib/libc.so > $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libc.so; \
>  		$(SED) -i -e 's://:/:g' $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libc.so; \
>  	fi
> @@ -388,7 +393,7 @@ ifeq ($(HARDWIRED_ABSPATH),y)
>  	if [ -f $(top_builddir)lib/libpthread.so -a -f $(PREFIX)$(RUNTIME_PREFIX)$(MULTILIB_DIR)/libpthread.so.$(ABI_VERSION) ] ; then \
>  		$(RM) $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libpthread.so; \
>  		cp $(top_srcdir)extra/scripts/format.lds $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libpthread.so; \
> -		echo "GROUP ( $(RUNTIME_PREFIX)$(MULTILIB_DIR)/libpthread.so.$(ABI_VERSION) $(DEVEL_PREFIX)$(MULTILIB_DIR)/libpthread_nonshared.a )" \
> +		echo "GROUP ( $(RUNTIME_PREFIX)$(GROUP_DIR)/libpthread.so.$(ABI_VERSION) $(DEVEL_PREFIX)$(GROUP_DIR)/libpthread_nonshared.a )" \
>  			>> $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libpthread.so; \
>  		$(SED) -i -e 's://:/:g' $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libpthread.so; \
>  	fi
> _______________________________________________
> uClibc mailing list
> uClibc@uclibc.org
> http://lists.busybox.net/mailman/listinfo/uclibc
Steve Ellcey April 22, 2014, 8:41 p.m. UTC | #2
On Tue, 2014-04-08 at 16:07 +0200, Bernhard Reutner-Fischer wrote:

> except your PREFIX is more like "<root>/mips64r2/64/el/"
> i suppose?
> 
> i.e. your PREFIX is not correct WRT your --with-build-sysroot and/or
> --with-sysroot=
> 
> MULTILIB_DIR is supposed to be used for mulitilib setups (in the gcc
> sense) but since it was apparent back than that we (gcc) 'd also need
> something like multi-arch support we (uClibc) did not implement looping
> make over multilib- or multiarch- configs internally in the buildsys but
> (currently) rely on the user to configure, build and install all the
> multilib/multiarch variants she wants on their own.
> 
> Our install-path setup follows what debian needs, see defaults in
> extra/Configs/Config.in for RUNTIME_PREFIX, DEVEL_PREFIX, MULTILIB_DIR.
> 
> I hope that clarifies the purpose of the MULTILIB_DIR.
> Does that answer your question?
> 
> thanks,

I think that helps clarify their intended use, I am trying to create a
slightly different structure for my cross compiler which is why I am
having issues.

For example I was building/installing with
	PREFIX=<root-location> (i.e. something like /path/uclibc-root)
	MULTILIB_DIR=mips64r2/64/el
	DEVEL_PREFIX=/

I am trying to build a uclibc sysroot setup that mimics the glibc one I
have where there is a single <sysroot>/usr/include for the headers but
then multiple libc.a files in (for example) <sysroot>/usr/lib/libc.a,
<sysroot>/mips64r2/usr/lib/libc.a, or
<sysroot>/mips64r2/64/el/usr/lib/libc.a.

One thing I have just noticed is that this doesn't work because
usr/include contains uClibc_config.h which is different based on
what options you used to build uclibc (big or little endian; soft or
hard float; etc).  All the other header files appear to be identical.

Steve Ellcey
Bernhard Reutner-Fischer April 24, 2014, 11:30 a.m. UTC | #3
On 22 April 2014 22:41, Steve Ellcey <sellcey@mips.com> wrote:
> On Tue, 2014-04-08 at 16:07 +0200, Bernhard Reutner-Fischer wrote:
>
>> except your PREFIX is more like "<root>/mips64r2/64/el/"
>> i suppose?
>>
>> i.e. your PREFIX is not correct WRT your --with-build-sysroot and/or
>> --with-sysroot=
>>
>> MULTILIB_DIR is supposed to be used for mulitilib setups (in the gcc
>> sense) but since it was apparent back than that we (gcc) 'd also need
>> something like multi-arch support we (uClibc) did not implement looping
>> make over multilib- or multiarch- configs internally in the buildsys but
>> (currently) rely on the user to configure, build and install all the
>> multilib/multiarch variants she wants on their own.
>>
>> Our install-path setup follows what debian needs, see defaults in
>> extra/Configs/Config.in for RUNTIME_PREFIX, DEVEL_PREFIX, MULTILIB_DIR.
>>
>> I hope that clarifies the purpose of the MULTILIB_DIR.
>> Does that answer your question?
>>
>> thanks,
>
> I think that helps clarify their intended use, I am trying to create a
> slightly different structure for my cross compiler which is why I am
> having issues.
>
> For example I was building/installing with
>         PREFIX=<root-location> (i.e. something like /path/uclibc-root)
>         MULTILIB_DIR=mips64r2/64/el
>         DEVEL_PREFIX=/
>
> I am trying to build a uclibc sysroot setup that mimics the glibc one I
> have where there is a single <sysroot>/usr/include for the headers but
> then multiple libc.a files in (for example) <sysroot>/usr/lib/libc.a,
> <sysroot>/mips64r2/usr/lib/libc.a, or
> <sysroot>/mips64r2/64/el/usr/lib/libc.a.
>
> One thing I have just noticed is that this doesn't work because
> usr/include contains uClibc_config.h which is different based on
> what options you used to build uclibc (big or little endian; soft or
> hard float; etc).  All the other header files appear to be identical.

All others might or might not be identical i think but yes,
uClibc_config.h certainly is different. That's why i always thought you
would have to use different DEVEL_PREFIX _and_ RUNTIME_PREFIX
for multiarch installs anyway and leave MULTILIB_DIR alone for such
setups.

What you could of course do (in your own build-script) is to just
have separate uClibc_config.h per-multiarch, prepend that to your
default search-list and share all other headers in one common dir,
iff that works for your set of multi-arches, of course. I doubt that you
can generally do that though, can you?

thanks,
diff mbox

Patch

diff --git a/Makefile.in b/Makefile.in
index 5419704..ccd7729 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -361,6 +361,11 @@  install_startfiles: startfiles | $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)
 	-$(INSTALL) -m 644 $(startfiles) $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/
 
 # Installs development library links.
+
+ifeq ($(GROUP_DIR),)
+GROUP_DIR=$(MULTILIB_DIR)
+endif
+
 install_dev: install_headers install_runtime install_startfiles | $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)
 	-$(INSTALL) -m 644 $(top_builddir)lib/*.a $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/
 ifeq ($(HAVE_SHARED),y)
@@ -372,9 +377,9 @@  ifeq ($(HAVE_SHARED),y)
 ifeq ($(HARDWIRED_ABSPATH),y)
 	if [ -f $(top_builddir)lib/libc.so -a -f $(PREFIX)$(RUNTIME_PREFIX)$(MULTILIB_DIR)/$(SHARED_LIBNAME) ] ; then \
 		$(RM) $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libc.so; \
-		$(SED) -e 's:$(NONSHARED_LIBNAME):$(DEVEL_PREFIX)$(MULTILIB_DIR)/$(NONSHARED_LIBNAME):' \
-		    -e 's:$(SHARED_LIBNAME):$(RUNTIME_PREFIX)$(MULTILIB_DIR)/$(SHARED_LIBNAME):' \
-		    -e 's:$(UCLIBC_LDSO):$(RUNTIME_PREFIX)$(MULTILIB_DIR)/$(UCLIBC_LDSO):' \
+		$(SED) -e 's:$(NONSHARED_LIBNAME):$(DEVEL_PREFIX)$(GROUP_DIR)/$(NONSHARED_LIBNAME):' \
+		    -e 's:$(SHARED_LIBNAME):$(RUNTIME_PREFIX)$(GROUP_DIR)/$(SHARED_LIBNAME):' \
+		    -e 's:$(UCLIBC_LDSO):$(RUNTIME_PREFIX)$(GROUP_DIR)/$(UCLIBC_LDSO):' \
 		    $(top_builddir)lib/libc.so > $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libc.so; \
 		$(SED) -i -e 's://:/:g' $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libc.so; \
 	fi
@@ -388,7 +393,7 @@  ifeq ($(HARDWIRED_ABSPATH),y)
 	if [ -f $(top_builddir)lib/libpthread.so -a -f $(PREFIX)$(RUNTIME_PREFIX)$(MULTILIB_DIR)/libpthread.so.$(ABI_VERSION) ] ; then \
 		$(RM) $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libpthread.so; \
 		cp $(top_srcdir)extra/scripts/format.lds $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libpthread.so; \
-		echo "GROUP ( $(RUNTIME_PREFIX)$(MULTILIB_DIR)/libpthread.so.$(ABI_VERSION) $(DEVEL_PREFIX)$(MULTILIB_DIR)/libpthread_nonshared.a )" \
+		echo "GROUP ( $(RUNTIME_PREFIX)$(GROUP_DIR)/libpthread.so.$(ABI_VERSION) $(DEVEL_PREFIX)$(GROUP_DIR)/libpthread_nonshared.a )" \
 			>> $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libpthread.so; \
 		$(SED) -i -e 's://:/:g' $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libpthread.so; \
 	fi