Only source auto-multilib.sh, when FEATURES=force-multilib
[proj/portage.git] / bin / auto-multilib.sh
1 # Copyright 1999-2006 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # $Header$
4
5
6 # @FUNCTION: _debug
7 # @USAGE: <name_of_variable> <content_of_variable>
8 # @DESCRIPTION: print debug output if MULTILIB_DEBUG is set
9 _debug() {
10 [[ -n ${MULTILIB_DEBUG} ]] && einfo "MULTILIB_DEBUG: ${1}=\"${2}\""
11 }
12
13 # Internal function
14 # @FUNCTION: _save_abi_env
15 # @USAGE: <ABI>
16 # @DESCRIPTION: Save environment for ABI
17 _save_abi_env() {
18 [[ -n ${MULTILIB_DEBUG} ]] && \
19 einfo "MULTILIB_DEBUG: Saving Environment:" "${1}"
20 mkdir -p ${PORTAGE_BUILDDIR}/abi-code
21 __save_ebuild_env --exclude-init-phases | __filter_readonly_variables \
22 --filter-path --filter-sandbox --allow-extra-vars --filter-metadata > ${PORTAGE_BUILDDIR}/abi-code/environment."${1}"
23 [[ $UID == 0 ]] && chown portage:portage ${PORTAGE_BUILDDIR}/abi-code/environment."${1}"
24 }
25
26 # Internal function
27 # @FUNCTION: _restore_abi_env
28 # @USAGE: <ABI>
29 # @DESCRIPTION: Restore environment for ABI
30 _restore_abi_env() {
31 [[ -n ${MULTILIB_DEBUG} ]] && \
32 einfo "MULTILIB_DEBUG: Restoring Environment:" "${1}"
33 cp ${PORTAGE_BUILDDIR}/abi-code/environment."${1}" "${T}"/environment || die
34 __preprocess_ebuild_env --filter-metadata
35 }
36
37 # @FUNCTION: portage-get_abi_var
38 # @USAGE: <VAR> [ABI]
39 # @RETURN: returns the value of ${<VAR>_<ABI>} which should be set in make.defaults
40 # @DESCRIPTION:
41 # ex:
42 # CFLAGS=$(portage-get_abi_var CFLAGS sparc32) # CFLAGS=-m32
43 #
44 # Note that the prefered method is to set CC="$(tc-getCC) $(get_abi_CFLAGS)"
45 # This will hopefully be added to portage soon...
46 #
47 # If <ABI> is not specified, ${ABI} is used.
48 # If <ABI> is not specified and ${ABI} is not defined, ${DEFAULT_ABI} is used.
49 # If <ABI> is not specified and ${ABI} and ${DEFAULT_ABI} are not defined, we return an empty string.
50 portage-get_abi_var() {
51 local flag=$1
52 local abi
53 if [ $# -gt 1 ]; then
54 abi=${2}
55 elif [ -n "${ABI}" ]; then
56 abi=${ABI}
57 elif [ -n "${DEFAULT_ABI}" ]; then
58 abi=${DEFAULT_ABI}
59 else
60 abi="default"
61 fi
62
63 local var="${flag}_${abi}"
64 echo ${!var}
65 }
66
67 # @FUNCTION prep_ml_binaries
68 # @USAGE:
69 # @DESCRIPTION: Use wrapper to support non-default binaries
70 prep_ml_binaries() {
71 for binary in "$@"; do
72 mv ${binary} ${binary}-${ABI} || die
73 _debug ${binary} ${binary}-${ABI}
74 if [[ ${ABI} == ${first_installed_abi} ]]; then
75 ln -s /bin/abi-wrapper ${binary} || die
76 _debug /bin/abi-wrapper ${binary}
77 fi
78 done
79 }
80
81 portage-getPROG() {
82 local var=$1
83 local prog=$2
84
85 if [[ -n ${!var} ]] ; then
86 echo "${!var}"
87 return 0
88 fi
89
90 local search=
91 [[ -n $3 ]] && search=$(type -p "$3-${prog}")
92 [[ -z ${search} && -n ${CHOST} ]] && search=$(type -p "${CHOST}-${prog}")
93 [[ -n ${search} ]] && prog=${search##*/}
94
95 export ${var}=${prog}
96 echo "${!var}"
97 }
98
99 has_multilib_profile() {
100 [[ -n "${MULTILIB_ABIS}" && "${MULTILIB_ABIS}" != "${MULTILIB_ABIS/ /}" ]]
101 }
102
103 is_auto-multilib() {
104 if has_multilib_profile && ! has multilib-native ${INHERITED} && ! use multilib; then
105 for i in ${MULTILIB_ABIS} ; do
106 use multilib_abi_"${i}" && [[ "${i}" != "${DEFAULT_ABI}" ]] && return 0
107 done
108 fi
109 return 1
110 }
111
112 is_ebuild() {
113 [[ ${PORTAGE_CALLER} == ebuild ]] && return 0 || return 1
114 }
115
116 get_abi_order() {
117 if [[ " ${FEATURES} " == *" force-multilib "* ]]; then
118 local order=
119 use multilib_abi_"${DEFAULT_ABI}" && order=${DEFAULT_ABI}
120
121 if is_auto-multilib; then
122 for x in ${MULTILIB_ABIS/${DEFAULT_ABI}} ; do
123 use multilib_abi_"${x}" && order+=" ${x}"
124 done
125 fi
126
127 if [ -z "${order}" ]; then
128 if ! [ -z "${DEFAULT_ABI}" ]; then
129 order=${DEFAULT_ABI}
130 else
131 die "Could not determine your profile ABI(s). Perhaps your USE flags or MULTILIB_ABIS are too restrictive for this package or your profile does not set DEFAULT_ABI."
132 fi
133 fi
134
135 echo ${order}
136 else
137 echo "default"
138 fi
139 }
140
141 get_abi_list() {
142 if [[ " ${FEATURES} " == *" force-multilib "* ]]; then
143 if ! is_ebuild; then
144 for my_abi in $(get_abi_order); do
145 [[ -e "${D%/}".${my_abi} ]] || break
146 done
147 fi
148
149 is_ebuild && echo $(get_abi_order) || echo ${my_abi}
150 else
151 echo "default"
152 fi
153 }
154
155 set_abi() {
156 if [ "$#" != "1" ]; then
157 die "set_abi needs to be given the ABI to use."
158 fi
159
160 local abi=${1}
161
162 # Save ABI if it is already set
163 if [[ -n "${ABI}" ]]; then
164 ABI_SAVE=${ABI}
165 else
166 unset ABI_SAVE
167 fi
168
169 if is_ebuild; then
170 if [ -d "${WORKDIR}" ]; then
171 _unset_abi_dir
172 fi
173
174 if [ -d "${WORKDIR}.${abi}" ]; then
175 # If it doesn't exist, then we're making it soon in dyn_unpack
176 mv ${WORKDIR}.${abi} ${WORKDIR} || die "IO Failure -- Failed to 'mv work.${abi} work'"
177 fi
178 fi
179
180 echo "${abi}" > ${PORTAGE_BUILDDIR}/.abi || die "IO Failure -- Failed to create .abi."
181 [[ $UID == 0 ]] && chown portage:portage ${PORTAGE_BUILDDIR}/.abi
182
183 # Export variables we need for toolchain
184 export ABI="${abi}"
185 echo ">>> ABI=${ABI}"
186 if [[ -f ${PORTAGE_BUILDDIR}/abi-code/environment."${ABI}" ]]; then
187 ABI=${abi} _restore_abi_env "${ABI}"
188 else
189 _save_abi_env "INIT"
190 _restore_abi_env "INIT"
191 _setup_abi_env "${ABI}"
192 _save_abi_env "${ABI}"
193 _restore_abi_env "${ABI}"
194 fi
195 }
196
197 _unset_abi_dir() {
198 if [ -f "${PORTAGE_BUILDDIR}/.abi" ]; then
199 local abi=$(cat ${PORTAGE_BUILDDIR}/.abi)
200 if [[ ${EBUILD_PHASE} != setup ]]; then
201 [ ! -d "${WORKDIR}" ] && die "unset_abi: .abi present (${abi}) but workdir not present."
202 fi
203 if [ -d "${WORKDIR}" ] ; then
204 mv ${WORKDIR} ${WORKDIR}.${abi} || die "IO Failure -- Failed to 'mv work work.${abi}'."
205 fi
206 rm -rf ${PORTAGE_BUILDDIR}/.abi || die "IO Failure -- Failed to 'rm -rf .abi'."
207 fi
208 }
209
210 unset_abi() {
211 is_auto-multilib || return 0;
212
213 if is_ebuild; then
214 _unset_abi_dir
215 fi
216 _save_abi_env "${ABI}"
217 export ABI=${DEFAULT_ABI}
218 if [[ -f ${PORTAGE_BUILDDIR}/abi-code/environment."${ABI}" ]]; then
219 _restore_abi_env "${ABI}"
220 else
221 set_abi "${ABI}"
222 fi
223 }
224
225 _get_abi_string() {
226 [[ " ${FEATURES} " == *" force-multilib "* ]] && \
227 is_auto-multilib && [ -n "${ABI}" ] && \
228 echo " (for ABI=${ABI})"
229 }
230
231 _setup_abi_env() {
232 if is_auto-multilib ; then
233 # Set the CHOST native first so that we pick up the native
234 # toolchain and not a cross-compiler by accident #202811.
235 export CHOST=$(portage-get_abi_var CHOST ${DEFAULT_ABI})
236 export AS="$(portage-getPROG AS as)"
237 export CC="$(portage-getPROG CC gcc)"
238 export CXX="$(portage-getPROG CXX g++)"
239 export FC="$(portage-getPROG FC gfortran)"
240 export CHOST=$(portage-get_abi_var CHOST $1)
241 export CBUILD=$(portage-get_abi_var CHOST $1)
242 export CDEFINE="$(portage-get_abi_var CDEFINE $1)"
243 export CCASFLAGS="${CCASFLAGS:-${CFLAGS}} $(portage-get_abi_var CFLAGS)"
244 export CFLAGS="${CFLAGS} $(portage-get_abi_var CFLAGS)"
245 export CPPFLAGS="${CPPFLAGS} $(portage-get_abi_var CPPFLAGS)"
246 export CXXFLAGS="${CXXFLAGS} $(portage-get_abi_var CFLAGS)"
247 export FCFLAGS="${FCFLAGS} $(portage-get_abi_var CFLAGS)"
248 export FFLAGS="${FFLAGS} $(portage-get_abi_var CFLAGS)"
249 export ASFLAGS="${ASFLAGS} $(portage-get_abi_var ASFLAGS)"
250 export LDFLAGS="${LDFLAGS} $(portage-get_abi_var CFLAGS)"
251 local LIBDIR=$(portage-get_abi_var LIBDIR $1)
252 export PKG_CONFIG_PATH="/usr/${LIBDIR}/pkgconfig"
253 if [[ "${ABI}" != "${DEFAULT_ABI}" ]]; then
254 [[ -z ${CCACHE_DIR} ]] || export CCACHE_DIR=${CCACHE_DIR}/${ABI}
255 fi
256 fi
257 }
258
259 # Remove symlinks for alternate ABIs so that packages that use
260 # symlink without using the force option to ln ("-f").
261 #
262 # Also, create multilib header redirects if any of the headers
263 # differ between ABIs.
264 #
265 # ABI_HEADER_DIRS defaults to /usr/include but the ebuild can override
266 #
267 _finalize_abi_install() {
268 local ALL_ABIS=$(get_abi_order)
269 local ALTERNATE_ABIS=${ALL_ABIS#* }
270 local dirs=${ABI_HEADER_DIRS-/usr/include}
271 local base=
272 local first_installed_abi=
273 local i
274
275 # Save header files for each ABI
276 for dir in ${dirs}; do
277 [ -d "${D}/${dir}" ] || continue
278 __vecho ">>> Saving headers $(_get_abi_string)"
279 base=${PORTAGE_BUILDDIR}/abi-code/gentoo-multilib/${dir}/gentoo-multilib
280 mkdir -p ${base}
281 [ -d ${base}/${ABI} ] && rm -rvf ${base}/${ABI}
282 mv ${D}/${dir} ${base}/${ABI} || die "ABI header save failed"
283 done
284
285 # Symlinks are not overwritten without the "-f" option, so
286 # remove them in second and following enabled ABIs
287 for i in ${ALL_ABIS} ; do
288 use multilib_abi_${i} && first_installed_abi=${i} && break
289 done
290 if [ "${ABI}" != "${first_installed_abi}" ]; then
291 __vecho ">>> Removing installed symlinks $(_get_abi_string)"
292 for i in $(find ${D} -type l) ; do
293 [[ -e "${D%/}".${first_installed_abi}/${i/${D}} ]] && rm -f ${i}
294 done
295 fi
296
297 # Create wrapper symlink for *-config files
298 local i=
299 prep_ml_binaries $(find "${D}"usr/bin "${D}"usr/sbin "${D}"bin "${D}"sbin -type f -name '*-config' 2>/dev/null)
300
301 local noabi=()
302 for i in ${MULTILIB_ABIS}; do
303 noabi+=( ! -name '*-'${i} )
304 done
305 if use abiwrapper ; then
306 for i in $(find "${D}"usr/bin/ "${D}"usr/sbin "${D}"bin "${D}"sbin -type f ${noabi[@]} 2>/dev/null); do
307 prep_ml_binaries "${i}"
308 done
309 fi
310 local LIBDIR=$(portage-get_abi_var LIBDIR $1)
311 if ( [[ -d "${D}${LIBDIR}" ]] || [[ -d "${D}usr/${LIBDIR}" ]] || [[ -d "${base}" ]] || \
312 (shopt -s nullglob dotglob; f=("${D}"usr/bin/*-config); ((${#f[@]}))) || \
313 ( use abiwrapper && \
314 ( [[ -d "${D}"usr/bin ]] || \
315 [[ -d "${D}"usr/sbin ]] || [[ -d "${D}"bin ]] || [[ -d "${D}"sbin ]])) ); then
316
317 mv "${D}" "${D%/}".${ABI} || die
318 for my_abi in ${ALL_ABIS}; do
319 [[ -e "${D%/}".${my_abi} ]] || return 0
320 done
321 else
322 if is_ebuild; then
323 mv "${D}" "${D%/}".${ABI} || die
324 for my_abi in ${ALL_ABIS}; do
325 [[ -e "${D%/}".${my_abi} ]] || return 0
326 done
327 fi
328 fi
329
330 mkdir -p "${D}"
331 # After final ABI is installed, if headers differ
332 # then create multilib header redirects
333 local diffabi= abis_differ=
334 for dir in ${dirs}; do
335 base=${PORTAGE_BUILDDIR}/abi-code/gentoo-multilib/${dir}/gentoo-multilib
336 [ -d "${base}" ] || continue
337 for diffabi in ${ALTERNATE_ABIS}; do
338 diff -rNq ${base}/${DEFAULT_ABI} ${base}/${diffabi} >/dev/null || abis_differ=1
339 done
340 done
341
342 #FIXME: workaround:no multiabi-headers for linux-headers
343 if [ -z "${abis_differ}" ] || [[ ${PN} == linux-headers ]]; then
344 # No differences, restore original header files for default ABI
345 for dir in ${dirs}; do
346 base=${PORTAGE_BUILDDIR}/abi-code/gentoo-multilib/${dir}/gentoo-multilib
347 [ -d "${base}" ] || continue
348 [[ -d "${D}"/${dir} ]] || mkdir -p "${D}"/${dir}
349 if ! rmdir "${base}"/${DEFAULT_ABI} 2>/dev/null; then
350 mv "${base}"/${DEFAULT_ABI}/* "${D}"/${dir} || die "ABI header restore failed"
351 fi
352 done
353 else # ABIS differ
354 __vecho ">>> Creating multilib headers"
355 base=${PORTAGE_BUILDDIR}/abi-code/gentoo-multilib
356 local files_differ=
357 for dir in ${dirs}; do
358 if use multilib_abi_"${DEFAULT_ABI}" ; then
359 cd "${base}${dir}/gentoo-multilib/${DEFAULT_ABI}" || die
360 for i in $(find . -type l ; find . -type f); do
361 # Ignore symbolic links, they can't be
362 # ABI-ized and diff is confused when the
363 # link's target is removed (by this
364 # loop).
365 if ! [[ -L ${i} ]]; then
366 for diffabi in ${ALTERNATE_ABIS}; do
367 diff -q "${i}" ../${diffabi}/"${i}" >/dev/null || files_differ=1
368 done
369 fi
370
371 if [ -z "${files_differ}" ]; then
372 [ -d "${D}${dir}/${i%/*}" ] || mkdir -p "${D}${dir}/${i%/*}"
373 mv ${base}${dir}/gentoo-multilib/${DEFAULT_ABI}/"${i}" "${D}${dir}/${i}" || die "$DEFAULT_ABI failed"
374 rm -rf ${base}${dir}/gentoo-multilib/*/"${i}"
375 fi
376 files_differ=
377 done
378 fi
379 done
380 pushd "${base}" >/dev/null
381 find . | tar -c -T - -f - | tar -x -f - -C ${D}
382 popd >/dev/null
383
384 # This 'set' stuff is required by mips profiles to properly pass
385 # CDEFINE's (which have spaces) to sub-functions
386 set --
387 for dir in ${dirs} ; do
388 set -- "$@" "${dir}"
389 for diffabi in ${ALL_ABIS}; do
390 local define_var=CDEFINE_${diffabi}
391 set -- "$@" "${!define_var}:${dir}/gentoo-multilib/${diffabi}"
392 done
393 _create_abi_includes "$@"
394 done
395 fi
396
397 for my_abi in ${ALTERNATE_ABIS}; do
398 [[ -d "${D%/}.${my_abi}" ]] || continue
399 cd "${D%/}.${my_abi}"
400 find . | tar -c -T - -f - | tar -x -f - -C "${D}"
401 cd ..
402 rm -rf "${D%/}.${my_abi}"
403 done
404 if [[ -d "${D%/}.${DEFAULT_ABI}" ]]; then
405 cd "${D%/}.${DEFAULT_ABI}"
406 find . | tar -c -T - -f - | tar -x -f - -C "${D}"
407 cd ..
408 rm -rf "${D%/}.${DEFAULT_ABI}"
409 fi
410 }
411
412 #
413 # These _create_abi_includes* routines were ripped pretty wholesale from multilib.eclass
414 #
415
416 # The first argument is the common dir. The remaining args are of the
417 # form <symbol>:<dir> where <symbol> is what is put in the #ifdef for
418 # choosing that dir.
419 #
420 # Ideas for this code came from debian's sparc-linux headers package.
421 #
422 # Example:
423 # _create_abi_includes /usr/include/asm __sparc__:/usr/include/asm-sparc __sparc64__:/usr/include/asm-sparc64
424 # _create_abi_includes /usr/include/asm __i386__:/usr/include/asm-i386 __x86_64__:/usr/include/asm-x86_64
425 #
426 # Warning: Be careful with the ordering here. The default ABI has to be the
427 # last, because it is always defined (by GCC)
428 _create_abi_includes() {
429 local dest=$1
430 shift
431 local basedirs=$(_create_abi_includes-listdirs "$@")
432
433 _create_abi_includes-makedestdirs ${dest} ${basedirs}
434
435 local file
436 for file in $(_create_abi_includes-allfiles ${basedirs}) ; do
437 #local name=$(echo ${file} | tr '[:lower:]' '[:upper:]' | sed 's:[^[:upper:]]:_:g')
438 (
439 echo "/* Autogenerated by portage FEATURE auto-multilib */"
440
441 local dir
442 for dir in ${basedirs}; do
443 if [[ -f ${D}/${dir}/${file} ]] ; then
444 echo ""
445 local sym=$(_create_abi_includes-sym_for_dir ${dir} "$@")
446 if [[ ${sym/=} != "${sym}" ]] ; then
447 echo "#if ${sym}"
448 elif [[ ${sym::1} == "!" ]] ; then
449 echo "#ifndef ${sym:1}"
450 else
451 echo "#ifdef ${sym}"
452 fi
453 echo "# include <$(_create_abi_includes-absolute ${dir}/${file})>"
454 echo "#endif /* ${sym} */"
455 fi
456 done
457
458 #echo "#endif /* __CREATE_ABI_INCLUDES_STUB_${name}__ */"
459 ) > "${D}/${dest}/${file}"
460 done
461 }
462
463 # Helper function for _create_abi_includes
464 _create_abi_includes-absolute() {
465 local dst="$(_create_abi_includes-tidy_path $1)"
466
467 dst=(${dst//\// })
468
469 local i
470 for ((i=0; i<${#dst[*]}; i++)); do
471 [ "${dst[i]}" == "include" ] && break
472 done
473
474 local strip_upto=$i
475
476 for ((i=strip_upto+1; i<${#dst[*]}-1; i++)); do
477 echo -n ${dst[i]}/
478 done
479
480 echo -n ${dst[i]}
481 }
482
483 # Helper function for _create_abi_includes
484 _create_abi_includes-tidy_path() {
485 local removed=$1
486
487 if [ -n "${removed}" ]; then
488 # Remove multiple slashes
489 while [ "${removed}" != "${removed/\/\//\/}" ]; do
490 removed=${removed/\/\//\/}
491 done
492
493 # Remove . directories
494 while [ "${removed}" != "${removed//\/.\//\/}" ]; do
495 removed=${removed//\/.\//\/}
496 done
497 [ "${removed##*/}" = "." ] && removed=${removed%/*}
498
499 # Removed .. directories
500 while [ "${removed}" != "${removed//\/..\/}" ]; do
501 local p1="${removed%%\/..\/*}"
502 local p2="${removed#*\/..\/}"
503
504 removed="${p1%\/*}/${p2}"
505 done
506
507 # Remove trailing ..
508 [ "${removed##*/}" = ".." ] && removed=${removed%/*/*}
509
510 # Remove trailing /
511 [ "${removed##*/}" = "" ] && removed=${removed%/*}
512
513 echo ${removed}
514 fi
515 }
516
517 # Helper function for create_abi_includes
518 _create_abi_includes-listdirs() {
519 local dirs
520 local data
521 for data in "$@"; do
522 dirs="${dirs} ${data/*:/}"
523 done
524 echo ${dirs:1}
525 }
526
527 # Helper function for _create_abi_includes
528 _create_abi_includes-makedestdirs() {
529 local dest=$1
530 shift
531 local basedirs=$@
532
533 dodir ${dest}
534
535 local basedir
536 for basedir in ${basedirs}; do
537 local dir
538 for dir in $(find ${D}/${basedir} -type d); do
539 dodir ${dest}/${dir/${D}\/${basedir}/}
540 done
541 done
542 }
543
544 # Helper function for _create_abi_includes
545 _create_abi_includes-allfiles() {
546 local basedir file
547 for basedir in "$@" ; do
548 for file in $(find "${D}"/${basedir} -type f); do
549 echo ${file/${D}\/${basedir}\//}
550 done
551 done | sort | uniq
552 }
553
554 # Helper function for _create_abi_includes
555 _create_abi_includes-sym_for_dir() {
556 local dir=$1
557 shift
558 local data
559 for data in "$@"; do
560 if [[ ${data} == *:${dir} ]] ; then
561 echo ${data/:*/}
562 return 0
563 fi
564 done
565 echo "Shouldn't be here -- _create_abi_includes-sym_for_dir $1 $@"
566 # exit because we'll likely be called from a subshell
567 exit 1
568 }