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

Contents of /eclass/ruby-ng.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.27 - (show annotations) (download)
Mon Aug 30 22:08:24 2010 UTC (3 years, 10 months ago) by flameeyes
Branch: MAIN
Changes since 1.26: +22 -12 lines
Factor out the ree18→rubyee18 conversion and use it when generating the binwrapper (closes bug #335328).

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

  ViewVC Help
Powered by ViewVC 1.1.20