################################################################################
#
# ruby.cygclass - functions for building Ruby modules
#
# Part of cygport - Cygwin packaging application
# Copyright (C) 2006-2015 Yaakov Selkowitz
# Provided by the Cygwin Ports project <http://sourceware.org/cygwinports/>
#
# cygport is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cygport is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cygport.  If not, see <http://www.gnu.org/licenses/>.
#
################################################################################

#****h* Cygclasses/ruby.cygclass
#  SYNOPSIS
#  inherit ruby
#  DESCRIPTION
#  Ruby is a general-purpose, object oriented scripting language.  Originally
#  developed in Japan and quite popular there, it has a relatively smaller but
#  growing user base in the English-speaking world.  The Ruby interpreter
#  supports extensions written in Ruby or C/C++.
#
#  This cygclass is primarily meant for building Ruby extension modules.
#  NOTE
#  Ruby C modules use the .so extension on all platforms, including Cygwin
#  where .dll is the norm.  The standard Ruby build systems will do this
#  correctly, but modules build with other build systems will usually need
#  a patch to force the use of the .so extension.  For instance, with
#  |html <a href="http://www.gnu.org/software/libtool/manual/html_node/Link-mode.html">automake and libtool</a>:
#    foo_la_LDFLAGS = -module -avoid-version -no-undefined -shrext '.so'
#  |html or with <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#prop_tgt:SUFFIX">CMake</a>:
#    set_target_properties(foo PROPERTIES PREFIX "" SUFFIX ".so")
#  INHERITED BY
#  rubygem.cygclass, ruby-gnome2.cygclass
#****

# cross-compiling is not (yet?) supported
__cross_compiling_error

check_prog_req ruby

#****d* ruby.cygclass/RUBY
#  DESCRIPTION
#  Absolute path to the Ruby interpreter.
#****
RUBY=/usr/bin/ruby

#****d* ruby.cygclass/RUBY_VERSION
#  DESCRIPTION
#  The version of the Ruby interpreter.
#  NOTE
#  Since Ruby 2.1, this changes with every point release.  For the API version
#  of Ruby, use ${RUBY_VERSION%.*}.0.
#****
RUBY_VERSION=$(${RUBY} -e 'print RUBY_VERSION')

#****d* ruby.cygclass/RUBY_LIB
#  DESCRIPTION
#  Path containing the Ruby standard library.
#  NOTE
#  Never install third-party extensions into RUBY_LIB; use RUBY_VENDORLIB instead.
#****
RUBY_LIB=$(${RUBY} -r rbconfig -e 'print RbConfig::CONFIG["rubylibdir"]')

#****d* ruby.cygclass/RUBY_ARCH
#  DESCRIPTION
#  Path containing the Ruby standard C extensions.
#  NOTE
#  Never install third-party extensions into RUBY_ARCH; use RUBY_VENDORARCH instead.
#****
RUBY_ARCH=$(${RUBY} -r rbconfig -e 'print RbConfig::CONFIG["archdir"]')

#****d* ruby.cygclass/RUBY_HEADERDIR
#  DESCRIPTION
#  Path containing the Ruby API headers.
#****
RUBY_HEADERDIR=$(${RUBY} -r rbconfig -e "print RbConfig::CONFIG['rubyhdrdir']")

# deprecated; use RUBY_VENDOR{LIB,ARCH} instead
RUBY_SITELIB=$(${RUBY} -r rbconfig -e 'print RbConfig::CONFIG["sitelibdir"]')
RUBY_SITEARCH=$(${RUBY} -r rbconfig -e 'print RbConfig::CONFIG["sitearchdir"]')

#****d* ruby.cygclass/RUBY_VENDORLIB
#  DESCRIPTION
#  Installation path for third-party Ruby libraries.
#****
RUBY_VENDORLIB=$(${RUBY} -r rbconfig -e 'print RbConfig::CONFIG["vendorlibdir"]')

