1 |
# Copyright 1999-2003 Gentoo Technologies, Inc. |
2 |
# Distributed under the terms of the GNU General Public License v2 |
3 |
# $Header: /home/cvsroot/gentoo-x86/eclass/flag-o-matic.eclass,v 1.40 2004/03/12 11:21:15 vapier Exp $ |
4 |
# |
5 |
# Author Bart Verwilst <verwilst@gentoo.org> |
6 |
|
7 |
ECLASS=flag-o-matic |
8 |
INHERITED="$INHERITED $ECLASS" |
9 |
|
10 |
# |
11 |
#### filter-flags <flags> #### |
12 |
# Remove particular flags from C[XX]FLAGS |
13 |
# Matches only complete flags |
14 |
# |
15 |
#### append-flags <flags> #### |
16 |
# Add extra flags to your current C[XX]FLAGS |
17 |
# |
18 |
#### replace-flags <orig.flag> <new.flag> ### |
19 |
# Replace a flag by another one |
20 |
# |
21 |
#### replace-cpu-flags <new.cpu> <old.cpus> ### |
22 |
# Replace march/mcpu flags that specify <old.cpus> |
23 |
# with flags that specify <new.cpu> |
24 |
# |
25 |
#### is-flag <flag> #### |
26 |
# Returns "true" if flag is set in C[XX]FLAGS |
27 |
# Matches only complete a flag |
28 |
# |
29 |
#### strip-flags #### |
30 |
# Strip C[XX]FLAGS of everything except known |
31 |
# good options. |
32 |
# |
33 |
#### strip-unsupported-flags #### |
34 |
# Strip C[XX]FLAGS of any flags not supported by |
35 |
# installed version of gcc |
36 |
# |
37 |
#### get-flag <flag> #### |
38 |
# Find and echo the value for a particular flag |
39 |
# |
40 |
#### replace-sparc64-flags #### |
41 |
# Sets mcpu to v8 and uses the original value |
42 |
# as mtune if none specified. |
43 |
# |
44 |
#### filter-mfpmath <math types> #### |
45 |
# Remove specified math types from the fpmath specification |
46 |
# If the user has -mfpmath=sse,386, running `filter-mfpmath sse` |
47 |
# will leave the user with -mfpmath=386 |
48 |
# |
49 |
#### append-ldflags #### |
50 |
# Add extra flags to your current LDFLAGS |
51 |
# |
52 |
#### filter-ldflags <flags> #### |
53 |
# Remove particular flags from LDFLAGS |
54 |
# Matches only complete flags |
55 |
# |
56 |
#### etexec-flags #### |
57 |
# hooked function for hardened-gcc that appends |
58 |
# -yet_exec {C,CXX,LD}FLAGS when hardened-gcc is installed |
59 |
# and a package is filtering -fPIC,-fpic, -fPIE, -fpie |
60 |
# |
61 |
#### fstack-flags #### |
62 |
# hooked function for hardened-gcc that appends |
63 |
# -yno_propolice to {C,CXX,LD}FLAGS when hardened-gcc is installed |
64 |
# and a package is filtering -fstack-protector, -fstack-protector-all |
65 |
# |
66 |
|
67 |
# C[XX]FLAGS that we allow in strip-flags |
68 |
setup-allowed-flags() { |
69 |
export ALLOWED_FLAGS="-O -O1 -O2 -mcpu -march -mtune -fstack-protector -pipe -g" |
70 |
case "${ARCH}" in |
71 |
mips) ALLOWED_FLAGS="${ALLOWED_FLAGS} -mips1 -mips2 -mips3 -mips4 -mabi" ;; |
72 |
amd64) ALLOWED_FLAGS="${ALLOWED_FLAGS} -fPIC" ;; |
73 |
alpha) ALLOWED_FLAGS="${ALLOWED_FLAGS} -fPIC" ;; |
74 |
ia64) ALLOWED_FLAGS="${ALLOWED_FLAGS} -fPIC" ;; |
75 |
esac |
76 |
|
77 |
# C[XX]FLAGS that we are think is ok, but needs testing |
78 |
# NOTE: currently -Os have issues with gcc3 and K6* arch's |
79 |
export UNSTABLE_FLAGS="-Os -O3 -freorder-blocks -fprefetch-loop-arrays" |
80 |
return 0 |
81 |
} |
82 |
|
83 |
filter-flags() { |
84 |
for x in "$@" ; do |
85 |
case "${x}" in |
86 |
-fPIC|-fpic|-fPIE|-fpie|-pie) etexec-flags;; |
87 |
-fstack-protector|-fstack-protector-all) fstack-flags;; |
88 |
*) ;; |
89 |
esac |
90 |
done |
91 |
|
92 |
# we do this fancy spacing stuff so as to not filter |
93 |
# out part of a flag ... we want flag atoms ! :D |
94 |
CFLAGS=" ${CFLAGS} " |
95 |
CXXFLAGS=" ${CXXFLAGS} " |
96 |
for x in "$@" ; do |
97 |
CFLAGS="${CFLAGS// ${x} / }" |
98 |
CXXFLAGS="${CXXFLAGS// ${x} / }" |
99 |
done |
100 |
CFLAGS="${CFLAGS:1:${#CFLAGS}-2}" |
101 |
CXXFLAGS="${CXXFLAGS:1:${#CXXFLAGS}-2}" |
102 |
return 0 |
103 |
} |
104 |
|
105 |
filter-lfs-flags() { |
106 |
filter-flags -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE |
107 |
} |
108 |
|
109 |
append-flags() { |
110 |
export CFLAGS="${CFLAGS} $@" |
111 |
export CXXFLAGS="${CXXFLAGS} $@" |
112 |
[ "`is-flag -fno-stack-protector`" -o "`is-flag -fno-stack-protector-all`" ] && fstack-flags |
113 |
return 0 |
114 |
} |
115 |
|
116 |
replace-flags() { |
117 |
# we do this fancy spacing stuff so as to not filter |
118 |
# out part of a flag ... we want flag atoms ! :D |
119 |
CFLAGS=" ${CFLAGS} " |
120 |
CXXFLAGS=" ${CXXFLAGS} " |
121 |
CFLAGS="${CFLAGS// ${1} / ${2} }" |
122 |
CXXFLAGS="${CXXFLAGS// ${1} / ${2} }" |
123 |
CFLAGS="${CFLAGS:1:${#CFLAGS}-2}" |
124 |
CXXFLAGS="${CXXFLAGS:1:${#CXXFLAGS}-2}" |
125 |
return 0 |
126 |
} |
127 |
|
128 |
replace-cpu-flags() { |
129 |
local newcpu="$1" ; shift |
130 |
local oldcpu="" |
131 |
for oldcpu in "$@" ; do |
132 |
replace-flags -march=${oldcpu} -march=${newcpu} |
133 |
replace-flags -mcpu=${oldcpu} -mcpu=${newcpu} |
134 |
replace-flags -mtune=${oldcpu} -mtune=${newcpu} |
135 |
done |
136 |
return 0 |
137 |
} |
138 |
|
139 |
is-flag() { |
140 |
for x in ${CFLAGS} ${CXXFLAGS} ; do |
141 |
if [ "${x}" == "$1" ] ; then |
142 |
echo true |
143 |
return 0 |
144 |
fi |
145 |
done |
146 |
return 1 |
147 |
} |
148 |
|
149 |
filter-mfpmath() { |
150 |
# save the original -mfpmath flag |
151 |
local orig_mfpmath="`get-flag -mfpmath`" |
152 |
# get the value of the current -mfpmath flag |
153 |
local new_math=" `get-flag mfpmath | tr , ' '` " |
154 |
# figure out which math values are to be removed |
155 |
local prune_math="" |
156 |
for prune_math in "$@" ; do |
157 |
new_math="${new_math/ ${prune_math} / }" |
158 |
done |
159 |
new_math="`echo ${new_math:1:${#new_math}-2} | tr ' ' ,`" |
160 |
|
161 |
if [ -z "${new_math}" ] ; then |
162 |
# if we're removing all user specified math values are |
163 |
# slated for removal, then we just filter the flag |
164 |
filter-flags ${orig_mfpmath} |
165 |
else |
166 |
# if we only want to filter some of the user specified |
167 |
# math values, then we replace the current flag |
168 |
replace-flags ${orig_mfpmath} -mfpmath=${new_math} |
169 |
fi |
170 |
return 0 |
171 |
} |
172 |
|
173 |
strip-flags() { |
174 |
setup-allowed-flags |
175 |
|
176 |
local NEW_CFLAGS="" |
177 |
local NEW_CXXFLAGS="" |
178 |
|
179 |
# Allow unstable C[XX]FLAGS if we are using unstable profile ... |
180 |
if [ `has ~${ARCH} ${ACCEPT_KEYWORDS}` ] ; then |
181 |
[ `use debug` ] && einfo "Enabling the use of some unstable flags" |
182 |
ALLOWED_FLAGS="${ALLOWED_FLAGS} ${UNSTABLE_FLAGS}" |
183 |
fi |
184 |
|
185 |
set -f |
186 |
|
187 |
for x in ${CFLAGS} |
188 |
do |
189 |
for y in ${ALLOWED_FLAGS} |
190 |
do |
191 |
flag=${x%%=*} |
192 |
if [ "${flag%%${y}}" = "" ] |
193 |
then |
194 |
NEW_CFLAGS="${NEW_CFLAGS} ${x}" |
195 |
break |
196 |
fi |
197 |
done |
198 |
done |
199 |
|
200 |
for x in ${CXXFLAGS} |
201 |
do |
202 |
for y in ${ALLOWED_FLAGS} |
203 |
do |
204 |
flag=${x%%=*} |
205 |
if [ "${flag%%${y}}" = "" ] |
206 |
then |
207 |
NEW_CXXFLAGS="${NEW_CXXFLAGS} ${x}" |
208 |
break |
209 |
fi |
210 |
done |
211 |
done |
212 |
|
213 |
# In case we filtered out all optimization flags fallback to -O2 |
214 |
if [ "${CFLAGS/-O}" != "${CFLAGS}" -a "${NEW_CFLAGS/-O}" = "${NEW_CFLAGS}" ]; then |
215 |
NEW_CFLAGS="${NEW_CFLAGS} -O2" |
216 |
fi |
217 |
if [ "${CXXFLAGS/-O}" != "${CXXFLAGS}" -a "${NEW_CXXFLAGS/-O}" = "${NEW_CXXFLAGS}" ]; then |
218 |
NEW_CXXFLAGS="${NEW_CXXFLAGS} -O2" |
219 |
fi |
220 |
|
221 |
set +f |
222 |
|
223 |
[ `use debug` ] \ |
224 |
&& einfo "CFLAGS=\"${NEW_CFLAGS}\"" \ |
225 |
&& einfo "CXXFLAGS=\"${NEW_CXXFLAGS}\"" |
226 |
|
227 |
export CFLAGS="${NEW_CFLAGS}" |
228 |
export CXXFLAGS="${NEW_CXXFLAGS}" |
229 |
return 0 |
230 |
} |
231 |
|
232 |
test_flag() { |
233 |
if gcc -S -xc "$@" -o /dev/null /dev/null >/dev/null 2>&1; then |
234 |
echo "$@" |
235 |
return 0 |
236 |
fi |
237 |
return 1 |
238 |
} |
239 |
|
240 |
strip-unsupported-flags() { |
241 |
for x in ${CFLAGS} ; do |
242 |
NEW_CFLAGS=${NEW_CFLAGS}" ""`test_flag ${x}`" |
243 |
done |
244 |
for x in ${CXXFLAGS} ; do |
245 |
NEW_CXXFLAGS=${NEW_CXXFLAGS}" ""`test_flag ${x}`" |
246 |
done |
247 |
|
248 |
export CFLAGS="${NEW_CFLAGS}" |
249 |
export CXXFLAGS="${NEW_CXXFLAGS}" |
250 |
} |
251 |
|
252 |
get-flag() { |
253 |
# this code looks a little flaky but seems to work for |
254 |
# everything we want ... |
255 |
# for example, if CFLAGS="-march=i686": |
256 |
# `get-flags -march` == "-march=i686" |
257 |
# `get-flags march` == "i686" |
258 |
local findflag="$1" |
259 |
for f in ${CFLAGS} ${CXXFLAGS} ; do |
260 |
if [ "${f/${findflag}}" != "${f}" ] ; then |
261 |
echo "${f/-${findflag}=}" |
262 |
return 0 |
263 |
fi |
264 |
done |
265 |
return 1 |
266 |
} |
267 |
|
268 |
replace-sparc64-flags() { |
269 |
local SPARC64_CPUS="ultrasparc v9" |
270 |
|
271 |
if [ "${CFLAGS/mtune}" != "${CFLAGS}" ] |
272 |
then |
273 |
for x in ${SPARC64_CPUS} |
274 |
do |
275 |
CFLAGS="${CFLAGS/-mcpu=${x}/-mcpu=v8}" |
276 |
done |
277 |
else |
278 |
for x in ${SPARC64_CPUS} |
279 |
do |
280 |
CFLAGS="${CFLAGS/-mcpu=${x}/-mcpu=v8 -mtune=${x}}" |
281 |
done |
282 |
fi |
283 |
|
284 |
if [ "${CXXFLAGS/mtune}" != "${CXXFLAGS}" ] |
285 |
then |
286 |
for x in ${SPARC64_CPUS} |
287 |
do |
288 |
CXXFLAGS="${CXXFLAGS/-mcpu=${x}/-mcpu=v8}" |
289 |
done |
290 |
else |
291 |
for x in ${SPARC64_CPUS} |
292 |
do |
293 |
CXXFLAGS="${CXXFLAGS/-mcpu=${x}/-mcpu=v8 -mtune=${x}}" |
294 |
done |
295 |
fi |
296 |
} |
297 |
|
298 |
append-ldflags() { |
299 |
LDFLAGS="${LDFLAGS} $@" |
300 |
return 0 |
301 |
} |
302 |
|
303 |
filter-ldflags() { |
304 |
# we do this fancy spacing stuff so as to not filter |
305 |
# out part of a flag ... we want flag atoms ! :D |
306 |
LDFLAGS=" ${LDFLAGS} " |
307 |
for x in "$@" ; do |
308 |
LDFLAGS="${LDFLAGS// ${x} / }" |
309 |
done |
310 |
LDFLAGS="${LDFLAGS:1:${#LDFLAGS}-2}" |
311 |
return 0 |
312 |
} |
313 |
|
314 |
etexec-flags() { |
315 |
has_version sys-devel/hardened-gcc |
316 |
if [ $? == 0 ] ; then |
317 |
if [ "`is-flag -yet_exec`" != "true" ]; then |
318 |
debug-print ">>> appending flags -yet_exec" |
319 |
append-flags -yet_exec |
320 |
append-ldflags -yet_exec |
321 |
fi |
322 |
fi |
323 |
} |
324 |
|
325 |
fstack-flags() { |
326 |
has_version sys-devel/hardened-gcc |
327 |
if [ $? == 0 ] ; then |
328 |
if [ "`is-flag -yno_propolice`" != "true" ]; then |
329 |
debug-print ">>> appending flags -yno_propolice" |
330 |
append-flags -yno_propolice |
331 |
append-ldflags -yno_propolice |
332 |
fi |
333 |
fi |
334 |
} |