From c660f75b220bf2d6d5d48418b0ecbbf77ea62e4f Mon Sep 17 00:00:00 2001
From: Zac Medico <zmedico@gentoo.org>
Date: Wed, 11 Aug 2010 04:06:35 -0700
Subject: [PATCH] In EAPI 4, add a TDEPEND variable for build-time target dependencies.

In EAPI 4 or later, DEPEND has been divided into two parts:
DEPEND for build-time host dependencies, and TDEPEND for
build-time target dependencies. This division is designed
specifically to minimize difficulty in the process of
adapting ebuilds that were written for earlier EAPIs,
and therefore it also minimizes the adjustments that
ebuild developers will have to make to the thought
processes involved when writing ebuilds from scratch. In
an environment that does not involve cross-compilation,
TDEPEND behaves the same as DEPEND. When an ebuild is
converted from EAPI 3 or earlier to EAPI 4 or later,
in order to support cross-compilation environments, some
dependencies may need to be migrated to TDEPEND.

For ebuilds that have EAPI 4 or later, the emerge
--root-deps option has no effect since it is made obsolete
by division between DEPEND and TDEPEND. If EAPI 3 or
earlier ebuilds are used in combination with EAPI 4 or
later ebuilds, the --root-deps behavior will still be
applied to the EAPI 3 or earlier ebuilds (there is no
behavior change for ebuilds having older EAPIs).
---
 bin/ebuild.sh                     |   24 +++++++++++++------
 doc/package/ebuild/eapi/4.docbook |   44 +++++++++++++++++++++++++++++++++++++
 man/ebuild.5                      |   18 +++++++++++++++
 man/emerge.1                      |   15 +++++++++---
 pym/_emerge/Package.py            |    2 +-
 pym/_emerge/depgraph.py           |   39 +++++++++++++++++++++-----------
 pym/_emerge/help.py               |   15 +++++++++---
 pym/portage/__init__.py           |    4 +-
 pym/portage/dbapi/bintree.py      |    7 +++--
 pym/portage/dbapi/porttree.py     |    2 +-
 pym/portage/dbapi/vartree.py      |    2 +-
 11 files changed, 134 insertions(+), 38 deletions(-)

