From a407ad2f27231944f3b3d75020a601fa521b07bd Mon Sep 17 00:00:00 2001
From: Zac Medico <zmedico@gentoo.org>
Date: Thu, 12 Aug 2010 20:02:47 -0700
Subject: [PATCH] In EAPI 4, add HDEPEND variable for build-time host dependencies.

In EAPI 4 or later, DEPEND has been divided into two parts:
DEPEND for build-time target dependencies, and HDEPEND for
build-time host 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,
HDEPEND 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 HDEPEND.

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 HDEPEND. 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                     |   28 ++++++++++++++++------
 doc/package/ebuild/eapi/4.docbook |   44 +++++++++++++++++++++++++++++++++++++
 man/ebuild.5                      |   18 +++++++++++++++
 man/emerge.1                      |   15 +++++++++---
 pym/_emerge/Package.py            |    2 +-
 pym/_emerge/depgraph.py           |   40 +++++++++++++++++++++-----------
 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, 139 insertions(+), 38 deletions(-)

diff --git a/bin/ebuild.sh b/bin/ebuild.sh
index f9bfb34..55c51ce 100755
--- a/bin/ebuild.sh
+++ b/bin/ebuild.sh
@@ -1284,6 +1284,7 @@ inherit() {
 	local B_DEPEND
 	local B_RDEPEND
 	local B_PDEPEND
+	local B_HDEPEND
 	while [ "$1" ]; do
 		location="${ECLASSDIR}/${1}.eclass"
 		olocation=""
@@ -1322,20 +1323,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_HDEPEND
 		[ "${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
+		[ "${HDEPEND+set}"    = set ] && B_HDEPEND="${HDEPEND}"
+		unset IUSE REQUIRED_USE DEPEND RDEPEND PDEPEND HDEPEND
 		#turn on glob expansion
 		set +f
 
@@ -1351,6 +1353,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}"
+		[ "${HDEPEND+set}"    = set ] && export E_HDEPEND="${E_HDEPEND} ${HDEPEND}"
 
 		[ "${B_IUSE+set}"     = set ] && IUSE="${B_IUSE}"
 		[ "${B_IUSE+set}"     = set ] || unset IUSE
@@ -1367,6 +1370,9 @@ inherit() {
 		[ "${B_PDEPEND+set}"  = set ] && PDEPEND="${B_PDEPEND}"
 		[ "${B_PDEPEND+set}"  = set ] || unset PDEPEND
 
+		[ "${B_HDEPEND+set}"  = set ] && HDEPEND="${B_HDEPEND}"
+		[ "${B_HDEPEND+set}"  = set ] || unset HDEPEND
+
 		#turn on glob expansion
 		set +f
 
@@ -1626,7 +1632,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 HDEPEND HOMEPAGE INHERITED IUSE REQUIRED_USE KEYWORDS LICENSE
 	PDEPEND PROVIDE RDEPEND RESTRICT SLOT SRC_URI"
 
 READONLY_PORTAGE_VARS="D EBUILD EBUILD_PHASE \
@@ -1800,7 +1806,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_HDEPEND
 
 # Turn of extended glob matching so that g++ doesn't get incorrectly matched.
 shopt -u extglob
@@ -1904,7 +1910,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 HDEPEND IUSE REQUIRED_USE
 
 		if [[ $PORTAGE_DEBUG != 1 || ${-/x/} != $- ]] ; then
 			source "$EBUILD" || die "error sourcing ebuild"
@@ -1932,9 +1938,10 @@ if ! hasq "$EBUILD_PHASE" clean cleanrm ; then
 		DEPEND="${DEPEND} ${E_DEPEND}"
 		RDEPEND="${RDEPEND} ${E_RDEPEND}"
 		PDEPEND="${PDEPEND} ${E_PDEPEND}"
+		HDEPEND="${HDEPEND} ${E_HDEPEND}"
 		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_HDEPEND
 
 		# alphabetically ordered by $EBUILD_PHASE value
 		case "$EAPI" in
@@ -2179,11 +2186,16 @@ 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 HDEPEND 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 HDEPEND
+				;;
+		esac
 
 		if [ -n "${dbkey}" ] ; then
 			> "${dbkey}"
diff --git a/doc/package/ebuild/eapi/4.docbook b/doc/package/ebuild/eapi/4.docbook
index 8d7942b..e0eab47 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>HDEPEND</title>
+<para>
+In EAPI 4 or later, DEPEND has been divided into two parts:
+DEPEND for build-time target dependencies, and HDEPEND for
+build-time host 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 target dependencies</entry>
+</row>
+<row>
+<entry>HDEPEND</entry>
+<entry>build-time host 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,
+HDEPEND 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 HDEPEND.
+</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..dbd2123 100644
--- a/man/ebuild.5
+++ b/man/ebuild.5
@@ -415,6 +415,24 @@ will use that to consider the dependency satisfied.
 
 .RE
 .TP
+\fBHDEPEND\fR
+In EAPI 4 or later, \fBDEPEND\fR has been divided into two parts:
+\fBDEPEND\fR for build-time target dependencies, and
+\fBHDEPEND\fR for build-time host 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,
+\fBHDEPEND\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 \fBHDEPEND\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..8fa5462 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 \fBHDEPEND\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 90a5d03..60c22d7 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", "HDEPEND"]
 
 	def __init__(self, **kwargs):
 		Task.__init__(self, **kwargs)
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
index 56ea1bd..a508007 100644
--- a/pym/_emerge/depgraph.py
+++ b/pym/_emerge/depgraph.py
@@ -967,7 +967,7 @@ class depgraph(object):
 		removal_action = "remove" in self._dynamic_config.myparams
 
 		edepend={}
-		depkeys = ["DEPEND","RDEPEND","PDEPEND"]
+		depkeys = ["DEPEND","RDEPEND","PDEPEND","HDEPEND"]
 		for k in depkeys:
 			edepend[k] = metadata[k]
 
@@ -977,7 +977,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":
@@ -988,29 +987,42 @@ 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["HDEPEND"] = ""
 
 		if removal_action and self._frozen_config.myopts.get("--with-bdeps", "y") == "n":
 			edepend["DEPEND"] = ""
+			edepend["HDEPEND"] = ""
 
 		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"] = ""
+			if pkg.metadata['EAPI'] not 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 target dependencies, and HDEPEND for
+				# build-time host dependencies.
+				depend_root = myroot
+			else:
+				depend_root = "/"
+				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),
+			("/", edepend["HDEPEND"],
+				self._priority(buildtime=(not pkg.built),
+				optional=pkg.built),
+				pkg.built),
+			(depend_root, edepend["DEPEND"],
+				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..c9368ae 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 HDEPEND. 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 a6760b2..0e62de7 100644
--- a/pym/portage/__init__.py
+++ b/pym/portage/__init__.py
@@ -419,7 +419,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):
@@ -481,7 +481,7 @@ auxdbkeys = (
 	'RESTRICT',  'HOMEPAGE',  'LICENSE',   'DESCRIPTION',
 	'KEYWORDS',  'INHERITED', 'IUSE', 'REQUIRED_USE',
 	'PDEPEND',   'PROVIDE', 'EAPI',
-	'PROPERTIES', 'DEFINED_PHASES', 'UNUSED_05', 'UNUSED_04',
+	'PROPERTIES', 'DEFINED_PHASES', 'HDEPEND', '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..a22cac4 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", "HDEPEND"])
 		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", "HDEPEND"]
 			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" : "",
+				"HDEPEND"        : "",
 			}
 			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..b6c1ef8 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", "HDEPEND"])
 
 		self._aux_cache = {}
 		self._broken_ebuilds = set()
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 6f587f7..7cd685b 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", "HDEPEND"])
 		self._aux_cache_obj = None
 		self._aux_cache_filename = os.path.join(self.root,
 			CACHE_PATH, "vdb_metadata.pickle")
-- 
1.7.1.1

