Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 458842

Summary: sys-devel/crossdev: swallowing sysrooted system libdirs (and multilib paths)
Product: Gentoo Linux Reporter: Alexander E. Patrakov <patrakov>
Component: [OLD] LibraryAssignee: Embedded Gentoo Team <embedded>
Status: RESOLVED OBSOLETE    
Severity: normal CC: ambrop7, freedesktop-bugs
Priority: Normal    
Version: unspecified   
Hardware: All   
OS: Linux   
Whiteboard:
Package list:
Runtime testing required: ---
Attachments: nss-3.14.3-nspr-libs.patch
nss-3.14.3.ebuild.patch

Description Alexander E. Patrakov 2013-02-23 10:36:14 UTC
Hello.

While fixing bug #436216, you added this line to dev-libs/nss ebuilds:

append-ldflags $(${PKG_CONFIG} nspr --libs-only-L)

In normal builds, it expands to nothing and thus has no effect. However, in cross-builds (or when trying to convert nspr and nss to multilib, as I did in my local overlay), this results in something like this command in the middle of the build:

x86_64-pc-linux-gnu-gcc -m32 -shared  -Wl,-z,defs -Wl,-soname -Wl,libssl3.so  -Wl,--version-script,Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/ssl.def -Wl,-O1 -Wl,--as-needed -L/usr/lib32    -o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/libssl3.so Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/derive.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/dtlscon.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/prelib.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/ssl3con.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/ssl3gthr.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslauth.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslcon.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/ssldef.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslenum.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslerr.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslerrstrs.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslinit.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/ssl3ext.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslgathr.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslmutex.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslnonce.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslreveal.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslsecur.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslsnce.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslsock.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/ssltrace.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslver.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/authcert.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/cmpcert.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/sslinfo.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/ssl3ecc.o Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/unix_err.o   ../freebl/Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/libfreebl.a  -L../../../dist/Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/lib -lnss3 -L../../../dist/Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/lib -lnssutil3 -L/usr/portage/packages/portage/dev-libs-x86/nss-3.14.3/temp/fake-dir -lplc4 -lplds4 -lnspr4  -lpthread  -ldl -lc -lz
Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/ssl3con.o: In function `ssl3_HandleRecord':
ssl3con.c:(.text+0xd71b): undefined reference to `PK11_SignWithSymKey'

The -L/usr/lib32 comes from your added line. Note that it affects not only the search paths for nspr libraries, but also the search path for libnss3 and libnssutil3. I.e., they will be searched in /usr/lib32 before the intended location, ../../../dist/Linux2.6_x86_x86_64-pc-linux-gnu-gcc_glibc_PTH_OPT.OBJ/lib, and found there if there is a prior install of cross-compiled nss. In other words, your solution works as intended only during the forst install of nss and breaks upgrades (resulting in libssl3 being linked against the system-installed libnss3 instead of the just-built one - so no wonder that the newly added function PK11_SignWithSymKey is not found).

Reproducible: Always
Comment 1 Ambroz Bizjak 2013-02-23 14:10:40 UTC
There seem to be two sides of this problem. Check out /usr/lib/pkgconfig/nspr.pc, both in your sysroot and in the build system. They *both* include this line (or lib64 instead of lib):

Libs: -L/usr/lib -lplds4 -lplc4 -lnspr4

However:

# pkg-config --libs nspr
-lplds4 -lplc4 -lnspr4
# armv5tel-softfloat-linux-gnueabi-pkg-config --libs nspr
-L/mnt/cross-armv5/usr/lib -lplds4 -lplc4 -lnspr4

On the build system pkg-config filters out the -L refering to a system directory but not for the cross-compile case. To get the wrapper out of the way, this produces the same results:

# PKG_CONFIG_LIBDIR=/mnt/cross-armv5/usr/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=/mnt/cross-armv5 pkg-config --libs nspr
-L/mnt/cross-armv5/usr/lib -lplds4 -lplc4 -lnspr4

So it seems that it's pkg-config that's at fault here. There are a ton of other .pc files that also specify -L/usr/lib, so the nspr.pc is all right.

