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

Contents of /eclass/ruby-ng.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.23 - (show annotations) (download)
Fri Jul 30 15:05:08 2010 UTC (4 years, 3 months 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 # 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.22 2010/07/14 13:11:51 flameeyes 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 # @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_atoms_samelib_generic() {
116 eshopts_push -o noglob
117 echo "RUBYTARGET? ("
118 for token in $*; do
119 case "$token" in
120 "||" | "(" | ")" | *"?")
121 echo "${token}" ;;
122 *])
123 echo "${token%[*}[RUBYTARGET,${token/*[}" ;;
124 *)
125 echo "${token}[RUBYTARGET]" ;;
126 esac
127 done
128 echo ")"
129 eshopts_pop
130 }
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 }
139
140 _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 # @FUNCTION: ruby_add_rdepend
152 # @USAGE: dependencies
153 # @DESCRIPTION:
154 # 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 ruby_add_rdepend() {
164 case $# in
165 1) ;;
166 2)
167 [[ "${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 ;;
171 *)
172 die "bad number of arguments to $0"
173 ;;
174 esac
175
176 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 DEPEND="${DEPEND} test? ( ${dependency} )"
183 hasq test "$IUSE" || IUSE="${IUSE} test"
184 }
185
186 # @FUNCTION: ruby_add_bdepend
187 # @USAGE: dependencies
188 # @DESCRIPTION:
189 # 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 ruby_add_bdepend() {
196 case $# in
197 1) ;;
198 2)
199 [[ "${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 ;;
203 *)
204 die "bad number of arguments to $0"
205 ;;
206 esac
207
208 local dependency=$(_ruby_atoms_samelib "$1")
209
210 DEPEND="${DEPEND} $dependency"
211 RDEPEND="${RDEPEND}"
212 }
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 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 sub_S=$(eval ls -d ${sub_S} 2>/dev/null)
235 popd &>/dev/null
236 fi
237
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 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 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 # Unpack the source archive.
299 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 _PHASE="source copy" \
350 _ruby_each_implementation _ruby_source_copy
351
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 local libruby_soname=$(scanelf -F "%S#F" -qS "/usr/$(get_libdir)/${libruby_basename}")
396 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 # 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
409 # The current implementation lacks libruby (i.e.: jruby)
410 [[ -z ${libruby_soname} ]] && return 0
411
412 # 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 | 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 ewarn "Extensions installed for ${_ruby_implementation} with missing links to ${libruby_soname}"
422 ewarn $(< "${T}"/ruby-ng-${_ruby_implementation}-mislink.log )
423 die "Missing links to ${libruby_soname}"
424 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 # @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 # @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 [[ -z ${RUBY} ]] && die "\$RUBY is not set"
455 ( # don't want to pollute calling env
456 insinto $(ruby_rbconfig_value 'sitelibdir')
457 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 local rubyhdrdir=$(ruby_rbconfig_value 'rubyhdrdir')
472
473 if [[ "${rubyhdrdir}" = "nil" ]] ; then
474 rubyhdrdir=$(ruby_rbconfig_value 'archdir')
475 fi
476
477 echo "${rubyhdrdir}"
478 }
479
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