summaryrefslogtreecommitdiff
blob: feac748f821068eb0fd62751a231d272a30ddb95 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/eclass/multilib-build.eclass,v 1.2 2013/02/10 11:44:00 mgorny Exp $

# @ECLASS: multilib-build.eclass
# @MAINTAINER:
# Michał Górny <mgorny@gentoo.org>
# @BLURB: flags and utility functions for building multilib packages
# @DESCRIPTION:
# The multilib-build.eclass exports USE flags and utility functions
# necessary to build packages for multilib in a clean and uniform
# manner.
#
# Please note that dependency specifications for multilib-capable
# dependencies shall use the USE dependency string in ${MULTILIB_USEDEP}
# to properly request multilib enabled.

if [[ ! ${_MULTILIB_BUILD} ]]; then

# EAPI=5 is required for meaningful MULTILIB_USEDEP.
case ${EAPI:-0} in
	5) ;;
	*) die "EAPI=${EAPI} is not supported" ;;
esac

inherit multilib multiprocessing

# @ECLASS-VARIABLE: _MULTILIB_FLAGS
# @INTERNAL
# @DESCRIPTION:
# The list of multilib flags and corresponding ABI values.
_MULTILIB_FLAGS=(
	abi_x86_32:x86
	abi_x86_64:amd64
)

# @ECLASS-VARIABLE: MULTILIB_USEDEP
# @DESCRIPTION:
# The USE-dependency to be used on dependencies (libraries) needing
# to support multilib as well.
#
# Example use:
# @CODE
# RDEPEND="dev-libs/libfoo[${MULTILIB_USEDEP}]
#	net-libs/libbar[ssl,${MULTILIB_USEDEP}]"
# @CODE

_multilib_build_set_globals() {
	local flags=( "${_MULTILIB_FLAGS[@]%:*}" )
	local usedeps=${flags[@]/%/(-)?}

	IUSE=${flags[*]}
	MULTILIB_USEDEP=${usedeps// /,}
}
_multilib_build_set_globals

# @FUNCTION: multilib_get_enabled_abis
# @DESCRIPTION:
# Return the ordered list of enabled ABIs if multilib builds
# are enabled. The best (most preferred) ABI will come last.
#
# If multilib is disabled, the default ABI will be returned
# in order to enforce consistent testing with multilib code.
multilib_get_enabled_abis() {
	debug-print-function ${FUNCNAME} "${@}"

	local abis=( $(get_all_abis) )

	local abi i found
	for abi in "${abis[@]}"; do
		for i in "${_MULTILIB_FLAGS[@]}"; do
			local m_abi=${i#*:}
			local m_flag=${i%:*}

			if [[ ${m_abi} == ${abi} ]] && use "${m_flag}"; then
				echo "${abi}"
				found=1
			fi
		done
	done

	if [[ ! ${found} ]]; then
		debug-print "${FUNCNAME}: no ABIs enabled, fallback to ${DEFAULT_ABI}"
		echo ${DEFAULT_ABI}
	fi
}

# @FUNCTION: multilib_foreach_abi
# @USAGE: <argv>...
# @DESCRIPTION:
# If multilib support is enabled, sets the toolchain up for each
# supported ABI along with the ABI variable and correct BUILD_DIR,
# and runs the given commands with them.
#
# If multilib support is disabled, it just runs the commands. No setup
# is done.
multilib_foreach_abi() {
	local initial_dir=${BUILD_DIR:-${S}}

	local ABI
	for ABI in $(multilib_get_enabled_abis); do
		multilib_toolchain_setup "${ABI}"
		BUILD_DIR=${initial_dir%%/}-${ABI} "${@}"
	done
}

# @FUNCTION: multilib_parallel_foreach_abi
# @USAGE: <argv>...
# @DESCRIPTION:
# If multilib support is enabled, sets the toolchain up for each
# supported ABI along with the ABI variable and correct BUILD_DIR,
# and runs the given commands with them. The commands are run
# in parallel with number of jobs being determined from MAKEOPTS.
#
# If multilib support is disabled, it just runs the commands. No setup
# is done.
#
# Useful for running configure scripts.
multilib_parallel_foreach_abi() {
	local initial_dir=${BUILD_DIR:-${S}}

	multijob_init

	local ABI
	for ABI in $(multilib_get_enabled_abis); do
		(
			multijob_child_init

			multilib_toolchain_setup "${ABI}"
			BUILD_DIR=${initial_dir%%/}-${ABI}
			"${@}"
		) &

		multijob_post_fork
	done

	multijob_finish
}

# @FUNCTION: multilib_check_headers
# @DESCRIPTION:
# Check whether the header files are consistent between ABIs.
#
# This function needs to be called after each ABI's installation phase.
# It obtains the header file checksums and compares them with previous
# runs (if any). Dies if header files differ.
multilib_check_headers() {
	_multilib_header_cksum() {
		find "${ED}"usr/include -type f \
			-exec cksum {} + | sort -k2
	}

	local cksum=$(_multilib_header_cksum)
	local cksum_file=${T}/.multilib_header_cksum

	if [[ -f ${cksum_file} ]]; then
		local cksum_prev=$(< "${cksum_file}")

		if [[ ${cksum} != ${cksum_prev} ]]; then
			echo "${cksum}" > "${cksum_file}.new"

			eerror "Header files have changed between ABIs."

			if type -p diff &>/dev/null; then
				eerror "$(diff -du "${cksum_file}" "${cksum_file}.new")"
			else
				eerror "Old checksums in: ${cksum_file}"
				eerror "New checksums in: ${cksum_file}.new"
			fi

			die "Header checksum mismatch, aborting."
		fi
	else
		echo "${cksum}" > "${cksum_file}"
	fi
}

_MULTILIB_BUILD=1
fi