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

Contents of /eclass/ruby-ng.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.12 - (show annotations) (download)
Fri Apr 30 17:40:10 2010 UTC (4 years, 4 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 # 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.11 2010/04/26 15:07:58 a3li 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_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 hasq $condition "$IUSE" || IUSE="${IUSE} $condition"
125 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 hasq $condition "$IUSE" || IUSE="${IUSE} $condition"
138 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 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
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 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 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 # Unpack the source archive.
291 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 _PHASE="source copy" \
342 _ruby_each_implementation _ruby_source_copy
343
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 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
401 # The current implementation lacks libruby (i.e.: jruby)
402 [[ -z ${libruby_soname} ]] && return 0
403
404 scanelf -qnR "${D}${sitedir}" \
405 | 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 # @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 # @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 [[ -z ${RUBY} ]] && die "\$RUBY is not set"
443 ( # don't want to pollute calling env
444 insinto $(ruby_rbconfig_value 'sitelibdir')
445 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 local rubyhdrdir=$(ruby_rbconfig_value 'rubyhdrdir')
460
461 if [[ "${rubyhdrdir}" = "nil" ]] ; then
462 rubyhdrdir=$(ruby_rbconfig_value 'archdir')
463 fi
464
465 echo "${rubyhdrdir}"
466 }
467
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