From 03ea18123180f28643f158a7db942b82125a7b8c Mon Sep 17 00:00:00 2001 From: maxice8 Date: Tue, 30 Oct 2018 19:54:02 -0300 Subject: [PATCH] build_style: Add gemspec build_style --- Manual.md | 6 + common/build-style/gemspec.sh | 187 ++++++++++++++++++++++ common/environment/build-style/gemspec.sh | 3 + 3 files changed, 196 insertions(+) create mode 100644 common/build-style/gemspec.sh create mode 100644 common/environment/build-style/gemspec.sh diff --git a/Manual.md b/Manual.md index 96460a3267c..e77de544be7 100644 --- a/Manual.md +++ b/Manual.md @@ -781,6 +781,12 @@ with the character `r` in the `version` variable. The `distfiles` location will automatically be set as well as the package made to depend on `R`. +- `gemspec` For packages that use +[gemspec](https://guides.rubygems.org/specification-reference/) files for building a ruby +gem and then installing it. The gem command can be overridden by `gem_cmd`. `configure_args` +can be used to pass arguments during compilation. If your package does not make use of compiled +extensions consider using the `gem` build style instead. + - `gem` For packages that are installed using gems from [RubyGems](https://rubygems.org/). The gem command can be overridden by `gem_cmd`. `noarch` is set unconditionally and `distfiles` is set by the build style if the template does not do so. If your gem provides extensions which diff --git a/common/build-style/gemspec.sh b/common/build-style/gemspec.sh new file mode 100644 index 00000000000..9482ec0db0c --- /dev/null +++ b/common/build-style/gemspec.sh @@ -0,0 +1,187 @@ +# +# This helper is for templates using gemspec files from upstream or Rubygems. +# +do_build() { + : ${gem_cmd:=gem} + : ${gemspec:=${pkgname#ruby-}.gemspec} + + # Fix packages that keep Gem.gemspec as the name instead of the proper + # $pkgname.gemspec + if [ -f Gem.gemspec ]; then + gemspec=Gem.gemspec + fi + + if [ -f .gemspec ]; then + gemspec=.gemspec + fi + + # Hardcode name and version just in case they try something funny like + # requiring RELEASE to be on the environment to not append -rc0 to version + # Some even forget to update the version in the gemspec after releasing + sed -ri "s|(\.name .*)=.*|\1 = \"${pkgname#ruby-}\"|g" $gemspec + sed -ri "s|(\.version .*)=.*|\1 = \"${version}\"|g" $gemspec + + # Replace use of `git ls-files` with find, use printf so we can print without starting + # dot-slash path + sed -i 's|`git ls-files`|`find . -type f -printf "%P\\n"`|g' $gemspec + + # Sadly ruby isn't capable of handling nullbytes in a command so we have to use + # -print0, then try using sed to remove the suffix + # The end result is: + # `find . -type f -print0 | sed -e "s@\\./@@g"` + sed -i 's|`git ls-files -z`|`find . -type f -print0 \| sed -e "s@\\\\./@@g"`|g' $gemspec + + if [ "$CROSS_BUILD" ]; then + # Create a .extconf file that forces the Makefile to use our environment + # this allows us to cross-compile like it is done with meson cross-files + cat>append<> $f + fi + done + fi + + # If we are downloading a gem file then create a spec out of it + for f in $distfiles; do + if [ "${f##*.}" = "gem" ]; then + $gem_cmd spec \ + "${XBPS_SRCDISTDIR}/${pkgname}-${version}/${f##*/}" \ + --ruby > $gemspec + fi + done + + $gem_cmd build --verbose ${gemspec} + + if [ "$CROSS_BUILD" ]; then + # Restore previous extconf.rb which we ship. + find . -type f -name 'extconf.rb.orig' | while read -r f; do + mv $f ${f%.*} + done + fi +} + +do_install() { + : ${gem_cmd:=gem} + + local _GEMDIR _INSTDIR _TARGET_PLATFORM _HOST_PLATFORM _HOST_EXT_DIR _TARGET_EXT_DIR + + _GEMDIR=$($gem_cmd env gemdir) + _INSTDIR=${DESTDIR}/${_GEMDIR}/gems/${pkgname#ruby-}-${version} + + if [ "$CROSS_BUILD" ]; then + # Convert to the platforms used in our ruby packages + case "$XBPS_TARGET_MACHINE" in + x86_64) _TARGET_PLATFORM=x86_64-linux ;; + x86_64-musl) _TARGET_PLATFORM=x86_64-linux-musl ;; + i686) _TARGET_PLATFORM=i686-linux ;; + i686-musl) _TARGET_PLATFORM=i686-linux-musl ;; + armv7l|armv7hf) _TARGET_PLATFORM=armv7l-linux-eabihf ;; + armv6l|armv6hf) _TARGET_PLATFORM=arm-linux-eabihf ;; + armv7l-musl|armv7hf-musl) _TARGET_PLATFORM=armv7l-linux-musleabihf ;; + armv6l-musl|armv6hf-musl) _TARGET_PLATFORM=arm-linux-musleabihf ;; + aarch64) _TARGET_PLATFORM=aarch64-linux ;; + aarch64-musl) _TARGET_PLATFORM=aarch64-linux-musl ;; + esac + + case "$XBPS_MACHINE" in + x86_64) _HOST_PLATFORM=x86_64-linux ;; + x86_64-musl) _HOST_PLATFORM=x86_64-linux-musl ;; + i686) _HOST_PLATFORM=i686-linux ;; + i686-musl) _HOST_PLATFORM=i686-linux-musl ;; + armv7l|armv7hf) _HOST_PLATFORM=armv7l-linux-eabihf ;; + armv6l|armv6hf) _HOST_PLATFORM=arm-linux-eabihf ;; + armv7l-musl|armv7hf-musl) _HOST_PLATFORM=armv7l-linux-musleabihf ;; + armv6l-musl|armv6hf-musl) _HOST_PLATFORM=arm-linux-musleabihf ;; + aarch64) _HOST_PLATFORM=aarch64-linux ;; + aarch64-musl) _HOST_PLATFORM=aarch64-linux-musl ;; + esac + fi + + $gem_cmd install \ + --local \ + --install-dir ${DESTDIR}/${_GEMDIR} \ + --bindir ${DESTDIR}/usr/bin \ + --ignore-dependencies \ + --no-document \ + --verbose \ + "${pkgname#ruby-}-${version}.gem" \ + -- $configure_args + + # Remove cache + rm -rf ${DESTDIR}/${_GEMDIR}/cache + + # Remove ext directory, they are only source code and configuration + # The actual extensions are in a arch path guarded + rm -rf ${_INSTDIR}/ext + + # Remove duplicated library that is available in a arch guarded + # extension + rm -rf ${_INSTDIR}/lib/*.so + + # Remove installed tests and benchmarks + rm -rf ${_INSTDIR}/{test,tests,autotest,benchmark,benchmarks,script,examples,demo} + + # Remove files shipped on the root of the gem, most of the time they are useless + find ${_INSTDIR} -maxdepth 1 -type f -delete + + # Remove unnecessary files + find ${DESTDIR}/${_GEMDIR}/extensions \( -name mkmf.log -o -name gem_make.out \) -delete + + # Place manpages in usr/share/man/man[0-9] + find ${_INSTDIR}/man -type f -name '*.[0-8n]' | while read -r m; do + vman ${m} + done + + rm -rf "${_INSTDIR}/man" + + # Place executables in /usr/bin + if [ -d "${_INSTDIR}/bin" ]; then + for f in "${_INSTDIR}"/bin/*; do + vbin "${f}" + done + fi + + rm -rf ${_INSTDIR}/bin + + # Place conf files in their places + find ${_INSTDIR}/etc -type f | while read -r c; do + vmkdir $(dirname ${c}) + mv ${c} "${DESTDIR}/${c##*${_INSTDIR}/etc/}/" + done + + rm -rf ${_INSTDIR}/etc + + if [ "$CROSS_BUILD" ]; then + # Path to the extensions on a package, ruby installs against the platform + # of the host, so we have to move them to the correct place + _HOST_EXT_DIR="${DESTDIR}/${_GEMDIR}/extensions/${_HOST_PLATFORM}" + _TARGET_EXT_DIR="${DESTDIR}/${_GEMDIR}/extensions/${_TARGET_PLATFORM}" + + if [ -d ${_HOST_EXT_DIR} ]; then + mv ${_HOST_EXT_DIR} ${_TARGET_EXT_DIR} + fi + + # Fix Makefile locations to point to the correct platform + for f in $(find ${DESTDIR}/${_GEMDIR} -type f -name 'Makefile'); do + sed -i "s|${_HOST_PLATFORM}|${_TARGET_PLATFORM}|g" $f + done + fi +} diff --git a/common/environment/build-style/gemspec.sh b/common/environment/build-style/gemspec.sh new file mode 100644 index 00000000000..b3025a9ec47 --- /dev/null +++ b/common/environment/build-style/gemspec.sh @@ -0,0 +1,3 @@ +lib32disabled=yes +hostmakedepends+=" ruby-devel" +makedepends+=" ruby-devel"