1 |
# Copyright 1999-2004 Gentoo Foundation |
2 |
# Distributed under the terms of the GNU General Public License v2 |
3 |
# $Header: /var/cvsroot/gentoo-x86/eclass/multilib.eclass,v 1.27 2005/04/12 19:52:21 eradicator Exp $ |
4 |
# |
5 |
# Author: Jeremy Huddleston <eradicator@gentoo.org> |
6 |
# |
7 |
# This eclass is for all functions pertaining to handling multilib. |
8 |
# configurations. |
9 |
|
10 |
INHERITED="$INHERITED $ECLASS" |
11 |
|
12 |
DESCRIPTION="Based on the ${ECLASS} eclass" |
13 |
|
14 |
# has_multilib_profile: |
15 |
# Return true if the current profile is a multilib profile and lists more than |
16 |
# one abi in ${MULTILIB_ABIS}. You might want to use this like |
17 |
# 'use multilib || has_multilib_profile' until all profiles utilizing the |
18 |
# 'multilib' use flag are removed from portage |
19 |
|
20 |
# is_final_abi: |
21 |
# Return true if ${ABI} is the final abi to be installed (and thus we are |
22 |
# on our last run through a src_* function. |
23 |
|
24 |
# number_abis: |
25 |
# echo the number of ABIs we will be installing for |
26 |
|
27 |
# get_install_abis: |
28 |
# Return a list of the ABIs we want to install for with |
29 |
# the last one in the list being the default. |
30 |
|
31 |
# get_all_abis: |
32 |
# Return a list of the ABIs supported by this profile. |
33 |
# the last one in the list being the default. |
34 |
|
35 |
# get_all_libdirs: |
36 |
# Returns a list of all the libdirs used by this profile. This includes |
37 |
# those that might not be touched by the current ebuild and always includes |
38 |
# "lib". |
39 |
|
40 |
# get_libdir: |
41 |
# Returns the libdir for the selected ABI. This is backwards compatible |
42 |
# and simply calls get_abi_LIBDIR() on newer profiles. You should use this |
43 |
# to determine where to install shared objects (ex: /usr/$(get_libdir)) |
44 |
|
45 |
# get_abi_var <VAR> [<ABI>]: |
46 |
# returns the value of ${<VAR>_<ABI>} which should be set in make.defaults |
47 |
# |
48 |
# get_abi_CFLAGS: |
49 |
# get_abi_CDEFINE: |
50 |
# get_abi_LIBDIR: |
51 |
# Aliases for 'get_abi_var CFLAGS', etc. |
52 |
|
53 |
# get_ml_incdir [<include dir> [<ABI>]] |
54 |
# include dir defaults to /usr/include |
55 |
# ABI defaults to ${ABI} or ${DEFAULT_ABI} |
56 |
# |
57 |
# If a multilib include dir is associated with the passed include dir, then |
58 |
# we return it, otherwise, we just echo back the include dir. This is |
59 |
# neccessary when a built script greps header files rather than testing them |
60 |
# via #include (like perl) to figure out features. |
61 |
|
62 |
# prep_ml_includes: |
63 |
# Some includes (include/asm, glibc, etc) are ABI dependent. In this case, |
64 |
# We can install them in different locations for each ABI and create a common |
65 |
# header which includes the right one based on CDEFINE_${ABI}. If your |
66 |
# package installs ABI-specific headers, just add 'prep_ml_includes' to the |
67 |
# end of your src_install(). It takes a list of directories that include |
68 |
# files are installed in (default is /usr/include if none are passed). |
69 |
# |
70 |
# Example: |
71 |
# src_install() { |
72 |
# ... |
73 |
# prep_ml_includes /usr/qt/3/include |
74 |
# } |
75 |
|
76 |
# create_ml_includes <include dir> <symbol 1>:<dir 1> [<symbol 2>:<dir 2> ...] |
77 |
# If you need more control than prep_ml_includes can offer (like linux-headers |
78 |
# for the asm-* dirs, then use create_ml_includes. The firs argument is the |
79 |
# common dir. The remaining args are of the form <symbol>:<dir> where |
80 |
# <symbol> is what is put in the #ifdef for choosing that dir. |
81 |
# |
82 |
# Ideas for this code came from debian's sparc-linux headers package. |
83 |
# |
84 |
# Example: |
85 |
# create_ml_includes /usr/include/asm __sparc__:/usr/include/asm-sparc __sparc64__:/usr/include/asm-sparc64 |
86 |
# create_ml_includes /usr/include/asm __i386__:/usr/include/asm-i386 __x86_64__:/usr/include/asm-x86_64 |
87 |
|
88 |
### END DOCUMENTATION ### |
89 |
|
90 |
# Defaults: |
91 |
export MULTILIB_ABIS=${MULTILIB_ABIS:-"default"} |
92 |
export DEFAULT_ABI=${DEFAULT_ABI:-"default"} |
93 |
# This causes econf to set --libdir=/usr/lib where it didn't before |
94 |
#export ABI=${ABI:-"default"} |
95 |
export CFLAGS_default |
96 |
export LDFLAGS_default |
97 |
export CHOST_default=${CHOST_default:-${CHOST}} |
98 |
export LIBDIR_default=${CONF_LIBDIR:-"lib"} |
99 |
export CDEFINE_default="__unix__" |
100 |
|
101 |
# has_multilib_profile() |
102 |
has_multilib_profile() { |
103 |
[ -n "${MULTILIB_ABIS}" -a "${MULTILIB_ABIS}" != "${MULTILIB_ABIS/ /}" ] |
104 |
} |
105 |
|
106 |
# This function simply returns the desired lib directory. With portage |
107 |
# 2.0.51, we now have support for installing libraries to lib32/lib64 |
108 |
# to accomidate the needs of multilib systems. It's no longer a good idea |
109 |
# to assume all libraries will end up in lib. Replace any (sane) instances |
110 |
# where lib is named directly with $(get_libdir) if possible. |
111 |
# |
112 |
# Travis Tilley <lv@gentoo.org> (24 Aug 2004) |
113 |
# |
114 |
# Jeremy Huddleston <eradicator@gentoo.org> (23 Dec 2004): |
115 |
# Added support for ${ABI} and ${DEFAULT_ABI}. If they're both not set, |
116 |
# fall back on old behavior. Any profile that has these set should also |
117 |
# depend on a newer version of portage (not yet released) which uses these |
118 |
# over CONF_LIBDIR in econf, dolib, etc... |
119 |
get_libdir() { |
120 |
local CONF_LIBDIR |
121 |
if [ -n "${CONF_LIBDIR_OVERRIDE}" ] ; then |
122 |
# if there is an override, we want to use that... always. |
123 |
echo ${CONF_LIBDIR_OVERRIDE} |
124 |
else |
125 |
get_abi_LIBDIR |
126 |
fi |
127 |
} |
128 |
|
129 |
get_multilibdir() { |
130 |
if has_multilib_profile; then |
131 |
eerror "get_multilibdir called, but it shouldn't be needed with the new multilib approach. Please file a bug at http://bugs.gentoo.org and assign it to eradicator@gentoo.org" |
132 |
exit 1 |
133 |
fi |
134 |
echo ${CONF_MULTILIBDIR:=lib32} |
135 |
} |
136 |
|
137 |
# Sometimes you need to override the value returned by get_libdir. A good |
138 |
# example of this is xorg-x11, where lib32 isnt a supported configuration, |
139 |
# and where lib64 -must- be used on amd64 (for applications that need lib |
140 |
# to be 32bit, such as adobe acrobat). Note that this override also bypasses |
141 |
# portage version sanity checking. |
142 |
# get_libdir_override expects one argument, the result get_libdir should |
143 |
# return: |
144 |
# |
145 |
# get_libdir_override lib64 |
146 |
# |
147 |
# Travis Tilley <lv@gentoo.org> (31 Aug 2004) |
148 |
get_libdir_override() { |
149 |
if has_multilib_profile; then |
150 |
eerror "get_libdir_override called, but it shouldn't be needed with the new multilib approach. Please file a bug at http://bugs.gentoo.org and assign it to eradicator@gentoo.org" |
151 |
exit 1 |
152 |
fi |
153 |
CONF_LIBDIR="$1" |
154 |
CONF_LIBDIR_OVERRIDE="$1" |
155 |
LIBDIR_default="$1" |
156 |
} |
157 |
|
158 |
# get_abi_var <VAR> [<ABI>] |
159 |
# returns the value of ${<VAR>_<ABI>} which should be set in make.defaults |
160 |
# |
161 |
# ex: |
162 |
# CFLAGS=$(get_abi_var CFLAGS sparc32) # CFLAGS=-m32 |
163 |
# |
164 |
# Note that the prefered method is to set CC="$(tc-getCC) $(get_abi_CFLAGS)" |
165 |
# This will hopefully be added to portage soon... |
166 |
# |
167 |
# If <ABI> is not specified, ${ABI} is used. |
168 |
# If <ABI> is not specified and ${ABI} is not defined, ${DEFAULT_ABI} is used. |
169 |
# If <ABI> is not specified and ${ABI} and ${DEFAULT_ABI} are not defined, we return an empty string. |
170 |
# |
171 |
# Jeremy Huddleston <eradicator@gentoo.org> |
172 |
get_abi_var() { |
173 |
local flag=${1} |
174 |
local abi |
175 |
if [ $# -gt 1 ]; then |
176 |
abi=${2} |
177 |
elif [ -n "${ABI}" ]; then |
178 |
abi=${ABI} |
179 |
elif [ -n "${DEFAULT_ABI}" ]; then |
180 |
abi=${DEFAULT_ABI} |
181 |
else |
182 |
abi="default" |
183 |
fi |
184 |
|
185 |
local var="${flag}_${abi}" |
186 |
echo ${!var} |
187 |
} |
188 |
|
189 |
get_abi_CFLAGS() { get_abi_var CFLAGS "${@}"; } |
190 |
get_abi_LDFLAGS() { get_abi_var LDFLAGS "${@}"; } |
191 |
get_abi_CHOST() { get_abi_var CHOST "${@}"; } |
192 |
get_abi_FAKE_TARGETS() { get_abi_var FAKE_TARGETS "${@}"; } |
193 |
get_abi_CDEFINE() { get_abi_var CDEFINE "${@}"; } |
194 |
get_abi_LIBDIR() { get_abi_var LIBDIR "${@}"; } |
195 |
|
196 |
# Return a list of the ABIs we want to install for with |
197 |
# the last one in the list being the default. |
198 |
get_install_abis() { |
199 |
local order="" |
200 |
|
201 |
if [ -z "${MULTILIB_ABIS}" ]; then |
202 |
echo "default" |
203 |
return 0 |
204 |
fi |
205 |
|
206 |
if hasq multilib-pkg-force ${RESTRICT} || |
207 |
{ hasq multilib-pkg ${FEATURES} && hasq multilib-pkg ${RESTRICT}; }; then |
208 |
for x in ${MULTILIB_ABIS}; do |
209 |
if [ "${x}" != "${DEFAULT_ABI}" ]; then |
210 |
hasq ${x} ${ABI_DENY} || ordera="${ordera} ${x}" |
211 |
fi |
212 |
done |
213 |
hasq ${DEFAULT_ABI} ${ABI_DENY} || order="${ordera} ${DEFAULT_ABI}" |
214 |
|
215 |
if [ -n "${ABI_ALLOW}" ]; then |
216 |
local ordera="" |
217 |
for x in ${order}; do |
218 |
if hasq ${x} ${ABI_ALLOW}; then |
219 |
ordera="${ordera} ${x}" |
220 |
fi |
221 |
done |
222 |
order="${ordera}" |
223 |
fi |
224 |
else |
225 |
order="${DEFAULT_ABI}" |
226 |
fi |
227 |
|
228 |
if [ -z "${order}" ]; then |
229 |
die "The ABI list is empty. Are you using a proper multilib profile? Perhaps your USE flags or MULTILIB_ABIS are too restrictive for this package." |
230 |
fi |
231 |
|
232 |
echo ${order} |
233 |
return 0 |
234 |
} |
235 |
|
236 |
# Return a list of the ABIs supported by this profile. |
237 |
# the last one in the list being the default. |
238 |
get_all_abis() { |
239 |
local order="" |
240 |
|
241 |
if [ -z "${MULTILIB_ABIS}" ]; then |
242 |
echo "default" |
243 |
return 0 |
244 |
fi |
245 |
|
246 |
for x in ${MULTILIB_ABIS}; do |
247 |
if [ "${x}" != "${DEFAULT_ABI}" ]; then |
248 |
order="${order:+${order }}${x}" |
249 |
fi |
250 |
done |
251 |
order="${order:+${order} }${DEFAULT_ABI}" |
252 |
|
253 |
echo ${order} |
254 |
return 0 |
255 |
} |
256 |
|
257 |
# get_all_libdirs() |
258 |
# Returns a list of all the libdirs used by this profile. This includes |
259 |
# those that might not be touched by the current ebuild. |
260 |
get_all_libdirs() { |
261 |
local libdirs="lib" |
262 |
local abi |
263 |
local dir |
264 |
|
265 |
if has_multilib_profile; then |
266 |
for abi in ${MULTILIB_ABIS}; do |
267 |
[ "$(get_abi_LIBDIR ${abi})" != "lib" ] && libdirs="${libdirs} $(get_abi_LIBDIR ${abi})" |
268 |
done |
269 |
elif [ -n "${CONF_LIBDIR}" ]; then |
270 |
for dir in ${CONF_LIBDIR} ${CONF_MULTILIBDIR:-lib32}; do |
271 |
[ "${dir}" != "lib" ] && libdirs="${libdirs} ${dir}" |
272 |
done |
273 |
fi |
274 |
|
275 |
echo "${libdirs}" |
276 |
} |
277 |
|
278 |
# Return true if ${ABI} is the last ABI on our list (or if we're not |
279 |
# using the new multilib configuration. This can be used to determine |
280 |
# if we're in the last (or only) run through src_{unpack,compile,install} |
281 |
is_final_abi() { |
282 |
has_multilib_profile || return 0 |
283 |
local ALL_ABIS=$(get_install_abis) |
284 |
local LAST_ABI=${ALL_ABIS/* /} |
285 |
[[ ${LAST_ABI} == ${ABI} ]] |
286 |
} |
287 |
|
288 |
# echo the number of ABIs we will be installing for |
289 |
number_abis() { |
290 |
get_install_abis | wc -w |
291 |
} |
292 |
|
293 |
# get_ml_incdir [<include dir> [<ABI>]] |
294 |
# include dir defaults to /usr/include |
295 |
# ABI defaults to ${ABI} or ${DEFAULT_ABI} |
296 |
get_ml_incdir() { |
297 |
local dir=/usr/include |
298 |
|
299 |
if [[ ${#} -gt 0 ]]; then |
300 |
incdir=${1} |
301 |
shift |
302 |
fi |
303 |
|
304 |
if [[ -z "${MULTILIB_ABIS}" ]]; then |
305 |
echo ${incdir} |
306 |
return 0 |
307 |
fi |
308 |
|
309 |
local abi=${ABI-${DEFAULT_ABI}} |
310 |
if [[ ${#} -gt 0 ]]; then |
311 |
abi=${1} |
312 |
shift |
313 |
fi |
314 |
|
315 |
if [[ -d "${dir}/gentoo-multilib/${abi}" ]]; then |
316 |
echo ${dir}/gentoo-multilib/${abi} |
317 |
else |
318 |
echo ${dir} |
319 |
fi |
320 |
} |
321 |
|
322 |
# prep_ml_includes: |
323 |
# |
324 |
# Some includes (include/asm, glibc, etc) are ABI dependent. In this case, |
325 |
# We can install them in different locations for each ABI and create a common |
326 |
# header which includes the right one based on CDEFINE_${ABI}. If your |
327 |
# package installs ABI-specific headers, just add 'prep_ml_includes' to the |
328 |
# end of your src_install(). It takes a list of directories that include |
329 |
# files are installed in (default is /usr/include if none are passed). |
330 |
# |
331 |
# Example: |
332 |
# src_install() { |
333 |
# ... |
334 |
# prep_ml_includes /usr/qt/3/include |
335 |
# } |
336 |
|
337 |
prep_ml_includes() { |
338 |
if [ $(number_abis) -gt 1 ]; then |
339 |
local dir |
340 |
local dirs |
341 |
local base |
342 |
|
343 |
if [ ${#} -eq 0 ]; then |
344 |
dirs="/usr/include" |
345 |
else |
346 |
dirs="${@}" |
347 |
fi |
348 |
|
349 |
for dir in ${dirs}; do |
350 |
base=${T}/gentoo-multilib/${dir}/gentoo-multilib |
351 |
mkdir -p ${base} |
352 |
[ -d ${base}/${ABI} ] && rm -rf ${base}/${ABI} |
353 |
mv ${D}/${dir} ${base}/${ABI} |
354 |
done |
355 |
|
356 |
if is_final_abi; then |
357 |
base=${T}/gentoo-multilib |
358 |
pushd ${base} |
359 |
find . | tar -c -T - -f - | tar -x --no-same-owner -f - -C ${D} |
360 |
popd |
361 |
|
362 |
for dir in ${dirs}; do |
363 |
local args=${dir} |
364 |
local abi |
365 |
for abi in $(get_install_abis); do |
366 |
args="${args} $(get_abi_CDEFINE ${abi}):${dir}/gentoo-multilib/${abi}" |
367 |
done |
368 |
create_ml_includes ${args} |
369 |
done |
370 |
fi |
371 |
fi |
372 |
} |
373 |
|
374 |
# If you need more control than prep_ml_includes can offer (like linux-headers |
375 |
# for the asm-* dirs, then use create_ml_includes. The firs argument is the |
376 |
# common dir. The remaining args are of the form <symbol>:<dir> where |
377 |
# <symbol> is what is put in the #ifdef for choosing that dir. |
378 |
# |
379 |
# Ideas for this code came from debian's sparc-linux headers package. |
380 |
# |
381 |
# Example: |
382 |
# create_ml_includes /usr/include/asm __sparc__:/usr/include/asm-sparc __sparc64__:/usr/include/asm-sparc64 |
383 |
# create_ml_includes /usr/include/asm __i386__:/usr/include/asm-i386 __x86_64__:/usr/include/asm-x86_64 |
384 |
create_ml_includes() { |
385 |
local dest="${1}" |
386 |
shift |
387 |
local mlinfo="${@}" |
388 |
local basedirs=$(create_ml_includes-listdirs ${mlinfo}) |
389 |
|
390 |
create_ml_includes-makedestdirs ${dest} ${basedirs} |
391 |
|
392 |
local file |
393 |
for file in $(create_ml_includes-allfiles ${basedirs}); do |
394 |
local name="$(echo $file | tr a-z A-Z | sed 's:[^A-Z]:_:g')" |
395 |
{ |
396 |
echo "/* Common header file autogenerated by create_ml_includes in multilib.eclass */" |
397 |
|
398 |
local dir |
399 |
for dir in ${basedirs}; do |
400 |
if [ -f "${D}/${dir}/${file}" ]; then |
401 |
local sym=$(create_ml_includes-sym_for_dir ${dir} ${mlinfo}) |
402 |
if [[ ${sym::1} == "!" ]]; then |
403 |
echo "#ifndef ${sym:1}" |
404 |
else |
405 |
echo "#ifdef ${sym}" |
406 |
fi |
407 |
echo "#include <$(create_ml_includes-absolute ${dir}/${file})>" |
408 |
echo "#endif /* ${sym} */" |
409 |
echo "" |
410 |
fi |
411 |
done |
412 |
|
413 |
#echo "#endif /* __CREATE_ML_INCLUDES_STUB_${name}__ */" |
414 |
} > ${D}/${dest}/${file} |
415 |
done |
416 |
} |
417 |
|
418 |
# Helper function for create_ml_includes |
419 |
create_ml_includes-absolute() { |
420 |
local dst="$(create_ml_includes-tidy_path ${1})" |
421 |
|
422 |
dst=(${dst//\// }) |
423 |
|
424 |
local i |
425 |
for ((i=0; i<${#dst[*]}; i++)); do |
426 |
[ "${dst[i]}" == "include" ] && break |
427 |
done |
428 |
|
429 |
local strip_upto=$i |
430 |
|
431 |
for ((i=strip_upto+1; i<${#dst[*]}-1; i++)); do |
432 |
echo -n ${dst[i]}/ |
433 |
done |
434 |
|
435 |
echo -n ${dst[i]} |
436 |
} |
437 |
|
438 |
# Helper function for create_ml_includes |
439 |
create_ml_includes-tidy_path() { |
440 |
local removed="${1}" |
441 |
|
442 |
if [ -n "${removed}" ]; then |
443 |
# Remove multiple slashes |
444 |
while [ "${removed}" != "${removed/\/\//\/}" ]; do |
445 |
removed=${removed/\/\//\/} |
446 |
done |
447 |
|
448 |
# Remove . directories |
449 |
while [ "${removed}" != "${removed//\/.\//\/}" ]; do |
450 |
removed=${removed//\/.\//\/} |
451 |
done |
452 |
[ "${removed##*/}" = "." ] && removed=${removed%/*} |
453 |
|
454 |
# Removed .. directories |
455 |
while [ "${removed}" != "${removed//\/..\/}" ]; do |
456 |
local p1="${removed%%\/..\/*}" |
457 |
local p2="${removed#*\/..\/}" |
458 |
|
459 |
removed="${p1%\/*}/${p2}" |
460 |
done |
461 |
|
462 |
# Remove trailing .. |
463 |
[ "${removed##*/}" = ".." ] && removed=${removed%/*/*} |
464 |
|
465 |
# Remove trailing / |
466 |
[ "${removed##*/}" = "" ] && removed=${removed%/*} |
467 |
|
468 |
echo ${removed} |
469 |
fi |
470 |
} |
471 |
|
472 |
# Helper function for create_ml_includes |
473 |
create_ml_includes-listdirs() { |
474 |
local dirs |
475 |
local data |
476 |
for data in ${@}; do |
477 |
dirs="${dirs} ${data/*:/}" |
478 |
done |
479 |
echo ${dirs:1} |
480 |
} |
481 |
|
482 |
# Helper function for create_ml_includes |
483 |
create_ml_includes-makedestdirs() { |
484 |
local dest=${1} |
485 |
shift |
486 |
local basedirs=${@} |
487 |
|
488 |
dodir ${dest} |
489 |
|
490 |
local basedir |
491 |
for basedir in ${basedirs}; do |
492 |
local dir |
493 |
for dir in $(find ${D}/${basedir} -type d); do |
494 |
dodir ${dest}/${dir/${D}\/${basedir}/} |
495 |
done |
496 |
done |
497 |
} |
498 |
|
499 |
# Helper function for create_ml_includes |
500 |
create_ml_includes-allfiles() { |
501 |
local basedirs=${@} |
502 |
|
503 |
local basedir |
504 |
for basedir in ${basedirs}; do |
505 |
local file |
506 |
for file in $(find ${D}/${basedir} -type f); do |
507 |
echo ${file/${D}\/${basedir}\//} |
508 |
done |
509 |
done | sort | uniq |
510 |
} |
511 |
|
512 |
# Helper function for create_ml_includes |
513 |
create_ml_includes-sym_for_dir() { |
514 |
local dir="${1}" |
515 |
shift |
516 |
local data |
517 |
for data in ${@}; do |
518 |
if [ "${dir}" = "${data/*:/}" ]; then |
519 |
echo ${data/:*/} |
520 |
return 0 |
521 |
fi |
522 |
done |
523 |
echo "Shouldn't be here -- create_ml_includes-sym_for_dir ${1} ${@}" |
524 |
# exit because we'll likely be called from a subshell |
525 |
exit 1 |
526 |
} |