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

Contents of /eclass/ruby-ng.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.23 - (hide annotations) (download)
Fri Jul 30 15:05:08 2010 UTC (4 years, 1 month ago) by flameeyes
Branch: MAIN
Changes since 1.22: +7 -3 lines
Fix broken test for mislink with the new Ruby 1.9.2 ebuilds.

With 1.9.2 the sitedir is now the same between 1.8 and 1.9, so you
cannot just go look for all the extensions within that or you'll hit
the one for the other implementation as well. Instead use the
sitelibdir that encodes the version as well.

While at it, extend the test to the Gems-installed extensions, and
remove an awk call by using the --format option of scanelf.

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.23 # $Header: /var/cvsroot/gentoo-x86/eclass/ruby-ng.eclass,v 1.22 2010/07/14 13:11:51 flameeyes 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 flameeyes 1.17 _ruby_atoms_samelib_generic() {
116 flameeyes 1.18 eshopts_push -o noglob
117 flameeyes 1.17 echo "RUBYTARGET? ("
118 flameeyes 1.14 for token in $*; do
119     case "$token" in
120 flameeyes 1.16 "||" | "(" | ")" | *"?")
121 flameeyes 1.14 echo "${token}" ;;
122 flameeyes 1.21 *])
123     echo "${token%[*}[RUBYTARGET,${token/*[}" ;;
124 flameeyes 1.14 *)
125 flameeyes 1.17 echo "${token}[RUBYTARGET]" ;;
126 flameeyes 1.14 esac
127     done
128 flameeyes 1.17 echo ")"
129 flameeyes 1.18 eshopts_pop
130 flameeyes 1.17 }
131    
132     _ruby_atoms_samelib() {
133     local atoms=$(_ruby_atoms_samelib_generic "$*")
134    
135     for _ruby_implementation in $USE_RUBY; do
136     echo "${atoms//RUBYTARGET/ruby_targets_${_ruby_implementation}}"
137     done
138 flameeyes 1.14 }
139    
140 flameeyes 1.16 _ruby_wrap_conditions() {
141     local conditions="$1"
142     local atoms="$2"
143    
144     for condition in $conditions; do
145     atoms="${condition}? ( ${atoms} )"
146     done
147    
148     echo "$atoms"
149     }
150    
151 graaff 1.1 # @FUNCTION: ruby_add_rdepend
152 flameeyes 1.16 # @USAGE: dependencies
153 graaff 1.1 # @DESCRIPTION:
154 flameeyes 1.16 # Adds the specified dependencies, with use condition(s) to RDEPEND,
155     # taking the current set of ruby targets into account. This makes sure
156     # that all ruby dependencies of the package are installed for the same
157     # ruby targets. Use this function for all ruby dependencies instead of
158     # setting RDEPEND yourself. The list of atoms uses the same syntax as
159     # normal dependencies.
160     #
161     # Note: runtime dependencies are also added as build-time test
162     # dependencies.
163 graaff 1.1 ruby_add_rdepend() {
164     case $# in
165 flameeyes 1.16 1) ;;
166 graaff 1.1 2)
167 flameeyes 1.16 [[ "${GENTOO_DEV}" == "yes" ]] && eqawarn "You can now use the usual syntax in ruby_add_rdepend for $CATEGORY/$PF"
168     ruby_add_rdepend "$(_ruby_wrap_conditions "$1" "$2")"
169     return
170 graaff 1.1 ;;
171     *)
172     die "bad number of arguments to $0"
173     ;;
174     esac
175    
176 flameeyes 1.16 local dependency=$(_ruby_atoms_samelib "$1")
177    
178     RDEPEND="${RDEPEND} $dependency"
179    
180     # Add the dependency as a test-dependency since we're going to
181     # execute the code during test phase.
182 flameeyes 1.20 DEPEND="${DEPEND} test? ( ${dependency} )"
183     hasq test "$IUSE" || IUSE="${IUSE} test"
184 graaff 1.1 }
185    
186     # @FUNCTION: ruby_add_bdepend
187 flameeyes 1.16 # @USAGE: dependencies
188 graaff 1.1 # @DESCRIPTION:
189 flameeyes 1.16 # Adds the specified dependencies, with use condition(s) to DEPEND,
190     # taking the current set of ruby targets into account. This makes sure
191     # that all ruby dependencies of the package are installed for the same
192     # ruby targets. Use this function for all ruby dependencies instead of
193     # setting DEPEND yourself. The list of atoms uses the same syntax as
194     # normal dependencies.
195 graaff 1.1 ruby_add_bdepend() {
196     case $# in
197 flameeyes 1.16 1) ;;
198 graaff 1.1 2)
199 flameeyes 1.16 [[ "${GENTOO_DEV}" == "yes" ]] && eqawarn "You can now use the usual syntax in ruby_add_bdepend for $CATEGORY/$PF"
200     ruby_add_bdepend "$(_ruby_wrap_conditions "$1" "$2")"
201     return
202 graaff 1.1 ;;
203     *)
204     die "bad number of arguments to $0"
205     ;;
206     esac
207    
208 flameeyes 1.16 local dependency=$(_ruby_atoms_samelib "$1")
209    
210     DEPEND="${DEPEND} $dependency"
211 flameeyes 1.19 RDEPEND="${RDEPEND}"
212 graaff 1.1 }
213    
214     for _ruby_implementation in $USE_RUBY; do
215     IUSE="${IUSE} ruby_targets_${_ruby_implementation}"
216    
217     # If you specify RUBY_OPTIONAL you also need to take care of
218     # ruby useflag and dependency.
219     if [[ ${RUBY_OPTIONAL} != "yes" ]]; then
220     DEPEND="${DEPEND} ruby_targets_${_ruby_implementation}? ( $(ruby_implementation_depend $_ruby_implementation) )"
221     RDEPEND="${RDEPEND} ruby_targets_${_ruby_implementation}? ( $(ruby_implementation_depend $_ruby_implementation) )"
222     fi
223     done
224    
225     _ruby_invoke_environment() {
226     old_S=${S}
227 flameeyes 1.12 sub_S=${S#${WORKDIR}/}
228    
229     # Special case, for the always-lovely GitHub fetches. With this,
230     # we allow the star glob to just expand to whatever directory it's
231     # called.
232     if [[ ${sub_S} = *"*" ]]; then
233     pushd "${WORKDIR}"/all &>/dev/null
234 flameeyes 1.13 sub_S=$(eval ls -d ${sub_S} 2>/dev/null)
235 flameeyes 1.12 popd &>/dev/null
236     fi
237 graaff 1.1
238     environment=$1; shift
239    
240     my_WORKDIR="${WORKDIR}"/${environment}
241     S="${my_WORKDIR}"/"${sub_S}"
242    
243     if [[ -d "${S}" ]]; then
244     pushd "$S" &>/dev/null
245     elif [[ -d "${my_WORKDIR}" ]]; then
246     pushd "${my_WORKDIR}" &>/dev/null
247     else
248     pushd "${WORKDIR}" &>/dev/null
249     fi
250    
251     ebegin "Running ${_PHASE:-${EBUILD_PHASE}} phase for $environment"
252     "$@"
253     popd &>/dev/null
254    
255     S=${old_S}
256     }
257    
258     _ruby_each_implementation() {
259     local invoked=no
260     for _ruby_implementation in ${USE_RUBY}; do
261     # only proceed if it's requested
262     use ruby_targets_${_ruby_implementation} || continue
263    
264 a3li 1.9 local _ruby_name=$_ruby_implementation
265    
266     # Add all USE_RUBY values where the flag name diverts from the binary here
267     case $_ruby_implementation in
268     ree18)
269     _ruby_name=rubyee18
270     ;;
271     esac
272    
273     RUBY=$(type -p $_ruby_name 2>/dev/null)
274 graaff 1.1 invoked=yes
275    
276     if [[ -n "$1" ]]; then
277     _ruby_invoke_environment $_ruby_implementation "$@"
278     fi
279    
280     unset RUBY
281     done
282    
283     [[ ${invoked} == "no" ]] && die "You need to select at least one Ruby implementation by setting RUBY_TARGETS in /etc/make.conf."
284     }
285    
286     # @FUNCTION: ruby-ng_pkg_setup
287     # @DESCRIPTION:
288     # Check whether at least one ruby target implementation is present.
289     ruby-ng_pkg_setup() {
290     # This only checks that at least one implementation is present
291     # before doing anything; by leaving the parameters empty we know
292     # it's a special case.
293     _ruby_each_implementation
294     }
295    
296     # @FUNCTION: ruby-ng_src_unpack
297     # @DESCRIPTION:
298 graaff 1.5 # Unpack the source archive.
299 graaff 1.1 ruby-ng_src_unpack() {
300     mkdir "${WORKDIR}"/all
301     pushd "${WORKDIR}"/all &>/dev/null
302    
303     # We don't support an each-unpack, it's either all or nothing!
304     if type all_ruby_unpack &>/dev/null; then
305     _ruby_invoke_environment all all_ruby_unpack
306     else
307     [[ -n ${A} ]] && unpack ${A}
308     fi
309    
310     popd &>/dev/null
311     }
312    
313     _ruby_apply_patches() {
314     for patch in "${RUBY_PATCHES[@]}"; do
315     if [ -f "${patch}" ]; then
316     epatch "${patch}"
317     elif [ -f "${FILESDIR}/${patch}" ]; then
318     epatch "${FILESDIR}/${patch}"
319     else
320     die "Cannot find patch ${patch}"
321     fi
322     done
323    
324     # This is a special case: instead of executing just in the special
325     # "all" environment, this will actually copy the effects on _all_
326     # the other environments, and is thus executed before the copy
327     type all_ruby_prepare &>/dev/null && all_ruby_prepare
328     }
329    
330     _ruby_source_copy() {
331     # Until we actually find a reason not to, we use hardlinks, this
332     # should reduce the amount of disk space that is wasted by this.
333     cp -prl all ${_ruby_implementation} \
334     || die "Unable to copy ${_ruby_implementation} environment"
335     }
336    
337     # @FUNCTION: ruby-ng_src_prepare
338     # @DESCRIPTION:
339     # Apply patches and prepare versions for each ruby target
340     # implementation. Also carry out common clean up tasks.
341     ruby-ng_src_prepare() {
342     # Way too many Ruby packages are prepared on OSX without removing
343     # the extra data forks, we do it here to avoid repeating it for
344     # almost every other ebuild.
345     find . -name '._*' -delete
346    
347     _ruby_invoke_environment all _ruby_apply_patches
348    
349 flameeyes 1.7 _PHASE="source copy" \
350     _ruby_each_implementation _ruby_source_copy
351 graaff 1.1
352     if type each_ruby_prepare &>/dev/null; then
353     _ruby_each_implementation each_ruby_prepare
354     fi
355     }
356    
357     # @FUNCTION: ruby-ng_src_configure
358     # @DESCRIPTION:
359     # Configure the package.
360     ruby-ng_src_configure() {
361     if type each_ruby_configure &>/dev/null; then
362     _ruby_each_implementation each_ruby_configure
363     fi
364    
365     type all_ruby_configure &>/dev/null && \
366     _ruby_invoke_environment all all_ruby_configure
367     }
368    
369     # @FUNCTION: ruby-ng_src_compile
370     # @DESCRIPTION:
371     # Compile the package.
372     ruby-ng_src_compile() {
373     if type each_ruby_compile &>/dev/null; then
374     _ruby_each_implementation each_ruby_compile
375     fi
376    
377     type all_ruby_compile &>/dev/null && \
378     _ruby_invoke_environment all all_ruby_compile
379     }
380    
381     # @FUNCTION: ruby-ng_src_test
382     # @DESCRIPTION:
383     # Run tests for the package.
384     ruby-ng_src_test() {
385     if type each_ruby_test &>/dev/null; then
386     _ruby_each_implementation each_ruby_test
387     fi
388    
389     type all_ruby_test &>/dev/null && \
390     _ruby_invoke_environment all all_ruby_test
391     }
392    
393     _each_ruby_check_install() {
394     local libruby_basename=$(${RUBY} -rrbconfig -e 'puts Config::CONFIG["LIBRUBY_SO"]')
395 flameeyes 1.23 local libruby_soname=$(scanelf -F "%S#F" -qS "/usr/$(get_libdir)/${libruby_basename}")
396 flameeyes 1.2 local sitedir=$(${RUBY} -rrbconfig -e 'puts Config::CONFIG["sitedir"]')
397     local sitelibdir=$(${RUBY} -rrbconfig -e 'puts Config::CONFIG["sitelibdir"]')
398    
399     # Look for wrong files in sitedir
400 flameeyes 1.22 # if [[ -d "${D}${sitedir}" ]]; then
401     # local f=$(find "${D}${sitedir}" -mindepth 1 -maxdepth 1 -not -wholename "${D}${sitelibdir}")
402     # if [[ -n ${f} ]]; then
403     # eerror "Found files in sitedir, outsite sitelibdir:"
404     # eerror "${f}"
405     # die "Misplaced files in sitedir"
406     # fi
407     # fi
408 graaff 1.1
409     # The current implementation lacks libruby (i.e.: jruby)
410     [[ -z ${libruby_soname} ]] && return 0
411    
412 flameeyes 1.23 # Check also the gems directory, since we could be installing compiled
413     # extensions via ruby-fakegem; make sure to check only in sitelibdir, since
414     # that's what changes between two implementations (otherwise you'd get false
415     # positives now that Ruby 1.9.2 installs with the same sitedir as 1.8)
416     scanelf -qnR "${D}${sitelibdir}" "${D}${sitelibdir/site_ruby/gems}" \
417 graaff 1.1 | fgrep -v "${libruby_soname}" \
418     > "${T}"/ruby-ng-${_ruby_implementation}-mislink.log
419    
420     if [[ -s "${T}"/ruby-ng-${_ruby_implementation}-mislink.log ]]; then
421 flameeyes 1.15 ewarn "Extensions installed for ${_ruby_implementation} with missing links to ${libruby_soname}"
422 graaff 1.1 ewarn $(< "${T}"/ruby-ng-${_ruby_implementation}-mislink.log )
423 flameeyes 1.15 die "Missing links to ${libruby_soname}"
424 graaff 1.1 fi
425     }
426    
427     # @FUNCTION: ruby-ng_src_install
428     # @DESCRIPTION:
429     # Install the package for each ruby target implementation.
430     ruby-ng_src_install() {
431     if type each_ruby_install &>/dev/null; then
432     _ruby_each_implementation each_ruby_install
433     fi
434    
435     type all_ruby_install &>/dev/null && \
436     _ruby_invoke_environment all all_ruby_install
437    
438     _PHASE="check install" \
439     _ruby_each_implementation _each_ruby_check_install
440     }
441    
442 a3li 1.11 # @FUNCTION: ruby_rbconfig_value
443     # @USAGE: rbconfig item
444     # @RETURN: Returns the value of the given rbconfig item of the Ruby interpreter in ${RUBY}.
445     ruby_rbconfig_value() {
446     echo $(${RUBY} -rrbconfig -e "puts Config::CONFIG['$1']")
447     }
448    
449 graaff 1.1 # @FUNCTION: doruby
450     # @USAGE: file [file...]
451     # @DESCRIPTION:
452     # Installs the specified file(s) into the sitelibdir of the Ruby interpreter in ${RUBY}.
453     doruby() {
454 flameeyes 1.4 [[ -z ${RUBY} ]] && die "\$RUBY is not set"
455 graaff 1.1 ( # don't want to pollute calling env
456 a3li 1.11 insinto $(ruby_rbconfig_value 'sitelibdir')
457 graaff 1.1 insopts -m 0644
458     doins "$@"
459     ) || die "failed to install $@"
460     }
461    
462     # @FUNCTION: ruby_get_libruby
463     # @RETURN: The location of libruby*.so belonging to the Ruby interpreter in ${RUBY}.
464     ruby_get_libruby() {
465     ${RUBY} -rrbconfig -e 'puts File.join(Config::CONFIG["libdir"], Config::CONFIG["LIBRUBY"])'
466     }
467    
468     # @FUNCTION: ruby_get_hdrdir
469     # @RETURN: The location of the header files belonging to the Ruby interpreter in ${RUBY}.
470     ruby_get_hdrdir() {
471 a3li 1.11 local rubyhdrdir=$(ruby_rbconfig_value 'rubyhdrdir')
472 graaff 1.1
473     if [[ "${rubyhdrdir}" = "nil" ]] ; then
474 a3li 1.11 rubyhdrdir=$(ruby_rbconfig_value 'archdir')
475 graaff 1.1 fi
476    
477     echo "${rubyhdrdir}"
478     }
479 a3li 1.10
480     # @FUNCTION: ruby_get_version
481     # @RETURN: The version of the Ruby interpreter in ${RUBY}, or what 'ruby' points to.
482     ruby_get_version() {
483     local ruby=${RUBY:-$(type -p ruby 2>/dev/null)}
484    
485     echo $(${ruby} -e 'puts RUBY_VERSION')
486     }
487    
488     # @FUNCTION: ruby_get_implementation
489     # @RETURN: The implementation of the Ruby interpreter in ${RUBY}, or what 'ruby' points to.
490     ruby_get_implementation() {
491     local ruby=${RUBY:-$(type -p ruby 2>/dev/null)}
492    
493     case $(${ruby} --version) in
494     *Enterprise*)
495     echo "ree"
496     ;;
497     *jruby*)
498     echo "jruby"
499     ;;
500     *)
501     echo "mri"
502     ;;
503     esac
504     }

  ViewVC Help
Powered by ViewVC 1.1.20