dev-libs/ldc2-runtime - 1.40.0 (dlang)

Search

Package Information

Description:
LLVM D Compiler
Homepage:
https://github.com/ldc-developers/ldc
License:
BSD Boost-1.0 BZIP2 ZLIB curl public-domain

Ebuild Details

Version EAPI Keywords Slot
1.40.0 8 ~amd64 ~arm64 ~x86 $(ver_cut 1-2)/0
View Raw Ebuild
# Copyright 2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

EAPI=8

DLANG_COMPAT=( ldc2-1_$(ver_cut 2) )
inherit dlang-single multilib cmake-multilib

PATCH_VER=1
PATCH_TAG_NAME="${PV}-patches-${PATCH_VER}"
PATCH_URL_BASE="https://github.com/the-horo/ldc-patches/archive/refs/tags"

DESCRIPTION="LLVM D Compiler"
HOMEPAGE="https://github.com/ldc-developers/ldc"
MY_PV="${PV//_/-}"
MY_P="ldc-${MY_PV}-src"
SRC_URI="
	https://github.com/ldc-developers/ldc/releases/download/v${MY_PV}/${MY_P}.tar.gz
	${PATCH_URL_BASE}/${PATCH_TAG_NAME}.tar.gz -> ldc2-${PV}-patches-${PATCH_VER}.tar.gz
"
S=${WORKDIR}/${MY_P}
LICENSE="BSD"
# runtime libs, see dmd-r1.eclass for more details
LICENSE+=" Boost-1.0 BZIP2 ZLIB curl public-domain"

# Only increase subslot in case of ABI breakage
SLOT="$(ver_cut 1-2)/0"
LDC2_SLOT="$(ver_cut 1-2)" # SLOT without subslot
KEYWORDS="~amd64 ~arm64 ~x86"

IUSE="static-libs test"
RESTRICT="!test? ( test )"

REQUIRED_USE=${DLANG_REQUIRED_USE}
RDEPEND="
	sys-libs/zlib:0/1
	net-misc/curl[${MULTILIB_USEDEP}]
"
# curl is dlopened. The tests do need it though.
DEPEND="
	sys-libs/zlib:0/1
	test? (
		  net-misc/curl[${MULTILIB_USEDEP}]
	)
"
# We purposefully ignore DLANG_DEPS, we only need the ldc2 compiler and only in BROOT
BDEPEND="dev-lang/ldc2:${LDC2_SLOT}"
IDEPEND=">=app-eselect/eselect-dlang-20241230"

INSTALL_PREFIX="${EPREFIX}/usr/lib/ldc2/${LDC2_SLOT}" # /usr/lib/ldc2/1.40
STRING_IMPORTS_DIR="${T}/views"
LDC2_CONF_DIR="${WORKDIR}/conf"

src_prepare() {
	mkdir -p "${STRING_IMPORTS_DIR}" || die
	local tzpath="${STRING_IMPORTS_DIR}/TZDatabaseDirFile"
	# std.datetime.timezone default search path, instead of /usr/share/zoneinfo/
	echo "${EPREFIX}/usr/share/zoneinfo/" > "${tzpath}" || die

	# Create wrappers for ldc2 because the cmake file only supports
	# passing arguments to the compiler at the end of the command line.
	# This breaks the -conf= argument that we want to use.
	cat <<-EOF > "${T}/ldc2" || die
	#!/bin/sh
	exec "${DC}" -conf="${LDC2_CONF_DIR}/ldc2.conf" "\${@}"
	EOF
	cat <<-EOF > "${T}/ldmd2" || die
	#!/bin/sh
	exec "$(dlang_get_dmdw)" -conf="${LDC2_CONF_DIR}/ldc2.conf" "\${@}"
	EOF
	chmod +x "${T}/ldc2" "${T}/ldmd2" || die

	apply_patches

	cmake_src_prepare
}

src_configure() {
	add_multilib_sections() {
		multilib_is_native_abi && return
		add_multilib_section "${S}/ldc2_phobos.conf.in" "${BUILD_DIR}/$(get_libdir)"
		add_multilib_section "${S}/ldc2_install.conf.in" "${INSTALL_PREFIX}/$(get_libdir)"
	}
	multilib_foreach_abi add_multilib_sections

	multilib-minimal_src_configure
}

multilib_src_configure() {
	local mycmakeargs=(
		-DBUILD_SHARED_LIBS=$(usex static-libs BOTH ON)
		# flags for the runtime, the need to be separated by ;
		-DD_FLAGS_RELEASE="${DCFLAGS// /;}"
		# Slight improvements with this
		-DCOMPILE_ALL_D_FILES_AT_ONCE=OFF

		-DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}"
		-DPHOBOS_SYSTEM_ZLIB=ON
		-DLDC_EXE_FULL="${T}/ldc2"
		-DLDMD_EXE_FULL="${T}/ldmd2"
		# needed for the sake of EPREFIX
		-DPHOBOS2_EXTRA_FLAGS="-J;${STRING_IMPORTS_DIR};-d-version=TZDatabaseDir"
		# ${EDC}                   # ldc2-1.40
		#   .dlang_get_fe_version  # 2.110
		#   .ver_cut(2)            # 110
		-DDMDFE_MINOR_VERSION="$(ver_cut 2 $(dlang_get_fe_version ${EDC}))"
		-DDMDFE_PATCH_VERSION="$(ver_cut 3)"
	)
	if ! multilib_is_native_abi; then
		# configure multilib flags
		mycmakeargs+=(
			-DD_EXTRA_FLAGS="$(dlang_get_model_flag)"
			-DRT_CFLAGS="$(get_abi_CFLAGS)"
		)
	else
		# we save the config file from the native build
		mycmakeargs+=(-DCONFIG_FILE_OUTPUT_DIR="${LDC2_CONF_DIR}")
	fi

	CMAKE_USE_DIR="${S}/runtime" cmake_src_configure
}

