/[gentoo-x86]/eclass/ruby-ng.eclass
Gentoo

Contents of /eclass/ruby-ng.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.12 - (hide annotations) (download)
Fri Apr 30 17:40:10 2010 UTC (4 years, 3 months ago) by flameeyes
Branch: MAIN
Changes since 1.11: +11 -2 lines
Create a special handling of S variable for github-based packages.

Since using GitHub is widely common for Ruby packages, especially
those not packaging the tests within the gem, we would be
reimplementing this so many times that it's worth special casing here.

1 a3li 1.6 # Copyright 1999-2009 Gentoo Foundation
2 graaff 1.1 # Distributed under the terms of the GNU General Public License v2
3 flameeyes 1.12 # $Header: /var/cvsroot/gentoo-x86/eclass/ruby-ng.eclass,v 1.11 2010/04/26 15:07:58 a3li Exp $
4 graaff 1.1 #
5     # @ECLASS: ruby-ng.eclass
6     # @MAINTAINER:
7     # Ruby herd <ruby@gentoo.org>
8     #
9     # Author: Diego E. Pettenò <flameeyes@gentoo.org>
10     #
11     # Author: Alex Legler <a3li@gentoo.org>
12     #
13     # Author: Hans de Graaff <graaff@gentoo.org>
14     #
15     # @BLURB: An eclass for installing Ruby packages with proper support for multiple Ruby slots.
16     # @DESCRIPTION:
17     # The Ruby eclass is designed to allow an easier installation of Ruby packages
18     # and their incorporation into the Gentoo Linux system.
19     #
20     # Currently available targets are:
21     # * ruby18 - Ruby (MRI) 1.8.x
22     # * ruby19 - Ruby (MRI) 1.9.x
23     # * ree18 - Ruby Enterprise Edition 1.8.x
24     # * jruby - JRuby
25     #
26     # This eclass does not define the implementation of the configure,
27     # compile, test, or install phases. Instead, the default phases are
28     # used. Specific implementations of these phases can be provided in
29     # the ebuild either to be run for each Ruby implementation, or for all
30     # Ruby implementations, as follows:
31     #
32     # * each_ruby_configure
33     # * all_ruby_configure
34    
35     # @ECLASS-VARIABLE: USE_RUBY
36     # @DESCRIPTION:
37     # This variable contains a space separated list of targets (see above) a package
38     # is compatible to. It must be set before the `inherit' call. There is no
39     # default. All ebuilds are expected to set this variable.
40    
41     # @ECLASS-VARIABLE: RUBY_PATCHES
42     # @DESCRIPTION:
43     # A String or Array of filenames of patches to apply to all implementations.
44    
45     # @ECLASS-VARIABLE: RUBY_OPTIONAL
46     # @DESCRIPTION:
47     # Set the value to "yes" to make the dependency on a Ruby interpreter optional.
48    
49     inherit eutils toolchain-funcs
50    
51     EXPORT_FUNCTIONS src_unpack src_prepare src_configure src_compile src_test src_install pkg_setup
52    
53     case ${EAPI} in
54     0|1)
55     die "Unsupported EAPI=${EAPI} (too old) for ruby-ng.eclass" ;;
56     2) ;;
57     *)
58     die "Unknown EAPI=${EAPI} for ruby-ng.eclass"
59     esac
60    
61     # @FUNCTION: ruby_implementation_depend
62     # @USAGE: target [comparator [version]]
63     # @RETURN: Package atom of a Ruby implementation to be used in dependencies.
64     # @DESCRIPTION:
65     # This function returns the formal package atom for a Ruby implementation.
66     #
67     # `target' has to be one of the valid values for USE_RUBY (see above)
68     #
69     # Set `comparator' and `version' to include a comparator (=, >=, etc.) and a
70     # version string to the returned string
71     ruby_implementation_depend() {
72     local rubypn=
73     local rubyslot=
74    
75     case $1 in
76     ruby18)
77     rubypn="dev-lang/ruby"
78     rubyslot=":1.8"
79     ;;
80     ruby19)
81     rubypn="dev-lang/ruby"
82     rubyslot=":1.9"
83     ;;
84     ree18)
85     rubypn="dev-lang/ruby-enterprise"
86     rubyslot=":1.8"
87     ;;
88     jruby)
89     rubypn="dev-java/jruby"
90     rubyslot=""
91     ;;
92     *) die "$1: unknown Ruby implementation"
93     esac
94    
95     echo "$2${rubypn}$3${rubyslot}"
96     }
97    
98     # @FUNCTION: ruby_samelib
99     # @RETURN: use flag string with current ruby implementations
100     # @DESCRIPTION:
101     # Convenience function to output the use dependency part of a
102     # dependency. Used as a building block for ruby_add_rdepend() and
103     # ruby_add_bdepend(), but may also be useful in an ebuild to specify
104     # more complex dependencies.
105     ruby_samelib() {
106     local res=
107     for _ruby_implementation in $USE_RUBY; do
108     has -${_ruby_implementation} $@ || \
109     res="${res}ruby_targets_${_ruby_implementation}?,"
110     done
111    
112     echo "[${res%,}]"
113     }
114    
115     _ruby_implementation_depend() {
116     echo "ruby_targets_${1}? ( ${2}[ruby_targets_${1}] )"
117     }
118    
119     _ruby_add_bdepend() {
120     local atom=$1
121     local conditions=$2
122    
123     for condition in $conditions; do
124 flameeyes 1.8 hasq $condition "$IUSE" || IUSE="${IUSE} $condition"
125 graaff 1.1 atom="${condition}? ( ${atom} )"
126     done
127    
128     DEPEND="${DEPEND} ${atom}"
129     RDEPEND="${RDEPEND}"
130     }
131    
132     _ruby_add_rdepend() {
133     local atom=$1
134     local conditions=$2
135    
136     for condition in $conditions; do
137 flameeyes 1.8 hasq $condition "$IUSE" || IUSE="${IUSE} $condition"
138 graaff 1.1 atom="${condition}? ( ${atom} )"
139     done
140    
141     RDEPEND="${RDEPEND} ${atom}"
142     _ruby_add_bdepend "$atom" test
143     }
144    
145     # @FUNCTION: ruby_add_rdepend
146     # @USAGE: [conditions] atom
147     # @DESCRIPTION:
148     # Adds the specified atom(s) with optional use condition(s) to
149     # RDEPEND, taking the current set of ruby targets into account. This
150     # makes sure that all ruby dependencies of the package are installed
151     # for the same ruby targets. Use this function for all ruby
152     # dependencies instead of setting RDEPEND yourself. Both atom and
153     # conditions can be a space-separated list of atoms or conditions.
154     ruby_add_rdepend() {
155     local atoms=
156     local conditions=
157     case $# in
158     1)
159     atoms=$1
160     ;;
161     2)
162     conditions=$1
163     atoms=$2
164     ;;
165     *)
166     die "bad number of arguments to $0"
167     ;;
168     esac
169    
170     for atom in $atoms; do
171     _ruby_add_rdepend "${atom}$(ruby_samelib)" "$conditions"
172     done
173     }
174    
175     # @FUNCTION: ruby_add_bdepend
176     # @USAGE: [conditions] atom
177     # @DESCRIPTION:
178     # Adds the specified atom(s) with optional use condition(s) to both
179     # DEPEND and RDEPEND, taking the current set of ruby targets into
180     # account. This makes sure that all ruby dependencies of the package
181     # are installed for the same ruby targets. Use this function for all
182     # ruby dependencies instead of setting DEPEND and RDEPEND
183     # yourself. Both atom and conditions can be a space-separated list of
184     # atoms or conditions.
185     ruby_add_bdepend() {
186     local atoms=
187     local conditions=
188     case $# in
189     1)
190     atoms=$1
191     ;;
192     2)
193     conditions=$1
194     atoms=$2
195     ;;
196     *)
197     die "bad number of arguments to $0"
198     ;;
199     esac
200    
201     for atom in $atoms; do
202     _ruby_add_bdepend "${atom}$(ruby_samelib)" "$conditions"
203     done
204     }
205    
206     for _ruby_implementation in $USE_RUBY; do
207     IUSE="${IUSE} ruby_targets_${_ruby_implementation}"
208    
209     # If you specify RUBY_OPTIONAL you also need to take care of
210     # ruby useflag and dependency.
211     if [[ ${RUBY_OPTIONAL} != "yes" ]]; then
212     DEPEND="${DEPEND} ruby_targets_${_ruby_implementation}? ( $(ruby_implementation_depend $_ruby_implementation) )"
213     RDEPEND="${RDEPEND} ruby_targets_${_ruby_implementation}? ( $(ruby_implementation_depend $_ruby_implementation) )"
214     fi
215     done
216    
217     _ruby_invoke_environment() {
218     old_S=${S}
219 flameeyes 1.12 sub_S=${S#${WORKDIR}/}
220    
221     # Special case, for the always-lovely GitHub fetches. With this,
222     # we allow the star glob to just expand to whatever directory it's
223     # called.
224     if [[ ${sub_S} = *"*" ]]; then
225     pushd "${WORKDIR}"/all &>/dev/null
226     sub_S=$(eval ls -d ${sub_S})
227     popd &>/dev/null
228     fi
229 graaff 1.1
230     environment=$1; shift
231    
232     my_WORKDIR="${WORKDIR}"/${environment}
233     S="${my_WORKDIR}"/"${sub_S}"
234    
235     if [[ -d "${S}" ]]; then
236     pushd "$S" &>/dev/null
237     elif [[ -d "${my_WORKDIR}" ]]; then
238     pushd "${my_WORKDIR}" &>/dev/null
239     else
240     pushd "${WORKDIR}" &>/dev/null
241     fi
242    
243     ebegin "Running ${_PHASE:-${EBUILD_PHASE}} phase for $environment"
244     "$@"
245     popd &>/dev/null
246    
247     S=${old_S}
248     }
249    
250     _ruby_each_implementation() {
251     local invoked=no
252     for _ruby_implementation in ${USE_RUBY}; do
253     # only proceed if it's requested
254     use ruby_targets_${_ruby_implementation} || continue
255    
256 a3li 1.9 local _ruby_name=$_ruby_implementation
257    
258     # Add all USE_RUBY values where the flag name diverts from the binary here
259     case $_ruby_implementation in
260     ree18)
261     _ruby_name=rubyee18
262     ;;
263     esac
264    
265     RUBY=$(type -p $_ruby_name 2>/dev/null)
266 graaff 1.1 invoked=yes
267    
268     if [[ -n "$1" ]]; then
269     _ruby_invoke_environment $_ruby_implementation "$@"
270     fi
271    
272     unset RUBY
273     done
274    
275     [[ ${invoked} == "no" ]] && die "You need to select at least one Ruby implementation by setting RUBY_TARGETS in /etc/make.conf."
276     }
277    
278     # @FUNCTION: ruby-ng_pkg_setup
279     # @DESCRIPTION:
280     # Check whether at least one ruby target implementation is present.
281     ruby-ng_pkg_setup() {
282     # This only checks that at least one implementation is present
283     # before doing anything; by leaving the parameters empty we know
284     # it's a special case.
285     _ruby_each_implementation
286     }
287    
288     # @FUNCTION: ruby-ng_src_unpack
289     # @DESCRIPTION:
290 graaff 1.5 # Unpack the source archive.
291 graaff 1.1 ruby-ng_src_unpack() {
292     mkdir "${WORKDIR}"/all
293     pushd "${WORKDIR}"/all &>/dev/null
294    
295     # We don't support an each-unpack, it's either all or nothing!
296     if type all_ruby_unpack &>/dev/null; then
297     _ruby_invoke_environment all all_ruby_unpack
298     else
299     [[ -n ${A} ]] && unpack ${A}
300     fi
301    
302     popd &>/dev/null
303     }
304    
305     _ruby_apply_patches() {
306     for patch in "${RUBY_PATCHES[@]}"; do
307     if [ -f "${patch}" ]; then
308     epatch "${patch}"
309     elif [ -f "${FILESDIR}/${patch}" ]; then
310     epatch "${FILESDIR}/${patch}"
311     else
312     die "Cannot find patch ${patch}"
313     fi
314     done
315    
316     # This is a special case: instead of executing just in the special
317     # "all" environment, this will actually copy the effects on _all_
318     # the other environments, and is thus executed before the copy
319     type all_ruby_prepare &>/dev/null && all_ruby_prepare
320     }
321    
322     _ruby_source_copy() {
323     # Until we actually find a reason not to, we use hardlinks, this
324     # should reduce the amount of disk space that is wasted by this.
325     cp -prl all ${_ruby_implementation} \
326     || die "Unable to copy ${_ruby_implementation} environment"
327     }
328    
329     # @FUNCTION: ruby-ng_src_prepare
330     # @DESCRIPTION:
331     # Apply patches and prepare versions for each ruby target
332     # implementation. Also carry out common clean up tasks.
333     ruby-ng_src_prepare() {
334     # Way too many Ruby packages are prepared on OSX without removing
335     # the extra data forks, we do it here to avoid repeating it for
336     # almost every other ebuild.
337     find . -name '._*' -delete
338    
339     _ruby_invoke_environment all _ruby_apply_patches
340    
341 flameeyes 1.7 _PHASE="source copy" \
342     _ruby_each_implementation _ruby_source_copy
343 graaff 1.1
344     if type each_ruby_prepare &>/dev/null; then
345     _ruby_each_implementation each_ruby_prepare
346     fi
347     }
348    
349     # @FUNCTION: ruby-ng_src_configure
350     # @DESCRIPTION:
351     # Configure the package.
352     ruby-ng_src_configure() {
353     if type each_ruby_configure &>/dev/null; then
354     _ruby_each_implementation each_ruby_configure
355     fi
356    
357     type all_ruby_configure &>/dev/null && \
358     _ruby_invoke_environment all all_ruby_configure
359     }
360    
361     # @FUNCTION: ruby-ng_src_compile
362     # @DESCRIPTION:
363     # Compile the package.
364     ruby-ng_src_compile() {
365     if type each_ruby_compile &>/dev/null; then
366     _ruby_each_implementation each_ruby_compile
367     fi
368    
369     type all_ruby_compile &>/dev/null && \
370     _ruby_invoke_environment all all_ruby_compile
371     }
372    
373     # @FUNCTION: ruby-ng_src_test
374     # @DESCRIPTION:
375     # Run tests for the package.
376     ruby-ng_src_test() {
377     if type each_ruby_test &>/dev/null; then
378     _ruby_each_implementation each_ruby_test
379     fi
380    
381     type all_ruby_test &>/dev/null && \
382     _ruby_invoke_environment all all_ruby_test
383     }
384    
385     _each_ruby_check_install() {
386     local libruby_basename=$(${RUBY} -rrbconfig -e 'puts Config::CONFIG["LIBRUBY_SO"]')
387     local libruby_soname=$(scanelf -qS "/usr/$(get_libdir)/${libruby_basename}" | awk '{ print $1 }')
388 flameeyes 1.2 local sitedir=$(${RUBY} -rrbconfig -e 'puts Config::CONFIG["sitedir"]')
389     local sitelibdir=$(${RUBY} -rrbconfig -e 'puts Config::CONFIG["sitelibdir"]')
390    
391     # Look for wrong files in sitedir
392     if [[ -d "${D}${sitedir}" ]]; then
393     local f=$(find "${D}${sitedir}" -mindepth 1 -maxdepth 1 -not -wholename "${D}${sitelibdir}")
394     if [[ -n ${f} ]]; then
395     eerror "Found files in sitedir, outsite sitelibdir:"
396     eerror "${f}"
397     die "Misplaced files in sitedir"
398     fi
399     fi
400 graaff 1.1
401     # The current implementation lacks libruby (i.e.: jruby)
402     [[ -z ${libruby_soname} ]] && return 0
403    
404 flameeyes 1.3 scanelf -qnR "${D}${sitedir}" \
405 graaff 1.1 | fgrep -v "${libruby_soname}" \
406     > "${T}"/ruby-ng-${_ruby_implementation}-mislink.log
407    
408     if [[ -s "${T}"/ruby-ng-${_ruby_implementation}-mislink.log ]]; then
409     ewarn "Extensions installed for ${_ruby_implementation} with missing links to ${libruby}"
410     ewarn $(< "${T}"/ruby-ng-${_ruby_implementation}-mislink.log )
411     die "Missing links to ${libruby}"
412     fi
413     }
414    
415     # @FUNCTION: ruby-ng_src_install
416     # @DESCRIPTION:
417     # Install the package for each ruby target implementation.
418     ruby-ng_src_install() {
419     if type each_ruby_install &>/dev/null; then
420     _ruby_each_implementation each_ruby_install
421     fi
422    
423     type all_ruby_install &>/dev/null && \
424     _ruby_invoke_environment all all_ruby_install
425    
426     _PHASE="check install" \
427     _ruby_each_implementation _each_ruby_check_install
428     }
429    
430 a3li 1.11 # @FUNCTION: ruby_rbconfig_value
431     # @USAGE: rbconfig item
432     # @RETURN: Returns the value of the given rbconfig item of the Ruby interpreter in ${RUBY}.
433     ruby_rbconfig_value() {
434     echo $(${RUBY} -rrbconfig -e "puts Config::CONFIG['$1']")
435     }
436    
437 graaff 1.1 # @FUNCTION: doruby
438     # @USAGE: file [file...]
439     # @DESCRIPTION:
440     # Installs the specified file(s) into the sitelibdir of the Ruby interpreter in ${RUBY}.
441     doruby() {
442 flameeyes 1.4 [[ -z ${RUBY} ]] && die "\$RUBY is not set"
443 graaff 1.1 ( # don't want to pollute calling env
444 a3li 1.11 insinto $(ruby_rbconfig_value 'sitelibdir')
445 graaff 1.1 insopts -m 0644
446     doins "$@"
447     ) || die "failed to install $@"
448     }
449    
450     # @FUNCTION: ruby_get_libruby
451     # @RETURN: The location of libruby*.so belonging to the Ruby interpreter in ${RUBY}.
452     ruby_get_libruby() {
453     ${RUBY} -rrbconfig -e 'puts File.join(Config::CONFIG["libdir"], Config::CONFIG["LIBRUBY"])'
454     }
455    
456     # @FUNCTION: ruby_get_hdrdir
457     # @RETURN: The location of the header files belonging to the Ruby interpreter in ${RUBY}.
458     ruby_get_hdrdir() {
459 a3li 1.11 local rubyhdrdir=$(ruby_rbconfig_value 'rubyhdrdir')
460 graaff 1.1
461     if [[ "${rubyhdrdir}" = "nil" ]] ; then
462 a3li 1.11 rubyhdrdir=$(ruby_rbconfig_value 'archdir')
463 graaff 1.1 fi
464    
465     echo "${rubyhdrdir}"
466     }
467 a3li 1.10
468     # @FUNCTION: ruby_get_version
469     # @RETURN: The version of the Ruby interpreter in ${RUBY}, or what 'ruby' points to.
470     ruby_get_version() {
471     local ruby=${RUBY:-$(type -p ruby 2>/dev/null)}
472    
473     echo $(${ruby} -e 'puts RUBY_VERSION')
474     }
475    
476     # @FUNCTION: ruby_get_implementation
477     # @RETURN: The implementation of the Ruby interpreter in ${RUBY}, or what 'ruby' points to.
478     ruby_get_implementation() {
479     local ruby=${RUBY:-$(type -p ruby 2>/dev/null)}
480    
481     case $(${ruby} --version) in
482     *Enterprise*)
483     echo "ree"
484     ;;
485     *jruby*)
486     echo "jruby"
487     ;;
488     *)
489     echo "mri"
490     ;;
491     esac
492     }

  ViewVC Help
Powered by ViewVC 1.1.20