commit:     02e60ee7974e31d94d7210bfc566c1427d4df6df
Author:     Andrei Horodniceanu <a.horodniceanu <AT> proton <DOT> me>
AuthorDate: Sat Mar  2 17:56:22 2024 +0000
Commit:     Horodniceanu Andrei <a.horodniceanu <AT> proton <DOT> me>
CommitDate: Sat Apr 13 22:47:30 2024 +0000
URL:        https://gitweb.gentoo.org/repo/user/dlang.git/commit/?id=02e60ee7

dmd-r1.eclass: new eclass

Signed-off-by: Andrei Horodniceanu <a.horodniceanu <AT> proton.me>

 eclass/dmd-r1.eclass | 414 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 414 insertions(+)

diff --git a/eclass/dmd-r1.eclass b/eclass/dmd-r1.eclass
new file mode 100644
index 0000000..802e820
--- /dev/null
+++ b/eclass/dmd-r1.eclass
@@ -0,0 +1,414 @@
+# Copyright 2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: dmd-r1.eclass
+# @MAINTAINER:
+# Andrei Horodniceanu <[email protected]>
+# @AUTHOR:
+# Andrei Horodniceanu <[email protected]>
+# Based on dmd.eclass by Marco Leise <[email protected]>.
+# @BUGREPORTS:
+# Please report bugs via https://github.com/gentoo/dlang/issues
+# @VCSURL: https://github.com/gentoo/dlang
+# @SUPPORTED_EAPIS: 8
+# @BLURB: Captures most of the logic for building and installing DMD
+# @DESCRIPTION:
+# Helps with the maintenance of the various DMD versions by capturing common
+# logic.
+
+if [[ ! ${_ECLASS_ONCE_DMD_R1} ]] ; then
+_ECLASS_ONCE_DMD_R1=1
+
+case ${EAPI:-0} in
+       8) ;;
+       *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
+esac
+
+DESCRIPTION="Reference compiler for the D programming language"
+HOMEPAGE="https://dlang.org/";
+
+# DMD supports amd64/x86 exclusively
+# @ECLASS_VARIABLE: MULTILIB_COMPAT
+# @DESCRIPTION:
+# A list of multilib ABIs supported by $PN. It only supports
+# abi_x86_{32,64}. See the multilib-build.eclass documentation for this
+# variable for more information.
+MULTILIB_COMPAT=( abi_x86_{32,64} )
+
+inherit desktop edos2unix dlang-single multilib-build multiprocessing 
optfeature
+
+LICENSE=Boost-1.0
+SLOT=$(ver_cut 1-2)
+readonly MAJOR=$(ver_cut 1)
+readonly MINOR=$(ver_cut 2)
+readonly PATCH=$(ver_cut 3)
+readonly VERSION=$(ver_cut 1-3)
+readonly BETA=$(ver_cut 4-)
+
+# For prereleases, 2.097.0_rc1 -> 2.097.0-rc.1
+MY_VER=$(ver_rs 3 - 4 .)
+
+DLANG_ORG=https://downloads.dlang.org/${BETA:+pre-}releases/2.x/${VERSION}
+SRC_URI="
+       https://github.com/dlang/${PN}/archive/refs/tags/v${MY_VER}.tar.gz -> 
${PN}-${MY_VER}.tar.gz
+       https://github.com/dlang/phobos/archive/refs/tags/v${MY_VER}.tar.gz -> 
phobos-${MY_VER}.tar.gz
+       selfhost? ( ${DLANG_ORG}/dmd.${MY_VER}.linux.tar.xz )
+       doc? ( ${DLANG_ORG}/dmd.${MY_VER}.linux.tar.xz )
+"
+
+IUSE="doc examples +selfhost static-libs"
+REQUIRED_USE="^^ ( selfhost ${DLANG_REQUIRED_USE} )"
+IDEPEND=">=app-eselect/eselect-dlang-20140709"
+BDEPEND="!selfhost? ( ${DLANG_DEPS} )"
+# We don't need anything in DEPEND, curl is dl-opened
+# so it belongs in RDEPEND.
+#DEPEND=
+# Since 2.107.0, dmd links the standard library of the host
+# compiler. Since this eclass is only used by >=dmd-2.107.0-r1 the
+# dependency is added unconditionally.
+RDEPEND="
+       ${IDEPEND}
+       net-misc/curl[${MULTILIB_USEDEP}]
+       !selfhost? ( ${DLANG_DEPS} )
+"
+
+dmd-r1_pkg_setup() {
+       if use !selfhost; then
+               dlang-single_pkg_setup
+               # set by dlang-single.eclass:
+               # $EDC, $DC, $DLANG_LDFLAGS, $DCFLAGS
+
+               # Now let's build our environment
+               export DMDW=$(dlang_get_dmdw)
+               export DMDW_DCFLAGS=$(dlang_get_dmdw_dcflags)
+               export DMDW_LDFLAGS=$(dlang_get_dmdw_ldflags)
+       else
+               # Setup up similar variables to the above
+               export EDC=dmd-${SLOT}
+               #export DC= # is set inside src_unpack
+               #export DMDW= # is set inside src_unpack
+               export DLANG_LDFLAGS=$(dlang_get_ldflags)
+               # Should we put user DMDFLAGS here?
+               export DMDW_DCFLAGS= DCFLAGS=
+               export DMDW_LDFLAGS=$(dlang_get_dmdw_ldflags)
+       fi
+}
+
+dmd-r1_src_unpack() {
+       # Here because pkgdev complains about it being in pkg_setup
+       if use selfhost; then
+               export DC=${WORKDIR}/dmd2/linux/bin$(_get_abi_bits)/dmd
+               export DMDW=${DC}
+       fi
+
+       default
+
+       # $S may collide with $PN-$MY_VER
+       mv "${PN}-${MY_VER}" tmp || die
+       mkdir "${S}" || die
+       mv -T tmp "${S}/${PN}" || die
+       mv -T "phobos-${MY_VER}" "${S}/phobos" || die
+}
+
+dmd-r1_src_prepare() {
+       einfo "Removing dos-style line endings."
+       local file
+       while read -rd '' file; do
+               edos2unix "${file}"
+       done < <( find "${WORKDIR}" \( -name '*.txt' -o -name '*.html' -o -name 
'*.d' \
+                                  -o -name '*.di' -o -name '*.ddoc' -type f \) 
\
+                                  -print0 )
+
+       default
+}
+
+dmd-r1_src_compile() {
+       einfo "Building dmd build script"
+       dlang_compile_bin dmd/compiler/src/build{,.d}
+       local BUILD_D=${S}/dmd/compiler/src/build
+
+       local cmd=(
+               env
+               VERBOSE=1
+               HOST_DMD="${DMDW}"
+               # Just like old dmd.eclass.
+               #
+               # TODO, this has to be fixed but right now we either do
+               # ENABLE_RELEASE (we add -O -inline -release) or build.d will
+               # add -g.
+               ENABLE_RELEASE=1
+               "${BUILD_D}"
+               -j$(makeopts_jobs)
+               # A bit overkill to specify the flags here but it does get the
+               # jobs done.
+               DFLAGS="${DMDW_DCFLAGS} ${DMDW_LDFLAGS}"
+       )
+
+       einfo "Building dmd"
+       echo "${cmd[@]}"
+       "${cmd[@]}" || die "Failed to build dmd"
+
+       # The release here is from ENABLE_RELEASE, keep them in sync.
+       export 
GENERATED_DMD=${S}/dmd/generated/linux/release/$(_get_abi_bits)/dmd
+
+       compile_libraries() {
+               local commonMakeArgs=(
+                       DMD="${GENERATED_DMD}"
+                       MODEL=${MODEL}
+
+                       # Just like how multilib_toolchain_setup does it:
+                       CC="$(tc-getCC) $(get_abi_CFLAGS)"
+                       # The flags are, a little, project dependent
+                       #CFLAGS=
+
+                       # With DFLAGS we have 2 problems:
+                       #
+                       # 1. it's pretty hard to specify them for druntime so
+                       #    it would need a makefile patch
+                       #
+                       # 2. we have the same question as in pkg_setup, do we
+                       #    respect DMDFLAGS when building with the generated 
dmd?
+                       #
+                       #DFLAGS=
+               )
+               local druntimeMakeArgs=(
+                       # Calls git in global scope, only used for whitespace 
checks.
+                       MANIFEST=
+
+                       # Specifying user flags here discards the, hopefully
+                       # relevant, values from the makefile so add them back.
+                       CFLAGS="${CFLAGS} -fPIC -DHAVE_UNISTD_H" # -m32/64 is 
added in $CC.
+
+                       # druntime's notion of a shared library is a static 
archive
+                       # that is embedded into the phobos shared library.
+                       #
+                       # Technically there is the dll_so target which is the 
proper
+                       # so file but who's gonna use it? Perhaps if phobos 
would
+                       # not incorporate druntime we could install them as 
separate
+                       # libraries (like ldc2 and gdc).
+                       $(usex static-libs 'lib dll' dll)
+
+                       # We also need to copy the headers to the proper 
location
+                       import
+               )
+               local phobosMakeArgs=(
+                       # If unspecified, would rebuild druntime.
+                       CUSTOM_DRUNTIME=1
+
+                       # Like druntime, specifying flags removes the makefile 
added ones.
+                       CFLAGS="${CFLAGS} -fPIC -std=c11 -DHAVE_UNISTD_H" # 
-m32/64 is added in $CC.
+
+                       # Overkill but it does work. Remember that we have to
+                       # convert $LDFLAGS to something dmd understands.
+                       DFLAGS="$(dlang_get_ldflags ${PN}-${SLOT})"
+
+                       # By default builds both static+dynamic libraries.
+                       $(usex static-libs 'lib dll' dll)
+               )
+
+               emake -C dmd/druntime "${commonMakeArgs[@]}" 
"${druntimeMakeArgs[@]}"
+               emake -C phobos "${commonMakeArgs[@]}" "${phobosMakeArgs[@]}"
+       }
+
+       _dmd_foreach_abi compile_libraries
+
+       # Build the man pages
+       local cmd=(
+               env
+               VERBOSE=1
+               HOST_DMD="${GENERATED_DMD}"
+               "${BUILD_D}"
+               -j$(makeopts_jobs)
+               man
+               # ${GENERATED_DMD} is not yet fully functional as we didn't
+               # create a good dmd.conf. But instead of doing that we're going
+               # to specify our flags here.
+               DFLAGS="-defaultlib=phobos2 
-L-rpath=${S}/phobos/generated/linux/release/$(_get_abi_bits)"
+       )
+       echo "${cmd[@]}"
+       "${cmd[@]}" || die "Could not generate man pages"
+
+       # Now clean up some artifacts that would make the install phase
+       # harder (we rely on globbing and recursive calls a lot).
+
+       # The object file is useless
+       rm -f phobos/generated/linux/release/*/libphobos2.so.0.${MINOR}.o || die
+       # the zlib folder contains source code which is no longer
+       # needed. Don't touch etc/c/zlib.d however, that's important.
+       rm -rf phobos/etc/c/zlib || die
+}
+
+dmd-r1_src_test() {
+       # As opposed to old dmd.eclass we have access to actual tests. For
+       # porting reasons we're going to keep only the old test,
+       # hello_world.
+
+       test_hello_world() {
+               local phobosDir=${S}/phobos/generated/linux/release/${MODEL}
+               local commandArgs=(
+                       # Copied from _gen_dmd.conf
+                       -L--export-dynamic
+                       -defaultlib=phobos2 # If unspecified, defaults to 
libphobos2.a
+                       -fPIC
+                       -L-L"${phobosDir}"
+                       -L-rpath="${phobosDir}"
+
+                       -conf= # Don't use dmd.conf
+                       -m${MODEL}
+                       -Iphobos
+                       -Idmd/druntime/import
+               )
+
+               "${GENERATED_DMD}" "${commandArgs[@]}" 
dmd/compiler/samples/hello.d \
+                       || die "Failed to build hello.d (${MODEL}-bit)"
+               ./hello ${MODEL}-bit || die "Failed to run test sample 
(${MODEL}-bit)"
+       }
+
+       _dmd_foreach_abi test_hello_world
+
+}
+
+dmd-r1_src_install() {
+       local EDC=${PN}-${SLOT} # overwrite the one from pkg_setup
+       local dmd_prefix=/usr/lib/${PN}/$(dlang_get_be_version)
+
+       dodir /etc/dmd
+       _gen_dmd.conf > "${ED}"/etc/dmd/${SLOT}.conf || die "Could not generate 
dmd.conf"
+       # Put a symlink to dmd.conf into the same folder as the dmd
+       # executable so it gets picked up automatically (and instead of
+       # /etc/dmd.conf).
+       dosym -r "/etc/dmd/${SLOT}.conf" "${dmd_prefix}/bin/dmd.conf"
+
+       into "${dmd_prefix}"
+       dobin "${GENERATED_DMD}"
+       dosym -r "${dmd_prefix}/bin/dmd" "/usr/bin/dmd-${SLOT}"
+
+       insinto "${dmd_prefix}"
+       doins -r dmd/druntime/import
+
+       # Old dmd.eclass installed the so to $(get_libdir) and symlinked it
+       # into ${dmd_prefix}. We do it the other way around.
+       install_phobos_2() {
+               local G=phobos/generated/linux/release/${MODEL}
+               into /usr
+
+               dlang_dolib.so "${G}"/libphobos2.so*
+               use static-libs && dlang_dolib.a "${G}"/libphobos2.a
+
+               # The symlinks under $(get_libdir) are only for backwards
+               # compatibility purposes.
+               local filename=libphobos2.so.0.${MINOR}
+               dosym -r "/usr/$(dlang_get_libdir)/${filename}" 
"/usr/$(get_libdir)/${filename}"
+               dosym -r "/usr/$(dlang_get_libdir)/${filename}.${PATCH}" 
"/usr/$(get_libdir)/${filename}.${PATCH}"
+       }
+       _dmd_foreach_abi install_phobos_2
+       insinto "${dmd_prefix}"/import
+       doins -r phobos/{etc,std}
+
+       insinto "${dmd_prefix}"/man/man1
+       doins dmd/generated/docs/man/man1/dmd.1
+       insinto "${dmd_prefix}"/man/man5
+       doins dmd/generated/docs/man/man5/dmd.conf.5
+
+       if use examples; then
+               insinto "${dmd_prefix}"/samples
+               doins -r dmd/compiler/samples/*
+               docompress -x "${dmd_prefix}"/samples
+       fi
+
+       if use doc; then
+               HTML_DOCS=( "${WORKDIR}"/dmd2/html/* )
+               einstalldocs
+               insinto "/usr/share/doc/${PF}/html"
+               doins "${FILESDIR}/dmd-doc.png"
+               make_desktop_entry "xdg-open 
${EPREFIX}/usr/share/doc/${PF}/html/d/index.html" \
+                                                  "DMD ${PV}" \
+                                                  
"${EPREFIX}/usr/share/doc/${PF}/html/dmd-doc.png" \
+                                                  "Development"
+       fi
+}
+
+dmd-r1_pkg_postinst() {
+       "${EROOT}"/usr/bin/eselect dlang update dmd
+
+       use examples && elog "Examples can be found in: ${dmd_prefix}/samples"
+       use doc && elog "HTML documentation is in: /usr/share/doc/${PF}/html"
+
+       optfeature "additional D development tools" "dev-util/dlang-tools"
+}
+
+dmd-r1_pkg_postrm() {
+       "${ERROT}"/usr/bin/eselect dlang update dmd
+}
+
+# @FUNCTION: _gen_dmd.conf
+# @INTERNAL
+# @DESCRIPTION:
+# Print a dmd.conf to be installed on the user system. Needs $EDC to be
+# set up up beforehand.
+_gen_dmd.conf() {
+       debug-print-function ${FUNCNAME} "${@}"
+
+       # Note, the logic for which libdir is used is all kept in
+       # dlang-utils.eclass in order not to duplicate code.
+
+       local import_dir=${EPREFIX}/usr/lib/${PN}/$(dlang_get_be_version)/import
+       # Should this, instead, check which ABIs have been enabled?
+       if has_multilib_profile; then
+               local libdir_amd64=${EPREFIX}/usr/$(ABI=amd64 dlang_get_libdir)
+               local libdir_x86=${EPREFIX}/usr/$(ABI=x86 dlang_get_libdir)
+               cat <<EOF
+[Environment]
+DFLAGS=-I${import_dir} -L--export-dynamic -defaultlib=phobos2 -fPIC
+[Environment32]
+DFLAGS=%DFLAGS% -L-L${libdir_x86} -L-rpath=${libdir_x86}
+[Environment64]
+DFLAGS=%DFLAGS% -L-L${libdir_amd64} -L-rpath=${libdir_amd64}
+EOF
+
+       else
+               local libdir=${EPREFIX}/usr/$(dlang_get_libdir)
+               cat <<EOF
+[Environment]
+DFLAGS=-I${import_dir} -L--export-dynamic -defaultlib=phobos2 -fPIC 
-L-L${libdir} -L-rpath=${libdir}
+EOF
+
+       fi
+}
+
+# @FUNCTION: _get_abi_bits
+# @USAGE: [<abi>]
+# @INTERNAL
+# @DESCRIPTION:
+# Echo the bits of abi, 64 for amd64 and 32 for x86. If unspecified, the
+# value is taken from $ABI.
+_get_abi_bits() {
+       case "${1:-${ABI}}" in
+               amd64*) echo 64 ;;
+               x86*) echo 32 ;;
+               *) die "Unknown ABI: ${ABI}." ;;
+       esac
+}
+
+# @FUNCTION: _dmd_foreach_abi
+# @USAGE: <cmd> [<args>...]
+# @INTERNAL
+# @DESCRIPTION:
+# Run a command for each enabled ABI, similar to multilib_foreach_abi but
+# without setting $BUILD_DIR. Sets up $ABI and $MODEL (bits)
+# appropriately.
+_dmd_foreach_abi() {
+       debug-print-function ${FUNCNAME} "${@}"
+
+       local ABI
+       for ABI in $(multilib_get_enabled_abis); do
+               local MODEL=$(_get_abi_bits)
+               einfo "Executing ${1} in ${MODEL}-bit"
+               "${@}"
+       done
+}
+
+fi
+
+EXPORT_FUNCTIONS pkg_setup src_unpack src_prepare src_compile src_test 
src_install \
+                                pkg_postinst pkg_postrm

Reply via email to