Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Subject: Re: [gentoo-portage-dev] Pre RFC on RFC: Add compiler information to exported a Package Manger's Cached Information.
Date: Mon, 02 Mar 2015 03:25:26
Message-Id: 54F3D81F.5080806@gentoo.org
In Reply to: Re: [gentoo-portage-dev] Pre RFC on RFC: Add compiler information to exported a Package Manger's Cached Information. by Zac Medico
1 On 02/25/2015 04:07 PM, Zac Medico wrote:
2 > On 02/25/2015 03:41 PM, Anthony G. Basile wrote:
3 >> On 02/25/15 15:38, Zac Medico wrote:
4 >>> On 02/25/2015 12:01 PM, Anthony G. Basile wrote:
5 >>>> On 02/25/15 14:51, Anthony G. Basile wrote:
6 >>>>> On 02/22/15 01:30, Zac Medico wrote:
7 >>>>>> On 02/21/2015 10:22 PM, Zac Medico wrote:
8 >>>>>>> If we put the real/canonical libstdc++.so path in the DT_NEEDED
9 >>>>>>> section,
10 >>>>>>> then it will automatically work with existing soname dependency
11 >>>>>>> support.
12 >>>>>>
13 >>>>>> Actually, we'd also have to add a way for you to put the full path of
14 >>>>>> the libstdc++.so in PROVIDES. For example:
15 >>>>>>
16 >>>>>> PROVIDES_ABSOLUTE="/usr/lib/gcc/*/*/libstdc++.so.6"
17 >>>>>>
18 >>>>>
19 >>>>> I guess I don't understand how this would work exactly. What if
20 >>>>> someone
21 >>>>> has gcc-4.8.3. Builds library libfoo.so which uses c++. Then upgrades
22 >>>>> to gcc-4.9, removes 4.8 and then tries to build bar which is also
23 >>>>> written in c++ and links against libfoo.so. We would have mismatching
24 >>>>> abis. How would this catch it and trigger the correct rebuilds?
25 >>>>>
26 >>>>> Unless I'm misunderstanding your *'s in that line. Are you using
27 >>>>> PROVIDES_ABSOLUTE as a way of recording what version of the compiler
28 >>>>> libfoo.so was build with? So that you'd have a line that says
29 >>>>> libfoo.so
30 >>>>> links against /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.3/libstdc++.so, so
31 >>>>> that parsing that line gives 4.8.3?
32 >>>>>
33 >>>>> Also if you had the absolute path in VDB somewhere, like in PROVIDES,
34 >>>>> then you don't need it in the elf's rpath which would make me feel
35 >>>>> better.
36 >>>>>
37 >>>>
38 >>>> Actually no, you'd still need rpath for the elf itslef otherwise you can
39 >>>> still link against the wrong version of libstdc++.so. Note in my
40 >>>> following example that even though I build test.cpp with 4.7.3 I still
41 >>>> wind up linking aginast 4.8.3.
42 >>>
43 >>> If DT_NEEDED contains the absolute libstdc++.so path, it's guaranteed to
44 >>> link against the correct version, regardless of rpath.
45 >>>
46 >>
47 >> How do you get DT_NEEDED to the absolute libstdc++.so path when building?
48 >
49 > I'm not sure how we're going to accomplish that yet, but it should be
50 > feasible. Ideally, the build system would support it. The worst case
51 > would be that we would have to patch the DT_NEEDED sections after
52 > src_install.
53
54 Using patchelf built from git [1], I tried to patch the DT_NEEDED of a
55 "hello world" program:
56 $ cat hello.cpp
57 #include <iostream>
58 using namespace std;
59 int main() { cout << "Hello World!" << endl ; }
60 $ g++ -o hello hello.cpp
61 $ scanelf -qF '%a;%p;%S;%r;%n' hello
62 EM_X86_64;hello;;;libstdc++.so.6,libm.so.6,libgcc_s.so.1,libc.so.6
63 $ ldd hello
64 linux-vdso.so.1 (0x00007fff5992a000)
65 libstdc++.so.6 =>
66 /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.3/libstdc++.so.6 (0x00007f38f6a82000)
67 libm.so.6 => /lib64/libm.so.6 (0x00007f38f6783000)
68 libgcc_s.so.1 =>
69 /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.3/libgcc_s.so.1 (0x00007f38f656d000)
70 libc.so.6 => /lib64/libc.so.6 (0x00007f38f61c7000)
71 /lib64/ld-linux-x86-64.so.2 (0x00007f38f6d86000)
72 $ ./hello
73 Hello World!
74 $ patchelf --replace-needed libstdc++.so.6
75 /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.3/libstdc++.so.6 hello
76 $ scanelf -qF '%a;%p;%S;%r;%n' hello
77 EM_X86_64;hello;;;/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.3/libstdc++.so.6,libm.so.6,libgcc_s.so.1,libc.so.6
78 $ ldd hello
79 Inconsistency detected by ld.so: dl-version.c: 224:
80 _dl_check_map_versions: Assertion `needed != ((void *)0)' failed!
81 $ ./hello
82 Inconsistency detected by ld.so: dl-version.c: 224:
83 _dl_check_map_versions: Assertion `needed != ((void *)0)' failed!
84
85 Apparently the ld.so is not capable of resolving absolute paths in
86 DT_NEEDED. Maybe it's more practical to go with -rpath instead.
87
88 [1] https://github.com/NixOS/patchelf
89 --
90 Thanks,
91 Zac