#****d* ruby.cygclass/RUBY_VENDORARCH
#  DESCRIPTION
#  Installation path for third-party Ruby C extensions.
#****
RUBY_VENDORARCH=$(${RUBY} -r rbconfig -e 'print RbConfig::CONFIG["vendorarchdir"]')

#****d* ruby.cygclass/RI_SITEDIR
#  DESCRIPTION
#  Installation path for RI docs for third-party Ruby extensions.
#****
RI_SITEDIR=/usr/share/ri/${RUBY_VERSION%.*}.0/site

#****d* ruby.cygclass/LIBRUBY
#  DESCRIPTION
#  Link flags for the Ruby C library.
#****
LIBRUBY=$(${RUBY} -r rbconfig -e 'print RbConfig::CONFIG["LIBRUBYARG"]')

case ${PN} in ruby-*)
#****o* ruby.cygclass/CATEGORY (ruby)
#  DEFINITION
CATEGORY="Ruby"
#  NOTE
#  This is defined only if PN begins with "ruby-".
#****
#****o* ruby.cygclass/SUMMARY (ruby)
#  DEFINITION
SUMMARY="Ruby ${PN#ruby-} module"
#  NOTE
#  This is defined only if PN begins with "ruby-".
#****
;;
esac

#****C* ruby.cygclass/ruby_compile
#  SYNOPSIS
#  cd $B
#  ruby_compile
#  DESCRIPTION
#  Configures and builds a Ruby extension using one of the supported build
#  systems:
#  * install.rb: executes 'config' and 'setup' commands
#  * setup.rb: executes 'config' and 'setup' commands
#  * extconf.rb: calls ruby_ext_compile
#  * Rakefile: runs the 'rake' command
#  If RDOC_SOURCE is defined, RI docs are then generated.
#****
ruby_compile() {
	if [ -e install.rb ]
	then
		${RUBY} install.rb config --prefix=/usr ${@} || error "install.rb config failed"
		${RUBY} install.rb setup || error "install.rb setup failed"
	elif [ -e setup.rb ]
	then
		${RUBY} setup.rb config --prefix=/usr ${@} || error "setup.rb config failed"
		${RUBY} setup.rb setup || error "setup.rb setup failed"
	elif [ -e extconf.rb ]
	then
		ruby_ext_compile ${@}
	elif [ -e Rakefile -o -e rakefile ]
	then
		check_prog_req rake
		rake ${@} || error "rake failed"
	else
		error "No Ruby module detected"
	fi

#****v* ruby_compile/RDOC_SOURCE
#  DESCRIPTION
#  Relative path to the Ruby source files containing RDoc documentation.
#****
	if defined RDOC_SOURCE
	then
		rdoc -U --ri --op ${B}/.rdoc ${RDOC_SOURCE}
	fi
}

#****C* ruby.cygclass/ruby_ext_compile
#  SYNOPSIS
#  ruby_ext_compile [CONFIGURE_OPTIONS]
#  DESCRIPTION
#  Runs extconf.rb to configure the build and generate a Makefile,
#  followed by cygmake to compile.
#****
ruby_ext_compile() {
	if [ ! -e extconf.rb ]
	then
		error "ruby_ext_compile: extconf.rb not found"
	fi

	${RUBY} extconf.rb --vendor ${@} || error "extconf.rb configure failed"
	cygmake cflags="${CFLAGS} ${CPPFLAGS}"
}

