Gentoo Archives: gentoo-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-dev@l.g.o
Cc: "Michał Górny" <mgorny@g.o>
Subject: [gentoo-dev] [PATCH] ltprune.eclass: Split prune_libtool_files out of eutils
Date: Sun, 12 Mar 2017 10:40:03
Message-Id: 20170312103943.23092-1-mgorny@gentoo.org
1 Move the prune_libtool_files into a dedicated ltprune.eclass.
2 The function is quite complex and depends on toolchain-funcs. It has
3 a separate maintainer, is not useful to non-autotools ebuilds, and even
4 there it is frequently replaced by the simpler 'find ... -delete' call.
5
6 Kill the unnecessary Prefix logic. There is no functional difference
7 between starting the find in ${D} and ${ED}, and the latter implies
8 unnecessary hackery for old EAPIs.
9
10 The new eclass is implicitly inherited by eutils in EAPI 6 and older
11 in order to preserve compatibility with existing ebuilds. However, all
12 ebuilds should switch to inheriting it directly.
13
14 The split has been suggested by Ulrich Müller.
15 ---
16 eclass/eutils.eclass | 150 +--------------------------------------------
17 eclass/ltprune.eclass | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++
18 2 files changed, 167 insertions(+), 149 deletions(-)
19 create mode 100644 eclass/ltprune.eclass
20
21 diff --git a/eclass/eutils.eclass b/eclass/eutils.eclass
22 index e036001dc5e1..c932d685c0e9 100644
23 --- a/eclass/eutils.eclass
24 +++ b/eclass/eutils.eclass
25 @@ -17,12 +17,10 @@
26 if [[ -z ${_EUTILS_ECLASS} ]]; then
27 _EUTILS_ECLASS=1
28
29 -inherit toolchain-funcs
30 -
31 # implicitly inherited (now split) eclasses
32 case ${EAPI:-0} in
33 0|1|2|3|4|5|6)
34 - inherit epatch estack multilib
35 + inherit epatch estack ltprune multilib toolchain-funcs
36 ;;
37 esac
38
39 @@ -869,152 +867,6 @@ use_if_iuse() {
40 use $1
41 }
42
43 -# @FUNCTION: prune_libtool_files
44 -# @USAGE: [--all|--modules]
45 -# @DESCRIPTION:
46 -# Locate unnecessary libtool files (.la) and libtool static archives
47 -# (.a) and remove them from installation image.
48 -#
49 -# By default, .la files are removed whenever the static linkage can
50 -# either be performed using pkg-config or doesn't introduce additional
51 -# flags.
52 -#
53 -# If '--modules' argument is passed, .la files for modules (plugins) are
54 -# removed as well. This is usually useful when the package installs
55 -# plugins and the plugin loader does not use .la files.
56 -#
57 -# If '--all' argument is passed, all .la files are removed without
58 -# performing any heuristic on them. You shouldn't ever use that,
59 -# and instead report a bug in the algorithm instead.
60 -#
61 -# The .a files are only removed whenever corresponding .la files state
62 -# that they should not be linked to, i.e. whenever these files
63 -# correspond to plugins.
64 -#
65 -# Note: if your package installs both static libraries and .pc files
66 -# which use variable substitution for -l flags, you need to add
67 -# pkg-config to your DEPEND.
68 -prune_libtool_files() {
69 - debug-print-function ${FUNCNAME} "$@"
70 -
71 - local removing_all removing_modules opt
72 - _eutils_eprefix_init
73 - for opt; do
74 - case "${opt}" in
75 - --all)
76 - removing_all=1
77 - removing_modules=1
78 - ;;
79 - --modules)
80 - removing_modules=1
81 - ;;
82 - *)
83 - die "Invalid argument to ${FUNCNAME}(): ${opt}"
84 - esac
85 - done
86 -
87 - local f
88 - local queue=()
89 - while IFS= read -r -d '' f; do # for all .la files
90 - local archivefile=${f/%.la/.a}
91 -
92 - # The following check is done by libtool itself.
93 - # It helps us avoid removing random files which match '*.la',
94 - # see bug #468380.
95 - if ! sed -n -e '/^# Generated by .*libtool/q0;4q1' "${f}"; then
96 - continue
97 - fi
98 -
99 - [[ ${f} != ${archivefile} ]] || die 'regex sanity check failed'
100 - local reason= pkgconfig_scanned=
101 - local snotlink=$(sed -n -e 's:^shouldnotlink=::p' "${f}")
102 -
103 - if [[ ${snotlink} == yes ]]; then
104 -
105 - # Remove static libs we're not supposed to link against.
106 - if [[ -f ${archivefile} ]]; then
107 - einfo "Removing unnecessary ${archivefile#${D%/}} (static plugin)"
108 - queue+=( "${archivefile}" )
109 - fi
110 -
111 - # The .la file may be used by a module loader, so avoid removing it
112 - # unless explicitly requested.
113 - if [[ ${removing_modules} ]]; then
114 - reason='module'
115 - fi
116 -
117 - else
118 -
119 - # Remove .la files when:
120 - # - user explicitly wants us to remove all .la files,
121 - # - respective static archive doesn't exist,
122 - # - they are covered by a .pc file already,
123 - # - they don't provide any new information (no libs & no flags).
124 -
125 - if [[ ${removing_all} ]]; then
126 - reason='requested'
127 - elif [[ ! -f ${archivefile} ]]; then
128 - reason='no static archive'
129 - elif [[ ! $(sed -nre \
130 - "s/^(dependency_libs|inherited_linker_flags)='(.*)'$/\2/p" \
131 - "${f}") ]]; then
132 - reason='no libs & flags'
133 - else
134 - if [[ ! ${pkgconfig_scanned} ]]; then
135 - # Create a list of all .pc-covered libs.
136 - local pc_libs=()
137 - if [[ ! ${removing_all} ]]; then
138 - local pc
139 - local tf=${T}/prune-lt-files.pc
140 - local pkgconf=$(tc-getPKG_CONFIG)
141 -
142 - while IFS= read -r -d '' pc; do # for all .pc files
143 - local arg libs
144 -
145 - # Use pkg-config if available (and works),
146 - # fallback to sed.
147 - if ${pkgconf} --exists "${pc}" &>/dev/null; then
148 - sed -e '/^Requires:/d' "${pc}" > "${tf}"
149 - libs=$(${pkgconf} --libs "${tf}")
150 - else
151 - libs=$(sed -ne 's/^Libs://p' "${pc}")
152 - fi
153 -
154 - for arg in ${libs}; do
155 - if [[ ${arg} == -l* ]]; then
156 - if [[ ${arg} == '*$*' ]]; then
157 - eqawarn "${FUNCNAME}: variable substitution likely failed in ${pc}"
158 - eqawarn "(arg: ${arg})"
159 - eqawarn "Most likely, you need to add virtual/pkgconfig to DEPEND."
160 - fi
161 -
162 - pc_libs+=( lib${arg#-l}.la )
163 - fi
164 - done
165 - done < <(find "${D}" -type f -name '*.pc' -print0)
166 -
167 - rm -f "${tf}"
168 - fi
169 -
170 - pkgconfig_scanned=1
171 - fi # pkgconfig_scanned
172 -
173 - has "${f##*/}" "${pc_libs[@]}" && reason='covered by .pc'
174 - fi # removal due to .pc
175 -
176 - fi # shouldnotlink==no
177 -
178 - if [[ ${reason} ]]; then
179 - einfo "Removing unnecessary ${f#${D%/}} (${reason})"
180 - queue+=( "${f}" )
181 - fi
182 - done < <(find "${ED}" -xtype f -name '*.la' -print0)
183 -
184 - if [[ ${queue[@]} ]]; then
185 - rm -f "${queue[@]}"
186 - fi
187 -}
188 -
189 # @FUNCTION: optfeature
190 # @USAGE: <short description> <package atom to match> [other atoms]
191 # @DESCRIPTION:
192 diff --git a/eclass/ltprune.eclass b/eclass/ltprune.eclass
193 new file mode 100644
194 index 000000000000..731d233cc14e
195 --- /dev/null
196 +++ b/eclass/ltprune.eclass
197 @@ -0,0 +1,166 @@
198 +# Copyright 1999-2017 Gentoo Foundation
199 +# Distributed under the terms of the GNU General Public License v2
200 +
201 +# @ECLASS: ltprune.eclass
202 +# @MAINTAINER:
203 +# Michał Górny <mgorny@g.o>
204 +# @BLURB: Smart .la file pruning
205 +# @DESCRIPTION:
206 +# A function to locate and remove unnecessary .la files.
207 +#
208 +# Discouraged. Whenever possible, please use much simpler:
209 +# @CODE
210 +# find "${D}" -name '*.la' -delete || die
211 +# @CODE
212 +
213 +if [[ -z ${_LTPRUNE_ECLASS} ]]; then
214 +
215 +inherit toolchain-funcs
216 +
217 +# @FUNCTION: prune_libtool_files
218 +# @USAGE: [--all|--modules]
219 +# @DESCRIPTION:
220 +# Locate unnecessary libtool files (.la) and libtool static archives
221 +# (.a) and remove them from installation image.
222 +#
223 +# By default, .la files are removed whenever the static linkage can
224 +# either be performed using pkg-config or doesn't introduce additional
225 +# flags.
226 +#
227 +# If '--modules' argument is passed, .la files for modules (plugins) are
228 +# removed as well. This is usually useful when the package installs
229 +# plugins and the plugin loader does not use .la files.
230 +#
231 +# If '--all' argument is passed, all .la files are removed without
232 +# performing any heuristic on them. You shouldn't ever use that,
233 +# and instead report a bug in the algorithm instead.
234 +#
235 +# The .a files are only removed whenever corresponding .la files state
236 +# that they should not be linked to, i.e. whenever these files
237 +# correspond to plugins.
238 +#
239 +# Note: if your package installs both static libraries and .pc files
240 +# which use variable substitution for -l flags, you need to add
241 +# pkg-config to your DEPEND.
242 +prune_libtool_files() {
243 + debug-print-function ${FUNCNAME} "$@"
244 +
245 + local removing_all removing_modules opt
246 + for opt; do
247 + case "${opt}" in
248 + --all)
249 + removing_all=1
250 + removing_modules=1
251 + ;;
252 + --modules)
253 + removing_modules=1
254 + ;;
255 + *)
256 + die "Invalid argument to ${FUNCNAME}(): ${opt}"
257 + esac
258 + done
259 +
260 + local f
261 + local queue=()
262 + while IFS= read -r -d '' f; do # for all .la files
263 + local archivefile=${f/%.la/.a}
264 +
265 + # The following check is done by libtool itself.
266 + # It helps us avoid removing random files which match '*.la',
267 + # see bug #468380.
268 + if ! sed -n -e '/^# Generated by .*libtool/q0;4q1' "${f}"; then
269 + continue
270 + fi
271 +
272 + [[ ${f} != ${archivefile} ]] || die 'regex sanity check failed'
273 + local reason= pkgconfig_scanned=
274 + local snotlink=$(sed -n -e 's:^shouldnotlink=::p' "${f}")
275 +
276 + if [[ ${snotlink} == yes ]]; then
277 +
278 + # Remove static libs we're not supposed to link against.
279 + if [[ -f ${archivefile} ]]; then
280 + einfo "Removing unnecessary ${archivefile#${D%/}} (static plugin)"
281 + queue+=( "${archivefile}" )
282 + fi
283 +
284 + # The .la file may be used by a module loader, so avoid removing it
285 + # unless explicitly requested.
286 + if [[ ${removing_modules} ]]; then
287 + reason='module'
288 + fi
289 +
290 + else
291 +
292 + # Remove .la files when:
293 + # - user explicitly wants us to remove all .la files,
294 + # - respective static archive doesn't exist,
295 + # - they are covered by a .pc file already,
296 + # - they don't provide any new information (no libs & no flags).
297 +
298 + if [[ ${removing_all} ]]; then
299 + reason='requested'
300 + elif [[ ! -f ${archivefile} ]]; then
301 + reason='no static archive'
302 + elif [[ ! $(sed -nre \
303 + "s/^(dependency_libs|inherited_linker_flags)='(.*)'$/\2/p" \
304 + "${f}") ]]; then
305 + reason='no libs & flags'
306 + else
307 + if [[ ! ${pkgconfig_scanned} ]]; then
308 + # Create a list of all .pc-covered libs.
309 + local pc_libs=()
310 + if [[ ! ${removing_all} ]]; then
311 + local pc
312 + local tf=${T}/prune-lt-files.pc
313 + local pkgconf=$(tc-getPKG_CONFIG)
314 +
315 + while IFS= read -r -d '' pc; do # for all .pc files
316 + local arg libs
317 +
318 + # Use pkg-config if available (and works),
319 + # fallback to sed.
320 + if ${pkgconf} --exists "${pc}" &>/dev/null; then
321 + sed -e '/^Requires:/d' "${pc}" > "${tf}"
322 + libs=$(${pkgconf} --libs "${tf}")
323 + else
324 + libs=$(sed -ne 's/^Libs://p' "${pc}")
325 + fi
326 +
327 + for arg in ${libs}; do
328 + if [[ ${arg} == -l* ]]; then
329 + if [[ ${arg} == '*$*' ]]; then
330 + eqawarn "${FUNCNAME}: variable substitution likely failed in ${pc}"
331 + eqawarn "(arg: ${arg})"
332 + eqawarn "Most likely, you need to add virtual/pkgconfig to DEPEND."
333 + fi
334 +
335 + pc_libs+=( lib${arg#-l}.la )
336 + fi
337 + done
338 + done < <(find "${D}" -type f -name '*.pc' -print0)
339 +
340 + rm -f "${tf}"
341 + fi
342 +
343 + pkgconfig_scanned=1
344 + fi # pkgconfig_scanned
345 +
346 + has "${f##*/}" "${pc_libs[@]}" && reason='covered by .pc'
347 + fi # removal due to .pc
348 +
349 + fi # shouldnotlink==no
350 +
351 + if [[ ${reason} ]]; then
352 + einfo "Removing unnecessary ${f#${D%/}} (${reason})"
353 + queue+=( "${f}" )
354 + fi
355 + done < <(find "${D}" -xtype f -name '*.la' -print0)
356 +
357 + if [[ ${queue[@]} ]]; then
358 + rm -f "${queue[@]}"
359 + fi
360 +}
361 +
362 +_LTPRUNE_ECLASS=1
363 +fi #_LTPRUNE_ECLASS
364 --
365 2.12.0

Replies

Subject Author
[gentoo-dev] [PATCH v2] ltprune.eclass "Michał Górny" <mgorny@g.o>