Gentoo Archives: gentoo-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-dev@l.g.o
Cc: python@g.o, "Michał Górny" <mgorny@g.o>
Subject: [gentoo-dev] [PATCH 1/8] Initial version of multibuild eclass.
Date: Wed, 27 Feb 2013 21:43:11
Message-Id: 1362001405-25636-1-git-send-email-mgorny@gentoo.org
In Reply to: [gentoo-dev] [RFC] multibuild.eclass -- a generic pluggable framework to handle multi-variant builds by "Michał Górny"
1 Based on the code from python-r1.
2 ---
3 gx86/eclass/multibuild.eclass | 172 ++++++++++++++++++++++++++++++++++++++++++
4 1 file changed, 172 insertions(+)
5 create mode 100644 gx86/eclass/multibuild.eclass
6
7 diff --git a/gx86/eclass/multibuild.eclass b/gx86/eclass/multibuild.eclass
8 new file mode 100644
9 index 0000000..716d34f
10 --- /dev/null
11 +++ b/gx86/eclass/multibuild.eclass
12 @@ -0,0 +1,172 @@
13 +# Copyright 1999-2013 Gentoo Foundation
14 +# Distributed under the terms of the GNU General Public License v2
15 +# $Header: $
16 +
17 +# @ECLASS: multibuild
18 +# @MAINTAINER:
19 +# Michał Górny <mgorny@g.o>
20 +# @AUTHOR:
21 +# Author: Michał Górny <mgorny@g.o>
22 +# @BLURB: A generic eclass for building multiple variants of packages.
23 +# @DESCRIPTION:
24 +# The multibuild eclass aims to provide a generic framework for building
25 +# multiple 'variants' of a package (e.g. multilib, Python
26 +# implementations).
27 +
28 +case "${EAPI:-0}" in
29 + 0|1|2|3|4)
30 + die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
31 + ;;
32 + 5)
33 + ;;
34 + *)
35 + die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
36 + ;;
37 +esac
38 +
39 +if [[ ! ${_MULTIBUILD} ]]; then
40 +
41 +inherit multiprocessing
42 +
43 +# @ECLASS-VARIABLE: MULTIBUILD_VARIANTS
44 +# @DESCRIPTION:
45 +# An array specifying all enabled variants which multilib_foreach* will
46 +# execute the process for.
47 +#
48 +# In ebuild, it can be set in global scope. Eclasses should set it
49 +# locally in function scope to support nesting properly.
50 +#
51 +# Example:
52 +# @CODE
53 +# python_foreach_impl() {
54 +# local MULTIBUILD_VARIANTS=( python{2_5,2_6,2_7} ... )
55 +# multibuild_foreach_impl python_compile
56 +# }
57 +# @CODE
58 +
59 +# @ECLASS-VARIABLE: MULTIBUILD_VARIANT
60 +# @DESCRIPTION:
61 +# The current variant which the function was executed for.
62 +#
63 +# Example value:
64 +# @CODE
65 +# python2_6
66 +# @CODE
67 +
68 +# @ECLASS-VARIABLE: MULTIBUILD_ID
69 +# @DESCRIPTION:
70 +# The unique identifier for a multibuild run. In a simple run, it is
71 +# equal to MULTIBUILD_VARIANT. In a nested multibuild environment, it
72 +# contains the complete selection tree.
73 +#
74 +# It can be used to create variant-unique directories and files.
75 +#
76 +# Example value:
77 +# @CODE
78 +# amd64-double
79 +# @CODE
80 +
81 +# @ECLASS-VARIABLE: BUILD_DIR
82 +# @DESCRIPTION:
83 +# The current build directory. In global scope, it is supposed to
84 +# contain an 'initial' build directory; if unset, it defaults to ${S}.
85 +#
86 +# multibuild_foreach() sets BUILD_DIR locally to variant-specific build
87 +# directories based on the initial value of BUILD_DIR.
88 +#
89 +# Example value:
90 +# @CODE
91 +# ${WORKDIR}/foo-1.3-python2_6
92 +# @CODE
93 +
94 +# @FUNCTION: multibuild_foreach
95 +# @USAGE: [<argv>...]
96 +# @DESCRIPTION:
97 +# Run the passed command repeatedly for each of the enabled package
98 +# variants.
99 +#
100 +# Each of the runs will have variant-specific BUILD_DIR set, and output
101 +# teed to a separate log in ${T}.
102 +#
103 +# The function returns 0 if all commands return 0, or the first non-zero
104 +# exit status otherwise. However, it performs all the invocations
105 +# nevertheless. It is preferred to call 'die' inside of the passed
106 +# function.
107 +multibuild_foreach() {
108 + debug-print-function ${FUNCNAME} "${@}"
109 +
110 + [[ ${MULTIBUILD_VARIANTS} ]] \
111 + || die "MULTIBUILD_VARIANTS need to be set"
112 +
113 + local bdir=${BUILD_DIR:-${S}}
114 + local prev_id=${MULTIBUILD_ID:+${MULTIBUILD_ID}-}
115 + local ret=0 lret=0 v
116 +
117 + debug-print "${FUNCNAME}: initial build_dir = ${bdir}"
118 +
119 + for v in "${MULTIBUILD_VARIANTS[@]}"; do
120 + local MULTIBUILD_VARIANT=${v}
121 + local MULTIBUILD_ID=${prev_id}${v}
122 + local BUILD_DIR=${bdir%%/}-${v}
123 +
124 + einfo "${v}: running ${@}" \
125 + | tee -a "${T}/build-${MULTIBUILD_ID}.log"
126 +
127 + # _multibuild_parallel() does redirection internally.
128 + # this is a hidden API to avoid writing multilib_foreach twice.
129 + if [[ ${1} == _multibuild_parallel ]]; then
130 + "${@}"
131 + else
132 + "${@}" 2>&1 | tee -a "${T}/build-${MULTIBUILD_ID}.log"
133 + fi
134 + lret=${?}
135 + done
136 + [[ ${ret} -eq 0 && ${lret} -ne 0 ]] && ret=${lret}
137 +
138 + return ${ret}
139 +}
140 +
141 +# @FUNCTION: multibuild_parallel_foreach
142 +# @USAGE: [<argv>...]
143 +# @DESCRIPTION:
144 +# Run the passed command repeatedly for each of the enabled package
145 +# variants alike multibuild_foreach. Multiple invocations of the command
146 +# will be performed in parallel, up to MULTIBUILD_JOBS tasks.
147 +#
148 +# The function returns 0 if all commands return 0, or the first non-zero
149 +# exit status otherwise. However, it performs all the invocations
150 +# nevertheless. It is preferred to call 'die' inside of the passed
151 +# function.
152 +multibuild_parallel_foreach() {
153 + debug-print-function ${FUNCNAME} "${@}"
154 +
155 + local ret lret
156 +
157 + _multibuild_parallel() {
158 + (
159 + multijob_child_init
160 + "${@}" 2>&1 | tee -a "${T}/build-${MULTIBUILD_ID}.log"
161 + exit ${PIPESTATUS[0]}
162 + ) &
163 + multijob_post_fork
164 + }
165 +
166 + local opts
167 + if [[ ${MULTIBUILD_JOBS} ]]; then
168 + opts=-j${MULTIBUILD_JOBS}
169 + else
170 + opts=${MAKEOPTS}
171 + fi
172 +
173 + multijob_init "${opts}"
174 + multibuild_foreach _multibuild_parallel "${@}"
175 + ret=${?}
176 + multijob_finish
177 + lret=${?}
178 +
179 + [[ ${ret} -eq 0 ]] && ret=${lret}
180 + return ${ret}
181 +}
182 +
183 +_MULTIBUILD=1
184 +fi
185 --
186 1.8.1.4