/[gentoo-x86]/eclass/distutils-r1.eclass
Gentoo

Contents of /eclass/distutils-r1.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.24 - (hide annotations) (download)
Sat Dec 1 10:54:50 2012 UTC (2 years ago) by mgorny
Branch: MAIN
Changes since 1.23: +40 -3 lines
Support parallel builds using multiprocessing eclass.

1 mgorny 1.1 # Copyright 1999-2012 Gentoo Foundation
2     # Distributed under the terms of the GNU General Public License v2
3 mgorny 1.24 # $Header: /var/cvsroot/gentoo-x86/eclass/distutils-r1.eclass,v 1.23 2012/12/01 10:53:40 mgorny Exp $
4 mgorny 1.1
5     # @ECLASS: distutils-r1
6     # @MAINTAINER:
7     # Michał Górny <mgorny@gentoo.org>
8     # Python herd <python@gentoo.org>
9     # @AUTHOR:
10     # Author: Michał Górny <mgorny@gentoo.org>
11     # Based on the work of: Krzysztof Pawlik <nelchael@gentoo.org>
12     # @BLURB: A simple eclass to build Python packages using distutils.
13     # @DESCRIPTION:
14     # A simple eclass providing functions to build Python packages using
15     # the distutils build system. It exports phase functions for all
16     # the src_* phases. Each of the phases runs two pseudo-phases:
17     # python_..._all() (e.g. python_prepare_all()) once in ${S}, then
18     # python_...() (e.g. python_prepare()) for each implementation
19     # (see: python_foreach_impl() in python-r1).
20     #
21     # In distutils-r1_src_prepare(), the 'all' function is run before
22     # per-implementation ones (because it creates the implementations),
23     # per-implementation functions are run in a random order.
24     #
25     # In remaining phase functions, the per-implementation functions are run
26     # before the 'all' one, and they are ordered from the least to the most
27     # preferred implementation (so that 'better' files overwrite 'worse'
28     # ones).
29     #
30     # If the ebuild doesn't specify a particular pseudo-phase function,
31     # the default one will be used (distutils-r1_...). Defaults are provided
32     # for all per-implementation pseudo-phases, python_prepare_all()
33     # and python_install_all(); whenever writing your own pseudo-phase
34     # functions, you should consider calling the defaults (and especially
35     # distutils-r1_python_prepare_all).
36     #
37 mgorny 1.5 # Please note that distutils-r1 sets RDEPEND and DEPEND unconditionally
38     # for you.
39     #
40     # Also, please note that distutils-r1 will always inherit python-r1
41     # as well. Thus, all the variables defined and documented there are
42     # relevant to the packages using distutils-r1.
43 mgorny 1.19 #
44     # For more information, please see the python-r1 Developer's Guide:
45     # http://www.gentoo.org/proj/en/Python/python-r1/dev-guide.xml
46 mgorny 1.1
47 mgorny 1.19 case "${EAPI:-0}" in
48 mgorny 1.1 0|1|2|3)
49 mgorny 1.19 die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
50 mgorny 1.1 ;;
51 mgorny 1.3 4|5)
52 mgorny 1.1 ;;
53     *)
54     die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
55     ;;
56     esac
57    
58 mgorny 1.19 if [[ ! ${_DISTUTILS_R1} ]]; then
59    
60 mgorny 1.24 inherit eutils multiprocessing python-r1
61 mgorny 1.1
62 mgorny 1.20 fi
63    
64 mgorny 1.1 EXPORT_FUNCTIONS src_prepare src_configure src_compile src_test src_install
65    
66 mgorny 1.20 if [[ ! ${_DISTUTILS_R1} ]]; then
67    
68 mgorny 1.11 RDEPEND=${PYTHON_DEPS}
69 mgorny 1.1 DEPEND=${PYTHON_DEPS}
70    
71 mgorny 1.5 # @ECLASS-VARIABLE: PATCHES
72     # @DEFAULT_UNSET
73     # @DESCRIPTION:
74     # An array containing patches to be applied to the sources before
75     # copying them.
76     #
77     # If unset, no custom patches will be applied.
78     #
79     # Please note, however, that at some point the eclass may apply
80     # additional distutils patches/quirks independently of this variable.
81     #
82     # Example:
83     # @CODE
84     # PATCHES=( "${FILESDIR}"/${P}-make-gentoo-happy.patch )
85     # @CODE
86    
87 mgorny 1.1 # @ECLASS-VARIABLE: DOCS
88     # @DEFAULT_UNSET
89     # @DESCRIPTION:
90 mgorny 1.5 # An array containing documents installed using dodoc. The files listed
91     # there must exist in the directory from which
92     # distutils-r1_python_install_all() is run (${S} by default).
93 mgorny 1.1 #
94 mgorny 1.5 # If unset, the function will instead look up files matching default
95     # filename pattern list (from the Package Manager Specification),
96     # and install those found.
97 mgorny 1.1 #
98     # Example:
99     # @CODE
100     # DOCS=( NEWS README )
101     # @CODE
102    
103     # @ECLASS-VARIABLE: HTML_DOCS
104     # @DEFAULT_UNSET
105     # @DESCRIPTION:
106 mgorny 1.5 # An array containing documents installed using dohtml. The files
107     # and directories listed there must exist in the directory from which
108     # distutils-r1_python_install_all() is run (${S} by default).
109     #
110     # If unset, no HTML docs will be installed.
111 mgorny 1.1 #
112     # Example:
113     # @CODE
114     # HTML_DOCS=( doc/html/ )
115     # @CODE
116    
117 mgorny 1.14 # @ECLASS-VARIABLE: DISTUTILS_IN_SOURCE_BUILD
118     # @DEFAULT_UNSET
119     # @DESCRIPTION:
120     # If set to a non-null value, in-source builds will be enabled.
121     # If unset, the default is to use in-source builds when python_prepare()
122     # is declared, and out-of-source builds otherwise.
123     #
124     # If in-source builds are used, the eclass will create a copy of package
125     # sources for each Python implementation in python_prepare_all(),
126     # and work on that copy afterwards.
127     #
128     # If out-of-source builds are used, the eclass will instead work
129     # on the sources directly, prepending setup.py arguments with
130     # 'build --build-base ${BUILD_DIR}' to enforce keeping & using built
131     # files in the specific root.
132    
133 mgorny 1.24 # @ECLASS-VARIABLE: DISTUTILS_NO_PARALLEL_BUILD
134     # @DEFAULT_UNSET
135     # @DESCRIPTION:
136     # If set to a non-null value, the parallel build feature will
137     # be disabled.
138     #
139     # When parallel builds are used, the implementation-specific sub-phases
140     # for selected Python implementation will be run in parallel. This will
141     # increase build efficiency with distutils which does not do parallel
142     # builds.
143     #
144     # This variable can be used to disable the afore-mentioned feature
145     # in case it causes issues with the package.
146    
147     #
148     # If in-source builds are used, the eclass will create a copy of package
149     # sources for each Python implementation in python_prepare_all(),
150     # and work on that copy afterwards.
151     #
152     # If out-of-source builds are used, the eclass will instead work
153     # on the sources directly, prepending setup.py arguments with
154     # 'build --build-base ${BUILD_DIR}' to enforce keeping & using built
155     # files in the specific root.
156 mgorny 1.13 # @ECLASS-VARIABLE: mydistutilsargs
157     # @DEFAULT_UNSET
158     # @DESCRIPTION:
159     # An array containing options to be passed to setup.py.
160     #
161     # Example:
162     # @CODE
163     # python_configure_all() {
164     # mydistutilsargs=( --enable-my-hidden-option )
165     # }
166     # @CODE
167    
168     # @FUNCTION: esetup.py
169     # @USAGE: [<args>...]
170     # @DESCRIPTION:
171     # Run the setup.py using currently selected Python interpreter
172     # (if ${PYTHON} is set; fallback 'python' otherwise). The setup.py will
173     # be passed default command-line arguments, then ${mydistutilsargs[@]},
174     # then any parameters passed to this command.
175     #
176     # This command dies on failure.
177     esetup.py() {
178     debug-print-function ${FUNCNAME} "${@}"
179    
180 mgorny 1.14 local args=()
181     if [[ ! ${DISTUTILS_IN_SOURCE_BUILD} ]]; then
182     if [[ ! ${BUILD_DIR} ]]; then
183     die 'Out-of-source build requested, yet BUILD_DIR unset.'
184     fi
185    
186 mgorny 1.16 args+=(
187     build
188     --build-base "${BUILD_DIR}"
189     # using a single directory for them helps us export ${PYTHONPATH}
190     --build-lib "${BUILD_DIR}/lib"
191     )
192 mgorny 1.14 fi
193    
194 mgorny 1.13 set -- "${PYTHON:-python}" setup.py \
195 mgorny 1.14 "${args[@]}" "${mydistutilsargs[@]}" "${@}"
196 mgorny 1.13
197     echo "${@}" >&2
198     "${@}" || die
199     }
200    
201 mgorny 1.1 # @FUNCTION: distutils-r1_python_prepare_all
202     # @DESCRIPTION:
203     # The default python_prepare_all(). It applies the patches from PATCHES
204     # array, then user patches and finally calls python_copy_sources to
205     # create copies of resulting sources for each Python implementation.
206 mgorny 1.5 #
207     # At some point in the future, it may also apply eclass-specific
208     # distutils patches and/or quirks.
209 mgorny 1.1 distutils-r1_python_prepare_all() {
210     debug-print-function ${FUNCNAME} "${@}"
211    
212     [[ ${PATCHES} ]] && epatch "${PATCHES[@]}"
213    
214     epatch_user
215    
216 mgorny 1.14 # by default, use in-source build if python_prepare() is used
217     if [[ ! ${DISTUTILS_IN_SOURCE_BUILD+1} ]]; then
218     if declare -f python_prepare >/dev/null; then
219     DISTUTILS_IN_SOURCE_BUILD=1
220     fi
221     fi
222    
223     if [[ ${DISTUTILS_IN_SOURCE_BUILD} ]]; then
224     # create source copies for each implementation
225     python_copy_sources
226     fi
227 mgorny 1.1 }
228    
229     # @FUNCTION: distutils-r1_python_prepare
230     # @DESCRIPTION:
231     # The default python_prepare(). Currently it is a no-op
232     # but in the future it may apply implementation-specific quirks
233     # to the build system.
234     distutils-r1_python_prepare() {
235     debug-print-function ${FUNCNAME} "${@}"
236    
237     :
238     }
239    
240     # @FUNCTION: distutils-r1_python_configure
241     # @DESCRIPTION:
242     # The default python_configure(). Currently a no-op.
243     distutils-r1_python_configure() {
244     debug-print-function ${FUNCNAME} "${@}"
245    
246     :
247     }
248    
249     # @FUNCTION: distutils-r1_python_compile
250     # @USAGE: [additional-args...]
251     # @DESCRIPTION:
252 mgorny 1.13 # The default python_compile(). Runs 'esetup.py build'. Any parameters
253     # passed to this function will be passed to setup.py.
254 mgorny 1.1 distutils-r1_python_compile() {
255     debug-print-function ${FUNCNAME} "${@}"
256    
257 mgorny 1.13 esetup.py build "${@}"
258 mgorny 1.1 }
259    
260     # @FUNCTION: distutils-r1_python_test
261     # @DESCRIPTION:
262     # The default python_test(). Currently a no-op.
263     distutils-r1_python_test() {
264     debug-print-function ${FUNCNAME} "${@}"
265    
266     :
267     }
268    
269 mgorny 1.21 # @FUNCTION: _distutils-r1_rename_scripts
270     # @USAGE: <path>
271     # @INTERNAL
272 mgorny 1.1 # @DESCRIPTION:
273     # Renames installed Python scripts to be implementation-suffixed.
274 mgorny 1.21 # ${EPYTHON} needs to be set to the implementation name.
275     #
276     # All executable scripts having shebang referencing ${EPYTHON}
277     # in given path will be renamed.
278     _distutils-r1_rename_scripts() {
279 mgorny 1.1 debug-print-function ${FUNCNAME} "${@}"
280    
281 mgorny 1.21 local path=${1}
282     [[ ${path} ]] || die "${FUNCNAME}: no path given"
283    
284 mgorny 1.1 local f
285     # XXX: change this if we ever allow directories in bin/sbin
286 mgorny 1.21 while IFS= read -r -d '' f; do
287     debug-print "${FUNCNAME}: found executable at ${f#${D}/}"
288    
289     if [[ "$(head -n 1 "${f}")" == '#!'*${EPYTHON}* ]]
290     then
291     debug-print "${FUNCNAME}: matching shebang: $(head -n 1 "${f}")"
292    
293     local newf=${f}-${EPYTHON}
294 mgorny 1.23 debug-print "${FUNCNAME}: renaming to ${newf#${D}/}"
295 mgorny 1.21 mv "${f}" "${newf}" || die
296 mgorny 1.23
297     debug-print "${FUNCNAME}: installing wrapper at ${f#${D}/}"
298     _python_ln_rel "${path}"/usr/bin/python-exec "${f}" || die
299 mgorny 1.1 fi
300 mgorny 1.21 done < <(find "${path}" -type f -executable -print0)
301 mgorny 1.1 }
302    
303     # @FUNCTION: distutils-r1_python_install
304     # @USAGE: [additional-args...]
305     # @DESCRIPTION:
306 mgorny 1.13 # The default python_install(). Runs 'esetup.py install', appending
307 mgorny 1.21 # the optimization flags. Then renames the installed scripts.
308 mgorny 1.13 # Any parameters passed to this function will be passed to setup.py.
309 mgorny 1.1 distutils-r1_python_install() {
310     debug-print-function ${FUNCNAME} "${@}"
311    
312     local flags
313    
314     case "${EPYTHON}" in
315     jython*)
316     flags=(--compile);;
317     *)
318     flags=(--compile -O2);;
319     esac
320     debug-print "${FUNCNAME}: [${EPYTHON}] flags: ${flags}"
321    
322 mgorny 1.15 # enable compilation for the install phase.
323 mgorny 1.18 local PYTHONDONTWRITEBYTECODE
324     export PYTHONDONTWRITEBYTECODE
325 mgorny 1.1
326 mgorny 1.22 local root=${D}/_${EPYTHON}
327 mgorny 1.1
328 mgorny 1.22 esetup.py install "${flags[@]}" --root="${root}" "${@}"
329     _distutils-r1_rename_scripts "${root}"
330    
331     # merge
332     cp -a -l -n "${root}"/* "${D}"/ || die "Merging ${EPYTHON} image failed."
333     rm -rf "${root}"
334 mgorny 1.1 }
335    
336     # @FUNCTION: distutils-r1_python_install_all
337     # @DESCRIPTION:
338 mgorny 1.23 # The default python_install_all(). It installs the documentation.
339 mgorny 1.1 distutils-r1_python_install_all() {
340     debug-print-function ${FUNCNAME} "${@}"
341    
342     if declare -p DOCS &>/dev/null; then
343     dodoc "${DOCS[@]}" || die "dodoc failed"
344     else
345     local f
346     # same list as in PMS
347     for f in README* ChangeLog AUTHORS NEWS TODO CHANGES \
348     THANKS BUGS FAQ CREDITS CHANGELOG; do
349     if [[ -s ${f} ]]; then
350     dodoc "${f}" || die "(default) dodoc ${f} failed"
351     fi
352     done
353     fi
354    
355     if declare -p HTML_DOCS &>/dev/null; then
356     dohtml -r "${HTML_DOCS[@]}" || die "dohtml failed"
357     fi
358     }
359    
360 mgorny 1.8 # @FUNCTION: distutils-r1_run_phase
361     # @USAGE: [<argv>...]
362     # @INTERNAL
363     # @DESCRIPTION:
364 mgorny 1.17 # Run the given command.
365     #
366     # If out-of-source builds are used, the phase function is run in source
367     # directory, with BUILD_DIR pointing at the build directory
368     # and PYTHONPATH having an entry for the module build directory.
369     #
370     # If in-source builds are used, the command is executed in the BUILD_DIR
371     # (the directory holding per-implementation copy of sources).
372 mgorny 1.8 distutils-r1_run_phase() {
373     debug-print-function ${FUNCNAME} "${@}"
374    
375 mgorny 1.14 if [[ ${DISTUTILS_IN_SOURCE_BUILD} ]]; then
376     pushd "${BUILD_DIR}" &>/dev/null || die
377 mgorny 1.17 else
378     local PYTHONPATH="${BUILD_DIR}/lib:${PYTHONPATH}"
379     export PYTHONPATH
380 mgorny 1.14 fi
381    
382 mgorny 1.24 if [[ ${DISTUTILS_NO_PARALLEL_BUILD} ]]; then
383     "${@}" || die "${1} failed."
384     else
385     multijob_child_init "${@}" || die "${1} failed."
386     fi
387 mgorny 1.14
388     if [[ ${DISTUTILS_IN_SOURCE_BUILD} ]]; then
389     popd &>/dev/null || die
390     fi
391 mgorny 1.8 }
392    
393 mgorny 1.1 distutils-r1_src_prepare() {
394     debug-print-function ${FUNCNAME} "${@}"
395    
396     # common preparations
397     if declare -f python_prepare_all >/dev/null; then
398     python_prepare_all
399     else
400     distutils-r1_python_prepare_all
401     fi
402    
403 mgorny 1.24 multijob_init
404 mgorny 1.1 if declare -f python_prepare >/dev/null; then
405 mgorny 1.8 python_foreach_impl distutils-r1_run_phase python_prepare
406 mgorny 1.1 else
407 mgorny 1.8 python_foreach_impl distutils-r1_run_phase distutils-r1_python_prepare
408 mgorny 1.1 fi
409 mgorny 1.24 multijob_finish
410 mgorny 1.1 }
411    
412     distutils-r1_src_configure() {
413 mgorny 1.24 multijob_init
414 mgorny 1.1 if declare -f python_configure >/dev/null; then
415 mgorny 1.8 python_foreach_impl distutils-r1_run_phase python_configure
416 mgorny 1.1 else
417 mgorny 1.8 python_foreach_impl distutils-r1_run_phase distutils-r1_python_configure
418 mgorny 1.1 fi
419 mgorny 1.24 multijob_finish
420 mgorny 1.1
421     if declare -f python_configure_all >/dev/null; then
422     python_configure_all
423     fi
424     }
425    
426     distutils-r1_src_compile() {
427     debug-print-function ${FUNCNAME} "${@}"
428    
429 mgorny 1.24 multijob_init
430 mgorny 1.1 if declare -f python_compile >/dev/null; then
431 mgorny 1.8 python_foreach_impl distutils-r1_run_phase python_compile
432 mgorny 1.1 else
433 mgorny 1.8 python_foreach_impl distutils-r1_run_phase distutils-r1_python_compile
434 mgorny 1.1 fi
435 mgorny 1.24 multijob_finish
436 mgorny 1.1
437     if declare -f python_compile_all >/dev/null; then
438     python_compile_all
439     fi
440     }
441    
442     distutils-r1_src_test() {
443     debug-print-function ${FUNCNAME} "${@}"
444    
445 mgorny 1.24 multijob_init
446 mgorny 1.1 if declare -f python_test >/dev/null; then
447 mgorny 1.8 python_foreach_impl distutils-r1_run_phase python_test
448 mgorny 1.1 else
449 mgorny 1.8 python_foreach_impl distutils-r1_run_phase distutils-r1_python_test
450 mgorny 1.1 fi
451 mgorny 1.24 multijob_finish
452 mgorny 1.1
453     if declare -f python_test_all >/dev/null; then
454     python_test_all
455     fi
456     }
457    
458     distutils-r1_src_install() {
459     debug-print-function ${FUNCNAME} "${@}"
460    
461 mgorny 1.24 multijob_init
462 mgorny 1.1 if declare -f python_install >/dev/null; then
463 mgorny 1.8 python_foreach_impl distutils-r1_run_phase python_install
464 mgorny 1.1 else
465 mgorny 1.8 python_foreach_impl distutils-r1_run_phase distutils-r1_python_install
466 mgorny 1.1 fi
467 mgorny 1.24 multijob_finish
468 mgorny 1.1
469     if declare -f python_install_all >/dev/null; then
470     python_install_all
471     else
472     distutils-r1_python_install_all
473     fi
474     }
475 mgorny 1.19
476     _DISTUTILS_R1=1
477     fi

  ViewVC Help
Powered by ViewVC 1.1.20