Merge commit 'v2.2.0_alpha55' into 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: 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=$(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 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} == ${DEFAULT_ABI} ]]; then
75 ln -s /usr/bin/abi-wrapper ${binary} || die
76 _debug /usr/bin/abi-wrapper ${binary}
77 fi
78 done
79 }
80
81 tc-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 local order=
118 use multilib_abi_"${DEFAULT_ABI}" && order=${DEFAULT_ABI}
119
120 if is_auto-multilib; then
121 for x in ${MULTILIB_ABIS/${DEFAULT_ABI}} ; do
122 use multilib_abi_"${x}" && order+=" ${x}"
123 done
124 fi
125
126 if [ -z "${order}" ]; then
127 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."
128 fi
129
130 echo ${order}
131 }
132
133 get_abi_list() {
134 if ! is_ebuild; then
135 for my_abi in $(get_abi_order); do
136 [[ -e "${D%/}".${my_abi} ]] || break
137 done
138 fi
139
140 is_ebuild && echo $(get_abi_order) || echo ${my_abi}
141 }
142
143 set_abi() {
144 if [ "$#" != "1" ]; then
145 die "set_abi needs to be given the ABI to use."
146 fi
147
148 local abi=${1}
149
150 # Save ABI if it is already set
151 if [[ -n "${ABI}" ]]; then
152 ABI_SAVE=${ABI}
153 else
154 unset ABI_SAVE
155 fi
156
157 if is_ebuild; then
158 if [ -d "${WORKDIR}" ]; then
159 _unset_abi_dir
160 fi
161
162 if [ -d "${WORKDIR}.${abi}" ]; then
163 # If it doesn't exist, then we're making it soon in dyn_unpack
164 mv ${WORKDIR}.${abi} ${WORKDIR} || die "IO Failure -- Failed to 'mv work.${abi} work'"
165 fi
166 fi
167
168 echo "${abi}" > ${PORTAGE_BUILDDIR}/.abi || die "IO Failure -- Failed to create .abi."
169 [[ $UID == 0 ]] && chown portage:portage ${PORTAGE_BUILDDIR}/.abi
170
171 # Export variables we need for toolchain
172 export ABI="${abi}"
173 echo ">>> ABI=${ABI}"
174 if [[ -f ${PORTAGE_BUILDDIR}/abi-code/environment."${ABI}" ]]; then
175 ABI=${abi} _restore_abi_env "${ABI}"
176 else
177 _save_abi_env "INIT"
178 _restore_abi_env "INIT"
179 _setup_abi_env "${ABI}"
180 _save_abi_env "${ABI}"
181 _restore_abi_env "${ABI}"
182 fi
183 }
184
185 _unset_abi_dir() {
186 if [ -f "${PORTAGE_BUILDDIR}/.abi" ]; then
187 local abi=$(cat ${PORTAGE_BUILDDIR}/.abi)
188 if [[ ${EBUILD_PHASE} != setup ]]; then
189 [ ! -d "${WORKDIR}" ] && die "unset_abi: .abi present (${abi}) but workdir not present."
190 fi
191 if [ -d "${WORKDIR}" ] ; then
192 mv ${WORKDIR} ${WORKDIR}.${abi} || die "IO Failure -- Failed to 'mv work work.${abi}'."
193 fi
194 rm -rf ${PORTAGE_BUILDDIR}/.abi || die "IO Failure -- Failed to 'rm -rf .abi'."
195 fi
196 }
197
198 unset_abi() {
199 is_auto-multilib || return 0;
200
201 if is_ebuild; then
202 _unset_abi_dir
203 fi
204 _save_abi_env "${ABI}"
205 export ABI=${DEFAULT_ABI}
206 if [[ -f ${PORTAGE_BUILDDIR}/abi-code/environment."${ABI}" ]]; then
207 _restore_abi_env "${ABI}"
208 else
209 set_abi "${ABI}"
210 fi
211 }
212
213 _get_abi_string() {
214 if is_auto-multilib && [ -n "${ABI}" ]; then
215 echo " (for ABI=${ABI})"
216 fi
217 }
218
219 _setup_abi_env() {
220 # Set the CHOST native first so that we pick up the native
221 # toolchain and not a cross-compiler by accident #202811.
222 export CHOST=$(get_abi_var CHOST ${DEFAULT_ABI})
223 export AS="$(tc-getPROG AS as)"
224 export CC="$(tc-getPROG CC gcc)"
225 export CXX="$(tc-getPROG CXX g++)"
226 export FC="$(tc-getPROG FC gfortran)"
227 export CHOST=$(get_abi_var CHOST $1)
228 export CBUILD=$(get_abi_var CHOST $1)
229 export CDEFINE="$(get_abi_var CDEFINE $1)"
230 export CCASFLAGS="${CCASFLAGS:-${CFLAGS}} $(get_abi_var CFLAGS)"
231 export CFLAGS="${CFLAGS} $(get_abi_var CFLAGS)"
232 export CPPFLAGS="${CPPFLAGS} $(get_abi_var CPPFLAGS)"
233 export CXXFLAGS="${CXXFLAGS} $(get_abi_var CFLAGS)"
234 export FCFLAGS="${FCFLAGS} $(get_abi_var CFLAGS)"
235 export FFLAGS="${FFLAGS} $(get_abi_var CFLAGS)"
236 export ASFLAGS="${ASFLAGS} $(get_abi_var ASFLAGS)"
237 export LDFLAGS="${LDFLAGS} $(get_abi_var CFLAGS)"
238 local LIBDIR=$(get_abi_var LIBDIR $1)
239 export PKG_CONFIG_PATH="/usr/${LIBDIR}/pkgconfig"
240 if [[ "${ABI}" != "${DEFAULT_ABI}" ]]; then
241 [[ -z ${CCACHE_DIR} ]] || export CCACHE_DIR=${CCACHE_DIR}/${ABI}
242 fi
243 }
244
245 # Remove symlinks for alternate ABIs so that packages that use
246 # symlink without using the force option to ln ("-f").
247 #
248 # Also, create multilib header redirects if any of the headers
249 # differ between ABIs.
250 #
251 # ABI_HEADER_DIRS defaults to /usr/include but the ebuild can override
252 #
253 _finalize_abi_install() {
254 local ALL_ABIS=$(get_abi_order)
255 local ALTERNATE_ABIS=${ALL_ABIS#* }
256 local dirs=${ABI_HEADER_DIRS-/usr/include}
257 local base=
258
259 # Save header files for each ABI
260 for dir in ${dirs}; do
261 [ -d "${D}/${dir}" ] || continue
262 vecho ">>> Saving headers $(_get_abi_string)"
263 base=${PORTAGE_BUILDDIR}/abi-code/gentoo-multilib/${dir}/gentoo-multilib
264 mkdir -p ${base}
265 [ -d ${base}/${ABI} ] && rm -rvf ${base}/${ABI}
266 mv ${D}/${dir} ${base}/${ABI} || die "ABI header save failed"
267 done
268
269 # Symlinks are not overwritten without the "-f" option, so
270 # remove them in non-default ABI
271 if [ "${ABI}" != "${DEFAULT_ABI}" ]; then
272 vecho ">>> Removing installed symlinks $(_get_abi_string)"
273 for i in $(find ${D} -type l) ; do
274 [[ -e "${D%/}".${DEFAULT_ABI}/${i/${D}} ]] && rm -f ${i}
275 done
276 fi
277
278 # Create wrapper symlink for *-config files
279 local i=
280 prep_ml_binaries $(find "${D}"usr/bin -type f -name '*-config' 2>/dev/null)
281
282 local noabi=()
283 for i in ${MULTILIB_ABIS}; do
284 noabi+=( ! -name '*-'${i} )
285 done
286 if [[ ${MULTILIB_BINARIES} == *${CATEGORY}/${PN}* ]]; then
287 for i in $(find "${D}"usr/bin/ -type f ${noabi[@]}) $(find "${D}"bin/ -type f ${noabi[@]}); do
288 prep_ml_binaries "${i}"
289 done
290 fi
291 local LIBDIR=$(get_abi_var LIBDIR $1)
292 if ( [[ -d "${D}${LIBDIR}" ]] || [[ -d "${D}usr/${LIBDIR}" ]] || [[ -d "${base}" ]] || \
293 (shopt -s nullglob dotglob; f=("${D}"usr/bin/*-config); ((${#f[@]}))) || \
294 ( [[ ${MULTILIB_BINARIES} == *${CATEGORY}/${PN}* ]] && [[ -d "${D}"usr/bin ]] ) ); then
295
296 mv "${D}" "${D%/}".${ABI} || die
297 for my_abi in ${ALL_ABIS}; do
298 [[ -e "${D%/}".${my_abi} ]] || return 0
299 done
300 else
301 if is_ebuild; then
302 mv "${D}" "${D%/}".${ABI} || die
303 for my_abi in ${ALL_ABIS}; do
304 [[ -e "${D%/}".${my_abi} ]] || return 0
305 done
306 fi
307 fi
308
309 mkdir -p "${D}"
310 # After final ABI is installed, if headers differ
311 # then create multilib header redirects
312 local diffabi= abis_differ=
313 for dir in ${dirs}; do
314 base=${PORTAGE_BUILDDIR}/abi-code/gentoo-multilib/${dir}/gentoo-multilib
315 [ -d "${base}" ] || continue
316 for diffabi in ${ALTERNATE_ABIS}; do
317 diff -rNq ${base}/${DEFAULT_ABI} ${base}/${diffabi} >/dev/null || abis_differ=1
318 done
319 done
320
321 #FIXME: workaround:no multiabi-headers for linux-headers
322 if [ -z "${abis_differ}" ] || [[ ${PN} == linux-headers ]]; then
323 # No differences, restore original header files for default ABI
324 for dir in ${dirs}; do
325 base=${PORTAGE_BUILDDIR}/abi-code/gentoo-multilib/${dir}/gentoo-multilib
326 [ -d "${base}" ] || continue
327 [[ -d "${D}"/${dir} ]] || mkdir -p "${D}"/${dir}
328 if ! rmdir "${base}"/${DEFAULT_ABI} 2>/dev/null; then
329 mv "${base}"/${DEFAULT_ABI}/* "${D}"/${dir} || die "ABI header restore failed"
330 fi
331 done
332 else # ABIS differ
333 vecho ">>> Creating multilib headers"
334 base=${PORTAGE_BUILDDIR}/abi-code/gentoo-multilib
335 local files_differ=
336 for dir in ${dirs}; do
337 if use multilib_abi_"${DEFAULT_ABI}" ; then
338 cd "${base}${dir}/gentoo-multilib/${DEFAULT_ABI}" || die
339 for i in $(find . -type l ; find . -type f); do
340 for diffabi in ${ALTERNATE_ABIS}; do
341 diff -q "${i}" ../${diffabi}/"${i}" >/dev/null || files_differ=1
342 done
343 if [ -z "${files_differ}" ]; then
344 [ -d "${D}${dir}/${i%/*}" ] || mkdir -p "${D}${dir}/${i%/*}"
345 mv ${base}${dir}/gentoo-multilib/${DEFAULT_ABI}/"${i}" "${D}${dir}/${i}" || die "$DEFAULT_ABI failed"
346 rm -rf ${base}${dir}/gentoo-multilib/*/"${i}"
347 fi
348 files_differ=
349 done
350 fi
351 done
352 pushd "${base}" >/dev/null
353 find . | tar -c -T - -f - | tar -x -f - -C ${D}
354 popd >/dev/null
355
356 # This 'set' stuff is required by mips profiles to properly pass
357 # CDEFINE's (which have spaces) to sub-functions
358 set --
359 for dir in ${dirs} ; do
360 set -- "$@" "${dir}"
361 for diffabi in ${ALL_ABIS}; do
362 local define_var=CDEFINE_${diffabi}
363 set -- "$@" "${!define_var}:${dir}/gentoo-multilib/${diffabi}"
364 done
365 _create_abi_includes "$@"
366 done
367 fi
368
369 for my_abi in ${ALTERNATE_ABIS}; do
370 [[ -d "${D%/}.${my_abi}" ]] || continue
371 cd "${D%/}.${my_abi}"
372 find . | tar -c -T - -f - | tar -x -f - -C "${D}"
373 cd ..
374 rm -rf "${D%/}.${my_abi}"
375 done
376 if [[ -d "${D%/}.${DEFAULT_ABI}" ]]; then
377 cd "${D%/}.${DEFAULT_ABI}"
378 find . | tar -c -T - -f - | tar -x -f - -C "${D}"
379 cd ..
380 rm -rf "${D%/}.${DEFAULT_ABI}"
381 fi
382 }
383
384 #
385 # These _create_abi_includes* routines were ripped pretty wholesale from multilib.eclass
386 #
387
388 # The first argument is the common dir. The remaining args are of the
389 # form <symbol>:<dir> where <symbol> is what is put in the #ifdef for
390 # choosing that dir.
391 #
392 # Ideas for this code came from debian's sparc-linux headers package.
393 #
394 # Example:
395 # _create_abi_includes /usr/include/asm __sparc__:/usr/include/asm-sparc __sparc64__:/usr/include/asm-sparc64
396 # _create_abi_includes /usr/include/asm __i386__:/usr/include/asm-i386 __x86_64__:/usr/include/asm-x86_64
397 #
398 # Warning: Be careful with the ordering here. The default ABI has to be the
399 # last, because it is always defined (by GCC)
400 _create_abi_includes() {
401 local dest=$1
402 shift
403 local basedirs=$(_create_abi_includes-listdirs "$@")
404
405 _create_abi_includes-makedestdirs ${dest} ${basedirs}
406
407 local file
408 for file in $(_create_abi_includes-allfiles ${basedirs}) ; do
409 #local name=$(echo ${file} | tr '[:lower:]' '[:upper:]' | sed 's:[^[:upper:]]:_:g')
410 (
411 echo "/* Autogenerated by portage FEATURE auto-multilib */"
412
413 local dir
414 for dir in ${basedirs}; do
415 if [[ -f ${D}/${dir}/${file} ]] ; then
416 echo ""
417 local sym=$(_create_abi_includes-sym_for_dir ${dir} "$@")
418 if [[ ${sym/=} != "${sym}" ]] ; then
419 echo "#if ${sym}"
420 elif [[ ${sym::1} == "!" ]] ; then
421 echo "#ifndef ${sym:1}"
422 else
423 echo "#ifdef ${sym}"
424 fi
425 echo "# include <$(_create_abi_includes-absolute ${dir}/${file})>"
426 echo "#endif /* ${sym} */"
427 fi
428 done
429
430 #echo "#endif /* __CREATE_ABI_INCLUDES_STUB_${name}__ */"
431 ) > "${D}/${dest}/${file}"
432 done
433 }
434
435 # Helper function for _create_abi_includes
436 _create_abi_includes-absolute() {
437 local dst="$(_create_abi_includes-tidy_path $1)"
438
439 dst=(${dst//\// })
440
441 local i
442 for ((i=0; i<${#dst[*]}; i++)); do
443 [ "${dst[i]}" == "include" ] && break
444 done
445
446 local strip_upto=$i
447
448 for ((i=strip_upto+1; i<${#dst[*]}-1; i++)); do
449 echo -n ${dst[i]}/
450 done
451
452 echo -n ${dst[i]}
453 }
454
455 # Helper function for _create_abi_includes
456 _create_abi_includes-tidy_path() {
457 local removed=$1
458
459 if [ -n "${removed}" ]; then
460 # Remove multiple slashes
461 while [ "${removed}" != "${removed/\/\//\/}" ]; do
462 removed=${removed/\/\//\/}
463 done
464
465 # Remove . directories
466 while [ "${removed}" != "${removed//\/.\//\/}" ]; do
467 removed=${removed//\/.\//\/}
468 done
469 [ "${removed##*/}" = "." ] && removed=${removed%/*}
470
471 # Removed .. directories
472 while [ "${removed}" != "${removed//\/..\/}" ]; do
473 local p1="${removed%%\/..\/*}"
474 local p2="${removed#*\/..\/}"
475
476 removed="${p1%\/*}/${p2}"
477 done
478
479 # Remove trailing ..
480 [ "${removed##*/}" = ".." ] && removed=${removed%/*/*}
481
482 # Remove trailing /
483 [ "${removed##*/}" = "" ] && removed=${removed%/*}
484
485 echo ${removed}
486 fi
487 }
488
489 # Helper function for create_abi_includes
490 _create_abi_includes-listdirs() {
491 local dirs
492 local data
493 for data in "$@"; do
494 dirs="${dirs} ${data/*:/}"
495 done
496 echo ${dirs:1}
497 }
498
499 # Helper function for _create_abi_includes
500 _create_abi_includes-makedestdirs() {
501 local dest=$1
502 shift
503 local basedirs=$@
504
505 dodir ${dest}
506
507 local basedir
508 for basedir in ${basedirs}; do
509 local dir
510 for dir in $(find ${D}/${basedir} -type d); do
511 dodir ${dest}/${dir/${D}\/${basedir}/}
512 done
513 done
514 }
515
516 # Helper function for _create_abi_includes
517 _create_abi_includes-allfiles() {
518 local basedir file
519 for basedir in "$@" ; do
520 for file in $(find "${D}"/${basedir} -type f); do
521 echo ${file/${D}\/${basedir}\//}
522 done
523 done | sort | uniq
524 }
525
526 # Helper function for _create_abi_includes
527 _create_abi_includes-sym_for_dir() {
528 local dir=$1
529 shift
530 local data
531 for data in "$@"; do
532 if [[ ${data} == *:${dir} ]] ; then
533 echo ${data/:*/}
534 return 0
535 fi
536 done
537 echo "Shouldn't be here -- _create_abi_includes-sym_for_dir $1 $@"
538 # exit because we'll likely be called from a subshell
539 exit 1
540 }