forked from gentoo/gentoo
-
Notifications
You must be signed in to change notification settings - Fork 1
/
ltprune.eclass
175 lines (149 loc) · 4.88 KB
/
ltprune.eclass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# Copyright 1999-2019 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: ltprune.eclass
# @MAINTAINER:
# Michał Górny <[email protected]>
# @SUPPORTED_EAPIS: 0 1 2 3 4 5 6
# @BLURB: Smart .la file pruning
# @DESCRIPTION:
# A function to locate and remove unnecessary .la files.
#
# Discouraged. Whenever possible, please use much simpler:
# @CODE
# find "${D}" -name '*.la' -type f -delete || die
# @CODE
if [[ -z ${_LTPRUNE_ECLASS} ]]; then
case ${EAPI:-0} in
0|1|2|3|4|5|6)
;;
*)
die "${ECLASS}: banned in EAPI=${EAPI}; use 'find' instead";;
esac
inherit toolchain-funcs
# @FUNCTION: prune_libtool_files
# @USAGE: [--all|--modules]
# @DESCRIPTION:
# Locate unnecessary libtool files (.la) and libtool static archives
# (.a) and remove them from installation image.
#
# By default, .la files are removed whenever the static linkage can
# either be performed using pkg-config or doesn't introduce additional
# flags.
#
# If '--modules' argument is passed, .la files for modules (plugins) are
# removed as well. This is usually useful when the package installs
# plugins and the plugin loader does not use .la files.
#
# If '--all' argument is passed, all .la files are removed without
# performing any heuristic on them. You shouldn't ever use that,
# and instead report a bug in the algorithm instead.
#
# The .a files are only removed whenever corresponding .la files state
# that they should not be linked to, i.e. whenever these files
# correspond to plugins.
#
# Note: if your package installs both static libraries and .pc files
# which use variable substitution for -l flags, you need to add
# pkg-config to your DEPEND.
prune_libtool_files() {
debug-print-function ${FUNCNAME} "$@"
local removing_all removing_modules opt
for opt; do
case "${opt}" in
--all)
removing_all=1
removing_modules=1
;;
--modules)
removing_modules=1
;;
*)
die "Invalid argument to ${FUNCNAME}(): ${opt}"
esac
done
local f
local queue=()
while IFS= read -r -d '' f; do # for all .la files
local archivefile=${f/%.la/.a}
# The following check is done by libtool itself.
# It helps us avoid removing random files which match '*.la',
# see bug #468380.
if ! sed -n -e '/^# Generated by .*libtool/q0;4q1' "${f}"; then
continue
fi
[[ ${f} != ${archivefile} ]] || die 'regex sanity check failed'
local reason= pkgconfig_scanned=
local snotlink=$(sed -n -e 's:^shouldnotlink=::p' "${f}")
if [[ ${snotlink} == yes ]]; then
# Remove static libs we're not supposed to link against.
if [[ -f ${archivefile} ]]; then
einfo "Removing unnecessary ${archivefile#${D%/}} (static plugin)"
queue+=( "${archivefile}" )
fi
# The .la file may be used by a module loader, so avoid removing it
# unless explicitly requested.
if [[ ${removing_modules} ]]; then
reason='module'
fi
else
# Remove .la files when:
# - user explicitly wants us to remove all .la files,
# - respective static archive doesn't exist,
# - they are covered by a .pc file already,
# - they don't provide any new information (no libs & no flags).
if [[ ${removing_all} ]]; then
reason='requested'
elif [[ ! -f ${archivefile} ]]; then
reason='no static archive'
elif [[ ! $(sed -nre \
"s/^(dependency_libs|inherited_linker_flags)='(.*)'$/\2/p" \
"${f}") ]]; then
reason='no libs & flags'
else
if [[ ! ${pkgconfig_scanned} ]]; then
# Create a list of all .pc-covered libs.
local pc_libs=()
if [[ ! ${removing_all} ]]; then
local pc
local tf=${T}/prune-lt-files.pc
local pkgconf=$(tc-getPKG_CONFIG)
while IFS= read -r -d '' pc; do # for all .pc files
local arg libs
# Use pkg-config if available (and works),
# fallback to sed.
if ${pkgconf} --exists "${pc}" &>/dev/null; then
sed -e '/^Requires:/d' "${pc}" > "${tf}"
libs=$(${pkgconf} --libs "${tf}")
else
libs=$(sed -ne 's/^Libs://p' "${pc}")
fi
for arg in ${libs}; do
if [[ ${arg} == -l* ]]; then
if [[ ${arg} == '*$*' ]]; then
eerror "${FUNCNAME}: variable substitution likely failed in ${pc}"
eerror "(arg: ${arg})"
eerror "Most likely, you need to add virtual/pkgconfig to DEPEND."
die "${FUNCNAME}: unsubstituted variable found in .pc"
fi
pc_libs+=( lib${arg#-l}.la )
fi
done
done < <(find "${D}" -type f -name '*.pc' -print0)
rm -f "${tf}"
fi
pkgconfig_scanned=1
fi # pkgconfig_scanned
has "${f##*/}" "${pc_libs[@]}" && reason='covered by .pc'
fi # removal due to .pc
fi # shouldnotlink==no
if [[ ${reason} ]]; then
einfo "Removing unnecessary ${f#${D%/}} (${reason})"
queue+=( "${f}" )
fi
done < <(find "${D}" -xtype f -name '*.la' -print0)
if [[ ${queue[@]} ]]; then
rm -f "${queue[@]}"
fi
}
_LTPRUNE_ECLASS=1
fi #_LTPRUNE_ECLASS