multilib_src_test() {
	# cmake.eclass modifies this internally but doesn't declare it as local making
	# changes to it carry out across invocations of ${FUNCNAME}
	local myctestargs

	# We compile the tests first so that $MAKEOPTS is respect, if
	# compiled during the tests, nproc jobs will be used.
	cmake_src_compile all-test-runners

	local CMAKE_SKIP_TESTS=(
		# These require valgrind
		druntime-test-gc
		druntime-test-valgrind
		# Should be fixed by https://github.com/dlang/dmd/pull/16851
		# Drop the above once the changes are merged into ldc2

		# This one fails due to an uncaught error, probably due to the
		# sandbox.
		druntime-test-cycles
	)
	if [[ ${ARCH} == arm64 ]]; then
		# https://github.com/ldc-developers/ldc/issues/4613

		# fails due to "innacuracy"
		CMAKE_SKIP_TESTS+=( std.internal.math.gammafunction )
		# Bad code generation with optimizations?
		CMAKE_SKIP_TESTS+=( std.math.exponential )
	fi

	# This test requires "${TEMP}/<some-file>" to be less than 108 characters.
	# We will run it separately and force ${TEMP} to be a shorter path.
	TMPDIR="." cmake_src_test -R std.socket
	CMAKE_SKIP_TESTS+=( std.socket )

	# We don't want to run gdb or valgrind tests
	local -x GDB=gdb-dont-find-me VALGRIND=valgrind-dont-find-me
	cmake_src_test
}

multilib_src_compile() {
	cmake_src_compile
	symlinks_release_runtime_to_debug "${BUILD_DIR}"
}

multilib_src_install() {
	cmake_src_install
	symlinks_release_runtime_to_debug "${D}/${INSTALL_PREFIX}"
}

multilib_src_install_all() {
	local ldc2_etc="${INSTALL_PREFIX#"${EPREFIX}"}/etc"
	insinto "${ldc2_etc}"
	newins "${LDC2_CONF_DIR}"/ldc2_install.conf ldc2.conf
	dosym -r "${ldc2_etc}"/ldc2.conf "/etc/ldc2/${LDC2_SLOT}.conf"
}

pkg_postinst() {
	"${EROOT}"/usr/bin/eselect dlang update ldc2
}

pkg_postrm() {
	"${EROOT}"/usr/bin/eselect dlang update ldc2
}

apply_patches() {
	local patches_dir="${WORKDIR}/ldc-patches-${PATCH_TAG_NAME}/runtime"
	einfo "Applying patches from: ${patches_dir}"
	local patch
	while read -rd '' patch; do
		eapply "${patch}"
	done < <(find "${patches_dir}" -mindepth 1 -maxdepth 1 \
				  -type f -name '*.patch' \
				  -print0)
}

# Create symlinks to libdruntime-ldc-shared et al from libdruntime-ldc-debug-shared
# Usage: <dir>
# The symlinks are made in <dir>/$(get_libdir)
symlinks_release_runtime_to_debug() {
	rename_in_dir() {
		local file find_cmd=(
			find "${1}" -mindepth 1 -maxdepth 1
			# Find files that look like a runtime library
			-regex ".*/lib\(druntime\|phobos\)[^/]*"
			# and are not a debug variant
			-not -name '*debug*'
			-printf '%f\0'
		)
		while read -rd '' file; do
			# and symlink them:
			# ${file}                 == libdruntime-ldc-shared
			# ${file/-ldc/-ldc-debug} == libdruntime-ldc-debug-shared
			ln -s "${file}" "${1}/${file/-ldc/-ldc-debug}" || die
		done < <("${find_cmd[@]}")
	}

	rename_in_dir "${1}/$(get_libdir)"
}

# USAGE: <ldc2_conf_file> <full_libdir>
add_multilib_section() {
	# NOTE: We're missing compiler-rt's libdir
	local filepath=${1} libdir=${2}
	local triple_without_vendor=$(sed -e 's/-[^-]*/-.*/' <<<"${CHOST}") # i686-.*-linux-gnu
	cat >> "${filepath}" <<EOF || die "Could not add multilib section"

"${triple_without_vendor}":
{
	lib-dirs = [
		"${libdir}",
	];
	rpath = "${libdir}";
};
EOF
}

USE Flags

Dependencies

DEPEND

	sys-libs/zlib:0/1
	test? (
		  net-misc/curl[${MULTILIB_USEDEP}]
	)

RDEPEND

	sys-libs/zlib:0/1
	net-misc/curl[${MULTILIB_USEDEP}]

BDEPEND

dev-lang/ldc2:$(ver_cut 1-2)