diff --git a/bin/ebuild.sh b/bin/ebuild.sh
index 0142294..f439867 100755
--- a/bin/ebuild.sh
+++ b/bin/ebuild.sh
@@ -1264,6 +1264,7 @@ inherit() {
 	local B_DEPEND
 	local B_RDEPEND
 	local B_PDEPEND
+	local B_TDEPEND
 	while [ "$1" ]; do
 		location="${ECLASSDIR}/${1}.eclass"
 		olocation=""
@@ -1302,20 +1303,21 @@ inherit() {
 				EBUILD_OVERLAY_ECLASSES="${EBUILD_OVERLAY_ECLASSES} ${location}"
 		fi
 
-		#We need to back up the value of DEPEND and RDEPEND to B_DEPEND and B_RDEPEND
+		#We need to back up the values of *DEPEND to B_*DEPEND
 		#(if set).. and then restore them after the inherit call.
 
 		#turn off glob expansion
 		set -f
 
 		# Retain the old data and restore it later.
-		unset B_IUSE B_REQUIRED_USE B_DEPEND B_RDEPEND B_PDEPEND
+		unset B_IUSE B_REQUIRED_USE B_DEPEND B_RDEPEND B_PDEPEND B_TDEPEND
 		[ "${IUSE+set}"       = set ] && B_IUSE="${IUSE}"
 		[ "${REQUIRED_USE+set}" = set ] && B_REQUIRED_USE="${REQUIRED_USE}"
 		[ "${DEPEND+set}"     = set ] && B_DEPEND="${DEPEND}"
 		[ "${RDEPEND+set}"    = set ] && B_RDEPEND="${RDEPEND}"
 		[ "${PDEPEND+set}"    = set ] && B_PDEPEND="${PDEPEND}"
-		unset IUSE REQUIRED_USE DEPEND RDEPEND PDEPEND
+		[ "${TDEPEND+set}"    = set ] && B_TDEPEND="${TDEPEND}"
+		unset IUSE REQUIRED_USE DEPEND RDEPEND PDEPEND TDEPEND
 		#turn on glob expansion
 		set +f
 
@@ -1331,6 +1333,7 @@ inherit() {
 		[ "${DEPEND+set}"     = set ] && export E_DEPEND="${E_DEPEND} ${DEPEND}"
 		[ "${RDEPEND+set}"    = set ] && export E_RDEPEND="${E_RDEPEND} ${RDEPEND}"
 		[ "${PDEPEND+set}"    = set ] && export E_PDEPEND="${E_PDEPEND} ${PDEPEND}"
+		[ "${TDEPEND+set}"    = set ] && export E_TDEPEND="${E_TDEPEND} ${TDEPEND}"
 
 		[ "${B_IUSE+set}"     = set ] && IUSE="${B_IUSE}"
 		[ "${B_IUSE+set}"     = set ] || unset IUSE
@@ -1347,6 +1350,9 @@ inherit() {
 		[ "${B_PDEPEND+set}"  = set ] && PDEPEND="${B_PDEPEND}"
 		[ "${B_PDEPEND+set}"  = set ] || unset PDEPEND
 
+		[ "${B_TDEPEND+set}"  = set ] && TDEPEND="${B_TDEPEND}"
+		[ "${B_TDEPEND+set}"  = set ] || unset TDEPEND
+
 		#turn on glob expansion
 		set +f
 
@@ -1606,7 +1612,7 @@ source_all_bashrcs() {
 # when portage is upgrading itself.
 
 READONLY_EBUILD_METADATA="DEFINED_PHASES DEPEND DESCRIPTION
-	EAPI HOMEPAGE INHERITED IUSE REQUIRED_USE KEYWORDS LICENSE
+	EAPI TDEPEND HOMEPAGE INHERITED IUSE REQUIRED_USE KEYWORDS LICENSE
 	PDEPEND PROVIDE RDEPEND RESTRICT SLOT SRC_URI"
 
 READONLY_PORTAGE_VARS="D EBUILD EBUILD_PHASE \
@@ -1780,7 +1786,7 @@ preprocess_ebuild_env() {
 export SANDBOX_ON="1"
 export S=${WORKDIR}/${P}
 
-unset E_IUSE E_REQUIRED_USE E_DEPEND E_RDEPEND E_PDEPEND
+unset E_IUSE E_REQUIRED_USE E_DEPEND E_RDEPEND E_PDEPEND E_TDEPEND
 
 # Turn of extended glob matching so that g++ doesn't get incorrectly matched.
 shopt -u extglob
@@ -1884,7 +1890,7 @@ if ! hasq "$EBUILD_PHASE" clean cleanrm ; then
 		# In order to ensure correct interaction between ebuilds and
 		# eclasses, they need to be unset before this process of
 		# interaction begins.
-		unset DEPEND RDEPEND PDEPEND IUSE REQUIRED_USE
+		unset DEPEND RDEPEND PDEPEND TDEPEND IUSE REQUIRED_USE
 
 		if [[ $PORTAGE_DEBUG != 1 || ${-/x/} != $- ]] ; then
 			source "$EBUILD" || die "error sourcing ebuild"
@@ -1912,9 +1918,10 @@ if ! hasq "$EBUILD_PHASE" clean cleanrm ; then
 		DEPEND="${DEPEND} ${E_DEPEND}"
 		RDEPEND="${RDEPEND} ${E_RDEPEND}"
 		PDEPEND="${PDEPEND} ${E_PDEPEND}"
+		TDEPEND="${TDEPEND} ${E_TDEPEND}"
 		REQUIRED_USE="${REQUIRED_USE} ${E_REQUIRED_USE}"
 		
-		unset ECLASS E_IUSE E_REQUIRED_USE E_DEPEND E_RDEPEND E_PDEPEND 
+		unset ECLASS E_IUSE E_REQUIRED_USE E_DEPEND E_RDEPEND E_PDEPEND E_TDEPEND
 
 		# alphabetically ordered by $EBUILD_PHASE value
 		case "$EAPI" in
@@ -2159,13 +2166,14 @@ ebuild_main() {
 
 		auxdbkeys="DEPEND RDEPEND SLOT SRC_URI RESTRICT HOMEPAGE LICENSE
 			DESCRIPTION KEYWORDS INHERITED IUSE REQUIRED_USE PDEPEND PROVIDE EAPI
-			PROPERTIES DEFINED_PHASES UNUSED_05 UNUSED_04
+			PROPERTIES DEFINED_PHASES TDEPEND UNUSED_04
 			UNUSED_03 UNUSED_02 UNUSED_01"
 
 		#the extra $(echo) commands remove newlines
 		[ -n "${EAPI}" ] || EAPI=0
 		case "$EAPI" in
 			0|1|2|3)
+				unset TDEPEND
 				unset REQUIRED_USE
 				;;
 		esac
diff --git a/doc/package/ebuild/eapi/4.docbook b/doc/package/ebuild/eapi/4.docbook
index 8d7942b..ad40de3 100644
--- a/doc/package/ebuild/eapi/4.docbook
+++ b/doc/package/ebuild/eapi/4.docbook
@@ -17,6 +17,50 @@ The dodoc helper now has a -r option which enables recursion.
 </section>
 <section id='package-ebuild-eapi-4_pre1-metadata'>
 <title>Metadata</title>
+<section id='package-ebuild-eapi-4_pre1-metadata-dependencies'>
+<title>Dependencies</title>
+<section id='package-ebuild-eapi-4_pre1-metadata-dependencies-tdepend'>
+<title>TDEPEND</title>
+<para>
+In EAPI 4 or later, DEPEND has been divided into two parts:
+DEPEND for build-time host dependencies, and TDEPEND for
+build-time target dependencies.
+<table><title>Build-Time Dependencies</title>
+<tgroup cols='2' align='left' >
+<colspec colname='variable'/>
+<colspec colname='description'/>
+<thead>
+<row>
+<entry>Variable</entry>
+<entry>Description</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry>DEPEND</entry>
+<entry>build-time host dependencies</entry>
+</row>
+<row>
+<entry>TDEPEND</entry>
+<entry>build-time target dependencies</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+This division is designed
+specifically to minimize difficulty in the process of
+adapting ebuilds that were written for earlier EAPIs,
+and therefore it also minimizes the adjustments that
+ebuild developers will have to make to the thought
+processes involved when writing ebuilds from scratch. In
+an environment that does not involve cross-compilation,
+TDEPEND behaves the same as DEPEND. When an ebuild is
+converted from EAPI 3 or earlier to EAPI 4 or later,
+in order to support cross-compilation environments, some
+dependencies may need to be migrated to TDEPEND.
+</para>
+</section>
+</section>
 <section id='package-ebuild-eapi-4_pre1-metadata-required-use'>
 <title>REQUIRED_USE</title>
 <para>
diff --git a/man/ebuild.5 b/man/ebuild.5
index 1fcc383..cfe7dae 100644
--- a/man/ebuild.5
+++ b/man/ebuild.5
@@ -415,6 +415,24 @@ will use that to consider the dependency satisfied.
 
 .RE
 .TP
+\fBTDEPEND\fR
+In EAPI 4 or later, \fBDEPEND\fR has been divided into two parts:
+\fBDEPEND\fR for build-time host dependencies, and
+\fBTDEPEND\fR for build-time target dependencies.
+This division is designed
+specifically to minimize difficulty in the process of
+adapting ebuilds that were written for earlier \fBEAPI\fRs, and
+therefore it also minimizes the adjustments that ebuild
+developers will have to make to the thought processes
+involved when writing ebuilds from scratch. In an
+environment that does not involve cross-compilation,
+\fBTDEPEND\fR behaves the same as \fBDEPEND\fR. When an ebuild is
+converted from \fBEAPI 3\fR or earlier to \fBEAPI 4\fR or later,
+in order to support cross-compilation environments, some
+dependencies may need to be migrated to \fBTDEPEND\fR.
+.br
+You may use the same syntax to vary dependencies as seen above in \fBDEPEND\fR.
+.TP
 \fBRDEPEND\fR
 This should contain a list of all packages that are required for this
 program to run (aka runtime depend). If this is not set in \fBEAPI\fR
diff --git a/man/emerge.1 b/man/emerge.1
index 73c90d3..82e0098 100644
--- a/man/emerge.1
+++ b/man/emerge.1
@@ -548,10 +548,17 @@ If no argument is given then build\-time dependencies of packages for
 \fBROOT\fR instead of /. If the \fBrdeps\fR argument is given then discard
 all build\-time dependencies of packages for \fBROOT\fR. This option is
 only meaningful when used together with \fBROOT\fR and it should not
-be enabled under normal circumstances. For currently supported
-\fBEAPI\fR values, the build-time dependencies are specified in the
-\fBDEPEND\fR variable. However, behavior may change for new
-\fBEAPI\fRs when related extensions are added in the future.
+be enabled under normal circumstances. For ebuilds that have \fBEAPI\fR
+3 or earlier, the build\-time dependencies are specified in the
+\fBDEPEND\fR variable. For ebuilds that have \fBEAPI 4\fR or later,
+the emerge \-\-root\-deps option has no effect
+since it is made obsolete by division
+between \fBDEPEND\fR and \fBTDEPEND\fR. If \fBEAPI 3\fR or
+earlier ebuilds are used in combination with
+\fBEAPI 4\fR or later ebuilds, the \-\-root\-deps
+behavior will still be applied to the \fBEAPI
+3\fR or earlier ebuilds (there is no behavior
+change for ebuilds having older \fBEAPI\fRs).
 .TP
 .BR "\-\-select"[=n]
 Add specified packages to the world set (inverse of
diff --git a/pym/_emerge/Package.py b/pym/_emerge/Package.py
index 992851b..d06ae45 100644
--- a/pym/_emerge/Package.py
+++ b/pym/_emerge/Package.py
@@ -31,7 +31,7 @@ class Package(Task):
 		"INHERITED", "IUSE", "KEYWORDS",
 		"LICENSE", "PDEPEND", "PROVIDE", "RDEPEND",
 		"repository", "PROPERTIES", "RESTRICT", "SLOT", "USE",
-		"_mtime_", "DEFINED_PHASES", "REQUIRED_USE"]
+		"_mtime_", "DEFINED_PHASES", "REQUIRED_USE", "TDEPEND"]
 
 	def __init__(self, **kwargs):
 		Task.__init__(self, **kwargs)
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
index c660728..0df8b00 100644
--- a/pym/_emerge/depgraph.py
+++ b/pym/_emerge/depgraph.py
@@ -1137,7 +1137,7 @@ class depgraph(object):
 		removal_action = "remove" in self._dynamic_config.myparams
 
 		edepend={}
-		depkeys = ["DEPEND","RDEPEND","PDEPEND"]
+		depkeys = ["DEPEND","RDEPEND","PDEPEND","TDEPEND"]
 		for k in depkeys:
 			edepend[k] = metadata[k]
 
@@ -1147,7 +1147,6 @@ class depgraph(object):
 			"empty" not in self._dynamic_config.myparams:
 			edepend["RDEPEND"] = ""
 			edepend["PDEPEND"] = ""
-		bdeps_optional = False
 
 		if pkg.built and not removal_action:
 			if self._frozen_config.myopts.get("--with-bdeps", "n") == "y":
@@ -1158,29 +1157,41 @@ class depgraph(object):
 				# could make --with-bdeps=y less effective if it is used to
 				# adjust merge order to prevent built_with_use() calls from
 				# failing.
-				bdeps_optional = True
+				pass
 			else:
 				# built packages do not have build time dependencies.
 				edepend["DEPEND"] = ""
+				edepend["TDEPEND"] = ""
 
 		if removal_action and self._frozen_config.myopts.get("--with-bdeps", "y") == "n":
 			edepend["DEPEND"] = ""
+			edepend["TDEPEND"] = ""
 
 		if removal_action:
-			bdeps_root = myroot
+			depend_root = myroot
 		else:
-			bdeps_root = "/"
-			root_deps = self._frozen_config.myopts.get("--root-deps")
-			if root_deps is not None:
-				if root_deps is True:
-					bdeps_root = myroot
-				elif root_deps == "rdeps":
-					edepend["DEPEND"] = ""
+			depend_root = "/"
+			if pkg.metadata['EAPI'] in ('0', '1', '2', '3'):
+				# For ebuilds that have EAPI 4 or later, --root-deps
+				# has no effect, since DEPEND has been divided into two parts:
+				# DEPEND for build-time host dependencies, and TDEPEND for
+				# build-time target dependencies.
+
+				root_deps = self._frozen_config.myopts.get("--root-deps")
+				if root_deps is not None:
+					if root_deps is True:
+						depend_root = myroot
+					elif root_deps == "rdeps":
+						edepend["DEPEND"] = ""
 
 		deps = (
-			(bdeps_root, edepend["DEPEND"],
-				self._priority(buildtime=(not bdeps_optional),
-				optional=bdeps_optional),
+			(depend_root, edepend["DEPEND"],
+				self._priority(buildtime=(not pkg.built),
+				optional=pkg.built),
+				pkg.built),
+			(myroot, edepend["TDEPEND"],
+				self._priority(buildtime=(not pkg.built),
+				optional=pkg.built),
 				pkg.built),
 			(myroot, edepend["RDEPEND"],
 				self._priority(runtime=True),
diff --git a/pym/_emerge/help.py b/pym/_emerge/help.py
index 72bb56d..1c619af 100644
--- a/pym/_emerge/help.py
+++ b/pym/_emerge/help.py
@@ -601,10 +601,17 @@ def help(myopts, havecolor=1):
 			"ROOT instead of /. If the rdeps argument is given then discard " + \
 			"all build-time dependencies of packages for ROOT. This option is " + \
 			"only meaningful when used together with ROOT and it should not " + \
-			"be enabled under normal circumstances. For currently supported " + \
-			"EAPI values, the build-time dependencies are specified in the " + \
-			"DEPEND variable. However, behavior may change for new " + \
-			"EAPIs when related extensions are added in the future."
+			"be enabled under normal circumstances. For ebuilds that have EAPI " + \
+			"3 or earlier, the build-time dependencies are specified in the " + \
+			"DEPEND variable. For ebuilds that have EAPI 4 or later, " + \
+			"the emerge --root-deps option has no effect " + \
+			"since it is made obsolete by division " + \
+			"between DEPEND and TDEPEND. If EAPI 3 or " + \
+			"earlier ebuilds are used in combination with " + \
+			"EAPI 4 or later ebuilds, the --root-deps " + \
+			"behavior will still be applied to the EAPI " + \
+			"3 or earlier ebuilds (there is no behavior " + \
+			"change for ebuilds having older EAPIs)."
 		for line in wrap(desc, desc_width):
 			print(desc_indent + line)
 		print()
diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py
index cb84218..b55ff96 100644
--- a/pym/portage/__init__.py
+++ b/pym/portage/__init__.py
@@ -418,7 +418,7 @@ def abssymlink(symlink):
 
 _doebuild_manifest_exempt_depend = 0
 
-_testing_eapis = frozenset()
+_testing_eapis = frozenset(['4_pre0_tdepend',])
 _deprecated_eapis = frozenset(["3_pre2", "3_pre1", "2_pre3", "2_pre2", "2_pre1"])
 
 def _eapi_is_deprecated(eapi):
@@ -480,7 +480,7 @@ auxdbkeys = (
 	'RESTRICT',  'HOMEPAGE',  'LICENSE',   'DESCRIPTION',
 	'KEYWORDS',  'INHERITED', 'IUSE', 'REQUIRED_USE',
 	'PDEPEND',   'PROVIDE', 'EAPI',
-	'PROPERTIES', 'DEFINED_PHASES', 'UNUSED_05', 'UNUSED_04',
+	'PROPERTIES', 'DEFINED_PHASES', 'TDEPEND', 'UNUSED_04',
 	'UNUSED_03', 'UNUSED_02', 'UNUSED_01',
 )
 auxdbkeylen=len(auxdbkeys)
diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py
index d840316..f11ce25 100644
--- a/pym/portage/dbapi/bintree.py
+++ b/pym/portage/dbapi/bintree.py
@@ -55,7 +55,7 @@ class bindbapi(fakedbapi):
 			["BUILD_TIME", "CHOST", "DEPEND", "EAPI", "IUSE", "KEYWORDS",
 			"LICENSE", "PDEPEND", "PROPERTIES", "PROVIDE",
 			"RDEPEND", "repository", "RESTRICT", "SLOT", "USE", "DEFINED_PHASES",
-			"REQUIRED_USE"])
+			"REQUIRED_USE", "TDEPEND"])
 		self._aux_cache_slot_dict = slot_dict_class(self._aux_cache_keys)
 		self._aux_cache = {}
 
@@ -226,7 +226,7 @@ class binarytree(object):
 				["BUILD_TIME", "CHOST", "DEPEND", "DESCRIPTION", "EAPI",
 				"IUSE", "KEYWORDS", "LICENSE", "PDEPEND", "PROPERTIES",
 				"PROVIDE", "RDEPEND", "repository", "SLOT", "USE", "DEFINED_PHASES",
-				"REQUIRED_USE"]
+				"REQUIRED_USE", "TDEPEND"]
 			self._pkgindex_aux_keys = list(self._pkgindex_aux_keys)
 			self._pkgindex_use_evaluated_keys = \
 				("LICENSE", "RDEPEND", "DEPEND",
@@ -252,7 +252,8 @@ class binarytree(object):
 				"SLOT"    : "0",
 				"USE"     : "",
 				"DEFINED_PHASES" : "",
-				"REQUIRED_USE" : ""
+				"REQUIRED_USE" : "",
+				"TDEPEND"        : "",
 			}
 			self._pkgindex_inherited_keys = ["CHOST", "repository"]
 			self._pkgindex_default_header_data = {
diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py
index 4b266b4..21edc57 100644
--- a/pym/portage/dbapi/porttree.py
+++ b/pym/portage/dbapi/porttree.py
@@ -319,7 +319,7 @@ class portdbapi(dbapi):
 		self._aux_cache_keys = set(
 			["DEPEND", "EAPI", "INHERITED", "IUSE", "KEYWORDS", "LICENSE",
 			"PDEPEND", "PROPERTIES", "PROVIDE", "RDEPEND", "repository",
-			"RESTRICT", "SLOT", "DEFINED_PHASES", "REQUIRED_USE"])
+			"RESTRICT", "SLOT", "DEFINED_PHASES", "REQUIRED_USE", "TDEPEND"])
 
 		self._aux_cache = {}
 		self._broken_ebuilds = set()
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 6f587f7..d84b75c 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -850,7 +850,7 @@ class vardbapi(dbapi):
 			"EAPI", "HOMEPAGE", "IUSE", "KEYWORDS",
 			"LICENSE", "PDEPEND", "PROPERTIES", "PROVIDE", "RDEPEND",
 			"repository", "RESTRICT" , "SLOT", "USE", "DEFINED_PHASES",
-			"REQUIRED_USE"])
+			"REQUIRED_USE", "TDEPEND"])
 		self._aux_cache_obj = None
 		self._aux_cache_filename = os.path.join(self.root,
 			CACHE_PATH, "vdb_metadata.pickle")
-- 
1.7.1.1