#****I* ruby.cygclass/ruby_install
#  SYNOPSIS
#  cd $B
#  ruby_install
#  DESCRIPTION
#  Installs a Ruby extension into $D using one of the supported build systems:
#  * install.rb: executes 'config' and 'install' commands
#  * setup.rb: executes 'config' and 'install' commands
#  * extconf.rb: runs cyginstall
#  * Rakefile: runs 'rake install'
#  If RDOC_SOURCE is defined, the RI docs generated in ruby_compile are
#  also installed into RI_SITEDIR.
#****
ruby_install() {
	if [ -f Makefile ]
	then
		cyginstall ${@}
	elif [ -e install.rb ]
	then
		${RUBY} install.rb config --prefix=${D}/usr ${@} || error "install.rb config failed"
		${RUBY} install.rb install || error "install.rb install failed"
	elif [ -e setup.rb ]
	then
		${RUBY} setup.rb config --prefix=/usr ${@} || error "setup.rb config failed"
		${RUBY} setup.rb install --prefix=${D} || error "setup.rb install failed"
	elif [ -e Rakefile -o -e rakefile ]
	then
		check_prog_req rake
		rake install DESTDIR=${D} ${@} || error "rake install failed"
	else
		error "No Ruby module detected"
	fi

#****v* ruby_install/RDOC_MODULE
#  DESCRIPTION
#  A whitespace-separated list of classes or namespaces whose RI docs
#  should be installed.  If RDOC_SOURCE is defined but RDOC_MODULE is
#  not, all generated documentation will be installed; this is often
#  undesirable, as private classes may also be documented.
#****

	if [ -d .rdoc ]
	then
		dodir ${RI_SITEDIR}

		pushd .rdoc
		for mod in ${RDOC_MODULE:-*/}
		do
			if [ ! -d ${mod} ]
			then
				warning "RI module ${mod} was not generated"
				continue
			fi

			cp -r ${mod} ${D}${RI_SITEDIR}/
		done
		popd
	fi
}

#****I* ruby.cygclass/rubyinto
#  SYNOPSIS
#  rubyinto SUBDIRECTORY
#  DESCRIPTION
#  Subdirectory of RUBY_VENDORLIB or RUBY_VENDORARCH that doruby should install.
#  This is usually unnecessary.
#****
rubyinto() {
	if (( $# != 1 ))
	then
	    error "rubyinto accepts exactly one argument";
	fi

	case ${1} in
    	/*) error "rubyinto argument should be only a subdirectory" ;;
	esac

	_rubyinto_dir=${1};
}

#****I* ruby.cygclass/doruby
#  SYNOPSIS
#  [rubyinto SUBDIRECTORY]
#  doruby FILES
#  DESCRIPTION
#  Installs Ruby extensions into RUBY_VENDORLIB or RUBY_VENDORARCH, or the
#  subdirectory thereof based on a previous call to rubyinto.
#****
doruby() {
	local rbdir
	local sodir
	local i

	if defined _rubyinto_dir
	then
		rbdir=${RUBY_VENDORLIB}/${_rubyinto_dir}
		sodir=${RUBY_VENDORARCH}/${_rubyinto_dir}
	else
		rbdir=${RUBY_VENDORLIB}
		sodir=${RUBY_VENDORARCH}
	fi

	dodir ${rbdir} ${sodir}

	for i
	do
		if [ -e ${i} ]
		then
			case ${i} in
				*.la|*.so)
					__doinstall 0755 ${i} ${sodir} || error "doruby ${i} failed"
					;;
				*.a|*.h)
					__doinstall 0644 ${i} ${sodir} || error "doruby ${i} failed"
					;;
				*)
					__doinstall 0644 ${i} ${rbdir} || error "doruby ${i} failed"
					;;
			esac
		else
			error "doruby: ${i}: file not found"
		fi
	done
}

#****I* ruby.cygclass/ruby_fix_shebang
#  SYNOPSIS
#  ruby_fix_shebang SCRIPT [SCRIPT ...]
#  DESCRIPTION
#  Fixes the designated interpreter of SCRIPT to RUBY.  This would be necessary
#  if the original uses an incorrect path (e.g. /usr/local/bin) or an
#  incorrectly versioned binary.  SCRIPT need not be prefixed by $D.
#****
ruby_fix_shebang() {
    __fix_shebang ${RUBY} ${D}/${@#${D}}
}

#****o* ruby.cygclass/src_compile (ruby)
#  DEFINITION
src_compile() {
	lndirs
	cd ${B}
	ruby_compile
}
#****

#****o* ruby.cygclass/src_install (ruby)
#  DEFINITION
src_install() {
	cd ${B}
	ruby_install
}
#****

readonly -f ruby_compile ruby_ext_compile ruby_install rubyinto doruby ruby_fix_shebang
