summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam James <sam@gentoo.org>2024-08-03 03:27:51 +0100
committerSam James <sam@gentoo.org>2024-09-29 01:18:08 +0100
commit799693623d76c89e8b04d2434d0dfece44bb49f9 (patch)
tree8b09d9ee0ca70a0b44148a7a533189aaf6041534
parenttoolchain.eclass: more Ada cleanup (diff)
downloadgentoo-799693623d76c89e8b04d2434d0dfece44bb49f9.tar.gz
gentoo-799693623d76c89e8b04d2434d0dfece44bb49f9.tar.bz2
gentoo-799693623d76c89e8b04d2434d0dfece44bb49f9.zip
toolchain.eclass: Ada rework
Look hard for an existing GNAT for use for bootstrapping without requiring users to run `gcc-config` / switch their system copy of GCC, which is both brittle in that it requires manual intervention, and also unclean. Started looking at this after https://public-inbox.gentoo.org/gentoo-dev/2a700166-f01a-4807-bd76-7b0cce72af0b@archeia.com/ although the approach is different. I did use it as a base although not much of it remains. We take the following approach: * Iterate over installed GCC slots (preferring ${SLOT}, then iterating from the latest version installed down to GCC 10) to find a copy of GNAT; * Create wrappers for gnat* to redirect calls when building GCC to our found bootstrap copy of GNAT; * Use an extracted spec file to redirect gnat1 calls to that bootstrap copy too, as the build system doesn't allow saying "just use this copy of gnat" (it always wants $(CC) to support it). The real nasty part here is that GCC's build system doesn't seem to have a way to point to 'ADACC' or similar (it looks like it did have 'ADAC' years ago). Remaining bits to be done: * Adapting/replacing/supplementing dev-lang/gnat-gpl with a version that can be installed in parallel to sys-devel/gcc:10 so it can be pulled in transparently for bootstrapping; * Build our own, or source some other copy (e.g. from Alire), of a newer bootstrap GNAT. https://github.com/alire-project/GNAT-FSF-builds is a likely candidate. I also hope that we can ultimately do the same for D. Bug: https://gcc.gnu.org/PR864 Bug: https://gcc.gnu.org/PR108909 Bug: https://bugs.gentoo.org/137268 Bug: https://bugs.gentoo.org/547358 Bug: https://bugs.gentoo.org/919667 Closes: https://bugs.gentoo.org/937774 Link: https://lists.fedorahosted.org/archives/list/epel-devel@lists.fedoraproject.org/thread/CVQ3JIOZI5ODYDZU2DZLA37JWSLMCIN7/ Signed-off-by: Sam James <sam@gentoo.org>
-rw-r--r--eclass/toolchain.eclass143
1 files changed, 141 insertions, 2 deletions
diff --git a/eclass/toolchain.eclass b/eclass/toolchain.eclass
index f8c290bf4a07..cfddba99a1a8 100644
--- a/eclass/toolchain.eclass
+++ b/eclass/toolchain.eclass
@@ -401,8 +401,6 @@ if tc_has_feature valgrind ; then
BDEPEND+=" valgrind? ( dev-debug/valgrind )"
fi
-# TODO: Add a pkg_setup & pkg_pretend check for whether the active compiler
-# supports Ada.
if [[ ${PN} != gnat-gpl ]] && tc_has_feature ada ; then
BDEPEND+=" ada? ( || ( sys-devel/gcc[ada] dev-lang/gnat-gpl[ada] ) )"
fi
@@ -558,6 +556,8 @@ SRC_URI=$(get_gcc_src_uri)
toolchain_pkg_pretend() {
if ! _tc_use_if_iuse cxx ; then
+ _tc_use_if_iuse ada && \
+ ewarn 'Ada requires a C++ compiler, disabled due to USE="-cxx"'
_tc_use_if_iuse go && \
ewarn 'Go requires a C++ compiler, disabled due to USE="-cxx"'
_tc_use_if_iuse objc++ && \
@@ -854,6 +854,143 @@ toolchain_src_configure() {
fi
[[ -n ${CBUILD} ]] && confgcc+=( --build=${CBUILD} )
+ _need_ada_bootstrap_mangling() {
+ if [[ ${CATEGORY}/${PN} == dev-lang/gnat-gpl ]] ; then
+ _tc_use_if_iuse system-bootstrap && return 0
+ return 1
+ fi
+
+ _tc_use_if_iuse ada
+ }
+
+ if _need_ada_bootstrap_mangling ; then
+ local latest_gcc=$(best_version -b "sys-devel/gcc")
+ latest_gcc="${latest_gcc#sys-devel/gcc-}"
+ latest_gcc=$(ver_cut 1 ${latest_gcc})
+
+ local ada_bootstrap
+ local ada_candidate
+ # We always prefer the version being built if possible
+ # as it has the greatest chance of success. Failing that,
+ # try the latest installed GCC and iterate downwards.
+ for ada_candidate in ${SLOT} $(seq ${latest_gcc} -1 10) ; do
+ has_version -b "sys-devel/gcc:${ada_candidate}" || continue
+
+ ebegin "Testing sys-devel/gcc:${ada_candidate} for Ada"
+ if has_version -b "sys-devel/gcc:${ada_candidate}[ada(-)]" ; then
+ # Make sure we set a path to the Ada bootstrap if gcc[ada] is not already
+ # installed. GNAT can usually be built using the last major version and
+ # the current version, at least.
+ ada_bootstrap=${ada_candidate}
+
+ eend 0
+ break
+ fi
+ eend 1
+ done
+
+ # As a last resort, use dev-lang/gnat-gpl.
+ # TODO: Make gnat-gpl coinstallable with gcc:10.
+ if [[ -z ${ada_bootstrap} ]] ; then
+ ebegin "Testing dev-lang/gnat-gpl for Ada"
+ if has_version -b "dev-lang/gnat-gpl" ; then
+ ada_bootstrap=10
+ eend 0
+ else
+ eend 1
+ fi
+ fi
+
+ # OK, even gnat-gpl didn't work. Give up for now.
+ # TODO: Source a newer, or build our own, bootstrap tarball.
+ if [[ -z ${ada_bootstrap} ]] ; then
+ die "Fallback ada-bootstrap path not yet implemented!"
+
+ #einfo "Using bootstrap GNAT compiler..."
+ #export PATH="${BROOT}/opt/ada-bootstrap-${GCCMAJOR}/bin:${PATH}"
+ fi
+
+ cat <<-"EOF" > "${T}"/ada.spec || die
+ # Extracted from gcc/ada/gcc-interface/lang-specs.h
+ .adb:
+ @ada
+
+ .ads:
+ @ada
+
+ # TODO: ADA_DUMPS_OPTIONS
+ @ada:
+ %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}} \
+ %{!S:%{!c:%e-c or -S required for Ada}} \
+ ${BROOT}/usr/libexec/gcc/${CBUILD}/${ada_bootstrap}/gnat1 %{I*} %{k8:-gnatk8} %{!Q:-quiet} \
+ %{nostdinc*} %{nostdlib*} \
+ %{fcompare-debug-second:-gnatd_A} \
+ %{O*} %{W*} %{w} %{p} %{pg:-p} \
+ %{coverage:-fprofile-arcs -ftest-coverage} \
+ %{Wall:-gnatwa} %{Werror:-gnatwe} %{w:-gnatws} \
+ %{gnatea:-gnatez} %{g*&m*&f*} \
+ %1 %{!S:%{o*:%w%*-gnatO}} \
+ %i %{S:%W{o*}%{!o*:-o %w%b.s}} \
+ %{gnatc*|gnats*: -o %j} %{-param*} \
+ %{!gnatc*:%{!gnats*:%(invoke_as)}}
+
+ @adawhy:
+ %{!c:%e-c required for gnat2why} \
+ gnat1why %{I*} %{k8:-gnatk8} %{!Q:-quiet} \
+ %{nostdinc*} %{nostdlib*} \
+ %{a} \
+ %{gnatea:-gnatez} %{g*&m*&f*} \
+ %1 %{o*:%w%*-gnatO} \
+ %i \
+ %{gnatc*|gnats*: -o %j} %{-param*}
+
+ @adascil:
+ %{!c:%e-c required for gnat2scil} \
+ gnat1scil %{I*} %{k8:-gnatk8} %{!Q:-quiet} \
+ %{nostdinc*} %{nostdlib*} \
+ %{a} \
+ %{gnatea:-gnatez} %{g*&m*&f*} \
+ %1 %{o*:%w%*-gnatO} \
+ %i \
+ %{gnatc*|gnats*: -o %j} %{-param*}
+ EOF
+
+ # Easier to substitute these values in rather than escape
+ # lots of bits above in heredoc.
+ sed -i \
+ -e "s:\${BROOT}:${BROOT}:" \
+ -e "s:\${CBUILD}:${CBUILD}:" \
+ -e "s:\${ada_bootstrap}:${ada_bootstrap}:" \
+ "${T}"/ada.spec || die
+
+ # The Makefile tries to find libgnat by querying $(CC) which
+ # won't work for us as the stage1 compiler doesn't necessarily
+ # have Ada support. Substitute the Ada compiler we found earlier.
+ local adalib
+ adalib=$(${CBUILD}-gcc-${ada_bootstrap} -print-libgcc-file-name || die "Finding adalib dir failed")
+ adalib="${adalib%/*}/adalib"
+ sed -i \
+ -e "s:adalib=.*:adalib=${adalib}:" \
+ "${S}"/gcc/ada/gcc-interface/Make-lang.in || die
+
+ # Create bin wrappers because not all of the build system
+ # respects GNATBIND or GNATMAKE.
+ mkdir "${T}"/ada-wrappers || die
+ local tool
+ for tool in gnat{,bind,chop,clean,kr,link,ls,make,name,prep} ; do
+ cat <<-EOF > "${T}"/ada-wrappers/${tool} || die
+ #!/bin/bash
+ exec $(type -P ${CBUILD}-${tool}-${ada_bootstrap}) -specs=${T}/ada.spec "\$@"
+ EOF
+ chmod +x "${T}"/ada-wrappers/${tool} || die
+
+ export "${tool^^}"=${CBUILD}-${tool}-${ada_bootstrap}
+ done
+
+ export PATH="${T}/ada-wrappers:${PATH}"
+ export CC="$(tc-getCC) -specs=${T}/ada.spec"
+ fi
+
confgcc+=(
--prefix="${PREFIX}"
--bindir="${BINPATH}"
@@ -1438,6 +1575,8 @@ toolchain_src_configure() {
einfo "DATAPATH: ${DATAPATH}"
einfo "STDCXX_INCDIR: ${STDCXX_INCDIR}"
einfo "Languages: ${GCC_LANG}"
+ einfo "GCC version: $($(tc-getCC) -v 2>&1 | grep ' version ' | awk '{ print $3 }')"
+ is_ada && einfo "GNAT version: $(gnat 2>&1 | grep GNAT | awk '{ print $2 }')"
echo
# Build in a separate build tree