On the other hand, somehow moving the flags returned from pkg-config to come after all the internally linked libraries have been specified would work around the issue.
Comment 2 Ambroz Bizjak 2013-02-23 14:12:55 UTC
Oops sorry CC zmedico by accident.
Comment 3 Alexander E. Patrakov 2013-02-23 14:19:30 UTC
(In reply to comment #1)
> So it seems that it's pkg-config that's at fault here. There are a ton of
> other .pc files that also specify -L/usr/lib, so the nspr.pc is all right.

Yes, the -L/usr/lib32 is just a trigger, not the problem that this bug is about.

> On the other hand, somehow moving the flags returned from pkg-config to come
> after all the internally linked libraries have been specified would work
> around the issue.

Yes, this should be done in the armv5 case, too, so that the newly built armv5 libssl3 is linked against the newly built libssl3. In other words, it is always wrong to insert any -L/some/path flag in the position just after --as-needed, if that path can contain an old copy of libnss3. And I don't think that it is a workaround to move the -L flag - it is the proper solution.
Comment 4 Alexander E. Patrakov 2013-02-23 14:20:54 UTC
(In reply to comment #3)

> Yes, this should be done in the armv5 case, too, so that the newly built
> armv5 libssl3 is linked against the newly built libssl3.

oops, I meant "against the newly built libnss3".
Comment 5 Ambroz Bizjak 2013-02-23 14:41:00 UTC
Created attachment 339796 [details, diff]
nss-3.14.3-nspr-libs.patch

Mass replacement to allow us to specify nspr link flags in the right place.
Comment 6 Ambroz Bizjak 2013-02-23 14:42:14 UTC
Created attachment 339798 [details, diff]
nss-3.14.3.ebuild.patch

Ebuild patch. Applies the above nss patch and passess nspr link flags properly.
Comment 7 Alexander E. Patrakov 2013-02-23 15:03:13 UTC
So the end result is that the ebuild ignores the $(NSPR_LIB_DIR) variable by always putting ${T}/fake-dir there, and passes all -L flags from pkg-config exactly after that. Not nice, but I think it is the necessary evil if there can be multiple -L flags from pkg-config. It may be a good idea to investigate why that ${T}/fake-dir thingy was introduced (this is the thingy you are effectively replacing), and possibly redo the patch with that in mind.

But I jave just tested the patch on my laptop, and it works for me in its current form, too. Thanks!
Comment 8 Markos Chandras (RETIRED) gentoo-dev 2013-02-23 16:03:51 UTC
pretty please don't CC random people on your own
Comment 9 Alexander E. Patrakov 2013-02-23 16:44:19 UTC
(In reply to comment #8)
> pretty please don't CC random people on your own

I thought that, as this is a continuation of the old incorrectly-fixed but not reopenable bug, CC-ing the same people who commented on the old bug would make sense. Sorry for that.
Comment 10 Ambroz Bizjak 2013-02-23 16:50:45 UTC
(In reply to comment #9)
> (In reply to comment #8)
> > pretty please don't CC random people on your own
> 
> I thought that, as this is a continuation of the old incorrectly-fixed but
> not reopenable bug, CC-ing the same people who commented on the old bug
> would make sense. Sorry for that.

It was my mistake, it's OK you CCd me. I was a bit too eager looking at who was the maintainer of pkg-config and CCd zmedico by accident, and I probably shouldn't have CCd pkg-config maintainer in the first place. Won't happen again, now let's not generate any more spam :)
Comment 11 SpanKY gentoo-dev 2013-03-03 00:27:16 UTC
(In reply to comment #3)

your conclusions are incorrect.  a cross-compiler (or multilib compiler) knows where to find its own system libs, so using -L/usr/lib (and such) are not necessary.  asking pkg-config for the -L paths needed to link against a specific package is perfectly reasonable and in fact often times necessary (for packages that stick the libs in subdirs like /usr/lib/foo).

the fact that pkg-config is emitting an -L path to the system libdir is the bug.  ignoring that and blaming nss/nspr is putting a bandaid on a gaping hole.

we probably have to make the existing pkg-config wrapper more intelligent since relying on just pkg-config itself is nigh impossible to get it right.
Comment 12 Alexander E. Patrakov 2013-03-03 04:33:47 UTC
(In reply to comment #11)
> (In reply to comment #3)
> 
> your conclusions are incorrect.  a cross-compiler (or multilib compiler)
> knows where to find its own system libs, so using -L/usr/lib (and such) are
> not necessary.  asking pkg-config for the -L paths needed to link against a
> specific package is perfectly reasonable and in fact often times necessary
> (for packages that stick the libs in subdirs like /usr/lib/foo).
> 
> the fact that pkg-config is emitting an -L path to the system libdir is the
> bug.  ignoring that and blaming nss/nspr is putting a bandaid on a gaping
> hole.
> 
> we probably have to make the existing pkg-config wrapper more intelligent
> since relying on just pkg-config itself is nigh impossible to get it right.

Sorry, I partially disagree with your analysis. There are two bugs here: one (1) for -L/usr/lib32 being emitted at all (which is specific to my overlay and thus invalid for the main gentoo bugzilla, unless also reproducible with crossdev) and one (2) for that -L swtich being put in the wrong place when linking nss libraries.

You have repurposed this bugzilla entry for (1) and ignored (2), which is what I disagree with. In order to convince me that (2) is invalid, please suppose for a moment that nspr libraries are in /usr/lib/nspr (not in /usr/lib) and tell me where -L/usr/lib/nspr should be put in that case when linking libssl3.
Comment 13 Alexander E. Patrakov 2013-03-03 04:52:34 UTC
(In reply to comment #12)

> You have repurposed this bugzilla entry for (1) and ignored (2), which is
> what I disagree with. In order to convince me that (2) is invalid, please
> suppose for a moment that nspr libraries are in /usr/lib/nspr (not in
> /usr/lib) and tell me where -L/usr/lib/nspr should be put in that case when
> linking libssl3.

OK, now I see what's wrong in my logic. The library directories that are subdirectories of /usr/lib are specific to a package being used, so it is reasonable to expect that there will be no old versions of the library being built there. OTOH, the following fact about the ebuild bugs me: the original makefile already has a variable in the correct place (just before lplc4) where it expects a directory where nspr libs are to be found. We set this to a fake value and then insert the very same information (the correct -L flag for nspr) in a _different_ place - even before the objects. Why?



Still, please contact mgorny, ask him to convert nspr and nss to multilib on his own, and you'll probably get a better analysis of the bug.
Comment 14 SpanKY gentoo-dev 2013-03-03 10:59:05 UTC
(In reply to comment #13)

the -L relationship to .o is irrelevant.  it only matters to -l flags.
Comment 15 Alexander E. Patrakov 2013-03-03 11:30:50 UTC
Yes, the -L flag only matters for -l flags that come after it. And now, please, look again at the failed command in the original bug report and note the positions of all -L and -l flags. So:

-L/usr/lib32 (or anything else injected via append-ldflags) affects -lnss3 -lnssutil3 -lplc4 -lplds4 -lnspr4  -lpthread  -ldl -lc -lz
-L.../dist/.../lib affects -lnss3 -lnssutil3 -lplc4 -lplds4 -lnspr4  -lpthread  -ldl -lc -lz
-L.../temp/fake-dir affects -lplc4 -lplds4 -lnspr4  -lpthread  -ldl -lc -lz

Here is where each library is supposed to come from:

-lnss3 -lnssutil3 come from .../dist/.../lib, but older versions may exist in system library directories such as /mnt/cross-armv5/usr/lib or /usr/lib32

-lplc4 -lplds4 -lnspr4 in Gentoo come from system library directories, but the ebuild calls ${PKG_CONFIG} nspr --libs-only-L for some unknown reason.

Now note where -L.../temp/fake-dir comes from and which variable it uses: it is ${NSPR_LIB_DIR} in the makefile. So, my question about the nss ebuild still stands, and actually grew into two questions (yes, I understand that (2) invalidates (1)):

1) Why are pkg-config-derived -L flags for nspr injected not in their upstream-intended place (before -lplc4), but in front of _all_ -l flags? In other words, why are you calling append-ldflags instead setting ${NSPR_LIB_DIR} to a possibly-non-fake value?

2) Why is ${PKG_CONFIG} called at all, if it is known that on Gentoo nspr is in a system library directory and supposedly no -L flags are needed?
Comment 16 Alexander E. Patrakov 2013-03-03 12:29:10 UTC
After chatting with mgorny on IRC, I have changed my opinion.

Here are his words that made me change the opinion: "LDFLAGS can contain user-set -L flags. If that breaks the build system, that's a problem with the build system."

So - we have two bugs here. Maybe it is worth having two bugzilla entries.

1. crossdev and multilib.eclass don't make pkg-config skip -L/usr/lib32, -L/mnt/cross-armv5/usr/lib and other system directories for ABIs different from the default one.

2. NSS build system can be easily broken by such -L flags. This happens because it uses the fragile -L.../dist/.../lib -lnss3 -lnssutil3 construction (that is vulnerable to poisoning by prior -L flags) for linking to just-built libraries instead of just saying .../dist/.../lib/libnss3.so .../dist/.../lib/libnssutil3.so (i.e. instead of specifying the full or relative path to the just-built *.so files directly).
Comment 17 SpanKY gentoo-dev 2015-05-19 04:58:43 UTC
i'm not sure what's left here (if anything).  pkg-config should handle swallowing the right -L paths, and nss/nspr are reliably cross-compiling for us in CrOS.