1 |
# Copyright 1999-2014 Gentoo Foundation |
2 |
# Distributed under the terms of the GNU General Public License v2 |
3 |
# $Header: /var/cvsroot/gentoo-x86/eclass/multilib-build.eclass,v 1.34 2014/04/03 22:09:36 mgorny Exp $ |
4 |
|
5 |
# @ECLASS: multilib-build.eclass |
6 |
# @MAINTAINER: |
7 |
# gx86-multilib team <multilib@gentoo.org> |
8 |
# @AUTHOR: |
9 |
# Author: Michał Górny <mgorny@gentoo.org> |
10 |
# @BLURB: flags and utility functions for building multilib packages |
11 |
# @DESCRIPTION: |
12 |
# The multilib-build.eclass exports USE flags and utility functions |
13 |
# necessary to build packages for multilib in a clean and uniform |
14 |
# manner. |
15 |
# |
16 |
# Please note that dependency specifications for multilib-capable |
17 |
# dependencies shall use the USE dependency string in ${MULTILIB_USEDEP} |
18 |
# to properly request multilib enabled. |
19 |
|
20 |
if [[ ! ${_MULTILIB_BUILD} ]]; then |
21 |
|
22 |
# EAPI=4 is required for meaningful MULTILIB_USEDEP. |
23 |
case ${EAPI:-0} in |
24 |
4|5) ;; |
25 |
*) die "EAPI=${EAPI} is not supported" ;; |
26 |
esac |
27 |
|
28 |
inherit multibuild multilib |
29 |
|
30 |
# @ECLASS-VARIABLE: _MULTILIB_FLAGS |
31 |
# @INTERNAL |
32 |
# @DESCRIPTION: |
33 |
# The list of multilib flags and corresponding ABI values. If the same |
34 |
# flag is reused for multiple ABIs (e.g. x86 on Linux&FreeBSD), multiple |
35 |
# ABIs may be separated by commas. |
36 |
# |
37 |
# Please contact multilib before modifying this list. This way we can |
38 |
# ensure that every *preliminary* work is done and the multilib can be |
39 |
# extended safely. |
40 |
_MULTILIB_FLAGS=( |
41 |
abi_x86_32:x86,x86_fbsd |
42 |
abi_x86_64:amd64,amd64_fbsd |
43 |
abi_x86_x32:x32 |
44 |
abi_mips_n32:n32 |
45 |
abi_mips_n64:n64 |
46 |
abi_mips_o32:o32 |
47 |
) |
48 |
|
49 |
# @ECLASS-VARIABLE: MULTILIB_USEDEP |
50 |
# @DESCRIPTION: |
51 |
# The USE-dependency to be used on dependencies (libraries) needing |
52 |
# to support multilib as well. |
53 |
# |
54 |
# Example use: |
55 |
# @CODE |
56 |
# RDEPEND="dev-libs/libfoo[${MULTILIB_USEDEP}] |
57 |
# net-libs/libbar[ssl,${MULTILIB_USEDEP}]" |
58 |
# @CODE |
59 |
|
60 |
_multilib_build_set_globals() { |
61 |
local flags=( "${_MULTILIB_FLAGS[@]%:*}" ) |
62 |
local usedeps=${flags[@]/%/(-)?} |
63 |
|
64 |
IUSE=${flags[*]} |
65 |
MULTILIB_USEDEP=${usedeps// /,} |
66 |
} |
67 |
_multilib_build_set_globals |
68 |
|
69 |
# @FUNCTION: multilib_get_enabled_abis |
70 |
# @DESCRIPTION: |
71 |
# Return the ordered list of enabled ABIs if multilib builds |
72 |
# are enabled. The best (most preferred) ABI will come last. |
73 |
# |
74 |
# If multilib is disabled, the default ABI will be returned |
75 |
# in order to enforce consistent testing with multilib code. |
76 |
multilib_get_enabled_abis() { |
77 |
debug-print-function ${FUNCNAME} "${@}" |
78 |
|
79 |
local abis=( $(get_all_abis) ) |
80 |
|
81 |
local abi i found |
82 |
for abi in "${abis[@]}"; do |
83 |
for i in "${_MULTILIB_FLAGS[@]}"; do |
84 |
local m_abis=${i#*:} m_abi |
85 |
local m_flag=${i%:*} |
86 |
|
87 |
# split on ,; we can't switch IFS for function scope because |
88 |
# paludis is broken (bug #486592), and switching it locally |
89 |
# for the split is more complex than cheating like this |
90 |
for m_abi in ${m_abis//,/ }; do |
91 |
if [[ ${m_abi} == ${abi} ]] && use "${m_flag}"; then |
92 |
echo "${abi}" |
93 |
found=1 |
94 |
break 2 |
95 |
fi |
96 |
done |
97 |
done |
98 |
done |
99 |
|
100 |
if [[ ! ${found} ]]; then |
101 |
# ${ABI} can be used to override the fallback (multilib-portage), |
102 |
# ${DEFAULT_ABI} is the safe fallback. |
103 |
local abi=${ABI:-${DEFAULT_ABI}} |
104 |
|
105 |
debug-print "${FUNCNAME}: no ABIs enabled, fallback to ${abi}" |
106 |
debug-print "${FUNCNAME}: ABI=${ABI}, DEFAULT_ABI=${DEFAULT_ABI}" |
107 |
echo ${abi} |
108 |
fi |
109 |
} |
110 |
|
111 |
# @FUNCTION: _multilib_multibuild_wrapper |
112 |
# @USAGE: <argv>... |
113 |
# @INTERNAL |
114 |
# @DESCRIPTION: |
115 |
# Initialize the environment for ABI selected for multibuild. |
116 |
_multilib_multibuild_wrapper() { |
117 |
debug-print-function ${FUNCNAME} "${@}" |
118 |
|
119 |
local ABI=${MULTIBUILD_VARIANT} |
120 |
multilib_toolchain_setup "${ABI}" |
121 |
"${@}" |
122 |
} |
123 |
|
124 |
# @FUNCTION: multilib_foreach_abi |
125 |
# @USAGE: <argv>... |
126 |
# @DESCRIPTION: |
127 |
# If multilib support is enabled, sets the toolchain up for each |
128 |
# supported ABI along with the ABI variable and correct BUILD_DIR, |
129 |
# and runs the given commands with them. |
130 |
# |
131 |
# If multilib support is disabled, it just runs the commands. No setup |
132 |
# is done. |
133 |
multilib_foreach_abi() { |
134 |
debug-print-function ${FUNCNAME} "${@}" |
135 |
|
136 |
local MULTIBUILD_VARIANTS=( $(multilib_get_enabled_abis) ) |
137 |
multibuild_foreach_variant _multilib_multibuild_wrapper "${@}" |
138 |
} |
139 |
|
140 |
# @FUNCTION: multilib_parallel_foreach_abi |
141 |
# @USAGE: <argv>... |
142 |
# @DESCRIPTION: |
143 |
# If multilib support is enabled, sets the toolchain up for each |
144 |
# supported ABI along with the ABI variable and correct BUILD_DIR, |
145 |
# and runs the given commands with them. The commands are run |
146 |
# in parallel with number of jobs being determined from MAKEOPTS. |
147 |
# |
148 |
# If multilib support is disabled, it just runs the commands. No setup |
149 |
# is done. |
150 |
# |
151 |
# Useful for running configure scripts. |
152 |
multilib_parallel_foreach_abi() { |
153 |
debug-print-function ${FUNCNAME} "${@}" |
154 |
|
155 |
local MULTIBUILD_VARIANTS=( $(multilib_get_enabled_abis) ) |
156 |
multibuild_parallel_foreach_variant _multilib_multibuild_wrapper "${@}" |
157 |
} |
158 |
|
159 |
# @FUNCTION: multilib_for_best_abi |
160 |
# @USAGE: <argv>... |
161 |
# @DESCRIPTION: |
162 |
# Runs the given command with setup for the 'best' (usually native) ABI. |
163 |
multilib_for_best_abi() { |
164 |
debug-print-function ${FUNCNAME} "${@}" |
165 |
|
166 |
local MULTIBUILD_VARIANTS=( $(multilib_get_enabled_abis) ) |
167 |
|
168 |
multibuild_for_best_variant _multilib_multibuild_wrapper "${@}" |
169 |
} |
170 |
|
171 |
# @FUNCTION: multilib_check_headers |
172 |
# @DESCRIPTION: |
173 |
# Check whether the header files are consistent between ABIs. |
174 |
# |
175 |
# This function needs to be called after each ABI's installation phase. |
176 |
# It obtains the header file checksums and compares them with previous |
177 |
# runs (if any). Dies if header files differ. |
178 |
multilib_check_headers() { |
179 |
_multilib_header_cksum() { |
180 |
[[ -d ${ED}usr/include ]] && \ |
181 |
find "${ED}"usr/include -type f \ |
182 |
-exec cksum {} + | sort -k2 |
183 |
} |
184 |
|
185 |
local cksum=$(_multilib_header_cksum) |
186 |
local cksum_file=${T}/.multilib_header_cksum |
187 |
|
188 |
if [[ -f ${cksum_file} ]]; then |
189 |
local cksum_prev=$(< "${cksum_file}") |
190 |
|
191 |
if [[ ${cksum} != ${cksum_prev} ]]; then |
192 |
echo "${cksum}" > "${cksum_file}.new" |
193 |
|
194 |
eerror "Header files have changed between ABIs." |
195 |
|
196 |
if type -p diff &>/dev/null; then |
197 |
eerror "$(diff -du "${cksum_file}" "${cksum_file}.new")" |
198 |
else |
199 |
eerror "Old checksums in: ${cksum_file}" |
200 |
eerror "New checksums in: ${cksum_file}.new" |
201 |
fi |
202 |
|
203 |
die "Header checksum mismatch, aborting." |
204 |
fi |
205 |
else |
206 |
echo "${cksum}" > "${cksum_file}" |
207 |
fi |
208 |
} |
209 |
|
210 |
# @FUNCTION: multilib_copy_sources |
211 |
# @DESCRIPTION: |
212 |
# Create a single copy of the package sources for each enabled ABI. |
213 |
# |
214 |
# The sources are always copied from initial BUILD_DIR (or S if unset) |
215 |
# to ABI-specific build directory matching BUILD_DIR used by |
216 |
# multilib_foreach_abi(). |
217 |
multilib_copy_sources() { |
218 |
debug-print-function ${FUNCNAME} "${@}" |
219 |
|
220 |
local MULTIBUILD_VARIANTS=( $(multilib_get_enabled_abis) ) |
221 |
multibuild_copy_sources |
222 |
} |
223 |
|
224 |
# @ECLASS-VARIABLE: MULTILIB_WRAPPED_HEADERS |
225 |
# @DESCRIPTION: |
226 |
# A list of headers to wrap for multilib support. The listed headers |
227 |
# will be moved to a non-standard location and replaced with a file |
228 |
# including them conditionally to current ABI. |
229 |
# |
230 |
# This variable has to be a bash array. Paths shall be relative to |
231 |
# installation root (${ED}), and name regular files. Recursive wrapping |
232 |
# is not supported. |
233 |
# |
234 |
# Please note that header wrapping is *discouraged*. It is preferred to |
235 |
# install all headers in a subdirectory of libdir and use pkg-config to |
236 |
# locate the headers. Some C preprocessors will not work with wrapped |
237 |
# headers. |
238 |
# |
239 |
# Example: |
240 |
# @CODE |
241 |
# MULTILIB_WRAPPED_HEADERS=( |
242 |
# /usr/include/foobar/config.h |
243 |
# ) |
244 |
# @CODE |
245 |
|
246 |
# @ECLASS-VARIABLE: MULTILIB_CHOST_TOOLS |
247 |
# @DESCRIPTION: |
248 |
# A list of tool executables to preserve for each multilib ABI. |
249 |
# The listed executables will be renamed to ${CHOST}-${basename}, |
250 |
# and the native variant will be symlinked to the generic name. |
251 |
# |
252 |
# This variable has to be a bash array. Paths shall be relative to |
253 |
# installation root (${ED}), and name regular files or symbolic |
254 |
# links to regular files. Recursive wrapping is not supported. |
255 |
# |
256 |
# If symbolic link is passed, both symlink path and symlink target |
257 |
# will be changed. As a result, the symlink target is expected |
258 |
# to be wrapped as well (either by listing in MULTILIB_CHOST_TOOLS |
259 |
# or externally). |
260 |
# |
261 |
# Please note that tool wrapping is *discouraged*. It is preferred to |
262 |
# install pkg-config files for each ABI, and require reverse |
263 |
# dependencies to use that. |
264 |
# |
265 |
# Packages that search for tools properly (e.g. using AC_PATH_TOOL |
266 |
# macro) will find the wrapper executables automatically. Other packages |
267 |
# will need explicit override of tool paths. |
268 |
# |
269 |
# Example: |
270 |
# @CODE |
271 |
# MULTILIB_CHOST_TOOLS=( |
272 |
# /usr/bin/foo-config |
273 |
# ) |
274 |
|
275 |
# @CODE |
276 |
# @FUNCTION: multilib_prepare_wrappers |
277 |
# @USAGE: [<install-root>] |
278 |
# @DESCRIPTION: |
279 |
# Perform the preparation of all kinds of wrappers for the current ABI. |
280 |
# This function shall be called once per each ABI, after installing |
281 |
# the files to be wrapped. |
282 |
# |
283 |
# Takes an optional custom <install-root> from which files will be |
284 |
# used. If no root is specified, uses ${ED}. |
285 |
# |
286 |
# The files to be wrapped are specified using separate variables, |
287 |
# e.g. MULTILIB_WRAPPED_HEADERS. Those variables shall not be changed |
288 |
# between the successive calls to multilib_prepare_wrappers |
289 |
# and multilib_install_wrappers. |
290 |
# |
291 |
# After all wrappers are prepared, multilib_install_wrappers shall |
292 |
# be called to commit them to the installation tree. |
293 |
multilib_prepare_wrappers() { |
294 |
debug-print-function ${FUNCNAME} "${@}" |
295 |
|
296 |
[[ ${#} -le 1 ]] || die "${FUNCNAME}: too many arguments" |
297 |
|
298 |
local root=${1:-${ED}} |
299 |
local f |
300 |
|
301 |
for f in "${MULTILIB_WRAPPED_HEADERS[@]}"; do |
302 |
# drop leading slash if it's there |
303 |
f=${f#/} |
304 |
|
305 |
if [[ ${f} != usr/include/* ]]; then |
306 |
die "Wrapping headers outside of /usr/include is not supported at the moment." |
307 |
fi |
308 |
# and then usr/include |
309 |
f=${f#usr/include} |
310 |
|
311 |
local dir=${f%/*} |
312 |
|
313 |
if [[ ! -f ${ED}/tmp/multilib-include${f} ]]; then |
314 |
dodir "/tmp/multilib-include${dir}" |
315 |
# a generic template |
316 |
cat > "${ED}/tmp/multilib-include${f}" <<_EOF_ |
317 |
/* This file is auto-generated by multilib-build.eclass |
318 |
* as a multilib-friendly wrapper. For the original content, |
319 |
* please see the files that are #included below. |
320 |
*/ |
321 |
|
322 |
#if defined(__x86_64__) /* amd64 */ |
323 |
# if defined(__ILP32__) /* x32 ABI */ |
324 |
# error "abi_x86_x32 not supported by the package." |
325 |
# else /* 64-bit ABI */ |
326 |
# error "abi_x86_64 not supported by the package." |
327 |
# endif |
328 |
#elif defined(__i386__) /* plain x86 */ |
329 |
# error "abi_x86_32 not supported by the package." |
330 |
#elif defined(__mips__) |
331 |
# if(_MIPS_SIM == _ABIN32) /* n32 */ |
332 |
# error "abi_mips_n32 not supported by the package." |
333 |
# elif(_MIPS_SIM == _ABI64) /* n64 */ |
334 |
# error "abi_mips_n64 not supported by the package." |
335 |
# elif(_MIPS_SIM == _ABIO32) /* o32 */ |
336 |
# error "abi_mips_o32 not supported by the package." |
337 |
# endif |
338 |
#else |
339 |
# error "No ABI matched, please report a bug to bugs.gentoo.org" |
340 |
#endif |
341 |
_EOF_ |
342 |
fi |
343 |
|
344 |
# Some ABIs may have install less files than others. |
345 |
if [[ -f ${root}/usr/include${f} ]]; then |
346 |
# $CHOST shall be set by multilib_toolchain_setup |
347 |
dodir "/tmp/multilib-include/${CHOST}${dir}" |
348 |
mv "${root}/usr/include${f}" "${ED}/tmp/multilib-include/${CHOST}${dir}/" || die |
349 |
|
350 |
# XXX: get abi_* directly |
351 |
local abi_flag |
352 |
case "${ABI}" in |
353 |
amd64|amd64_fbsd) |
354 |
abi_flag=abi_x86_64;; |
355 |
x86|x86_fbsd) |
356 |
abi_flag=abi_x86_32;; |
357 |
x32) |
358 |
abi_flag=abi_x86_x32;; |
359 |
n32) |
360 |
abi_flag=abi_mips_n32;; |
361 |
n64) |
362 |
abi_flag=abi_mips_n64;; |
363 |
o32) |
364 |
abi_flag=abi_mips_o32;; |
365 |
*) |
366 |
die "Header wrapping for ${ABI} not supported yet";; |
367 |
esac |
368 |
|
369 |
# Note: match a space afterwards to avoid collision potential. |
370 |
sed -e "/${abi_flag} /s&error.*&include <${CHOST}${f}>&" \ |
371 |
-i "${ED}/tmp/multilib-include${f}" || die |
372 |
fi |
373 |
done |
374 |
|
375 |
for f in "${MULTILIB_CHOST_TOOLS[@]}"; do |
376 |
# drop leading slash if it's there |
377 |
f=${f#/} |
378 |
|
379 |
local dir=${f%/*} |
380 |
local fn=${f##*/} |
381 |
|
382 |
if [[ -L ${root}/${f} ]]; then |
383 |
# rewrite the symlink target |
384 |
local target=$(readlink "${root}/${f}") |
385 |
local target_dir |
386 |
local target_fn=${target##*/} |
387 |
|
388 |
[[ ${target} == */* ]] && target_dir=${target%/*} |
389 |
|
390 |
ln -f -s "${target_dir+${target_dir}/}${CHOST}-${target_fn}" \ |
391 |
"${root}/${f}" || die |
392 |
fi |
393 |
|
394 |
mv "${root}/${f}" "${root}/${dir}/${CHOST}-${fn}" || die |
395 |
|
396 |
# symlink the native one back |
397 |
if multilib_build_binaries; then |
398 |
ln -s "${CHOST}-${fn}" "${root}/${f}" || die |
399 |
fi |
400 |
done |
401 |
} |
402 |
|
403 |
# @FUNCTION: multilib_install_wrappers |
404 |
# @USAGE: [<install-root>] |
405 |
# @DESCRIPTION: |
406 |
# Install the previously-prepared wrappers. This function shall |
407 |
# be called once, after all wrappers were prepared. |
408 |
# |
409 |
# Takes an optional custom <install-root> to which the wrappers will be |
410 |
# installed. If no root is specified, uses ${ED}. There is no need to |
411 |
# use the same root as when preparing the wrappers. |
412 |
# |
413 |
# The files to be wrapped are specified using separate variables, |
414 |
# e.g. MULTILIB_WRAPPED_HEADERS. Those variables shall not be changed |
415 |
# between the calls to multilib_prepare_wrappers |
416 |
# and multilib_install_wrappers. |
417 |
multilib_install_wrappers() { |
418 |
debug-print-function ${FUNCNAME} "${@}" |
419 |
|
420 |
[[ ${#} -le 1 ]] || die "${FUNCNAME}: too many arguments" |
421 |
|
422 |
local root=${1:-${ED}} |
423 |
|
424 |
if [[ -d "${ED}"/tmp/multilib-include ]]; then |
425 |
multibuild_merge_root \ |
426 |
"${ED}"/tmp/multilib-include "${root}"/usr/include |
427 |
# it can fail if something else uses /tmp |
428 |
rmdir "${ED}"/tmp &>/dev/null |
429 |
fi |
430 |
} |
431 |
|
432 |
# @FUNCTION: multilib_is_native_abi |
433 |
# @DESCRIPTION: |
434 |
# Determine whether the currently built ABI is the profile native. |
435 |
# Return true status (0) if that is true, otherwise false (1). |
436 |
# |
437 |
# This function is not intended to be used directly. Please use |
438 |
# multilib_build_binaries instead. |
439 |
multilib_is_native_abi() { |
440 |
debug-print-function ${FUNCNAME} "${@}" |
441 |
|
442 |
[[ ${#} -eq 0 ]] || die "${FUNCNAME}: too many arguments" |
443 |
|
444 |
[[ ${ABI} == ${DEFAULT_ABI} ]] |
445 |
} |
446 |
|
447 |
# @FUNCTION: multilib_build_binaries |
448 |
# @DESCRIPTION: |
449 |
# Determine whether to build binaries for the currently built ABI. |
450 |
# Returns true status (0) if the currently built ABI is the profile |
451 |
# native or COMPLETE_MULTILIB variable is set to 'yes', otherwise |
452 |
# false (1). |
453 |
# |
454 |
# This is often useful for configure calls when some of the options are |
455 |
# supposed to be disabled for multilib ABIs (like those used for |
456 |
# executables only). |
457 |
multilib_build_binaries() { |
458 |
debug-print-function ${FUNCNAME} "${@}" |
459 |
|
460 |
[[ ${#} -eq 0 ]] || die "${FUNCNAME}: too many arguments" |
461 |
|
462 |
[[ ${COMPLETE_MULTILIB} == yes ]] || multilib_is_native_abi |
463 |
} |
464 |
|
465 |
# @FUNCTION: multilib_native_use_with |
466 |
# @USAGE: <flag> [<opt-name> [<opt-value>]] |
467 |
# @DESCRIPTION: |
468 |
# Output --with configure option alike use_with if USE <flag> is enabled |
469 |
# and executables are being built (multilib_build_binaries is true). |
470 |
# Otherwise, outputs --without configure option. Arguments are the same |
471 |
# as for use_with in the EAPI. |
472 |
multilib_native_use_with() { |
473 |
if multilib_build_binaries; then |
474 |
use_with "${@}" |
475 |
else |
476 |
echo "--without-${2:-${1}}" |
477 |
fi |
478 |
} |
479 |
|
480 |
# @FUNCTION: multilib_native_use_enable |
481 |
# @USAGE: <flag> [<opt-name> [<opt-value>]] |
482 |
# @DESCRIPTION: |
483 |
# Output --enable configure option alike use_with if USE <flag> |
484 |
# is enabled and executables are being built (multilib_build_binaries |
485 |
# is true). Otherwise, outputs --disable configure option. Arguments are |
486 |
# the same as for use_enable in the EAPI. |
487 |
multilib_native_use_enable() { |
488 |
if multilib_build_binaries; then |
489 |
use_enable "${@}" |
490 |
else |
491 |
echo "--disable-${2:-${1}}" |
492 |
fi |
493 |
} |
494 |
|
495 |
# @FUNCTION: multilib_native_usex |
496 |
# @USAGE: <flag> [<true1> [<false1> [<true2> [<false2>]]]] |
497 |
# @DESCRIPTION: |
498 |
# Output the concatenation of <true1> (or 'yes' if unspecified) |
499 |
# and <true2> if USE <flag> is enabled and executables are being built |
500 |
# (multilib_build_binaries is true). Otherwise, output the concatenation |
501 |
# of <false1> (or 'no' if unspecified) and <false2>. Arguments |
502 |
# are the same as for usex in the EAPI. |
503 |
# |
504 |
# Note: in EAPI 4 you need to inherit eutils to use this function. |
505 |
multilib_native_usex() { |
506 |
if multilib_build_binaries; then |
507 |
usex "${@}" |
508 |
else |
509 |
echo "${3-no}${5}" |
510 |
fi |
511 |
} |
512 |
|
513 |
_MULTILIB_BUILD=1 |
514 |
fi |