Gentoo Archives: gentoo-dev

From: "Gregory M. Turner" <gmt@×××××.us>
To: gentoo-dev@l.g.o
Subject: [gentoo-dev] [PATCH/RFC] eclass/flag-o-matic.eclass: prepend-ldpath
Date: Sat, 06 Oct 2012 02:51:13
Message-Id: 506F9C61.3020500@malth.us
1 ----[ "eclass/flag-o-matic.eclass" ]----->8----->
2 --- PORTAGE/eclass/flag-o-matic.eclass
3 +++ OVERLAY/eclass/flag-o-matic.eclass
4 @@ -117,6 +117,42 @@
5 return 0
6 }
7
8 +# @FUNCTION: prepend-ldpath
9 +# @USAGE: <path>
10 +# @DESCRIPTION:
11 +# Place the specified ldpath into LDFLAGS before any options which could
12 +# add additional paths to ld's search path. Specifically, it will place
13 +# the new <path> "/foo" into LDFLAGS as "-L/foo" just before the first
14 +# occurance matching any of the globs: '-L*', '-T', '--library-path*',
15 +# and '--script*', but not matching any of the globs: '-Tbss=*',
16 +# '-Tdata=*', '-Ttext=*', and '-Ttext-segment=*'. If no such match is
17 +# found, then this is equivalent to "append-ldflags -L<path>".
18 +prepend-ldpath() {
19 + local new=()
20 + local f
21 + local done=no
22 + for f in ${LDFLAGS} ; do
23 + case "${f}" in
24 + -Tbss=*|-Tdata=*|-Ttext=*|-Ttext-segment=*)
25 + new+=( "${f}" )
26 + ;;
27 + -L*|-T*|--library-path*|--script*)
28 + if [[ ${done} == yes ]] ; then
29 + new+=( "${f}" )
30 + else
31 + new+=( "-L${1}" "${f}" )
32 + done=yes
33 + fi
34 + ;;
35 + *)
36 + new+=( "${f}" )
37 + ;;
38 + esac
39 + done
40 + [[ ${done} == no ]] && new+=( "-L${1}" )
41 + export LDFLAGS="${new[*]}"
42 +}
43 +
44 # @FUNCTION: filter-lfs-flags
45 # @DESCRIPTION:
46 # Remove flags that enable Large File Support.
47 <-----8<-----
48
49 I think my code is probably fine, or if it's buggy, so be it. A prior
50 question is: does this have sufficient utility?
51
52 I "need" (not exactly... keep reading) something like this for python.
53 Currently python*.ebuild contains:
54
55 append-ldflags "-L."
56
57 which is required in order to pull in the newly-rebuilt
58 libpython${VERSION}.so at ebuild-time, instead of the system version
59 (perhaps it's only so on obscure platforms?).
60
61 The problem is, LDFLAGS may already have some library paths coming in
62 from the environment. In this case, we end up with something like:
63
64 LDFLAGS="-Wl,--engage-warp-engines -L/random/prefix/usr/lib -L."
65
66 and python goes ahead links everything against, i.e.:
67
68 /random/prefix/usr/lib/libpython3.2.so,
69
70 or whatever is the version in question, so we achieve precisely nothing,
71 effecting the outcome we are trying to prevent (the problem manifests in
72 subtle, hard-to-diagnose ways, unfortunately).
73
74 In general, when we say append-ldflags -Lsomething, we may or may not
75 mean "always use something/libfoo, not $(libdir)/libfoo to link." In
76 the case where we do mean "always", append-ldflags is a broken approach.
77
78 An alternative would be to just replace
79
80 append-ldflags "-L."
81
82 with
83
84 export LDFLAGS="-L. ${LDFLAGS}".
85
86 however, there are problems with this:
87
88 First, it's aesthetically annoying that this spreads out the "-L*"
89 arguments into two different "zones" in LDFLAGS. No big deal, but it
90 definitely doesn't make visually scanning the logs any easier.
91
92 Second, although I'm not aware of any ld arguments which act as
93 "modifiers" to "-L" arguments (except the other -L arguments and
94 ldscript arguments, which the above patch scans for), ld does use
95 order-dependent patterns for other arguments.
96
97 For example: "-lfoo -( -lbar -lbaz -)" is not the same thing as "-(
98 -lfoo -lbar -) -lbaz". So order-dependencies might emerge in some
99 future binutils... in that case we'd still probably need to extend the
100 case statement above to include the new order-affecting arguments, but
101 at least we'd have a place in which to do so.
102
103 Third, although the meaning of -L* options may not be affected by other
104 arguments in an order-dependant manner, the reverse is not so. For
105 example, see --mri-script, --script (which both can affect and be
106 affected by the command-line library search path in an order-dependent
107 manner!), -rpath-link (SunOS only), etc...
108
109 One could certainly argue that, in practice, points two and three amount
110 to hopelessly obscure nitpicking and that nobody in their right mind
111 should be relying on this type of stuff in their LDFLAGS.
112
113 I'm not sure I'd state it quite so strongly as that, (after all these
114 might come just from profile.bashrc and be targeted to a particular
115 ebuild) but justification is clearly on the "thin" side.
116
117 Indeed, if we're going to worry about side effects, it's not entirely
118 clear that what what my patch does is safe. For example, if the
119 environment supplied "-L/foo/bar --script baz", and python for some
120 reason had a "baz" file in "${S}", then some kind of breakage would
121 surely happen when we did
122
123 prepend-ldpath "."
124
125 Also, we might also legitimately worry that the presence of this
126 function in flag-o-matic will somehow "encourage" people to do this
127 more, and, I'd have to agree that it's a pretty shitty approach to
128 getting gcc to find your generated libraries (perhaps I could answer
129 this concern by means of some kind of "don't use unless you must"
130 disclaimer, or by grafting this code into python.eclass during configure()?)
131
132 Gross as it may be, it's the approach we've adopted in dev-lang/python*,
133 a critically important, mandatory package, and it's broken. It's
134 definitely not just an academic problem, at least not for my
135 cygwin-overlay where it makes it impossible to toggle USE=threads for
136 this package. Presumably the same goes for BSD and any other platforms
137 relying on
138
139 So we either need to fix the tactics or the strategy -- personally I'm a
140 bit reluctant to mess with the latter, which, I guess, is how I end up
141 with the above, despite some misgivings.
142
143 -gmt

Replies

Subject Author
[gentoo-dev] Re: [PATCH/RFC] eclass/flag-o-matic.eclass: prepend-ldpath "Gregory M. Turner" <gmt@×××××.us>